diff --git a/Applications/Applications.cmake b/Applications/Applications.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..25c8fe2c2d4f3f78ea1dd4a2b3e6fb33020057a1
--- /dev/null
+++ b/Applications/Applications.cmake
@@ -0,0 +1,2 @@
+add_subdirectory(Applications/LidDrivenCavity)
+
diff --git a/Applications/IncludsList.cmake b/Applications/IncludsList.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ce0e9fb545bd648d459f5a1868bd3c748fceeaa3
--- /dev/null
+++ b/Applications/IncludsList.cmake
@@ -0,0 +1,3 @@
+INCLUDE_DIRECTORIES(${APPS_ROOT})
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/IncludsList.cmake)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/IncludsList.cmake) 
diff --git a/Applications/LidDrivenCavity/CMakeLists.txt b/Applications/LidDrivenCavity/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2c2df66d397b6277bc0c73c6970222ae49578d55
--- /dev/null
+++ b/Applications/LidDrivenCavity/CMakeLists.txt
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+########################################################
+## C++ PROJECT                                       ###
+########################################################
+PROJECT(LidDrivenCavity)
+
+INCLUDE(${APPS_ROOT}/IncludsList.cmake) 
+
+#################################################################
+###   LOCAL FILES                                             ###
+#################################################################
+FILE(GLOB SPECIFIC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+                         ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp  )
+ 
+SET(ALL_SOURCES ${ALL_SOURCES} ${SPECIFIC_FILES})
+SOURCE_GROUP(src FILES ${SPECIFIC_FILES})
+  
+SET(CAB_ADDITIONAL_LINK_LIBRARIES VirtualFluids)
+
+#################################################################
+###   CREATE PROJECT                                          ###
+#################################################################
+CREATE_CAB_PROJECT(LidDrivenCavity BINARY)
diff --git a/Applications/LidDrivenCavity/LidDrivenCavity.cpp b/Applications/LidDrivenCavity/LidDrivenCavity.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..21d3f7bb70fc2c717b39ffb8bc37da0dad14782c
--- /dev/null
+++ b/Applications/LidDrivenCavity/LidDrivenCavity.cpp
@@ -0,0 +1,244 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LidDrivenCavity.cpp
+//! \ingroup Applications
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include <string>
+
+#include "VirtualFluids.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+   try
+   {
+      //////////////////////////////////////////////////////////////////////////
+      // Simulation parameters
+      //////////////////////////////////////////////////////////////////////////
+
+      // set your output path here
+      string path = "./output";
+
+      const double L = 1.0;
+      const double Re = 1000.0;
+      const double velocity = 1.0;
+      const double dt = 0.5e-3;
+      const unsigned int nx = 64;
+
+      const double timeStepOut = 1000;
+      const double timeStepEnd = 25000;
+
+      // Number of OpenMP threads
+      int numOfThreads = 4;
+
+      //////////////////////////////////////////////////////////////////////////
+
+      double dx = L / double(nx);
+      const double velocityLB = velocity * dt / dx; // LB units
+      const double u = velocityLB / sqrt(2.0); // LB units
+      const double viscosityLB = nx * velocityLB / Re; // LB unit
+
+      //////////////////////////////////////////////////////////////////////////
+      // create grid
+      //////////////////////////////////////////////////////////////////////////
+      // bounding box
+      double g_minX1 = -0.5;
+      double g_minX2 = -0.5;
+      double g_minX3 = -0.5;
+
+      double g_maxX1 = 0.5;
+      double g_maxX2 = 0.5;
+      double g_maxX3 = 0.5;
+
+      // NullCommunicator is a place-holder for interprocess communication
+      SPtr<Communicator> comm = NullCommunicator::getInstance();
+      // new grid object
+      SPtr<Grid3D> grid(new Grid3D(comm));
+      // set grid spacing
+      grid->setDeltaX(dx);
+      // set block size for three dimensions
+      int blockSize = nx / 2;
+      grid->setBlockNX(blockSize,blockSize,blockSize);
+      
+      // Create simulation bounding box
+      SPtr<GbObject3D> gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
+      GbSystem3D::writeGeoObject(gridCube.get(), path + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+      UBLOG(logINFO, "Lid Driven Cavity:");
+      UBLOG(logINFO, "Domain size = " << nx << " x "<< nx << " x "<< nx);
+      UBLOG(logINFO, "Block size = " << blockSize << " x "<< blockSize << " x "<< blockSize);
+      UBLOG(logINFO, "velocity    = " << velocity << " m/s");
+      UBLOG(logINFO, "velocityLB  = " << velocityLB);
+      UBLOG(logINFO, "viscosityLB = " << viscosityLB);
+      UBLOG(logINFO, "u  = " << u);
+      UBLOG(logINFO, "Re = " << Re);
+      UBLOG(logINFO, "dx = " << dx);
+      UBLOG(logINFO, "dt = " << dt);
+      UBLOG(logINFO, "Preprocess - start");
+
+      // Generate block grid
+      GenBlocksGridVisitor genBlocks(gridCube);
+      grid->accept(genBlocks);
+
+      // Write block grid to VTK-file
+      SPtr<CoProcessor> ppblocks(new WriteBlocksCoProcessor(grid, SPtr<UbScheduler>(new UbScheduler(1)), path, WbWriterVtkXmlBinary::getInstance(), comm));
+      ppblocks->process(0);
+      ppblocks.reset();
+
+      // Create LBM kernel
+      SPtr<LBMKernel> kernel = SPtr<LBMKernel>(new CumulantK17LBMKernel());
+
+      //////////////////////////////////////////////////////////////////////////
+      // Create boundary conditions (BC)
+      //////////////////////////////////////////////////////////////////////////     
+      // Create no-slip BC
+      SPtr<BCAdapter> noSlipBCAdapter(new NoSlipBCAdapter());
+      noSlipBCAdapter->setBcAlgorithm(SPtr<BCAlgorithm>(new NoSlipBCAlgorithm()));
+      
+      // Velocity BC
+      mu::Parser fct;
+      fct.SetExpr("u");
+      fct.DefineConst("u", u);
+      // Set the same velocity in x and y-direction
+      SPtr<BCAdapter> velBCAdapter(new VelocityBCAdapter(true, true, false, fct, 0, BCFunction::INFCONST));
+      velBCAdapter->setBcAlgorithm(SPtr<BCAlgorithm>(new VelocityBCAlgorithm()));
+
+      // Add velocity boundary condition to visitor. No-slip boundary   
+      BoundaryConditionsBlockVisitor bcVisitor;
+      bcVisitor.addBC(velBCAdapter);
+
+      // Create boundary conditions processor
+      SPtr<BCProcessor> bcProc;
+      bcProc = SPtr<BCProcessor>(new BCProcessor());
+      kernel->setBCProcessor(bcProc);
+
+      // Create boundary conditions geometry
+      GbCuboid3DPtr wallXmin(new GbCuboid3D(g_minX1 - dx, g_minX2 - dx, g_minX3 - dx, g_minX1, g_maxX2 + dx, g_maxX3));
+      GbSystem3D::writeGeoObject(wallXmin.get(), path + "/geo/wallXmin", WbWriterVtkXmlASCII::getInstance());
+      GbCuboid3DPtr wallXmax(new GbCuboid3D(g_maxX1, g_minX2 - dx, g_minX3 - dx, g_maxX1 + dx, g_maxX2 + dx, g_maxX3));
+      GbSystem3D::writeGeoObject(wallXmax.get(), path + "/geo/wallXmax", WbWriterVtkXmlASCII::getInstance());
+      GbCuboid3DPtr wallYmin(new GbCuboid3D(g_minX1 - dx, g_minX2 - dx, g_minX3 - dx, g_maxX1 + dx, g_minX2, g_maxX3));
+      GbSystem3D::writeGeoObject(wallYmin.get(), path + "/geo/wallYmin", WbWriterVtkXmlASCII::getInstance());
+      GbCuboid3DPtr wallYmax(new GbCuboid3D(g_minX1 - dx, g_maxX2, g_minX3 - dx, g_maxX1 + dx, g_maxX2 + dx, g_maxX3));
+      GbSystem3D::writeGeoObject(wallYmax.get(), path + "/geo/wallYmax", WbWriterVtkXmlASCII::getInstance());
+      GbCuboid3DPtr wallZmin(new GbCuboid3D(g_minX1 - dx, g_minX2 - dx, g_minX3 - dx, g_maxX1 + dx, g_maxX2 + dx, g_minX3));
+      GbSystem3D::writeGeoObject(wallZmin.get(), path + "/geo/wallZmin", WbWriterVtkXmlASCII::getInstance());
+      GbCuboid3DPtr wallZmax(new GbCuboid3D(g_minX1 - dx, g_minX2 - dx, g_maxX3, g_maxX1 + dx, g_maxX2 + dx, g_maxX3 + dx));
+      GbSystem3D::writeGeoObject(wallZmax.get(), path + "/geo/wallZmax", WbWriterVtkXmlASCII::getInstance());
+
+      // Add boundary conditions to grid generator
+      SPtr<D3Q27Interactor> wallXminInt(new D3Q27Interactor(wallXmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+      SPtr<D3Q27Interactor> wallXmaxInt(new D3Q27Interactor(wallXmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
+      SPtr<D3Q27Interactor> wallYminInt(new D3Q27Interactor(wallYmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+      SPtr<D3Q27Interactor> wallYmaxInt(new D3Q27Interactor(wallYmax, grid, noSlipBCAdapter, Interactor3D::SOLID));
+      SPtr<D3Q27Interactor> wallZminInt(new D3Q27Interactor(wallZmin, grid, noSlipBCAdapter, Interactor3D::SOLID));
+      SPtr<D3Q27Interactor> wallZmaxInt(new D3Q27Interactor(wallZmax, grid, velBCAdapter, Interactor3D::SOLID));
+
+      InteractorsHelper intHelper(grid);
+      intHelper.addInteractor(wallZmaxInt);
+      intHelper.addInteractor(wallXminInt);
+      intHelper.addInteractor(wallXmaxInt);
+      intHelper.addInteractor(wallZminInt);
+      intHelper.addInteractor(wallYminInt);
+      intHelper.addInteractor(wallYmaxInt);
+
+      intHelper.selectBlocks();
+
+      // Generate grid
+      SetKernelBlockVisitor kernelVisitor(kernel, viscosityLB);
+      grid->accept(kernelVisitor);
+
+      intHelper.setBC();
+
+      // Initialization of distributions
+      InitDistributionsBlockVisitor initVisitor;
+      grid->accept(initVisitor);
+
+      // Set connectivity between blocks
+      SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, viscosityLB);
+      grid->accept(setConnsVisitor);
+
+      // Create lists of boundary nodes
+      grid->accept(bcVisitor);
+
+      // Write grid with boundary conditions information to VTK-file
+      SPtr<UbScheduler> geoSch(new UbScheduler(1));
+      WriteBoundaryConditionsCoProcessor ppgeo(grid, geoSch, path, WbWriterVtkXmlBinary::getInstance(), comm);
+      ppgeo.process(0);
+
+      UBLOG(logINFO, "Preprocess - end");
+      
+      UBLOG(logINFO, "Total Physical Memory (RAM): " << Utilities::getTotalPhysMem()/1e9 << " GB");
+      UBLOG(logINFO, "Physical Memory currently used: " << Utilities::getPhysMemUsed()/1e9 << " GB");
+      UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe()/1e9 << " GB");
+
+      // Create coprocessor object for writing macroscopic quantities to VTK-file
+      SPtr<UbScheduler> visSch(new UbScheduler(timeStepOut));
+      SPtr<CoProcessor> mqCoProcessor(new WriteMacroscopicQuantitiesCoProcessor(grid, visSch, path, WbWriterVtkXmlBinary::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter(L, velocity, 1.0, nx, velocityLB)), comm));
+      mqCoProcessor->process(0);
+
+      // Create coprocessor object for writing NUPS
+      SPtr<UbScheduler> nupsSch(new UbScheduler(100, 100));
+      SPtr<CoProcessor> nupsCoProcessor(new NUPSCounterCoProcessor(grid, nupsSch, numOfThreads, comm));
+
+      // OpenMP threads control
+#ifdef _OPENMP
+      omp_set_num_threads(numOfThreads);
+#endif
+      // Create simulation
+      SPtr<Calculator> calculator(new BasicCalculator(grid, visSch, (int)timeStepEnd));
+      // Add coprocessors objects to simulation
+      calculator->addCoProcessor(nupsCoProcessor);
+      calculator->addCoProcessor(mqCoProcessor);
+    
+      //////////////////////////////////////////////////////////////////////////
+      // Run simulation
+      //////////////////////////////////////////////////////////////////////////
+
+      UBLOG(logINFO, "Simulation-start");
+      calculator->calculate();
+      UBLOG(logINFO, "Simulation-end");
+   }
+   catch (std::exception& e)
+   {
+      cerr << e.what() << endl << flush;
+   }
+   catch (std::string& s)
+   {
+      cerr << s << endl;
+   }
+   catch (...)
+   {
+      cerr << "unknown exception" << endl;
+   }
+}
+
diff --git a/Applications/VirtualFluids.h b/Applications/VirtualFluids.h
new file mode 100644
index 0000000000000000000000000000000000000000..1553cebbe6b905d7358636224e7e815f575ac314
--- /dev/null
+++ b/Applications/VirtualFluids.h
@@ -0,0 +1,142 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file VirtualFluids.h
+//! \ingroup Applications
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef VirtualFluids_h__
+#define VirtualFluids_h__
+
+//VirtualFluids header files
+ 
+#ifdef _OPENMP
+#include <omp.h>
+#endif 
+
+#include <PointerDefinitions.h>
+
+#include <MuParser/include/muParser.h>
+
+#include <basics/container/CbArray2D.h>
+#include <basics/container/CbArray3D.h>
+#include <basics/container/CbArray4D.h>
+#include <basics/container/CbVector.h>
+
+#include <basics/objects/ObObject.h>
+
+#include <basics/utilities/UbComparators.h>
+#include <basics/utilities/UbEqual.h>
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbInfinity.h>
+#include <basics/utilities/UbKeys.h>
+#include <basics/utilities/UbLimits.h>
+#include <basics/utilities/UbLogger.h>
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbObservable.h>
+#include <basics/utilities/UbObserver.h>
+#include <basics/utilities/UbScheduler.h>
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbTiming.h>
+#include <basics/utilities/UbTuple.h>
+
+#include <basics/writer/WbWriter.h>
+#include <basics/writer/WbWriterVtkXmlASCII.h>
+#include <basics/writer/WbWriterVtkXmlBinary.h>
+
+#include <BoundaryConditions/BCArray3D.h>
+#include <BoundaryConditions/BCProcessor.h>
+#include <BoundaryConditions/BCAlgorithm.h>
+#include <BoundaryConditions/BCFunction.h>
+#include <BoundaryConditions/BoundaryConditions.h>
+#include <BoundaryConditions/BCAdapter.h>
+#include <BoundaryConditions/BCProcessor.h>
+#include <BoundaryConditions/NoSlipBCAdapter.h>
+#include <BoundaryConditions/VelocityBCAdapter.h>
+#include <BoundaryConditions/BCAlgorithm.h>
+#include <BoundaryConditions/VelocityBCAlgorithm.h>
+#include <BoundaryConditions/NoSlipBCAlgorithm.h>
+
+#include <Connectors/Block3DConnector.h>
+#include <Connectors/D3Q27ETFullDirectConnector.h>
+#include <Connectors/LocalBlock3DConnector.h>
+
+#include <Data/D3Q27EsoTwist3DSplittedVector.h>
+#include <Data/DataSet3D.h>
+#include <Data/DistributionArray3D.h>
+#include <Data/EsoTwist3D.h>
+#include <Data/EsoTwistD3Q27System.h>
+
+#include <Grid/Block3D.h>
+#include <Grid/Calculator.h>
+#include <Grid/BasicCalculator.h>
+#include <Grid/Grid3D.h>
+#include <Grid/Grid3DSystem.h>
+
+#include <Interactors/D3Q27Interactor.h>
+#include <Interactors/Interactor3D.h>
+#include <Interactors/InteractorsHelper.h>
+
+#include <CoProcessors/WriteBlocksCoProcessor.h>
+#include <CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h>
+#include <CoProcessors/WriteBoundaryConditionsCoProcessor.h>
+#include <CoProcessors/NUPSCounterCoProcessor.h>
+#include <CoProcessors/CoProcessor.h>
+
+#include <LBM/D3Q27System.h>
+#include <LBM/LBMKernel.h>
+#include <LBM/ILBMKernel.h>
+#include <LBM/CumulantK17LBMKernel.h>
+#include <LBM/LBMSystem.h>
+#include <LBM/LBMUnitConverter.h>
+
+#include <geometry3d/CoordinateTransformation3D.h>
+#include <geometry3d/GbCuboid3D.h>
+#include <geometry3d/GbLine3D.h>
+#include <geometry3d/GbObject3D.h>
+#include <geometry3d/GbPoint3D.h>
+#include <geometry3d/GbPolygon3D.h>
+#include <geometry3d/GbSystem3D.h>
+#include <geometry3d/GbTriangle3D.h>
+#include <geometry3d/GbVector3D.h>
+
+#include <Parallel/Communicator.h>
+#include <Parallel/NullCommunicator.h>
+
+#include <Utilities/MemoryUtil.h>
+
+#include <Visitors/Block3DVisitor.h>
+#include <Visitors/InitDistributionsBlockVisitor.h>
+#include <Visitors/SetConnectorsBlockVisitor.h>
+#include <Visitors/GenBlocksGridVisitor.h>
+#include <Visitors/Grid3DVisitor.h>
+#include <Visitors/SetKernelBlockVisitor.h>
+#include <Visitors/BoundaryConditionsBlockVisitor.h>
+
+#endif // VirtualFluids_h__
diff --git a/CMake/CMakeCABMacros.txt b/CMake/CMakeCABMacros.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d7a6601e94905869a7eacf6ffa369811b664e218
--- /dev/null
+++ b/CMake/CMakeCABMacros.txt
@@ -0,0 +1,317 @@
+###############################################################
+# Aktivieren von IF(ARG)...ELSE()...ENDIF() in CMake
+###############################################################
+SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 1)
+
+###############################################################################################################
+## Flags ruecksetzen
+###############################################################################################################
+SET(CAB_ADDTIONAL_COMPILER_FLAGS)
+#because of the fact that CMake does not support COMPILER_FLAGS_<CONFIG> right know we cannot use these options
+#SET(CAB_ADDTIONAL_COMPILER_FLAGS_DEBUG)
+#SET(CAB_ADDTIONAL_COMPILER_FLAGS_RELEASE)
+
+SET(CAB_ADDITIONAL_LINK_FLAGS)
+SET(CAB_ADDITIONAL_LINK_FLAGS_DEBUG)
+SET(CAB_ADDITIONAL_LINK_FLAGS_RELEASE)
+
+SET(CAB_ADDITIONAL_LINK_LIBRARIES)
+
+
+###############################################################
+# SOURCE_DIR variable wird beim einbinden automatisch gesetzt - ebenso das include dir!!!
+# SOURCE_DIR wird dem Projekt als Standardincludepfad hinzugefuegt
+###############################################################
+#CMakeCABMacros.txt liegt direkt im source-Ordner -> pfad == SOURCE_ROOT
+GET_FILENAME_COMPONENT( SOURCE_ROOT  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+STRING(REGEX REPLACE "(.*)/CMake" "\\1" SOURCE_ROOT "${SOURCE_ROOT}" )
+INCLUDE_DIRECTORIES(${SOURCE_ROOT})
+LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DSOURCE_ROOT=${SOURCE_ROOT} )
+
+###############################################################
+# hostename ermitteln -> CAB_MACHINE
+###############################################################
+IF(NOT CAB_MACHINE)
+   SET(CAB_MACHINE $ENV{CAB_MACHINE})
+
+   IF( CAB_MACHINE )
+     STRING(TOUPPER  "${CAB_MACHINE}" CAB_MACHINE)
+   ELSE()
+     EXECUTE_PROCESS( COMMAND hostname OUTPUT_VARIABLE CAB_MACHINE)
+     STRING(REGEX REPLACE "[ ]*([A-Za-z0-9]+).*[\\\\n]*" "\\1" CAB_MACHINE "${CAB_MACHINE}" )
+     STRING(TOUPPER  "${CAB_MACHINE}" CAB_MACHINE)
+   ENDIF()
+ENDIF()
+
+
+###############################################################
+# WITH_SUBFOLDERS_FOR_SG erstellen, wenn noch nicht vorhanden
+# ist diese auf true wird bei SOURCE_GROUP in VS unterordner erzeugt
+# dies funktioniert erst ab CMake-2.5 vernuenftig
+###############################################################
+IF(NOT WITH_SUBFOLDERS_FOR_SG)
+   SET(WITH_SUBFOLDERS_FOR_SG FALSE)
+ENDIF()
+
+
+############################################################################
+############################################################################
+##                  M      A      C      R      O      S                  ##
+##                  M      A      C      R      O      S                  ##
+##                  M      A      C      R      O      S                  ##
+############################################################################
+############################################################################
+# externe (ACHTUNG: die darin enthaltenen benoetigen teils noch macros die 
+# hier im Anschluss folgen
+INCLUDE("${SOURCE_ROOT}/CMake/CMakeSetCompilerFlags.txt")
+INCLUDE("${SOURCE_ROOT}/CMake/CMakeCompilerMacros.txt")
+
+################################################################
+###               ADD_TARGET_PROPERTIES                      ###
+################################################################
+MACRO(ADD_TARGET_PROPERTIES target property)
+
+   SET(property_values ${ARGN})
+   
+   # vorhandene properties holen
+   GET_TARGET_PROPERTY(TEMP_VAR ${target} ${property}) 
+   IF(TEMP_VAR)
+      LIST(APPEND property_values ${TEMP_VAR})     
+   ENDIF() 
+
+   #STRING(REGEX REPLACE ";" " " property_values ${property_values})
+   # doppelte Eintraege loeschen
+   SEPARATE_ARGUMENTS(property_values)
+   LIST(REMOVE_DUPLICATES property_values)
+
+   #aus Liste wieder einen String basteln (geht nich tmit regex replace...)
+   SET(new_property_values)
+   FOREACH(p ${property_values})
+      SET(new_property_values "${p} ${new_property_values}")
+   ENDFOREACH()
+
+   #property setzen
+   SET_TARGET_PROPERTIES(${target} PROPERTIES ${property} ${new_property_values})
+
+   #GET_TARGET_PROPERTY(TEMP_VAR ${target} ${property}) 
+   #MESSAGE("danach ${target} ${property} ${TEMP_VAR}")
+
+ENDMACRO(ADD_TARGET_PROPERTIES target property)
+
+
+################################################################
+###               CHECK_FOR_VARIABLE                         ###
+###  checks for a variable (also env-variables)
+###  if not found -> error-message!!!
+###  always: cache-entry update
+################################################################
+MACRO(CHECK_FOR_VARIABLE var)
+   #check ob evtl enviromentvariable gesetzt
+   IF(NOT DEFINED ${var})  #true if ${var} NOT: empty, 0, N, NO, OFF, FALSE, NOTFOUND, or <variable>-NOTFOUND
+     SET(${var} $ENV{${var}})
+   ENDIF()
+
+   IF(NOT DEFINED ${var})
+      SET(${var} "${var}-NOTFOUND" CACHE STRING "${ARGN}" FORCE)
+   ENDIF(NOT DEFINED ${var})
+
+   IF(${var} MATCHES ".*-NOTFOUND")
+      MESSAGE(FATAL_ERROR "CHECK_FOR_VARIABLE - error - set ${var}")
+   ENDIF()
+   
+   SET(${var} ${${var}} CACHE STRING "${ARGN}" FORCE) 
+ENDMACRO(CHECK_FOR_VARIABLE var)
+
+
+###############################################################
+###   CAB_SOURCE_GROUP( sourceGroupName )                   ###
+### creates a source group for the given folder and files.  ### 
+###############################################################
+MACRO(CAB_SOURCE_GROUP sourceGroupName)
+  SET(tempSourceGroupName ${sourceGroupName})
+  IF(WITH_SUBFOLDERS_FOR_SG)
+    STRING(REGEX REPLACE "/" "\\\\" tempSourceGroupName ${tempSourceGroupName})
+  ENDIF()
+  SOURCE_GROUP(${tempSourceGroupName} FILES ${ARGN})
+ENDMACRO(CAB_SOURCE_GROUP)
+
+#################################################################################
+###   COLLECT_PACKAGE_DATA( currentDir  sourceGroupName outFiles)             ###
+### collects header and cpp file of current dir and add them to "outfiles"    ###
+### all files will be put to the SOURCE_GROUP-folder "sourceGroupName"        ###
+### and this one will be with subfolders if  WITH_SUBFOLDERS_FOR_SG==YES      ###
+#################################################################################
+MACRO(COLLECT_PACKAGE_DATA currentDir sourceGroupName outFiles)
+  FILE( GLOB _HEADER_FILES ${currentDir}/*.h   )
+  FILE( GLOB _CPP_FILES    ${currentDir}/*.cpp )
+  FILE( GLOB _CXX_FILES    ${currentDir}/*.cxx )
+  FILE( GLOB _HPP_FILES    ${currentDir}/*.hpp )
+  FILE( GLOB _C_FILES      ${currentDir}/*.c   )
+  
+  IF(CAB_PACKAGE_DEFINTIONS)
+     SET_SOURCE_FILES_PROPERTIES( ${CPP_FILES} PROPERTIES COMPILE_FLAGS ${CAB_PACKAGE_DEFINTIONS} )
+  ENDIF(CAB_PACKAGE_DEFINTIONS)
+
+  CAB_SOURCE_GROUP( ${sourceGroupName} ${_HEADER_FILES} ${_CPP_FILES} ${_CXX_FILES} ${_HPP_FILES} ${_C_FILES} )
+
+  #SET( ${outFiles} ${${outFiles}} ${_HEADER_FILES} ${_CPP_FILES} ${_CXX_FILES} ${_HPP_FILES} ${_C_FILES} ) 
+  LIST(APPEND ${outFiles} ${_HEADER_FILES} ${_CPP_FILES} ${_CXX_FILES} ${_HPP_FILES} ${_C_FILES} )
+ENDMACRO(COLLECT_PACKAGE_DATA  currentDir sourceGroupName sourceGroupWithSubfolders outFiles)
+
+
+##################################################################################################################
+###   COLLECT_PACKAGE_DATA_WITH_OPTION( currentDir  outFiles [outOption] [outSourceGroupName]) ###
+### collects header and cpp file of current dir and add them to "outfiles"                                     ###
+### all files will be put to the SOURCE_GROUP-folder "sourceGroupName"                                         ###
+### and this one will be with subfolders if  WITH_SUBFOLDERS_FOR_SG==YES                                       ###
+##################################################################################################################
+MACRO(COLLECT_PACKAGE_DATA_WITH_OPTION currentDir outFiles)
+  STRING(REGEX REPLACE "(.*)/source/(.*)" "\\2" SOURCE_GROUP_NAME "${currentDir}")
+  STRING(REGEX REPLACE   "/" "_" OPTION_LABEL "${SOURCE_GROUP_NAME}")
+  STRING(REGEX REPLACE   ":" "" OPTION_LABEL "${OPTION_LABEL}")
+  STRING(TOUPPER ${OPTION_LABEL} OPTION_LABEL)  
+      
+  SET(OPTION_LABEL "BUILD_${OPTION_LABEL}")
+  OPTION(${OPTION_LABEL} "${currentDir}" ON)
+  
+  IF( ${OPTION_LABEL} ) 
+     COLLECT_PACKAGE_DATA( ${currentDir} ${SOURCE_GROUP_NAME} ${outFiles})
+  ENDIF(${OPTION_LABEL})
+
+  IF(${ARGC} GREATER 2)
+    SET( ${ARGV2} ${OPTION_LABEL} )
+  ENDIF()
+
+  IF(${ARGC} GREATER 3)
+     SET( ${ARGV3} ${SOURCE_GROUP_NAME} )
+  ENDIF()
+  
+ENDMACRO(COLLECT_PACKAGE_DATA_WITH_OPTION  currentDir outFiles)
+
+
+#################################################################
+###   GET_DIRECTORY_FROM_ENV( var env_var [CACHE] [STRING])   ###
+### if enn_var exists the value with corrected slashes will   ###
+### be stored in var.					      ###
+### if optional CACHE is activated the var will be stored as  ###
+### cache variable. optional you can use a status bar string   ###
+#################################################################
+MACRO(GET_DIRECTORY_FROM_ENV var env_var)
+  SET(${var} $ENV{${env_var}})
+  IF(${var}) 
+    STRING(REGEX REPLACE "\\\\" "/" ${var} ${${var}})   # "\" --> "/" 
+    IF(${ARGC} EQUAL 3 AND ${ARGV2} MATCHES "CACHE")
+       SET(${var} ${${var}} CACHE PATH "" FORCE)
+    ENDIF(${ARGC} EQUAL 3 AND ${ARGV2} MATCHES "CACHE")
+    IF(${ARGC} EQUAL 4 AND ${ARGV2} MATCHES "CACHE")
+       SET(${var} ${${var}} CACHE PATH "${ARGV3}" FORCE)
+    ENDIF(${ARGC} EQUAL 4 AND ${ARGV2} MATCHES "CACHE")
+  ENDIF(${var})
+ENDMACRO(GET_DIRECTORY_FROM_ENV var env_var)
+
+#################################################################
+###   GET_DIRECTORY_FROM_VAR( var  [CACHE] [STRING])          ###
+### if optional CACHE is activated the var will be stored as  ###
+### cache variable. optional you can use a status bar string   ###
+#################################################################
+MACRO(GET_DIRECTORY_FROM_VAR var )
+  IF(${var}) 
+    STRING(REGEX REPLACE "\\\\" "/" ${var} ${${var}})   # "\" --> "/" 
+    IF(${ARGC} EQUAL 2 AND ${ARGV1} MATCHES "CACHE")
+       SET(${var} ${${var}} CACHE PATH "" FORCE)
+    ENDIF(${ARGC} EQUAL 2 AND ${ARGV1} MATCHES "CACHE")
+    IF(${ARGC} EQUAL 3 AND ${ARGV1} MATCHES "CACHE")
+       SET(${var} ${${var}} CACHE PATH "${ARGV2}" FORCE)
+    ENDIF(${ARGC} EQUAL 3 AND ${ARGV1} MATCHES "CACHE")
+  ENDIF(${var})
+ENDMACRO(GET_DIRECTORY_FROM_VAR var env_var)
+
+
+#################################################################
+###   FINAL MACROS TO GENERATE PROJECT FILES                  ###
+###   project_name: name of the project                       ###
+###   build_type:   BINARY | SHARED | STATIC                  ###
+###   optinal:      prefix
+#################################################################
+MACRO(CREATE_CAB_PROJECT project_name build_type)
+
+   MESSAGE(STATUS "configuring ${project_name} (type=${build_type})...")
+
+   #################################################################
+   ###   OS DEFINES                                              ###
+   #################################################################
+   IF(WIN32)  
+      LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -D__WIN__)
+   ELSEIF(APPLE)
+      LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -D__APPLE__)
+   ELSEIF(UNIX)
+      LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -D__unix__)
+   ENDIF()
+
+   #################################################################
+   ###   ADDITIONAL_MAKE_CLEAN_FILES                             ###
+   #################################################################
+   SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${GENERATED_FILES}")
+   
+   #################################################################
+   ###   EXCECUTABLE                                             ###
+   #################################################################
+   IF(${build_type} MATCHES BINARY)
+      ADD_EXECUTABLE(${project_name} ${ALL_SOURCES} )
+   ELSEIF(${build_type} MATCHES SHARED)
+      ADD_LIBRARY(${project_name} SHARED ${ALL_SOURCES} )
+   ELSEIF(${build_type} MATCHES STATIC)
+      ADD_LIBRARY(${project_name} STATIC ${ALL_SOURCES} )
+   ELSE()
+      MESSAGE(FATAL_ERROR "build_type=${build_type} doesn't match BINARY, SHARED or STATIC")
+   ENDIF()
+
+   #################################################################
+   ###   ADDITIONAL LINK LIBRARIES                               ###
+   #################################################################
+   IF(CAB_ADDITIONAL_LINK_LIBRARIES)
+      TARGET_LINK_LIBRARIES(${project_name} ${CAB_ADDITIONAL_LINK_LIBRARIES}) 
+   ENDIF()
+
+   #################################################################
+   ###   COMPILER Flags                                          ###
+   #################################################################
+   ADD_COMPILER_FLAGS_TO_PROJECT(${CAB_COMPILER}  ${project_name} "CXX" ${build_type})
+   MESSAGE(STATUS "compiler flags for compiler ${CAB_COMPILER} on machine ${CAB_MACHINE} for project ${project_name} (${build_type}) have been configured")
+
+   IF(CAB_ADDTIONAL_COMPILER_FLAGS)
+     ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS ${CAB_ADDTIONAL_COMPILER_FLAGS}) 
+   ENDIF()
+   IF(CAB_ADDTIONAL_COMPILER_FLAGS_DEBUG)
+     MESSAGE(FATAL_ERROR "COMPILE_FLAGS_DEBUG_<CONFIG> not supported by cmake yet :-(")
+     ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS_DEBUG ${CAB_ADDTIONAL_COMPILER_FLAGS_DEBUG}) 
+   ENDIF()
+   IF(CAB_ADDTIONAL_COMPILER_FLAGS_RELEASE)
+     MESSAGE(FATAL_ERROR "COMPILE_FLAGS_<CONFIG> not supported by cmake yet :-(")
+     ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS_RELEASE ${CAB_ADDTIONAL_COMPILER_FLAGS_RELEASE}) 
+   ENDIF()
+
+   #################################################################
+   ###   ADDITIONAL LINK PROPERTIES                              ###
+   #################################################################
+   IF(CAB_ADDITIONAL_LINK_FLAGS)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS}) 
+   ENDIF()
+   IF(CAB_ADDITIONAL_LINK_FLAGS_DEBUG)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS_DEBUG ${CAB_ADDITIONAL_LINK_FLAGS_DEBUG}) 
+   ENDIF()
+   IF(CAB_ADDITIONAL_LINK_FLAGS_RELEASE)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS_RELEASE ${CAB_ADDITIONAL_LINK_FLAGS_RELEASE}) 
+   ENDIF()
+
+   SET(project_name ${project_name} CACHE STRING "name of binary")
+
+   MESSAGE(STATUS "configuring ${project_name} (type=${build_type})... done")
+
+ENDMACRO(CREATE_CAB_PROJECT project_name build_type)
+
+#################################################################
+# ALLGEMEINGUELTIGER STUFF
+# CAB_COMPILER setzen und machinespecific configfile laden
+###############################################################
+SET_CAB_COMPILER()
diff --git a/CMake/CMakeCompilerMacros.txt b/CMake/CMakeCompilerMacros.txt
new file mode 100644
index 0000000000000000000000000000000000000000..68d4ee4e5a8ab1ab8611d32d90a322f18e28e9d8
--- /dev/null
+++ b/CMake/CMakeCompilerMacros.txt
@@ -0,0 +1,384 @@
+###############################################################
+# Aktivieren von ELSIF in CMake
+###############################################################
+SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 1)
+
+###############################################################
+# IS_64BIT_SYSTEM (check put if OS is 64 bit compatible)
+###############################################################
+MACRO(IS_64BIT_SYSTEM is64BitOutVar)
+
+  SET(${is64BitOutVar} FALSE)
+
+  IF(APPLE)
+       EXEC_PROGRAM( arch                            
+                  ARGS -x86_64 echo "64bit"
+                  OUTPUT_VARIABLE CAB_SYSTEM_INFO_1 )
+    IF(${CAB_SYSTEM_INFO_1} MATCHES "64bit")
+      SET(${is64BitOutVar} TRUE)
+    ENDIF()
+
+  ELSEIF(UNIX)
+
+    EXEC_PROGRAM( uname                           
+                  ARGS -m
+                  OUTPUT_VARIABLE CAB_SYSTEM_INFO_1 )
+
+    STRING(REGEX MATCH "x86_64"  CAB_SYSTEM_INFO_1  ${CAB_SYSTEM_INFO_1})
+              
+
+    EXEC_PROGRAM( getconf
+                  ARGS -a | grep -i LONG_BIT
+                  OUTPUT_VARIABLE CAB_SYSTEM_INFO_2 )
+
+    STRING(REGEX MATCH "64"  CAB_SYSTEM_INFO_2  ${CAB_SYSTEM_INFO_2})
+
+    IF(CAB_SYSTEM_INFO_1 STREQUAL  "x86_64" AND CAB_SYSTEM_INFO_2 STREQUAL "64")
+      SET(${is64BitOutVar} TRUE)
+    ENDIF()
+
+  ELSEIF(WIN32)
+
+    MESSAGE(STATUS "IS_64BIT_SYSTEM: determining system type (32/64bit)...(this may take a few moments)")
+    EXEC_PROGRAM( SystemInfo OUTPUT_VARIABLE CAB_SYSTEM_INFO_1 )
+
+    STRING(REGEX MATCH "x64-based PC"  CAB_SYSTEM_INFO_1  ${CAB_SYSTEM_INFO_1})
+
+    IF(CAB_SYSTEM_INFO_1 MATCHES "x64-based PC")
+      SET(${is64BitOutVar} TRUE)
+      MESSAGE(STATUS "IS_64BIT_SYSTEM: determining system type (32/64bit)... done (-> 64 Bit)")
+    ELSE()
+      MESSAGE(STATUS "IS_64BIT_SYSTEM: determining system type (32/64bit)... done (-> 32 Bit)")
+    ENDIF()
+
+  ELSE()
+    MESSAGE(FATAL_ERROR "IS_64BIT_SYSTEM: unknown OS")
+  ENDIF()
+
+ENDMACRO(IS_64BIT_SYSTEM is64BitOutVar)
+
+
+###############################################################
+### SET_CAB_COMPILER                                        ###
+### Macro sets CAB_COMPILER variable if not set             ###
+### for msvc:      CMake Variables are used                 ###
+### for intel,gcc: --version call is evaluated              ###
+###############################################################
+MACRO(SET_CAB_COMPILER)
+   IF(NOT CMAKE_CXX_COMPILER)
+      MESSAGE(FATAL_ERROR "before SET_CAB_COMPILER-Macro PROJECT-Macro has to be called")
+   ELSE()
+      IF(NOT CAB_COMPILER)
+         IF(MSVC)
+		   IF(CMAKE_CL_64)
+		     SET( CAB_COMPILER "msvc19_64" )
+		   ELSE()
+		     SET( CAB_COMPILER "msvc19_32" )
+		   ENDIF()
+         #ELSEIF(APPLE)
+		 ELSEIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+            SET( CAB_COMPILER "clang" )
+         ELSE()
+           EXEC_PROGRAM( ${CMAKE_CXX_COMPILER}                          
+                          ARGS --version 
+                          OUTPUT_VARIABLE CAB_COMPILER_INFO )
+
+            STRING(REGEX REPLACE ".* \\((.*)\\) ([0-9]*)\\.([0-9]*)[\\. ]([0-9]*).*" "\\1" CAB_COMPILER_NAME          ${CAB_COMPILER_INFO})
+            STRING(REGEX REPLACE "[^ ]*[^0-9]*([0-9]*)\\.([0-9]*)[\\. ]([0-9]*)[^0-9]*.*" "\\1" CAB_COMPILER_VERSION_MAJOR ${CAB_COMPILER_INFO})
+            STRING(REGEX REPLACE "[^ ]*[^0-9]*([0-9]*)\\.([0-9]*)[\\. ]([0-9]*)[^0-9]*.*" "\\2" CAB_COMPILER_VERSION_MINOR ${CAB_COMPILER_INFO})
+            STRING(REGEX REPLACE "[^ ]*[^0-9]*([0-9]*)\\.([0-9]*)[\\. ]([0-9]*)[^0-9]*.*" "\\3" CAB_COMPILER_VERSION_PATCH ${CAB_COMPILER_INFO})
+
+            STRING(TOLOWER ${CAB_COMPILER_NAME} CAB_COMPILER_NAME)
+
+            IF(CMAKE_COMPILER_IS_GNUCXX)
+               SET(CAB_COMPILER_NAME "gcc")
+               SET(USE_GCC ON)
+            ENDIF()
+            
+            SET(CAB_COMPILER "${CAB_COMPILER_NAME}${CAB_COMPILER_VERSION_MAJOR}${CAB_COMPILER_VERSION_MINOR}")
+         ENDIF()
+      ENDIF()
+
+      SET(CAB_COMPILER ${CAB_COMPILER} CACHE STRING "compiler") 
+   ENDIF()
+
+ENDMACRO(SET_CAB_COMPILER)
+
+################################################################
+###               CHECK_FOR_VARIABLE                         ###
+###  checks for a variable (also env-variables)
+###  if not found -> error-message!!!
+###  always: cache-entry update
+################################################################
+MACRO(CHECK_FOR_VARIABLE var)
+   #check ob evtl enviromentvariable gesetzt
+   IF(NOT ${var})  #true if ${var} NOT: empty, 0, N, NO, OFF, FALSE, NOTFOUND, or <variable>-NOTFOUND
+     SET(${var} $ENV{${var}})
+   ENDIF()
+
+   IF(NOT DEFINED ${var})
+      SET(${var} "${var}-NOTFOUND" CACHE STRING "${ARGN}" FORCE)
+   ENDIF(NOT DEFINED ${var})
+
+   IF(NOT ${var})
+      MESSAGE(FATAL_ERROR "CHECK_FOR_VARIABLE - error - set ${var}")
+   ENDIF()
+   
+SET(${var} ${${var}} CACHE STRING "${ARGN}" FORCE) 
+ENDMACRO(CHECK_FOR_VARIABLE var)
+
+
+#################################################################
+###   ADD_CXX_FLAGS(flags)     				      ###
+### flags will be added to CMAKE_CXX_FLAGS                    ###
+#################################################################
+MACRO(ADD_CXX_FLAGS)
+  FOREACH(arg ${ARGN})
+    SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+    SEPARATE_ARGUMENTS(TMP)
+    FOREACH(option ${TMP})
+      STRING(REGEX REPLACE " ${option}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+      STRING(REGEX REPLACE "${option}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${option}" CACHE STRING "common C++ build flags" FORCE)
+    ENDFOREACH(option ${TMP})  
+  ENDFOREACH(arg ${ARGN})
+ENDMACRO(ADD_CXX_FLAGS)
+
+#################################################################
+###   ADD_CXX_FLAGS_IF(option flags)             	      ###
+### flags will be added to CMAKE_CXX_FLAGS if option exists   ###
+#################################################################
+MACRO(ADD_CXX_FLAGS_IF condition)
+  IF(${condition})
+    ADD_CXX_FLAGS(${ARGN})
+  ENDIF(${condition})
+ENDMACRO(ADD_CXX_FLAGS_IF)
+
+#################################################################
+###   REMOVE_CXX_FLAGS(flags)     	  	              ###
+### flags will be removed from CMAKE_CXX_FLAGS                ###
+#################################################################
+MACRO(REMOVE_CXX_FLAGS)
+  FOREACH(arg ${ARGN})
+    SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+    SEPARATE_ARGUMENTS(TMP)
+    FOREACH(option ${TMP})
+      STRING(REGEX REPLACE " ${option}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+      STRING(REGEX REPLACE "${option}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    ENDFOREACH(option ${TMP})  
+  ENDFOREACH(arg ${ARGN})
+ENDMACRO(REMOVE_CXX_FLAGS)
+
+#####################################################################
+###   REMOVE_CXX_FLAGS(option flags)     		          ###
+### flags will be removed from CMAKE_CXX_FLAGS if option exists   ###
+#####################################################################
+MACRO(REMOVE_CXX_FLAGS_IF condition)
+  IF(${condition})
+    REMOVE_CXX_FLAGS(${ARGN})
+  ENDIF(${condition})
+ENDMACRO(REMOVE_CXX_FLAGS_IF)
+
+#################################################################
+###   ADD_CXX_BUILDTYPE_FLAGS(buildtype flags)   	      ###
+### flags will be added to CMAKE_CXX_BUILDTYPE_FLAGS          ###
+#################################################################
+MACRO(ADD_CXX_BUILDTYPE_FLAGS buildtype)
+  IF(CMAKE_CXX_FLAGS_${buildtype})
+    FOREACH(arg ${ARGN})
+      SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+      SEPARATE_ARGUMENTS(TMP)
+      FOREACH(option ${TMP})
+        STRING(REGEX REPLACE " ${option}" "" CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}}")
+        STRING(REGEX REPLACE "${option}" "" CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}}")
+        SET(CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}} ${option}" CACHE STRING "common C++ build flags for ${buildtype}" FORCE)
+      ENDFOREACH(option ${TMP})  
+    ENDFOREACH(arg ${ARGN})
+  ENDIF(CMAKE_CXX_FLAGS_${buildtype})
+ENDMACRO(ADD_CXX_BUILDTYPE_FLAGS)
+
+#########################################################################
+###   ADD_CXX_BUILDTYPE_FLAGS(buildtype option flags)	              ###
+### flags will be added to CMAKE_CXX_BUILDTYPE_FLAGS if option exists ###
+#########################################################################
+MACRO(ADD_CXX_BUILDTYPE_FLAGS_IF buildtype condition)
+  IF(${condition})
+    ADD_CXX_BUILDTYPE_FLAGS(${buildtype} ${ARGN})
+  ENDIF(${condition})
+ENDMACRO(ADD_CXX_BUILDTYPE_FLAGS_IF)
+
+#################################################################
+###   REMOVE_CXX_BUILDTYPE_FLAGS(buildtype flags)             ###
+### flags will be removed from CMAKE_CXX_FLAGS                ###
+#################################################################
+MACRO(REMOVE_CXX_BUILDTYPE_FLAGS buildtype)
+  IF(CMAKE_CXX_FLAGS_${buildtype})
+    FOREACH(arg ${ARGN})
+      SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+      SEPARATE_ARGUMENTS(TMP)
+      FOREACH(option ${TMP})
+	STRING(REGEX REPLACE " ${option}" "" CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}}")
+        STRING(REGEX REPLACE "${option}" "" CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}}")
+        SET(CMAKE_CXX_FLAGS_${buildtype} "${CMAKE_CXX_FLAGS_${buildtype}}" 
+            CACHE STRING "C++ build flags for ${buildtype} configuration" FORCE)
+      ENDFOREACH(option ${TMP})  
+    ENDFOREACH(arg ${ARGN})
+  ENDIF(CMAKE_CXX_FLAGS_${buildtype})
+ENDMACRO(REMOVE_CXX_BUILDTYPE_FLAGS)
+
+#####################################################################
+###   REMOVE_CXX_BUILDTYPE_FLAGS_IF(buildtype option flags)       ###
+### flags will be removed from CMAKE_CXX_FLAGS if option exists   ###
+#####################################################################
+MACRO(REMOVE_CXX_BUILDTYPE_FLAGS_IF condition)
+  IF(${condition})
+    REMOVE_CXX_BUILDTYPE_FLAGS(${buildtype} ${ARGN})
+  ENDIF(${condition})
+ENDMACRO(REMOVE_CXX_BUILDTYPE_FLAGS_IF)
+
+#####################################################################
+###   SET_CXX_COMPILER( compiler)                                 ###
+### flags will be removed from CMAKE_CXX_FLAGS if option exists   ###
+#####################################################################
+#MACRO(SET_CXX_COMPILER compiler)
+#  INCLUDE (CMakeForceCompiler)
+#  SET(CMAKE_SYSTEM_NAME Generic)
+#  CMAKE_FORCE_CXX_COMPILER   (${compiler} "set by user")
+#  SET(CMAKE_CXX_COMPILER ${compiler} CACHE STRING "C++ compiler" FORCE)
+#ENDMACRO(SET_CXX_COMPILER)
+
+#################################################################
+###   ADD_C_FLAGS(flags)     				      ###
+### flags will be added to CMAKE_C_FLAGS                    ###
+#################################################################
+MACRO(ADD_C_FLAGS)
+  FOREACH(arg ${ARGN})
+    SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+    SEPARATE_ARGUMENTS(TMP)
+    FOREACH(option ${TMP})
+      STRING(REGEX REPLACE " ${option}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+      STRING(REGEX REPLACE "${option}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+      SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${option}" CACHE STRING "common C++ build flags" FORCE)
+    ENDFOREACH(option ${TMP})  
+  ENDFOREACH(arg ${ARGN})
+ENDMACRO(ADD_C_FLAGS)
+
+#################################################################
+###   ADD_C_FLAGS(option flags)     			      ###
+### flags will be added to CMAKE_C_FLAGS if option exists     ###
+#################################################################
+MACRO(ADD_C_FLAGS_IF condition)
+  IF(${condition})
+    ADD_C_FLAGS(${ARGN})
+  ENDIF(${condition})
+ENDMACRO(ADD_C_FLAGS_IF)
+
+#################################################################
+###   REMOVE_C_FLAGS(flags)     	  	              ###
+### flags will be removed from CMAKE_C_FLAGS                  ###
+#################################################################
+MACRO(REMOVE_C_FLAGS)
+  FOREACH(arg ${ARGN})
+    SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+    SEPARATE_ARGUMENTS(TMP)
+    FOREACH(option ${TMP})
+      STRING(REGEX REPLACE " ${option}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+      STRING(REGEX REPLACE "${option}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+    ENDFOREACH(option ${TMP})  
+  ENDFOREACH(arg ${ARGN})
+ENDMACRO(REMOVE_C_FLAGS)
+
+#####################################################################
+###   REMOVE_C_FLAGS(option flags)                                ###
+### flags will be removed from CMAKE_C_FLAGS if option exists     ###
+#####################################################################
+MACRO(REMOVE_C_FLAGS_IF condition)
+  IF(${condition})
+    REMOVE_C_FLAGS(${ARGN})
+  ENDIF(${condition})
+ENDMACRO(REMOVE_C_FLAGS_IF)
+
+#################################################################
+###   ADD_C_BUILDTYPE_FLAGS(buildtype flags)                  ###
+### flags will be added to CMAKE_C_BUILDTYPE_FLAGS            ###
+#################################################################
+MACRO(ADD_C_BUILDTYPE_FLAGS buildtype)
+  IF(CMAKE_C_FLAGS_${buildtype})
+    FOREACH(arg ${ARGN})
+      SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+      SEPARATE_ARGUMENTS(TMP)
+      FOREACH(option ${TMP})
+        STRING(REGEX REPLACE " ${option}" "" CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}}")
+        STRING(REGEX REPLACE "${option}" "" CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}}")
+        SET(CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}} ${option}" CACHE STRING "common C++ build flags for ${buildtype}" FORCE)
+      ENDFOREACH(option ${TMP})  
+    ENDFOREACH(arg ${ARGN})
+  ENDIF(CMAKE_C_FLAGS_${buildtype})
+ENDMACRO(ADD_C_BUILDTYPE_FLAGS)
+
+#########################################################################
+###   ADD_C_BUILDTYPE_FLAGS(buildtype option flags)	              ###
+### flags will be added to CMAKE_C_BUILDTYPE_FLAGS if option exists ###
+#########################################################################
+MACRO(ADD_C_BUILDTYPE_FLAGS_IF buildtype condition)
+  IF(${condition})
+    ADD_C_BUILDTYPE_FLAGS(${buildtype} ${ARGN})
+  ENDIF(${condition})
+ENDMACRO(ADD_C_BUILDTYPE_FLAGS_IF)
+
+#################################################################
+###   REMOVE_C_BUILDTYPE_FLAGS(buildtype flags)               ###
+### flags will be removed from CMAKE_C_FLAGS                  ###
+#################################################################
+MACRO(REMOVE_C_BUILDTYPE_FLAGS buildtype)
+  IF(CMAKE_C_FLAGS_${buildtype})
+    FOREACH(arg ${ARGN})
+      SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+      SEPARATE_ARGUMENTS(TMP)
+      FOREACH(option ${TMP})
+	STRING(REGEX REPLACE " ${option}" "" CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}}")
+        STRING(REGEX REPLACE "${option}" "" CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}}")
+        SET(CMAKE_C_FLAGS_${buildtype} "${CMAKE_C_FLAGS_${buildtype}}" 
+            CACHE STRING "C++ build flags for ${buildtype} configuration" FORCE)
+      ENDFOREACH(option ${TMP})  
+    ENDFOREACH(arg ${ARGN})
+  ENDIF(CMAKE_C_FLAGS_${buildtype})
+ENDMACRO(REMOVE_C_BUILDTYPE_FLAGS)
+
+#####################################################################
+###   REMOVE_C_BUILDTYPE_FLAGS_IF(buildtype option flags)         ###
+### flags will be removed from CMAKE_C_FLAGS if option exists     ###
+#####################################################################
+MACRO(REMOVE_C_BUILDTYPE_FLAGS_IF condition)
+  IF(${condition})
+    REMOVE_C_BUILDTYPE_FLAGS(${buildtype} ${ARGN})
+  ENDIF(${condition})
+ENDMACRO(REMOVE_C_BUILDTYPE_FLAGS_IF)
+
+#####################################################################
+###   SET_C_COMPILER( compiler)                                   ###
+### flags will be removed from CMAKE_C_FLAGS if option exists     ###
+#####################################################################
+MACRO(SET_C_COMPILER compiler)
+  INCLUDE (CMakeForceCompiler)
+  SET(CMAKE_SYSTEM_NAME Generic)
+  CMAKE_FORCE_C_COMPILER  (${compiler} "set by user")
+  SET(CMAKE_C_COMPILER ${compiler} CACHE STRING "C compiler" FORCE)
+ENDMACRO(SET_C_COMPILER)
+
+#################################################################
+###   ADD_EXE_LINKER_FLAGS(flags)                             ###
+### flags will be added to CMAKE_EXE_LINKER_FLAGS             ###
+#################################################################
+MACRO(ADD_EXE_LINKER_FLAGS)
+  FOREACH(arg ${ARGN})
+    SET(TMP ${arg}) #elsewise the Seperate command doesn't work)
+    SEPARATE_ARGUMENTS(TMP)
+    FOREACH(option ${TMP})
+      STRING(REGEX REPLACE " ${option}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+      STRING(REGEX REPLACE "${option}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+      SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${option}" CACHE STRING "common C++ build flags" FORCE)
+    ENDFOREACH(option ${TMP})  
+  ENDFOREACH(arg ${ARGN})
+ENDMACRO(ADD_EXE_LINKER_FLAGS)
+
diff --git a/CMake/CMakeSetCompilerFlags.txt b/CMake/CMakeSetCompilerFlags.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fbee7836f0694a9c96004a024f81bec3c68e3414
--- /dev/null
+++ b/CMake/CMakeSetCompilerFlags.txt
@@ -0,0 +1,139 @@
+################################################################
+###               SET_COMPILER_SPECIFIC_FLAGS                ###
+###  determines compiler flags variabels                     ###
+###  compiler_type: e.g. msvc9_x64                           ###
+###  build_type  :    BINARY, STATIC, SHARED                 ###
+################################################################
+MACRO(SET_COMPILER_SPECIFIC_FLAGS compiler_type build_type)
+   IF(NOT CMAKE_CXX_COMPILER)
+      MESSAGE(FATAL_ERROR "before SET_CAB_COMPILER-Macro PROJECT-Macro has to be called")
+   ENDIF()
+  
+  OPTION(USE_OPENMP "activate open" ON)
+  
+  IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+    SET(USE_OPENMP OFF)
+  ENDIF()
+  
+  ###############################################################################################################
+  ## Flags ruecksetzen
+  ###############################################################################################################
+  SET(CAB_COMPILER_ADDITIONAL_LINK_PROPS "")
+  SET(CAB_COMPILER_ADDITIONAL_LINK_PROPS_DEBUG "")
+  SET(CAB_COMPILER_ADDITIONAL_LINK_PROPS_RELEASE "")
+  
+  SET(CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "")
+  SET(CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS_DEBUG "")
+  SET(CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS_RELEASE "")
+
+  SET(CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "")
+  SET(CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS_DEBUG "")
+  SET(CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS_RELEASE "")
+
+   ###############################################################################################################
+   ## ggf. spezielles compiler flag file lesen
+   ###############################################################################################################
+   IF( SPECIFIC_COMPILER_FLAG_FILE )
+      INCLUDE( ${SPECIFIC_COMPILER_FLAG_FILE})
+   ###############################################################################################################
+   ## standard compiler flags
+   ###############################################################################################################
+   ELSEIF( EXISTS "${SOURCE_ROOT}/CMake/compilerflags/${CAB_COMPILER}.cmake" )
+	   INCLUDE( ${SOURCE_ROOT}/CMake/compilerflags/${CAB_COMPILER}.cmake)
+	###############################################################################################################
+	## unknown compiler
+	###############################################################################################################
+	ELSE()
+	   #MESSAGE(FATAL_ERROR "CAB_COMPILER=${CAB_COMPILER} seems to be a not supported compiler")
+	   MESSAGE(WARNING "CAB_COMPILER=${CAB_COMPILER} seems to be a not supported compiler; set to generic")
+	   SET(CAB_COMPILER "gccGeneric")
+	   INCLUDE( ${SOURCE_ROOT}/CMake/compilerflags/${CAB_COMPILER}.cmake)
+	ENDIF()
+   
+
+   ###############################################################################################################
+	#64 Bit compilation??
+   ###############################################################################################################
+   IF(NOT DEFINED USE_64BIT_COMPILER_OPTIONS) 
+      IF(MSVC AND NOT CMAKE_CL_64)      
+        SET(OPTION64 OFF)
+      ELSEIF(MSVC AND CMAKE_CL_64)      
+        SET(OPTION64 ON)
+      ELSE()
+         IS_64BIT_SYSTEM( IS64BITSYSTEM )
+         IF(IS64BITSYSTEM STREQUAL "TRUE")
+            SET(OPTION64 ON)
+         ELSE()
+            SET(OPTION64 OFF)
+         ENDIF()
+      ENDIF()
+   ENDIF()
+
+   OPTION(USE_64BIT_COMPILER_OPTIONS "set 64 bit compiler flags"  ${OPTION64})
+
+   ###############################################################################################################
+	# set flags
+   ###############################################################################################################
+IF(USE_64BIT_COMPILER_OPTIONS)
+      SET_COMPILER_SPECIFIC_FLAGS_INTERN( ${build_type} 1)
+else()
+      SET_COMPILER_SPECIFIC_FLAGS_INTERN( ${build_type} 0)
+endif()
+  
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS compiler_type build_type)
+
+################################################################
+###             ADD_COMPILER_FLAGS_TO_PROJECT                ###
+###  adds COMPILER_FLGAS TO project                          ###
+###  project_language:    CXX , C                            ###
+################################################################
+MACRO(ADD_COMPILER_FLAGS_TO_PROJECT compiler_type project_name project_language build_type)
+
+   IF(NOT ${project_language} MATCHES "C")
+      IF(NOT ${project_language} MATCHES "CXX")
+         MESSAGE(FATAL_ERROR "project_language must be CXX or C")
+      ENDIF()
+   ENDIF()
+
+   ################################################################
+   # SET_COMPILER_SPECIFIC_FLAGS
+   ################################################################
+   SET_COMPILER_SPECIFIC_FLAGS( ${compiler_type} ${build_type} )
+
+   #workaround für itanium processoren
+   IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ia64")
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS -D_M_IA64)
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   -D_M_IA64)
+   ENDIF()
+
+   ################################################################
+   # LINKER PROPS
+   ################################################################
+   IF(CAB_COMPILER_ADDITIONAL_LINK_PROPS)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS ${CAB_COMPILER_ADDITIONAL_LINK_PROPS}) 
+   ENDIF()
+   IF(CAB_COMPILER_ADDITIONAL_LINK_PROPS_DEBUG)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS ${CAB_COMPILER_ADDITIONAL_LINK_PROPS_DEBUG}) 
+   ENDIF()
+   IF(CAB_COMPILER_ADDITIONAL_LINK_PROPS_RELEASE)
+     ADD_TARGET_PROPERTIES(${project_name} LINK_FLAGS ${CAB_COMPILER_ADDITIONAL_LINK_PROPS_RELEASE}) 
+   ENDIF()
+
+   ################################################################
+   # COMPILER FLAGS
+   ################################################################
+   IF(CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS)
+     ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS ${CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS}) 
+   ENDIF()
+   IF(CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS_DEBUG)
+     MESSAGE(STATUS "ADD_COMPILER_FLAGS_TO_PROJECT: sorry, a long as CMake has no support for COMPILE_FLAGS_<CONFIG> -> DEBUG flags are neglected")
+     #ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS_DEBUG ${CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS_DEBUG}) 
+   ENDIF()
+   IF(CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS_RELEASE)
+     MESSAGE(STATUS "ADD_COMPILER_FLAGS_TO_PROJECT: sorry, a long as CMake has no support for COMPILE_FLAGS_<CONFIG> -> RELEASE flags are set for RELEASE AND DEBUG")
+     ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS ${CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS_RELEASE}) 
+     #ADD_TARGET_PROPERTIES(${project_name} COMPILE_FLAGS_RELEASE ${CAB_COMPILER_ADDTIONAL_${project_language}_COMPILER_FLAGS_RELEASE}) 
+   ENDIF()
+
+
+ENDMACRO(ADD_COMPILER_FLAGS_TO_PROJECT compiler_type project_name project_language build_type)
\ No newline at end of file
diff --git a/CMake/compilerflags/clang.cmake b/CMake/compilerflags/clang.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..98e13390792e78d65657c9660a1d75f238e62307
--- /dev/null
+++ b/CMake/compilerflags/clang.cmake
@@ -0,0 +1,68 @@
+###############################################################################################################
+## 
+##  clang
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -fPIC -Wbackslash-newline-escape")
+ 
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+
+   #############################################################################################################
+   # disable warning
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wbackslash-newline-escape") #backslash and newline separated by space
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wcomment") #'/*' within block comment
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-Wbackslash-newline-escape") #backslash and newline separated by space
+   
+   #############################################################################################################
+   # c++ 17 support
+   #############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++17")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++17")
+   
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fext-numeric-literals")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wregister")
+
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc33.cmake b/CMake/compilerflags/gcc33.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2fc6eb1751b0dd49e26c5575809af13d154b60cc
--- /dev/null
+++ b/CMake/compilerflags/gcc33.cmake
@@ -0,0 +1,44 @@
+###############################################################################################################
+## 
+##  gcc33
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -ffast-math -Wall -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-march=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-march=opteron" )
+     
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-march=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-march=opteron" )
+   ENDIF()
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+      MESSAGE(STATUS "gcc33 has no OpenMP support -> OpenMP deactivated")
+      SET(USE_OPENMP "OFF")
+   ENDIF()
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+
diff --git a/CMake/compilerflags/gcc34.cmake b/CMake/compilerflags/gcc34.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c0ac3476e4ef8f82e5381e7832ca172d9f8a4042
--- /dev/null
+++ b/CMake/compilerflags/gcc34.cmake
@@ -0,0 +1,44 @@
+###############################################################################################################
+## 
+##  gcc34
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -ffast-math -Wall -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+   
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+      MESSAGE(STATUS "gcc34 has no OpenMP support -> OpenMP deactivated")
+      SET(USE_OPENMP "OFF")
+   ENDIF()
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
diff --git a/CMake/compilerflags/gcc40.cmake b/CMake/compilerflags/gcc40.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c7bcf278e1cb992c900c828d94bab22d02eb9dd7
--- /dev/null
+++ b/CMake/compilerflags/gcc40.cmake
@@ -0,0 +1,54 @@
+###############################################################################################################
+## 
+##  gcc40
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## 64Bit support
+   ###############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	MESSAGE(STATUS "gcc40 has no OpenMP support -> OpenMP deactivated")
+   	SET(USE_OPENMP "OFF")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc41.cmake b/CMake/compilerflags/gcc41.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..60fc9de2a744879b2e2ea405092b91b0e1523db8
--- /dev/null
+++ b/CMake/compilerflags/gcc41.cmake
@@ -0,0 +1,51 @@
+###############################################################################################################
+## 
+##  gcc41
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+   ###############################################################################################################
+   ## 64Bit support
+   ###############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	MESSAGE(STATUS "gcc41 has no OpenMP support -> OpenMP deactivated")
+   	SET(USE_OPENMP "OFF")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc42.cmake b/CMake/compilerflags/gcc42.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..cac77bf08dfbcff105faec0728efaab1be5d1add
--- /dev/null
+++ b/CMake/compilerflags/gcc42.cmake
@@ -0,0 +1,57 @@
+###############################################################################################################
+## 
+##  gcc42
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   #Anmerkung: bei O3 oder "O2 mit finline-function" gibt es Probleme beim MuParser. bug im gcc? 
+   #Bug kann durch "test" in MuParser/examples ueberprueft werden
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O2 -fomit-frame-pointer -funroll-all-loops -fPIC")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O2 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## 64Bit support
+   ###############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc43.cmake b/CMake/compilerflags/gcc43.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..1ff9c1a8b496b991866acac59b5589b865de8c13
--- /dev/null
+++ b/CMake/compilerflags/gcc43.cmake
@@ -0,0 +1,49 @@
+###############################################################################################################
+## 
+##  gcc43
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## 64Bit support
+   ###############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc44.cmake b/CMake/compilerflags/gcc44.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9d3c2d57f2895f12a123f0f0c9ba21c2426c43a7
--- /dev/null
+++ b/CMake/compilerflags/gcc44.cmake
@@ -0,0 +1,54 @@
+###############################################################################################################
+## 
+##  gcc44
+##
+###############################################################################################################
+
+#MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+#ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+  
+   IF(CPU_TYPE MATCHES "Opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## 64Bit support
+   ###############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc45.cmake b/CMake/compilerflags/gcc45.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fbd6824f829ad950417cdfd8370c558caed3d0aa
--- /dev/null
+++ b/CMake/compilerflags/gcc45.cmake
@@ -0,0 +1,54 @@
+###############################################################################################################
+## 
+##  gcc45
+##
+###############################################################################################################
+
+#MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+#ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+  
+   # IF(CPU_TYPE MATCHES "Opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## 64Bit support
+   # ###############################################################################################################
+   # IF( ${use64BitOptions} ) 
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## OpenMP support
+   # ###############################################################################################################
+   # IF(USE_OPENMP)
+   	# LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## mt support
+   # ###############################################################################################################
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   # IF(NOT APPLE)
+      # LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   # ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc46.cmake b/CMake/compilerflags/gcc46.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fdf293b2b71910effddf0760e5d280e2192aa90a
--- /dev/null
+++ b/CMake/compilerflags/gcc46.cmake
@@ -0,0 +1,54 @@
+###############################################################################################################
+## 
+##  gcc46
+##
+###############################################################################################################
+
+#MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+#ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type)
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+  
+   # IF(CPU_TYPE MATCHES "Opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mtune=opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-mcpu=opteron" )
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mtune=opteron")
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-mcpu=opteron" )
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## 64Bit support
+   # ###############################################################################################################
+   # IF( ${use64BitOptions} ) 
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## OpenMP support
+   # ###############################################################################################################
+   # IF(USE_OPENMP)
+   	# LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+   # ENDIF()
+
+
+   # ###############################################################################################################
+   # ## mt support
+   # ###############################################################################################################
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   # LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   # IF(NOT APPLE)
+      # LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   # ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc47.cmake b/CMake/compilerflags/gcc47.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..2a6b91042c55e3bb0159030676310b541a952a2f
--- /dev/null
+++ b/CMake/compilerflags/gcc47.cmake
@@ -0,0 +1,42 @@
+###############################################################################################################
+## 
+##  gcc47
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+   	MESSAGE(STATUS "gcc41 has no OpenMP support -> OpenMP deactivated")
+   	SET(USE_OPENMP "OFF")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc48.cmake b/CMake/compilerflags/gcc48.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..989afcc3e886ef1a92921982bdda4e720f7df436
--- /dev/null
+++ b/CMake/compilerflags/gcc48.cmake
@@ -0,0 +1,42 @@
+###############################################################################################################
+## 
+##  gcc48
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+   	MESSAGE(STATUS "gcc48 has no OpenMP support -> OpenMP deactivated")
+   	SET(USE_OPENMP "OFF")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc49.cmake b/CMake/compilerflags/gcc49.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..26f641ae19d9d0270f17e234ee37b3c5e0496f20
--- /dev/null
+++ b/CMake/compilerflags/gcc49.cmake
@@ -0,0 +1,42 @@
+###############################################################################################################
+## 
+##  gcc49
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+   	MESSAGE(STATUS "gcc49 has no OpenMP support -> OpenMP deactivated")
+   	SET(USE_OPENMP "OFF")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc51.cmake b/CMake/compilerflags/gcc51.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..1c4df2a693a8104ef4204715f4910d576a777336
--- /dev/null
+++ b/CMake/compilerflags/gcc51.cmake
@@ -0,0 +1,50 @@
+###############################################################################################################
+## 
+##  gcc51
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc52.cmake b/CMake/compilerflags/gcc52.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..41649c34a3b94c3703878554309c1c3cf032876e
--- /dev/null
+++ b/CMake/compilerflags/gcc52.cmake
@@ -0,0 +1,50 @@
+###############################################################################################################
+## 
+##  gcc52
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc54.cmake b/CMake/compilerflags/gcc54.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..234797337a662621e76c23e621ecbe4e0c84c319
--- /dev/null
+++ b/CMake/compilerflags/gcc54.cmake
@@ -0,0 +1,50 @@
+###############################################################################################################
+## 
+##  gcc54
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc62.cmake b/CMake/compilerflags/gcc62.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5e80808ac777bf091434e1df1e43cff7a930c5f4
--- /dev/null
+++ b/CMake/compilerflags/gcc62.cmake
@@ -0,0 +1,50 @@
+###############################################################################################################
+## 
+##  gcc62
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc63.cmake b/CMake/compilerflags/gcc63.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c624265fa66e7c73bc9e7ad980f1ac5e9b6a670a
--- /dev/null
+++ b/CMake/compilerflags/gcc63.cmake
@@ -0,0 +1,52 @@
+###############################################################################################################
+## 
+##  gcc63
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 17 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++17")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++17")
+   
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fext-numeric-literals")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gcc82.cmake b/CMake/compilerflags/gcc82.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..13857f5ceb6f882ae21d2235df15e60c0cbf5fbe
--- /dev/null
+++ b/CMake/compilerflags/gcc82.cmake
@@ -0,0 +1,60 @@
+###############################################################################################################
+## 
+##  gcc82
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   #############################################################################################################
+   # c++ 17 support
+   #############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++17")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++17")
+   
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fext-numeric-literals")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wregister")
+
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/gccGeneric.cmake b/CMake/compilerflags/gccGeneric.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c39f0f0d8e8ec55ec35a7f8e80fcdc31838089f9
--- /dev/null
+++ b/CMake/compilerflags/gccGeneric.cmake
@@ -0,0 +1,60 @@
+###############################################################################################################
+## 
+##  gcc generic
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+   #############################################################################################################
+   # Flags
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wno-deprecated") #deprecated header warning (jarl benutzt sstream weil schneller und so) 
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops -fPIC")
+
+   #############################################################################################################
+   # 64Bit support
+   #############################################################################################################
+   IF( ${use64BitOptions} ) 
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-m64" )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS   "-m64" )
+   ENDIF()
+
+   #############################################################################################################
+   # OpenMP support
+   #############################################################################################################
+   IF(USE_OPENMP)
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fopenmp")
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fopenmp")
+   ENDIF()
+
+   #############################################################################################################
+   # mt support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+   
+   #############################################################################################################
+   # c++ 17 support
+   #############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++17")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++17")
+   
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fext-numeric-literals")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_GLIBCXX_USE_CXX11_ABI=0")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-Wregister")
+
+   
+
+   IF(NOT APPLE)
+      LIST(APPEND CAB_ADDITIONAL_LINK_PROPS "-lrt")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc101.cmake b/CMake/compilerflags/icc101.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..236b940ee2e6bba93460256a8501a5451469111c
--- /dev/null
+++ b/CMake/compilerflags/icc101.cmake
@@ -0,0 +1,51 @@
+###############################################################################################################
+## 
+##  intel10 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   IF( ${use64BitOptions} )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   ENDIF()
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+
+   IF(CPU_TYPE MATCHES "Opteron")
+     IF(WIN32)
+     		LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-QxO") #Enables SSE3, SSE2 and SSE instruction sets optimizations for non-Intel CPUs
+     		LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-QxO")     #Enables SSE3, SSE2 and SSE instruction sets optimizations for non-Intel CPUs
+      ELSE()
+     		#auf unserem cluster gibt es kein ss3 SET( CAB_CXX_FLAGS "${CAB_CXX_FLAGS} -xO")  #Enables SSE3, SSE2 and SSE instruction sets optimizations for non-Intel CPUs
+     		#gibt teils probleme beim ausfuehren: SET( CAB_C_FLAGS "${CAB_C_FLAGS} -xO")      #Enables SSE3, SSE2 and SSE instruction sets optimizations for non-Intel CPUs
+      ENDIF()
+   ELSE()
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-fast")
+     	LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-fast")    
+   ENDIF()
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc130.cmake b/CMake/compilerflags/icc130.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fa03ac7b095ddf86ab139f763b577e701eb633f0
--- /dev/null
+++ b/CMake/compilerflags/icc130.cmake
@@ -0,0 +1,38 @@
+###############################################################################################################
+## 
+##  intel10 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc140.cmake b/CMake/compilerflags/icc140.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..054326e248f3b1d2a0082d621bbc8d06d7a249d7
--- /dev/null
+++ b/CMake/compilerflags/icc140.cmake
@@ -0,0 +1,39 @@
+###############################################################################################################
+## 
+##  intel140 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium")
+   
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc150.cmake b/CMake/compilerflags/icc150.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..62d6a440d39ddd41c2a620f3e32cff0ac50736a5
--- /dev/null
+++ b/CMake/compilerflags/icc150.cmake
@@ -0,0 +1,38 @@
+###############################################################################################################
+## 
+##  intel150 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fomit-frame-pointer -finline-functions -funroll-all-loops")
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc160.cmake b/CMake/compilerflags/icc160.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..963c503dea8ed282e905966df5d00d70559c2c3d
--- /dev/null
+++ b/CMake/compilerflags/icc160.cmake
@@ -0,0 +1,43 @@
+###############################################################################################################
+## 
+##  intel160 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -ipo -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11"
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc170.cmake b/CMake/compilerflags/icc170.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..aa41f790419e37c463e50513715236ebfe3c6963
--- /dev/null
+++ b/CMake/compilerflags/icc170.cmake
@@ -0,0 +1,50 @@
+###############################################################################################################
+## 
+##  intel170 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -ipo -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1478") #auto_ptr warning from mu::Parser
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+   
+   #Debug
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-g -traceback")
+   
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-qopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc180.cmake b/CMake/compilerflags/icc180.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..db9f3a70e299eae5eee2fbc71bdf248fbca35b64
--- /dev/null
+++ b/CMake/compilerflags/icc180.cmake
@@ -0,0 +1,51 @@
+###############################################################################################################
+## 
+##  intel180 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -ipo -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1478") #auto_ptr warning from mu::Parser
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always -xCORE-AVX512 -qopt-zmm-usage=high")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always -xCORE-AVX512 -qopt-zmm-usage=high")
+   
+   #Debug
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-g -traceback")
+   
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-qopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc190.cmake b/CMake/compilerflags/icc190.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ff7aafd6da9a9c1e5e922acf21ad59dbb65457ba
--- /dev/null
+++ b/CMake/compilerflags/icc190.cmake
@@ -0,0 +1,51 @@
+###############################################################################################################
+## 
+##  intel190 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   #~ IF( ${use64BitOptions} )
+     #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   #~ ENDIF()
+
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+#~ 
+   #~ LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -ipo -fno-alias -mcmodel=medium -qopt-streaming-stores=always")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1478") #auto_ptr warning from mu::Parser
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always -xCORE-AVX512 -qopt-zmm-usage=high")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-xHOST -O3 -ip -fno-alias -mcmodel=medium -qopt-streaming-stores=always -xCORE-AVX512 -qopt-zmm-usage=high")
+   
+   #Debug
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-g -traceback")
+   
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-qopenmp")
+   ENDIF()
+
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   #LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+   
+   #############################################################################################################
+   # c++ 11 support
+   #############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-std=c++11")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-std=c++11")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/icc91.cmake b/CMake/compilerflags/icc91.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..351aa8fdf17b3a836e656e4921944856f73737a1
--- /dev/null
+++ b/CMake/compilerflags/icc91.cmake
@@ -0,0 +1,47 @@
+###############################################################################################################
+## 
+##  intel9 
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   IF( ${use64BitOptions} )
+     LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D__amd64" ) 
+   ENDIF()
+
+   #IF( ${compiler} MATCHES "INTEL_91_IPO")
+   #	LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-ipo" ) 
+   #	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-ipo" ) 
+   #	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-opt-mem-bandwidth2" ) 
+   #ENDIF( ${compiler} MATCHES "INTEL_91_IPO")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-O3 -fast -fomit-frame-pointer -finline-functions")
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd68" ) #integer conversion resulted in a change of sign
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd186") # pointless comparison of unsigned integer with zero
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd654")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1125") #virtual function override intended
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd1224") #warning directive: This file includes at least one deprecated or antiquated header
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd377")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-wd327")  #class "std::auto_ptr<RCF::I_ClientTransport>" has no suitable copy constructor
+
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-wd266")  #function "__GKfree" declared implicitly
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-O3 -fast -fomit-frame-pointer -finline-functions")
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-openmp")
+   ENDIF()
+
+   ###############################################################################################################
+   ## mt support
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-pthread")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_C_COMPILER_FLAGS "-pthread")
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
diff --git a/CMake/compilerflags/msvc19_32.cmake b/CMake/compilerflags/msvc19_32.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..d10f156430ded744a38fd99ceb38e1dc6869b1f8
--- /dev/null
+++ b/CMake/compilerflags/msvc19_32.cmake
@@ -0,0 +1,39 @@
+###############################################################################################################
+## 
+##  MSVC 2019 (Version 16.0) 32bit (msvc16_64)
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   IF(NOT ${use64BitOptions})
+      MESSAGE(FATAL_ERROR "SET_COMPILER_SPECIFIC_FLAGS: use64BitOptions must be ON for msvc16_64")
+   ENDIF()
+
+   ###############################################################################################################
+   ## USE_UNSECURE_STL_VECTORS_RELEASE ?
+   ###############################################################################################################
+   OPTION(USE_UNSECURE_STL_VECTORS_RELEASE "_SECURE_SCL=0" OFF)
+   IF(USE_UNSECURE_STL_VECTORS_RELEASE)
+      # More MSVC specific compilation flags
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_SECURE_SCL=0")
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_SCL_SECURE_NO_WARNINGS")
+   ENDIF()
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_CRT_SECURE_NO_DEPRECATE")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/wd4996") #deprecated strcpy...
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/wd4800") #forcing value to bool 'true' or 'false' (performance warning)
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/bigobj") #boost support
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/openmp")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
diff --git a/CMake/compilerflags/msvc19_64.cmake b/CMake/compilerflags/msvc19_64.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5e95f57c6914e345d0b775c9bbc25b7807b62e08
--- /dev/null
+++ b/CMake/compilerflags/msvc19_64.cmake
@@ -0,0 +1,39 @@
+###############################################################################################################
+## 
+##  MSVC 2019 (Version 16.0) 64bit (msvc16_64)
+##
+###############################################################################################################
+
+MACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
+   IF(NOT ${use64BitOptions})
+      MESSAGE(FATAL_ERROR "SET_COMPILER_SPECIFIC_FLAGS: use64BitOptions must be ON for msvc16_64")
+   ENDIF()
+
+   ###############################################################################################################
+   ## USE_UNSECURE_STL_VECTORS_RELEASE ?
+   ###############################################################################################################
+   OPTION(USE_UNSECURE_STL_VECTORS_RELEASE "_SECURE_SCL=0" OFF)
+   IF(USE_UNSECURE_STL_VECTORS_RELEASE)
+      # More MSVC specific compilation flags
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_SECURE_SCL=0")
+      LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_SCL_SECURE_NO_WARNINGS")
+   ENDIF()
+
+   ###############################################################################################################
+   ## Flags
+   ###############################################################################################################
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "-D_CRT_SECURE_NO_DEPRECATE")
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/wd4996") #deprecated strcpy...
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/wd4800") #forcing value to bool 'true' or 'false' (performance warning)
+   LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/bigobj") #boost support
+
+   ###############################################################################################################
+   ## OpenMP support
+   ###############################################################################################################
+   IF(USE_OPENMP)
+   	LIST(APPEND CAB_COMPILER_ADDTIONAL_CXX_COMPILER_FLAGS "/openmp")
+   ENDIF()
+
+ENDMACRO(SET_COMPILER_SPECIFIC_FLAGS_INTERN build_type use64BitOptions)
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..761289edff637b8b07f16a0288cec85024aeabd8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,27 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+PROJECT(VirtualFluids)
+
+set(SOURCE_ROOT "../source")
+
+SET(USE_INTEL OFF CACHE BOOL "include Intel compiler support")
+SET(USE_GCC OFF CACHE BOOL "include gcc compiler support")
+
+#CAB
+INCLUDE("CMake/CMakeCABMacros.txt")
+
+LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DNOMINMAX)
+
+IF(${USE_INTEL})
+   SET(CAB_ADDITIONAL_LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS} -parallel)
+ENDIF()
+
+IF(${USE_GCC})
+   SET(CAB_ADDITIONAL_LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS} -lgomp)
+ENDIF()
+
+add_subdirectory(VirtualFluidsCore)
+
+set(APPS_ROOT "${SOURCE_ROOT}/Applications")
+INCLUDE(${APPS_ROOT}/Applications.cmake)
+
diff --git a/COPYING.txt b/COPYING.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b4e13b152135c1fbc01cbb9741f1b1e66d83c2f4
--- /dev/null
+++ b/COPYING.txt
@@ -0,0 +1,676 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+
diff --git a/Documentation/doxygen/VF_Doxyfile.dox b/Documentation/doxygen/VF_Doxyfile.dox
new file mode 100644
index 0000000000000000000000000000000000000000..36f2954a21c22d26d373fb39940340990dfe553b
--- /dev/null
+++ b/Documentation/doxygen/VF_Doxyfile.dox
@@ -0,0 +1,2561 @@
+# Doxyfile 1.8.16
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = VirtualFluidsCPU
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = VirtualFluidsLogo_lowResolution.png
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION  = None
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line
+# such as
+# /***************
+# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
+# Javadoc-style will behave just like regular comments and it will not be
+# interpreted by doxygen.
+# The default value is: NO.
+
+JAVADOC_BANNER         = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE  = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is
+# Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 5.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS   = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
+# methods of a class will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIV_VIRTUAL   = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# (including Cygwin) ands Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = ../../ \
+                         ../../VirtualFluidsCore \
+                         ../../ThirdParty
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.vhd \
+                         *.vhdl
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = main.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# entity all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see https://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          =
+
+# If clang assisted parsing is enabled you can provide the clang parser with the
+# path to the compilation database (see:
+# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
+# were built. This is equivalent to specifying the "-p" option to a clang tool,
+# such as clang-check. These options will then be passed to the parser.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse_libclang=ON option for CMake.
+
+CLANG_DATABASE_PATH    =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via Javascript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have Javascript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: https://developer.apple.com/xcode/), introduced with OSX
+# 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# https://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = YES
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when not enabling USE_PDFLATEX the default is latex when enabling
+# USE_PDFLATEX the default is pdflatex and when in the later case latex is
+# chosen this is overwritten by pdflatex. For specific output languages the
+# default can have been set differently, this depends on the implementation of
+# the output language.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# Note: This tag is used in the Makefile / make.bat.
+# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
+# (.tex).
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
+# generate index for LaTeX. In case there is no backslash (\) as first character
+# it will be automatically added in the LaTeX code.
+# Note: This tag is used in the generated output file (.tex).
+# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
+# The default value is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_MAKEINDEX_CMD    = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
+# path from which the emoji images will be read. If a relative path is entered,
+# it will be relative to the LATEX_OUTPUT directory. If left blank the
+# LATEX_OUTPUT directory will be used.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EMOJI_DIRECTORY  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# configuration file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's configuration file. A template extensions file can be
+# generated using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
+# namespace members in file scope as well, matching the HTML output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_NS_MEMB_FILE_SCOPE = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = VF_FETOL \
+                         VF_MPI \
+                         VF_METIS \
+                         VF_ZOLTAN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/Documentation/doxygen/VirtualFluidsLogo_lowResolution.png b/Documentation/doxygen/VirtualFluidsLogo_lowResolution.png
new file mode 100644
index 0000000000000000000000000000000000000000..06325f4d26a31a0b0a3b003ed57708f932eb5865
Binary files /dev/null and b/Documentation/doxygen/VirtualFluidsLogo_lowResolution.png differ
diff --git a/ThirdParty/MuParser/CMakePackage.txt b/ThirdParty/MuParser/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7b3edddf003d9a8052c848fe2b6c78f4cc2ce28a
--- /dev/null
+++ b/ThirdParty/MuParser/CMakePackage.txt
@@ -0,0 +1,36 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH)
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES outOption outSourceGroupName)
+
+IF( ${outOption} )
+
+   #verzeichnis als std-include adden
+   INCLUDE_DIRECTORIES( ${CURRENT_DIR}/include )
+
+   OPTION(USE_MUPARSER_AS_LIB "MuParser will be compiled as lib" ON)
+
+   IF(USE_MUPARSER_AS_LIB)
+     FILE( GLOB muparser_HEADER_FILES ${CURRENT_DIR}/include/*.h   )
+     FILE( GLOB muparser_CXX_FILES    ${CURRENT_DIR}/src/*.cpp )
+
+     SET(MUPARSER_SRC_FILES ${muparser_HEADER_FILES} ${muparser_CXX_FILES})
+
+     ADD_LIBRARY(muParserLib ${MUPARSER_SRC_FILES})
+     
+     #lib projekt hinzufuegen	  
+     LIST(APPEND CAB_ADDITIONAL_LINK_LIBRARIES muParserLib)
+     
+     ADD_TARGET_PROPERTIES(muParserLib COMPILE_FLAGS "-I${CURRENT_DIR}/include")
+     
+     #compilerflags aktuellem projekt hinzufuegen	  
+     ADD_COMPILER_FLAGS_TO_PROJECT(${CAB_COMPILER} "muParserLib" "CXX" "STATIC")
+
+   ELSE() #not as lib
+      SET( CURRENT_DIR_TMP ${CURRENT_DIR} ) #wird im nächsten befehl geaendert
+      INCLUDE( ${CURRENT_DIR_TMP}/include/CMakePackage.txt)
+      INCLUDE( ${CURRENT_DIR_TMP}/src/CMakePackage.txt)
+   ENDIF()
+
+ENDIF( ${outOption} )
+
+
+
diff --git a/ThirdParty/MuParser/Changes.txt b/ThirdParty/MuParser/Changes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..87077a5d972cf2f027bb2211aff587cf4469c7e4
--- /dev/null
+++ b/ThirdParty/MuParser/Changes.txt
@@ -0,0 +1,557 @@
+#######################################################################
+#                                                                     #
+#                                                                     #
+#                 __________                                          #
+#    _____   __ __\______   \_____  _______  ______  ____ _______     #
+#   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \    #
+#  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/    #
+#  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|       #
+#        \/                       \/            \/      \/            #
+#					  Fast math parser Library                        #
+#                                                                     #
+#  Copyright (C) 2015 Ingo Berg                                       #
+#                                                                     #
+#  Web:     muparser.beltoforion.de                                   #
+#  e-mail:  muparser@beltoforion.de                                   #
+#                                                                     #
+#                                                                     #
+#######################################################################
+ 
+
+History:
+--------
+
+Rev 2.2.5: 27.04.2015
+---------------------
+  Changes:
+   * example2 extended to work with UNICODE character set
+   * Applied patch from Issue 9
+   
+  Bugfixes:
+   * muChar_t in muParserDLL.h was not set properly when UNICODE was used
+   * muparser.dll did not build on UNICODE systems
+   
+Rev 2.2.4: 02.10.2014
+---------------------
+  Changes:
+   * explicit positive sign allowed
+
+  Bugfixes:
+   * Fix for Issue 6 (https://code.google.com/p/muparser/issues/detail?id=6)
+   * String constants did not work properly. Using more than a single one 
+     was impossible.
+   * Project Files for VS2008 and VS2010 removed from the repository 
+   * Fix for Issue 4 (https://code.google.com/p/muparser/issues/detail?id=4)
+   * Fix for VS2013 64 bit build option
+   * return type of ParserError::GetPos changed to int
+   * OpenMP support enabled in the VS2013 project files and precompiled windows DLL's
+   * Bulkmode did not evaluate properly if "=" and "," operator was used in the expression
+	
+Rev 2.2.3: 22.12.2012
+---------------------
+
+  Removed features:
+   * build files for msvc2005, borland and watcom compiler were removed
+
+  Bugfixes:
+   * Bugfix for Intel Compilers added: The power operator did not work properly 
+     with Intel C++ composer XE 2011.
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/5117983/index/page/1)
+   * Issue 3509860: Callbacks of functions with string parameters called twice
+     (see http://sourceforge.net/tracker/?func=detail&aid=3509860&group_id=137191&atid=737979)
+   * Issue 3570423: example1 shows slot number in hexadecimal
+     (see https://sourceforge.net/tracker/?func=detail&aid=3570423&group_id=137191&atid=737979)
+   * Fixes for compiling with the "MUP_MATH_EXCEPTIONS" macro definition:
+ 	- division by zero in constant expressions was reported with the code "ec_GENERIC" 
+          instead of "ecDIV_BY_ZERO"
+        - added throwing of "ecDOMAIN_ERROR" to sqrt and log functions
+
+
+Rev 2.2.2: 18.02.2012
+---------------------
+  Bugfixes:
+   * Optimizer did'nt work properly for division:
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825)
+
+Rev 2.2.1: 22.01.2012
+---------------------
+  Bugfixes:
+   * Optimizer bug in 64 bit systems fixed
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/4977977/index/page/1)
+	 
+Rev 2.2.0: 22.01.2012
+---------------------
+  Improvements:
+   * Optimizer rewritten and improved. In general: more optimizations are 
+     now applied to the bytecode. The downside is that callback Functions 
+     can no longer be flagged as non-optimizable. (The flag is still present 
+     but ignored) This is necessary since the optimizer had to call the 
+     functions in order to precalculate the result (see Bugfixes). These calls 
+     posed a problems for callback functions with side  effects and if-then-else 
+     clauses in general since they undermined the shortcut evaluation prinziple.
+
+  Bugfixes:
+   * Infix operators where not properly detected in the presence of a constant 
+     name starting with an underscore which is a valid character for infix 
+     operators too (i.e. "-_pi").
+   * Issue 3463353: Callback functions are called twice during the first call to eval.
+   * Issue 3447007: GetUsedVar unnecessaryly executes callback functions.
+
+
+Rev 2.1.0: 19.11.2011
+---------------------
+  New feature:
+   * Function atan2 added
+
+  Bugfixes:
+   * Issue 3438380:  Changed behaviour of tellg with GCC >4.6 led to failures  
+                     in value detection callbacks.
+   * Issue 3438715:  only "double" is a valid MUP_BASETYPE 
+                     MUP_BASETYPE can now be any of:
+                       float, 
+                       double, 
+                       long double, 
+                       short, 
+                       unsigned short, 
+                       unsigned int, 
+                       long,
+                       unsigned long. 
+                     Previousely only floating point types were allowed. 
+                     Using "int" is still not allowed!
+   * Compiler issues with GCC 4.6 fixed
+   * Custom value recognition callbacks added with AddValIdent had lower
+     priority than built in functions. This was causing problems with 
+     hex value recognition since detection of non hex values had priority
+     over the detection of hex values. The "0" in the hex prefix "0x" would 
+     be read as a separate non-hex number leaving the rest of the expression
+     unparseable.
+
+Rev 2.0.0: 04.09.2011
+---------------------
+This release introduces a new version numbering scheme in order to make
+future changes in the ABI apparent to users of the library. The number is
+now based on the SONAME property as used by GNU/Linux. 
+
+  Changes:
+   * Beginning with this version all version numbers will be SONAME compliant
+   * Project files for MSVC2010 added
+   * Project files for MSVC2003 removed
+   * Bytecode parsing engine cleaned up and rewritten
+   * Retrieving all results of expressions made up of comma separate 
+     subexpressions is now possible with a new Eval overload.
+   * Callback functions with fixed number of arguments can now have up to 10 
+     Parameters (previous limit was 5)
+
+  New features:
+   * ternary if-then-else operator added (C++ like; "(...) ? ... : ..." )
+   * new intrinsic binary operators: "&&", "||" (logical and, or)
+   * A new bulkmode allows submitting large arrays as variables to compute large 
+     numbers of expressions with a single call. This can drastically improve 
+     parsing performance when interfacing the library from managed languages like 
+     C#. (It doesn't bring any performance benefit for C++ users though...)
+
+  Removed features:
+   * intrinsic "and", "or" and "xor" operators have been removed. I'd like to let 
+     users the freedom of defining them on their own versions (either as logical or bitwise 
+     operators).
+   * Implementation for complex numbers removed. This was merely a hack. If you 
+     need complex numbers try muParserX which provides native support for them.
+     (see: http://beltoforion.de/muparserx/math_expression_parser_en.html)
+
+  Bugfixes:
+   * User defined operators could collide with built in operators that entirely 
+     contained their identifier. i.e. user defined "&" would not work with the built 
+     in "&&" operator since the user defined operator was detected with a higher 
+     priority resulting in a syntax error.
+   * Detection of unknown variables did not work properly in case a postfix operator
+     was defined which was part of the undefined variable.
+     i.e. If a postfix operator "m" was defined expressions like "multi*1.0" did
+     not detect "multi" as an undefined variable.
+     (Reference:  http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979)
+   * Postfix operators sharing the first few characters were causing bogus parsing exception.
+     (Reference: https://sourceforge.net/tracker/?func=detail&aid=3358571&group_id=137191&atid=737979)
+
+Rev 1.34: 04.09.2010
+--------------------
+  Changes:
+   * The prefix needed for parsing hex values is now "0x" and no longer "$". 
+   * AddValIdent reintroduced into the DLL interface
+
+  New features:
+   * The associativity of binary operators can now be changed. The pow operator 
+     is now right associative. (This is what Mathematica is using) 
+   * Seperator can now be used outside of functions. This allows compound 
+     expressions like:
+     "a=10,b=20,c=a*b" The last "argument" will be taken as the return value
+
+  Bugfixes:	
+   * The copy constructor did not copy binary operator definitions. Those were lost
+     in the copied parser instance.
+   * Mixing special characters and alphabetic characters in binary operator names 
+     led to inconsistent parsing behaviour when parsing expressions like "a ++ b" 
+     and "a++b" when "++" is defined as a binary operator. Binary operators must 
+     now consist entirely of special characters or of alphabetic ones.
+     (original bug report: https://sourceforge.net/projects/muparser/forums/forum/462843/topic/3696881/index/page/1)
+   * User defined operators were not exactly handled like built in operators. This 
+     led to inconsistencies in expression evaluation when using them. The results 
+     differed due to slightly different precedence rules.
+   * Using empty string arguments ("") would cause a crash of muParser
+
+
+Rev 1.32: 29.01.2010 
+--------------------
+
+  Changes:
+   * "example3" renamed to "example2"
+   * Project/Makefiles files are now provided for:
+           - msvc2003 
+           - msvc2005 
+           - msvc2008
+           - watcom   (makefile)
+           - mingw    (makefile)
+           - bcc      (makefile)
+   * Project files for borland cpp builder were removed
+
+
+  New features:
+   * Added function returning muparsers version number
+   * Added function for resetting the locale
+
+
+  Bugfixes:	
+   * Changes example1 in order to fix issues with irritating memory leak reports. 
+     Added conditional code for memory leak detection with MSVC in example1.
+     (see: http://www.codeproject.com/KB/recipes/FastMathParser.aspx?msg=3286367#xx3286367xx)
+   * Fixed some warnings for gcc
+
+
+
+Rev 1.31cp: 15.01.2010  (Maintainance release for CodeProject)
+----------------------
+
+  Changes:
+   * Archive structure changed
+   * C# wrapper added
+   * Fixed issued that prevented compiling with VS2010 Beta2
+    
+
+Rev 1.30: 09.06.2008
+--------------------
+
+  Changes:
+   * Epsilon of the numerical differentiation algorithm changed to allow greater accuracy.
+
+  New features:
+   * Setting thousands separator and decimal separator is now possible
+
+  Bugfixes:
+   * The dll interface did not provide a callback for functions without any arguments.	 
+	
+
+Rev 1.29: Januar 2008
+---------------------
+
+  Unrelease Version available only via SVN.
+
+
+Rev 1.28: 02. July, 2007
+---------------------------
+ 
+  Library changes:
+  * Interface for the dynamic library changed and extended to create an interface 
+    using pure C functions only. 
+  * mupInit() removed
+
+  Build system:
+   * MSVC7 Project files removed in favor of MSVC8
+
+  Bugfixes:
+   * The dynamic library did not build on other systems than linux due to a misplaced 
+     preprocessor definition. This is fixed now.
+
+
+Rev 1.27:
+---------------------------
+
+  Build system:
+   * Modified build\ directory layout introducing some subfolders 
+     for the various IDE supported
+   * Project files for BCB and MSVC7 added
+   * Switched to use bakefile 0.2.1 which now correctly creates the 
+     "make uninstall" target for autoconf's Makefile.in
+   * Now the library debug builds are named "muparserd" instead of "muparser"
+     to allow multiple mixed release/debug builds to coexist; so e.g. on Windows
+     when building with DEBUG=1, you'll get "muparserd.lib" instead of "muparser.lib"
+
+  New Features:
+   * Factory functions can now take a user defined pointer
+   * String functions can now be used with up to two additional 
+     double parameters
+   * Support for UNICODE character types added
+   * Infix operator priority can now be changed by the user
+
+  Bugfixes:
+   * An internal error was raised when evaluating an empty 
+     expressions
+   * The error message raised in case of name collisions between 
+     implicitely defined variables and postfix operators did contain
+     misleading data.
+
+
+Rev 1.26: (unofficial release)
+------------------------------
+
+  New Features:
+   * Unary operator precedence can now be changed by the user.
+
+
+Rev 1.25: 5. February, 2006
+---------------------------
+
+  Build system: (special thanks to Francesco Montorsi for implementing it!)
+    * created a bakefile-based build system which adds support for the following win32 compilers:
+      -> MS visual C++ (6 and .NET)
+      -> BorlandC++ (5 or greater)
+      -> Mingw32 (tested with gcc 3.2)
+      -> Watcom (not tested)
+      and for GCC on Unix (using a standard autoconf's configure script).
+
+  Compatibility improvements:
+    * fixed some small warnings when using -Wall with GCC on Unix
+    * added inclusion guards for win32-specific portions of code
+    * added fixes that remove compiler warnings on Intel C++ and the Solaris C++ compiler.
+
+
+Rev 1.24: 29. October, 2005
+---------------------------
+
+Changes:
+
+  Compatibility improvements:
+    * parser now works on 64 bit compilers
+    * (bytecode base datatype can now be changed freely)
+
+
+Rev 1.23: 19. October, 2005
+---------------------------
+
+Changes:
+
+  Bugfixes:
+    * Variable factory examples in Example1.cpp and Example3.cpp contained a subtle bug.
+
+  New features:
+    * Added a MSVC6 project file and introduced muParserFixes.h in order to make it compile with MSVC6
+
+
+Rev 1.22: October, 2005
+-----------------------
+
+Release notes:
+
+All features of Version 1.22 are similar to Version 1.21. Version 1.22 fixes a compilation issue with
+gcc 4.0. In order to fix this issue I rewrote part of the library to remove some unnecessary templates. 
+This should make the code cleaner. The Borland Project files were removed. If you want to use it 
+with Borland either use the dll version or create your own project files. I can't support it since I don't 
+have this compiler at hand.
+
+Changes:
+
+  Project Changes:
+    * Borland project files removed
+      (The code should still compile with BCB but I cant provide you with project files)
+
+  Internal Changes:
+    * unnecessary template files have been removed:
+        - new files: muParserError.cpp, muParserTokenReader.cpp, muParserCallback.cpp
+        - removed Files: muIParserTypes.h
+
+
+Rev 1.2 / 1.21: April, 2005
+---------------------------
+
+Release Notes:
+First of all the interface has changed so this version is not backwards compatible.
+After receiving a couple of questions about it, this version features support for
+user defined binary operators. Consequently the built in operators can now be 
+turned off, thus you can deactivate them and write complete customized parser
+subclasses that only contain the functionality you want. Another new feature is 
+the introduction of callback functions taking string arguments, implicit 
+generation of variables and the Assignement operator.
+
+  Functionality
+    * New built in operator: xor; Logical xor.
+    * New built in operator: Assignement operator; Defining variables in terms of 
+                             other variables/constants
+    * New feature: Strings as arguments for callback functions
+    * New feature: User defined binary operators
+    * New feature: ParserInt a class with a sample implementation for
+                     integer numbers.
+    * New feature: Callbacks to value regognition functions.
+
+    * Removed:  all predefined postfix operators have been removed.
+    * New project file:  Now comes with a ready to use windows DLL.
+    * New project file:  Makefile for cygwin now included.
+    * New example:  Example3 shows usage of the DLL.
+
+  Interface changes
+    * New member function: DefineOprt For adding user defined binary operators.
+    * New member function: EnableBuiltInOprt(bool) Enables/Disables built in 
+                           binary operators.
+    * New member function: AddValIdent(...) to add callbacks for custom value 
+                           recognition functions.
+    * Removed: SetVar(), SetConst().
+    * Renamed: Most interface functions have been renamed
+    * Changed: The type for multiargument callbacks multfun_type has changed. 
+               It no longer takes a std::vector as input.
+
+  Internal changes
+    * new class muParserTokenReader.h encapsulates the token identification 
+      and token assignement.
+    * Internal handling of function callbacks unified as a result the performance 
+      of the bytecode evaluation increased.
+
+
+Rev 1.10 : December 30, 2004
+----------------------------
+
+Release Notes:
+This version does not contain major new feature compared to V1.07 but its internal structure has
+changed significantly. The String parsing routine is slower than the one of V1.07 but bytecode
+parsing is equally fast. On the other hand the error messages of V1.09 are more flexible and you
+can change its value datatype. It should work on 64-bit systems. For this reason I supply both
+versions for download. If you use V1.07 and are happy with it there is no need for updating
+your version.
+
+    * New example program: Archive now contains two demo programs: One for standard C++ and one for
+                           managed C++.
+    * New member function: RemoveVar(...) can be used for removing a single variable from the internal 
+                           storage.
+    * New member function: GetVar() can be used for querying the variable names and pointers of all
+                           variables defined in the parser.
+    * New member function: GetConst() can be used for querying all defined constants and their values.
+    * New member function: GetFunDef() can be used for querying all defined functions and the number of
+                           arguments they expect.
+    * Internal structure changed; hanging base datatype at compile time is now possible.
+    * Bugfix: Postfix operator parsing could fail in certain cases; This has been fixed now.
+    * Bugfix: Variable names must will now be tested if they conflict with constant or function names.
+    * Internal change:  Removed most dependencies from the C-string libraries.
+    * Internal change:  Bytecode is now stored in a separate class: ParserByteCode.h
+    * Internal change:  GetUsedVar() does no longer require that variables are defined at time of call.
+    * Internal change:  Error treatment changed. ParserException is no longer derived from
+                        std::runtime_error; Internal treatment of Error messages changed.
+    * New functions in Parser interface: ValidNameChars(), ValidOprtChars() and ValidPrefixOprtChars()
+                        they are used for defining the charset allowed for variable-, operator- and
+                        function names.
+
+
+Rev 1.09 : November 20, 2004
+----------------------------
+
+    * New member function:  RemoveVar(...) can be used for removing a single variable from the internal 
+                            storage.
+    * Internal structure changed; changing base datatype at compile time is now possible.
+    * Bug fix: Postfix operator parsing could fail in certain cases; This has been fixed now.
+    * Internal change:  Removed most dependencies from the C-string libraries.
+    * Internal change:  Bytecode is now stored in a seperate class: ParserByteCode.h.
+    * Internal change:  GetUsedVar() does no longer require that variables are defined at time of call.
+    * Internal change:  Error treatment changed. ParserException is no longer derived from 
+                        std::runtime_error; Internal treatment of Error messages changed.
+    * New functions in Parser interface; ValidNameChars(), ValidOprtChars() and ValidPrefixOprtChars()
+      they are used for defining the charset allowed for variable-, operator- and function names.
+
+
+Rev 1.08 : November, 2004 
+-------------------------
+
+    * unpublished; experimental template version with respect to data type and underlying string
+      type (string <-> widestring). The idea was dropped...
+
+
+Rev 1.07 : September 4 2004
+---------------------------
+
+    * Improved portability; Changes to make life for MSVC 6 user easier, there are probably still some
+      issues left.
+    * Improved portability; Changes in order to allow compiling on BCB.
+    * New function; value_type Diff(value_type *a_Var, value_type a_fPos) 4th order Differentiation with
+      respect to a certain variable; added in muParser.h.
+
+
+Rev 1.06 : August 20 2004
+-------------------------
+
+    * Volatile functions added; All overloaded AddFun(...) functions can now take a third parameter
+      indicating that the function can not be optimized.
+    * Internal changes: muParserStack.h simplified; refactorings
+    * Parser is now distributed under the MIT License; all comments changed accordingly.
+
+
+Rev 1.05 : August 20 2004
+-------------------------
+
+    * Variable/constant names will now be checked for invalid characters.
+    * Querying the names of all variables used in an expression is now possible; new function: GetUsedVar().
+    * Disabling bytecode parsing is now possible; new function: EnableByteCode(bool bStat).
+    * Predefined functions with variable number of arguments added: sum, avg, min, max.
+    * Unary prefix operators added; new functions: AddPrefixOp(...), ClearPrefixOp().
+    * Postfix operator interface names changed; new function names: AddPostfixOp(...), ClearPostfixOp().
+    * Hardcoded sign operators removed in favor of prefix operators; bytecode format changed accordingly.
+    * Internal changes: static array removed in Command code calculation routine; misc. changes.
+
+
+Rev 1.04 : August 16 2004
+-------------------------
+
+    * Support for functions with variable number of arguments added.
+    * Internal structure changed; new: ParserBase.h, ParserBase.cpp; removed: ParserException.h;
+      changed: Parser.h, Parser.cpp.
+    * Bug in the bytecode calculation function fixed (affected the unary minus operator).
+    * Optimizer can be deactivated; new function: EnableOptimizer(bool bStat).
+
+
+Rev 1.03 : August 10 2004
+-------------------------
+
+    * Support for user-defined unary postfix operators added; new functions: AddPostOp(), InitPostOp(),
+      ClearPostOp().
+    * Minor changes to the bytecode parsing routine.
+    * User defined functions can now have up to four parameters.
+    * Performance optimized: simple formula optimization added; (precalculation of constant parts of the
+      expression).
+    * Bug fixes: Multi-arg function parameters, constant name lookup and unary minus did not work properly.
+
+
+Rev 1.02 : July 30 2004
+-----------------------
+
+    * Support for user defined constants added; new functions: InitConst(), AddConst(), SetConst(),
+      ClearConst().
+    * Single variables can now be added using AddVar(); you have now the choice of adding them either
+      one by one or all at the same time using SetVar(const varmap_type &a_vVar).
+    * Internal handling of variables changed, is now similar to function handling.
+    * Virtual destructor added; InitFun(), InitConst() are now virtual too thus making it possible to
+      derive new parsers with a modified set of default functions and constants.
+    * Support for user defined functions with 2 or 3 parameters added; bytecode format changed to hold
+      function parameter count.
+
+
+Rev 1.01 : July 23 2004
+-----------------------
+
+    * Support for user defined functions has been added; new functions: AddFun(), ClearFun(),
+      InitFunctions().
+    * Built in constants have been removed; the parser contained undocumented built in
+      constants pi, e.
+      There was the possibility of name conflicts with user defined variables.
+    * Setting multiple variables with SetVar can now be done with a map of names and pointers as the only
+      argument. For this reason, a new type Parser::varmap_type was added. The old version that took 3
+      arguments (array of names, array of pointers, and array length) is now marked as deprecated.
+    * The names of logarithm functions have changed. The new names are: log2 for base 2, log10 or log for
+      base 10, and ln for base e.
+
+
+Rev 1.00 : July 21 2004
+-----------------------
+
+    * Initial release
diff --git a/ThirdParty/MuParser/Install.txt b/ThirdParty/MuParser/Install.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ed8ae9728225a79668c96db46d42ffda77f610a6
--- /dev/null
+++ b/ThirdParty/MuParser/Install.txt
@@ -0,0 +1,133 @@
+#######################################################################
+#                                                                     #
+#                                                                     #
+#                 __________                                          #
+#    _____   __ __\______   \_____  _______  ______  ____ _______     #
+#   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \    #
+#  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/    #
+#  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|       #
+#        \/                       \/            \/      \/            #
+#					  Fast math parser Library    #
+#                                                                     #
+#  Copyright (C) 2012 Ingo Berg                                       #
+#                                                                     #
+#  Web:     muparser.beltoforion.de                                   #
+#  e-mail:  muparser@beltoforion.de                                   #
+#                                                                     #
+#                                                                     #
+#######################################################################
+
+
+
+ Contents
+ ========
+
+ 1. Installation on win32
+ 2. Installation on unix
+    2.1 Other miscellaneous info Unix-specific
+ 3. Where to ask for help
+
+
+
+ 1. Installation on win32
+ ========================
+
+ muParser supports various win32 command-line compilers:
+ -> mingw
+ -> watcom
+ -> microsoft CL
+ and provides also the project files for MSVC6 IDE.
+
+ In order to compile muParser from makefiles, open an MSDOS
+ prompt and then move to the muParser/build directory and
+ type:
+   
+   mingw32-make -fmakefile.mingw    for mingw
+   nmake -fmakefile.vc              for msvc
+   make -fmakefile.bcc              for borland
+   wmake -fmakefile.wat             for watcom
+
+ All makefiles supports the following options:
+
+        # Set to 1 to build debug version [0,1]
+        #   0 - Release
+        #   1 - Debug
+        DEBUG = 0
+
+        # Set to 1 to build shared (DLL) version [0,1]
+        #   0 - Static
+        #   1 - DLL
+        SHARED = 0
+
+        # Set to 1 to compile samples [0,1]
+        SAMPLES = 1
+
+ The muParser library is created in the 'lib' folder and the sample
+ binaries are created in samples\example1 or samples\example2.
+
+ NOTE: samples\example1 can be compiled *only* when building
+       muParser as a STATIC library (SHARED=0).
+       samples\example2 can be compiled *only* when building
+       muParser as a SHARED library (SHARED=1).
+
+
+
+ 2. Installation on Unix/Linux
+ =============================
+
+ muParser can be installed just extracting the sources somewhere
+ and then, from a terminal, typing:
+
+   cd [path to muParser]
+   ./configure [--enable-shared=yes/no] [--enable-samples=yes/no]
+               [--enable-debug=yes/no]
+   make
+   [sudo*] make install
+   [sudo*] ldconfig
+   cd samples/example1
+   ./example1
+
+ * = this command must be executed with root permissions and thus
+     you have to use 'sudo' or just 'su' to gain root access.
+     Note that installation and ldconfig are not strictly required unless
+     you built in shared mode.
+
+ The "make" step will create the muParser library in 'lib' and the
+ sample binary in samples/example1.
+ The samples/example2 is win32-specific and thus won't be built.
+
+
+
+ 2.1 Other miscellaneous info Unix-specific
+ ==========================================
+
+ If you don't like to have your muParser folder filled by temporary
+ files created by GCC, then you can do the following:
+
+    mkdir mybuild && cd mybuild && ../configure && make
+
+ to put all object files in the "mybuild" directory.
+
+ If you want to use muParser library in your programs, you can use
+ the pkg-config program (this works only if muParser was installed
+ with 'make install' !). The commands:
+
+   pkg-config muparser --cflags
+   pkg-config muparser --libs
+
+ will return all useful info you need to build your programs against
+ muParser !
+
+
+
+ 3. Where to ask for help
+ ========================
+
+ If you find problems with either compilation, installation or usage
+ of muParser, then you can ask in the muParser forum at:
+
+  https://sourceforge.net/forum/forum.php?forum_id=462843
+
+ For more info about muParser, visit:
+  http://sourceforge.net/projects/muparser/
+  http://muparser.sourceforge.net
diff --git a/ThirdParty/MuParser/License.txt b/ThirdParty/MuParser/License.txt
new file mode 100644
index 0000000000000000000000000000000000000000..64286563696c3eb4d0c55ff572ac5c9aae3aecaa
--- /dev/null
+++ b/ThirdParty/MuParser/License.txt
@@ -0,0 +1,35 @@
+#######################################################################
+#                                                                     #
+#                                                                     #
+#                 __________                                          #
+#    _____   __ __\______   \_____  _______  ______  ____ _______     #
+#   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \    #
+#  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/    #
+#  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|       #
+#        \/                       \/            \/      \/            #
+#					  Fast math parser Library    #
+#                                                                     #
+#  Copyright (C) 2011 Ingo Berg                                       #
+#                                                                     #
+#  Web:     muparser.beltoforion.de                                   #
+#  e-mail:  muparser@beltoforion.de                                   #
+#                                                                     #
+#                                                                     #
+#######################################################################
+
+
+  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. 
+  OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ThirdParty/MuParser/docs/Doxyfile b/ThirdParty/MuParser/docs/Doxyfile
new file mode 100644
index 0000000000000000000000000000000000000000..9793afe34369e1dc4c9300d19984a89952d06ee1
--- /dev/null
+++ b/ThirdParty/MuParser/docs/Doxyfile
@@ -0,0 +1,1563 @@
+# Doxyfile 1.6.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "muParser API -"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 1.35
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = html/
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = YES
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 16
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set
+# FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = YES
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = html/misc/Main.txt \
+                         html/misc/example.txt \
+                         ../src/ \
+                         ../include/
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = html/misc/
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = classdocu/
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = html/misc/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help  
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvances is that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif 
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = jpg
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = "C:\Program Files (x86)\Graphviz2.20\bin"
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/ThirdParty/MuParser/docs/muparser_doc.html b/ThirdParty/MuParser/docs/muparser_doc.html
new file mode 100644
index 0000000000000000000000000000000000000000..09dbba14393dc6c06a6a64d126f8ad29439e4146
--- /dev/null
+++ b/ThirdParty/MuParser/docs/muparser_doc.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html style="height:100%;">
+<head>
+</head>
+
+<body style="height:100%; overflow:hidden;"> 
+
+  <div style="border: 0px; position:absolute; top:0px; left:0px; width:100%; bottom:0px; padding:0px; margin:0px;"> 
+    <iframe src="http://muparser.beltoforion.de" style="border: 0px; width:100%; height:100%;">
+    Sorry, your browser doesn't support IFrames. Click <a href="http://muparser.beltoforion.de">here</a> to load the muparser documentation directly.
+    </iframe>
+  </div>
+</body>
+
+</html>
diff --git a/ThirdParty/MuParser/include/muParser.h b/ThirdParty/MuParser/include/muParser.h
new file mode 100644
index 0000000000000000000000000000000000000000..451cf703611b7932f421254b6dfcb2940d18978a
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParser.h
@@ -0,0 +1,115 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+#ifndef MU_PARSER_H
+#define MU_PARSER_H
+
+//--- Standard includes ------------------------------------------------------------------------
+#include <vector>
+
+//--- Parser includes --------------------------------------------------------------------------
+#include "muParserBase.h"
+#include "muParserTemplateMagic.h"
+
+/** \file
+    \brief Definition of the standard floating point parser.
+*/
+
+namespace mu
+{
+  /** \brief Mathematical expressions parser.
+    
+    Standard implementation of the mathematical expressions parser. 
+    Can be used as a reference implementation for subclassing the parser.
+
+    <small>
+    (C) 2011 Ingo Berg<br>
+    muparser(at)beltoforion.de
+    </small>
+  */
+  /* final */ class Parser : public ParserBase
+  {
+  public:
+
+    Parser();
+
+    virtual void InitCharSets();
+    virtual void InitFun();
+    virtual void InitConst();
+    virtual void InitOprt();
+    virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
+
+    value_type Diff(value_type *a_Var, 
+                    value_type a_fPos, 
+                    value_type a_fEpsilon = 0) const;
+
+  protected:
+
+    // Trigonometric functions
+    static value_type  Sin(value_type);
+    static value_type  Cos(value_type);
+    static value_type  Tan(value_type);
+    static value_type  Tan2(value_type, value_type);
+    // arcus functions
+    static value_type  ASin(value_type);
+    static value_type  ACos(value_type);
+    static value_type  ATan(value_type);
+    static value_type  ATan2(value_type, value_type);
+
+    // hyperbolic functions
+    static value_type  Sinh(value_type);
+    static value_type  Cosh(value_type);
+    static value_type  Tanh(value_type);
+    // arcus hyperbolic functions
+    static value_type  ASinh(value_type);
+    static value_type  ACosh(value_type);
+    static value_type  ATanh(value_type);
+    // Logarithm functions
+    static value_type  Log2(value_type);  // Logarithm Base 2
+    static value_type  Log10(value_type); // Logarithm Base 10
+    static value_type  Ln(value_type);    // Logarithm Base e (natural logarithm)
+    // misc
+    static value_type  Exp(value_type);
+    static value_type  Abs(value_type);
+    static value_type  Sqrt(value_type);
+    static value_type  Rint(value_type);
+    static value_type  Sign(value_type);
+
+    // Prefix operators
+    // !!! Unary Minus is a MUST if you want to use negative signs !!!
+    static value_type  UnaryMinus(value_type);
+    static value_type  UnaryPlus(value_type);
+
+    // Functions with variable number of arguments
+    static value_type Sum(const value_type*, int);  // sum
+    static value_type Avg(const value_type*, int);  // mean value
+    static value_type Min(const value_type*, int);  // minimum
+    static value_type Max(const value_type*, int);  // maximum
+
+    static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal);
+  };
+} // namespace mu
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserBase.h b/ThirdParty/MuParser/include/muParserBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..a37927306ebe44c8b55de6f56cfd47edbb6b9349
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserBase.h
@@ -0,0 +1,317 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+#ifndef MU_PARSER_BASE_H
+#define MU_PARSER_BASE_H
+
+//--- Standard includes ------------------------------------------------------------------------
+#include <cmath>
+#include <string>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <locale>
+#include <limits.h>
+
+//--- Parser includes --------------------------------------------------------------------------
+#include "muParserDef.h"
+#include "muParserStack.h"
+#include "muParserTokenReader.h"
+#include "muParserBytecode.h"
+#include "muParserError.h"
+
+
+namespace mu
+{
+/** \file
+    \brief This file contains the class definition of the muparser engine.
+*/
+
+//--------------------------------------------------------------------------------------------------
+/** \brief Mathematical expressions parser (base parser engine).
+    \author (C) 2013 Ingo Berg
+
+  This is the implementation of a bytecode based mathematical expressions parser. 
+  The formula will be parsed from string and converted into a bytecode. 
+  Future calculations will be done with the bytecode instead the formula string
+  resulting in a significant performance increase. 
+  Complementary to a set of internally implemented functions the parser is able to handle 
+  user defined functions and variables. 
+*/
+class ParserBase 
+{
+friend class ParserTokenReader;
+
+private:
+
+    /** \brief Typedef for the parse functions. 
+    
+      The parse function do the actual work. The parser exchanges
+      the function pointer to the parser function depending on 
+      which state it is in. (i.e. bytecode parser vs. string parser)
+    */
+    typedef value_type (ParserBase::*ParseFunction)() const;  
+
+    /** \brief Type used for storing an array of values. */
+    typedef std::vector<value_type> valbuf_type;
+
+    /** \brief Type for a vector of strings. */
+    typedef std::vector<string_type> stringbuf_type;
+
+    /** \brief Typedef for the token reader. */
+    typedef ParserTokenReader token_reader_type;
+    
+    /** \brief Type used for parser tokens. */
+    typedef ParserToken<value_type, string_type> token_type;
+
+    /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
+    static const int s_MaxNumOpenMPThreads = 16;
+
+ public:
+
+    /** \brief Type of the error class. 
+    
+      Included for backwards compatibility.
+    */
+    typedef ParserError exception_type;
+
+    static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
+
+    ParserBase(); 
+    ParserBase(const ParserBase &a_Parser);
+    ParserBase& operator=(const ParserBase &a_Parser);
+
+    virtual ~ParserBase();
+    
+	  value_type  Eval() const;
+    value_type* Eval(int &nStackSize) const;
+    void Eval(value_type *results, int nBulkSize);
+
+    int GetNumResults() const;
+
+    void SetExpr(const string_type &a_sExpr);
+    void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
+
+    void SetDecSep(char_type cDecSep);
+    void SetThousandsSep(char_type cThousandsSep = 0);
+    void ResetLocale();
+
+    void EnableOptimizer(bool a_bIsOn=true);
+    void EnableBuiltInOprt(bool a_bIsOn=true);
+
+    bool HasBuiltInOprt() const;
+    void AddValIdent(identfun_type a_pCallback);
+
+    /** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) 
+        \brief Define a parser function without arguments.
+        \param a_strName Name of the function
+        \param a_pFun Pointer to the callback function
+        \param a_bAllowOpt A flag indicating this function may be optimized
+    */
+    template<typename T>
+    void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true)
+    {
+      AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
+    }
+
+    void DefineOprt(const string_type &a_strName, 
+                    fun_type2 a_pFun, 
+                    unsigned a_iPri=0, 
+                    EOprtAssociativity a_eAssociativity = oaLEFT,
+                    bool a_bAllowOpt = false);
+    void DefineConst(const string_type &a_sName, value_type a_fVal);
+    void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);
+    void DefineVar(const string_type &a_sName, value_type *a_fVar);
+    void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
+    void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);
+
+    // Clear user defined variables, constants or functions
+    void ClearVar();
+    void ClearFun();
+    void ClearConst();
+    void ClearInfixOprt();
+    void ClearPostfixOprt();
+    void ClearOprt();
+    
+    void RemoveVar(const string_type &a_strVarName);
+    const varmap_type& GetUsedVar() const;
+    const varmap_type& GetVar() const;
+    const valmap_type& GetConst() const;
+    const string_type& GetExpr() const;
+    const funmap_type& GetFunDef() const;
+    string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
+
+    const char_type ** GetOprtDef() const;
+    void DefineNameChars(const char_type *a_szCharset);
+    void DefineOprtChars(const char_type *a_szCharset);
+    void DefineInfixOprtChars(const char_type *a_szCharset);
+
+    const char_type* ValidNameChars() const;
+    const char_type* ValidOprtChars() const;
+    const char_type* ValidInfixOprtChars() const;
+
+    void SetArgSep(char_type cArgSep);
+    char_type GetArgSep() const;
+    
+    void  Error(EErrorCodes a_iErrc, 
+                int a_iPos = (int)mu::string_type::npos, 
+                const string_type &a_strTok = string_type() ) const;
+
+ protected:
+	  
+    void Init();
+
+    virtual void InitCharSets() = 0;
+    virtual void InitFun() = 0;
+    virtual void InitConst() = 0;
+    virtual void InitOprt() = 0; 
+
+    virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
+
+    static const char_type *c_DefaultOprt[]; 
+    static std::locale s_locale;  ///< The locale used by the parser
+    static bool g_DbgDumpCmdCode;
+    static bool g_DbgDumpStack;
+
+    /** \brief A facet class used to change decimal and thousands separator. */
+    template<class TChar>
+    class change_dec_sep : public std::numpunct<TChar>
+    {
+    public:
+      
+      explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
+        :std::numpunct<TChar>()
+        ,m_nGroup(nGroup)
+        ,m_cDecPoint(cDecSep)
+        ,m_cThousandsSep(cThousandsSep)
+      {}
+      
+    protected:
+      
+      virtual char_type do_decimal_point() const
+      {
+        return m_cDecPoint;
+      }
+
+      virtual char_type do_thousands_sep() const
+      {
+        return m_cThousandsSep;
+      }
+
+      virtual std::string do_grouping() const 
+      { 
+		// fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
+		// courtesy of Jens Bartsch
+		// original code:
+		//        return std::string(1, (char)m_nGroup); 
+		// new code:
+		return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));
+      }
+
+    private:
+
+      int m_nGroup;
+      char_type m_cDecPoint;  
+      char_type m_cThousandsSep;
+    };
+
+ private:
+
+    void Assign(const ParserBase &a_Parser);
+    void InitTokenReader();
+    void ReInit() const;
+
+    void AddCallback( const string_type &a_strName, 
+                      const ParserCallback &a_Callback, 
+                      funmap_type &a_Storage,
+                      const char_type *a_szCharSet );
+
+    void ApplyRemainingOprt(ParserStack<token_type> &a_stOpt,
+                                ParserStack<token_type> &a_stVal) const;
+    void ApplyBinOprt(ParserStack<token_type> &a_stOpt,
+                      ParserStack<token_type> &a_stVal) const;
+
+    void ApplyIfElse(ParserStack<token_type> &a_stOpt,
+                     ParserStack<token_type> &a_stVal) const;
+
+    void ApplyFunc(ParserStack<token_type> &a_stOpt,
+                   ParserStack<token_type> &a_stVal, 
+                   int iArgCount) const; 
+
+    token_type ApplyStrFunc(const token_type &a_FunTok,
+                            const std::vector<token_type> &a_vArg) const;
+
+    int GetOprtPrecedence(const token_type &a_Tok) const;
+    EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
+
+    void CreateRPN() const;
+
+    value_type ParseString() const; 
+    value_type ParseCmdCode() const;
+    value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;
+
+    void  CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
+    void  CheckOprt(const string_type &a_sName,
+                    const ParserCallback &a_Callback,
+                    const string_type &a_szCharSet) const;
+
+    void StackDump(const ParserStack<token_type > &a_stVal, 
+                   const ParserStack<token_type > &a_stOprt) const;
+
+    /** \brief Pointer to the parser function. 
+    
+      Eval() calls the function whose address is stored there.
+    */
+    mutable ParseFunction  m_pParseFormula;
+    mutable ParserByteCode m_vRPN;        ///< The Bytecode class.
+    mutable stringbuf_type  m_vStringBuf; ///< String buffer, used for storing string function arguments
+    stringbuf_type  m_vStringVarBuf;
+
+    std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
+
+    funmap_type  m_FunDef;         ///< Map of function names and pointers.
+    funmap_type  m_PostOprtDef;    ///< Postfix operator callbacks
+    funmap_type  m_InfixOprtDef;   ///< unary infix operator.
+    funmap_type  m_OprtDef;        ///< Binary operator callbacks
+    valmap_type  m_ConstDef;       ///< user constants.
+    strmap_type  m_StrVarDef;      ///< user defined string constants
+    varmap_type  m_VarDef;         ///< user defind variables.
+
+    bool m_bBuiltInOp;             ///< Flag that can be used for switching built in operators on and off
+
+    string_type m_sNameChars;      ///< Charset for names
+    string_type m_sOprtChars;      ///< Charset for postfix/ binary operator tokens
+    string_type m_sInfixOprtChars; ///< Charset for infix operator tokens
+    
+    mutable int m_nIfElseCounter;  ///< Internal counter for keeping track of nested if-then-else clauses
+
+    // items merely used for caching state information
+    mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
+    mutable int m_nFinalResultIdx;
+};
+
+} // namespace mu
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserBytecode.h b/ThirdParty/MuParser/include/muParserBytecode.h
new file mode 100644
index 0000000000000000000000000000000000000000..33e3c26c0a1cc0dbfb92c751698ae7414b7044d1
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserBytecode.h
@@ -0,0 +1,141 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2013 Ingo Berg
+
+  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. 
+*/
+#ifndef MU_PARSER_BYTECODE_H
+#define MU_PARSER_BYTECODE_H
+
+#include <cassert>
+#include <string>
+#include <stack>
+#include <vector>
+
+#include "muParserDef.h"
+#include "muParserError.h"
+#include "muParserToken.h"
+
+/** \file
+    \brief Definition of the parser bytecode class.
+*/
+
+
+namespace mu
+{
+  struct SToken
+  {
+    ECmdCode Cmd;
+    int StackPos;
+
+    union
+    {
+      struct //SValData
+      {
+        value_type *ptr;
+        value_type  data;
+        value_type  data2;
+      } Val;
+
+      struct //SFunData
+      {
+        // Note: generic_fun_type is merely a placeholder. The real type could be 
+        //       anything between gun_type1 and fun_type9. I can't use a void
+        //       pointer due to constraints in the ANSI standard which allows
+        //       data pointers and function pointers to differ in size.
+        generic_fun_type ptr;
+        int   argc;
+        int   idx;
+      } Fun;
+
+      struct //SOprtData
+      {
+        value_type *ptr;
+        int offset;
+      } Oprt;
+    };
+  };
+  
+  
+  /** \brief Bytecode implementation of the Math Parser.
+
+  The bytecode contains the formula converted to revers polish notation stored in a continious
+  memory area. Associated with this data are operator codes, variable pointers, constant 
+  values and function pointers. Those are necessary in order to calculate the result.
+  All those data items will be casted to the underlying datatype of the bytecode.
+
+  \author (C) 2004-2013 Ingo Berg 
+*/
+class ParserByteCode
+{
+private:
+
+    /** \brief Token type for internal use only. */
+    typedef ParserToken<value_type, string_type> token_type;
+
+    /** \brief Token vector for storing the RPN. */
+    typedef std::vector<SToken> rpn_type;
+
+    /** \brief Position in the Calculation array. */
+    unsigned m_iStackPos;
+
+    /** \brief Maximum size needed for the stack. */
+    std::size_t m_iMaxStackSize;
+    
+    /** \brief The actual rpn storage. */
+    rpn_type  m_vRPN;
+
+    bool m_bEnableOptimizer;
+
+    void ConstantFolding(ECmdCode a_Oprt);
+
+public:
+
+    ParserByteCode();
+    ParserByteCode(const ParserByteCode &a_ByteCode);
+    ParserByteCode& operator=(const ParserByteCode &a_ByteCode);
+    void Assign(const ParserByteCode &a_ByteCode);
+
+    void AddVar(value_type *a_pVar);
+    void AddVal(value_type a_fVal);
+    void AddOp(ECmdCode a_Oprt);
+    void AddIfElse(ECmdCode a_Oprt);
+    void AddAssignOp(value_type *a_pVar);
+    void AddFun(generic_fun_type a_pFun, int a_iArgc);
+    void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
+    void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);
+
+    void EnableOptimizer(bool bStat);
+
+    void Finalize();
+    void clear();
+    std::size_t GetMaxStackSize() const;
+    std::size_t GetSize() const;
+
+    const SToken* GetBase() const;
+    void AsciiDump();
+};
+
+} // namespace mu
+
+#endif
+
+
diff --git a/ThirdParty/MuParser/include/muParserCallback.h b/ThirdParty/MuParser/include/muParserCallback.h
new file mode 100644
index 0000000000000000000000000000000000000000..578bda0410b9030bfcccb069c8344def8c5501bf
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserCallback.h
@@ -0,0 +1,118 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2011 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_CALLBACK_H
+#define MU_PARSER_CALLBACK_H
+
+#include "muParserDef.h"
+
+/** \file
+    \brief Definition of the parser callback class.
+*/
+
+namespace mu
+{
+
+/** \brief Encapsulation of prototypes for a numerical parser function.
+
+    Encapsulates the prototyp for numerical parser functions. The class
+    stores the number of arguments for parser functions as well
+    as additional flags indication the function is non optimizeable.
+    The pointer to the callback function pointer is stored as void* 
+    and needs to be casted according to the argument count.
+    Negative argument counts indicate a parser function with a variable number
+    of arguments. 
+
+    \author (C) 2004-2011 Ingo Berg
+*/
+class ParserCallback
+{
+public:
+    ParserCallback(fun_type0  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type1  a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
+    ParserCallback(fun_type2  a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity);
+    ParserCallback(fun_type2  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type3  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type4  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type5  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type6  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type7  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type8  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type9  a_pFun, bool a_bAllowOpti);
+    ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti);
+
+    ParserCallback(bulkfun_type0  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type1  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type2  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type3  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type4  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type5  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type6  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type7  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type8  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type9  a_pFun, bool a_bAllowOpti);
+    ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti);
+
+    ParserCallback(multfun_type a_pFun, bool a_bAllowOpti);
+    ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti);
+    ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);
+    ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);
+    ParserCallback();
+    ParserCallback(const ParserCallback &a_Fun);
+    
+    ParserCallback* Clone() const;
+
+    bool  IsOptimizable() const;
+    void* GetAddr() const;
+    ECmdCode  GetCode() const;
+    ETypeCode GetType() const;
+    int GetPri()  const;
+    EOprtAssociativity GetAssociativity() const;
+    int GetArgc() const;
+
+private:
+    void *m_pFun;                   ///< Pointer to the callback function, casted to void
+    
+    /** \brief Number of numeric function arguments
+    
+        This number is negative for functions with variable number of arguments. in this cases
+        they represent the actual number of arguments found.
+    */
+    int   m_iArgc;      
+    int   m_iPri;                   ///< Valid only for binary and infix operators; Operator precedence.
+    EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators 
+    ECmdCode  m_iCode;
+    ETypeCode m_iType;
+    bool  m_bAllowOpti;             ///< Flag indication optimizeability 
+};
+
+//------------------------------------------------------------------------------
+/** \brief Container for Callback objects. */
+typedef std::map<string_type, ParserCallback> funmap_type; 
+
+} // namespace mu
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserDLL.h b/ThirdParty/MuParser/include/muParserDLL.h
new file mode 100644
index 0000000000000000000000000000000000000000..180b4760ed0018426a22903e0521fa38f5976b9d
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserDLL.h
@@ -0,0 +1,241 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  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. 
+*/
+#ifndef MU_PARSER_DLL_H
+#define MU_PARSER_DLL_H
+
+#if defined(WIN32) || defined(_WIN32)
+    #ifdef MUPARSERLIB_EXPORTS
+        #define API_EXPORT(TYPE) __declspec(dllexport) TYPE __cdecl
+    #else
+        #define API_EXPORT(TYPE) __declspec(dllimport) TYPE __cdecl
+    #endif
+#else
+    #define API_EXPORT(TYPE) TYPE
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/** \file 
+    \brief This file contains the DLL interface of muparser.
+*/
+
+// Basic types
+typedef void*  muParserHandle_t;    // parser handle
+
+#ifndef _UNICODE
+    typedef char   muChar_t;            // character type
+#else
+    typedef wchar_t   muChar_t;            // character type
+#endif
+
+typedef int    muBool_t;            // boolean type
+typedef int    muInt_t;             // integer type 
+typedef double muFloat_t;           // floating point type
+
+// function types for calculation
+typedef muFloat_t (*muFun0_t )(); 
+typedef muFloat_t (*muFun1_t )(muFloat_t); 
+typedef muFloat_t (*muFun2_t )(muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun3_t )(muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun4_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun5_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun6_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun7_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun8_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun9_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muFun10_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+
+// Function prototypes for bulkmode functions
+typedef muFloat_t (*muBulkFun0_t )(int, int); 
+typedef muFloat_t (*muBulkFun1_t )(int, int, muFloat_t); 
+typedef muFloat_t (*muBulkFun2_t )(int, int, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun3_t )(int, int, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun4_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun5_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun6_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun7_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun8_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun9_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+typedef muFloat_t (*muBulkFun10_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); 
+
+typedef muFloat_t (*muMultFun_t)(const muFloat_t*, muInt_t);
+typedef muFloat_t (*muStrFun1_t)(const muChar_t*);
+typedef muFloat_t (*muStrFun2_t)(const muChar_t*, muFloat_t);
+typedef muFloat_t (*muStrFun3_t)(const muChar_t*, muFloat_t, muFloat_t);
+
+// Functions for parser management
+typedef void (*muErrorHandler_t)(muParserHandle_t a_hParser);           // [optional] callback to an error handler
+typedef muFloat_t* (*muFacFun_t)(const muChar_t*, void*);               // [optional] callback for creating new variables
+typedef muInt_t (*muIdentFun_t)(const muChar_t*, muInt_t*, muFloat_t*); // [optional] value identification callbacks
+
+//-----------------------------------------------------------------------------------------------------
+// Constants
+static const int muOPRT_ASCT_LEFT  = 0;
+static const int muOPRT_ASCT_RIGHT = 1;
+
+static const int muBASETYPE_FLOAT  = 0;
+static const int muBASETYPE_INT    = 1;
+
+//-----------------------------------------------------------------------------------------------------
+//
+//
+// muParser C compatible bindings
+//
+//
+//-----------------------------------------------------------------------------------------------------
+
+
+// Basic operations / initialization  
+API_EXPORT(muParserHandle_t) mupCreate(int nBaseType);
+API_EXPORT(void) mupRelease(muParserHandle_t a_hParser);
+API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser);
+API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t *a_szExpr);
+API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void* pUserData);
+API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser);
+API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser);
+API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum);
+API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_fResult, int nSize);
+
+// Defining callbacks / variables / constants
+API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun0_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun3_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun4_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun5_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun6_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun7_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun8_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun9_t a_pFun, muBool_t a_bOptimize);
+API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun10_t a_pFun, muBool_t a_bOptimize);
+
+// Defining bulkmode functions
+API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun0_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun1_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun2_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun3_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun4_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun5_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun6_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun7_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun8_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun9_t a_pFun);
+API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun10_t a_pFun);
+
+// string functions
+API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun1_t a_pFun);
+API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun2_t a_pFun);
+API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun3_t a_pFun);
+
+API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser, 
+                                   const muChar_t* a_szName, 
+                                   muMultFun_t a_pFun, 
+                                   muBool_t a_bOptimize);
+
+API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser, 
+                                const muChar_t* a_szName, 
+                                muFun2_t a_pFun, 
+                                muInt_t a_nPrec, 
+                                muInt_t a_nOprtAsct,
+                                muBool_t a_bOptimize);
+
+API_EXPORT(void) mupDefineConst( muParserHandle_t a_hParser, 
+                                 const muChar_t* a_szName, 
+                                 muFloat_t a_fVal );
+
+API_EXPORT(void) mupDefineStrConst( muParserHandle_t a_hParser, 
+                                    const muChar_t* a_szName, 
+                                    const muChar_t *a_sVal );
+
+API_EXPORT(void) mupDefineVar( muParserHandle_t a_hParser, 
+                               const muChar_t* a_szName, 
+                               muFloat_t *a_fVar);
+
+API_EXPORT(void) mupDefineBulkVar( muParserHandle_t a_hParser, 
+                               const muChar_t* a_szName, 
+                               muFloat_t *a_fVar);
+
+API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser, 
+                                       const muChar_t* a_szName, 
+                                       muFun1_t a_pOprt, 
+                                       muBool_t a_bOptimize);
+
+
+API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser, 
+                                     const muChar_t* a_szName, 
+                                     muFun1_t a_pOprt, 
+                                     muBool_t a_bOptimize);
+
+// Define character sets for identifiers
+API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
+API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
+API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
+
+// Remove all / single variables
+API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName);
+API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser);
+API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser);
+API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser);
+API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser);
+
+// Querying variables / expression variables / constants
+API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser);
+API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser);
+API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser);
+API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);
+API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);
+API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t* a_pVar);
+API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
+API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
+API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
+API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser);
+
+// Add value recognition callbacks
+API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, muIdentFun_t);
+
+// Error handling
+API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser);
+API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser);
+API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pErrHandler);
+API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser);
+API_EXPORT(muInt_t) mupGetErrorCode(muParserHandle_t a_hParser);
+API_EXPORT(muInt_t) mupGetErrorPos(muParserHandle_t a_hParser);
+API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser);
+//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser);
+
+// This is used for .NET only. It creates a new variable allowing the dll to
+// manage the variable rather than the .NET garbage collector.
+API_EXPORT(muFloat_t*) mupCreateVar();
+API_EXPORT(void) mupReleaseVar(muFloat_t*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // include guard
diff --git a/ThirdParty/MuParser/include/muParserDef.h b/ThirdParty/MuParser/include/muParserDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8e3f930b02311bb40c2b8d382d951387e1be37a
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserDef.h
@@ -0,0 +1,368 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2014 Ingo Berg
+
+  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. 
+*/
+#ifndef MUP_DEF_H
+#define MUP_DEF_H
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <map>
+
+#include "muParserFixes.h"
+
+/** \file
+    \brief This file contains standard definitions used by the parser.
+*/
+
+#define MUP_VERSION _T("2.2.5")
+#define MUP_VERSION_DATE _T("20150427; GC")
+
+#define MUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+
+/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
+//#define MUP_MATH_EXCEPTIONS
+
+/** \brief Define the base datatype for values.
+
+  This datatype must be a built in value type. You can not use custom classes.
+  It should be working with all types except "int"!
+*/
+#define MUP_BASETYPE double
+
+/** \brief Activate this option in order to compile with OpenMP support. 
+
+  OpenMP is used only in the bulk mode it may increase the performance a bit. 
+*/
+//#define MUP_USE_OPENMP
+
+#if defined(_UNICODE)
+  /** \brief Definition of the basic parser string type. */
+  #define MUP_STRING_TYPE std::wstring
+
+  #if !defined(_T)
+    #define _T(x) L##x
+  #endif // not defined _T
+#else
+  #ifndef _T
+  #define _T(x) x
+  #endif
+  
+  /** \brief Definition of the basic parser string type. */
+  #define MUP_STRING_TYPE std::string
+#endif
+
+#if defined(_DEBUG)
+  /** \brief Debug macro to force an abortion of the programm with a certain message.
+  */
+  #define MUP_FAIL(MSG)     \
+          {                 \
+            bool MSG=false; \
+            assert(MSG);    \
+          }
+
+    /** \brief An assertion that does not kill the program.
+
+        This macro is neutralised in UNICODE builds. It's
+        too difficult to translate.
+    */
+    #define MUP_ASSERT(COND)                         \
+            if (!(COND))                             \
+            {                                        \
+              stringstream_type ss;                  \
+              ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \
+                 << __FILE__ << _T(" line ")         \
+                 << __LINE__ << _T(".");             \
+              throw ParserError( ss.str() );         \
+            }
+#else
+  #define MUP_FAIL(MSG)
+  #define MUP_ASSERT(COND)
+#endif
+
+
+namespace mu
+{
+#if defined(_UNICODE)
+
+  //------------------------------------------------------------------------------
+  /** \brief Encapsulate wcout. */
+  inline std::wostream& console()
+  {
+    return std::wcout;
+  }
+
+  /** \brief Encapsulate cin. */
+  inline std::wistream& console_in()
+  {
+    return std::wcin;
+  }
+
+#else
+
+  /** \brief Encapsulate cout. 
+  
+    Used for supporting UNICODE more easily.
+  */
+  inline std::ostream& console()
+  {
+    return std::cout;
+  }
+
+  /** \brief Encapsulate cin. 
+
+    Used for supporting UNICODE more easily.
+  */
+  inline std::istream& console_in()
+  {
+    return std::cin;
+  }
+
+#endif
+
+  //------------------------------------------------------------------------------
+  /** \brief Bytecode values.
+
+      \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!
+  */
+  enum ECmdCode
+  {
+    // The following are codes for built in binary operators
+    // apart from built in operators the user has the opportunity to
+    // add user defined operators.
+    cmLE            = 0,   ///< Operator item:  less or equal
+    cmGE            = 1,   ///< Operator item:  greater or equal
+    cmNEQ           = 2,   ///< Operator item:  not equal
+    cmEQ            = 3,   ///< Operator item:  equals
+    cmLT            = 4,   ///< Operator item:  less than
+    cmGT            = 5,   ///< Operator item:  greater than
+    cmADD           = 6,   ///< Operator item:  add
+    cmSUB           = 7,   ///< Operator item:  subtract
+    cmMUL           = 8,   ///< Operator item:  multiply
+    cmDIV           = 9,   ///< Operator item:  division
+    cmPOW           = 10,  ///< Operator item:  y to the power of ...
+    cmLAND          = 11,
+    cmLOR           = 12,
+    cmASSIGN        = 13,  ///< Operator item:  Assignment operator
+    cmBO            = 14,  ///< Operator item:  opening bracket
+    cmBC            = 15,  ///< Operator item:  closing bracket
+    cmIF            = 16,  ///< For use in the ternary if-then-else operator
+    cmELSE          = 17,  ///< For use in the ternary if-then-else operator
+    cmENDIF         = 18,  ///< For use in the ternary if-then-else operator
+    cmARG_SEP       = 19,  ///< function argument separator
+    cmVAR           = 20,  ///< variable item
+    cmVAL           = 21,  ///< value item
+
+    // For optimization purposes
+    cmVARPOW2,
+    cmVARPOW3,
+    cmVARPOW4,
+    cmVARMUL,
+    cmPOW2,
+
+    // operators and functions
+    cmFUNC,                ///< Code for a generic function item
+    cmFUNC_STR,            ///< Code for a function with a string parameter
+    cmFUNC_BULK,           ///< Special callbacks for Bulk mode with an additional parameter for the bulk index 
+    cmSTRING,              ///< Code for a string token
+    cmOPRT_BIN,            ///< user defined binary operator
+    cmOPRT_POSTFIX,        ///< code for postfix operators
+    cmOPRT_INFIX,          ///< code for infix operators
+    cmEND,                 ///< end of formula
+    cmUNKNOWN              ///< uninitialized item
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Types internally used by the parser.
+  */
+  enum ETypeCode
+  {
+    tpSTR  = 0,     ///< String type (Function arguments and constants only, no string variables)
+    tpDBL  = 1,     ///< Floating point variables
+    tpVOID = 2      ///< Undefined type.
+  };
+
+  //------------------------------------------------------------------------------
+  enum EParserVersionInfo
+  {
+    pviBRIEF,
+    pviFULL
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser operator precedence values. */
+  enum EOprtAssociativity
+  {
+    oaLEFT  = 0,
+    oaRIGHT = 1,
+    oaNONE  = 2
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Parser operator precedence values. */
+  enum EOprtPrecedence
+  {
+    // binary operators
+    prLOR     = 1,
+    prLAND    = 2,
+    prLOGIC   = 3,  ///< logic operators
+    prCMP     = 4,  ///< comparsion operators
+    prADD_SUB = 5,  ///< addition
+    prMUL_DIV = 6,  ///< multiplication/division
+    prPOW     = 7,  ///< power operator priority (highest)
+
+    // infix operators
+    prINFIX   = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
+    prPOSTFIX = 6  ///< Postfix operator priority (currently unused)
+  };
+
+  //------------------------------------------------------------------------------
+  // basic types
+
+  /** \brief The numeric datatype used by the parser. 
+  
+    Normally this is a floating point type either single or double precision.
+  */
+  typedef MUP_BASETYPE value_type;
+
+  /** \brief The stringtype used by the parser. 
+
+    Depends on wether UNICODE is used or not.
+  */
+  typedef MUP_STRING_TYPE string_type;
+
+  /** \brief The character type used by the parser. 
+  
+    Depends on wether UNICODE is used or not.
+  */
+  typedef string_type::value_type char_type;
+
+  /** \brief Typedef for easily using stringstream that respect the parser stringtype. */
+  typedef std::basic_stringstream<char_type,
+                                  std::char_traits<char_type>,
+                                  std::allocator<char_type> > stringstream_type;
+
+  // Data container types
+
+  /** \brief Type used for storing variables. */
+  typedef std::map<string_type, value_type*> varmap_type;
+  
+  /** \brief Type used for storing constants. */
+  typedef std::map<string_type, value_type> valmap_type;
+  
+  /** \brief Type for assigning a string name to an index in the internal string table. */
+  typedef std::map<string_type, std::size_t> strmap_type;
+
+  // Parser callbacks
+  
+  /** \brief Callback type used for functions without arguments. */
+  typedef value_type (*generic_fun_type)();
+
+  /** \brief Callback type used for functions without arguments. */
+  typedef value_type (*fun_type0)();
+
+  /** \brief Callback type used for functions with a single arguments. */
+  typedef value_type (*fun_type1)(value_type);
+
+  /** \brief Callback type used for functions with two arguments. */
+  typedef value_type (*fun_type2)(value_type, value_type);
+
+  /** \brief Callback type used for functions with three arguments. */
+  typedef value_type (*fun_type3)(value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with four arguments. */
+  typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions without arguments. */
+  typedef value_type (*bulkfun_type0)(int, int);
+
+  /** \brief Callback type used for functions with a single arguments. */
+  typedef value_type (*bulkfun_type1)(int, int, value_type);
+
+  /** \brief Callback type used for functions with two arguments. */
+  typedef value_type (*bulkfun_type2)(int, int, value_type, value_type);
+
+  /** \brief Callback type used for functions with three arguments. */
+  typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with four arguments. */
+  typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with five arguments. */
+  typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
+
+  /** \brief Callback type used for functions with a variable argument list. */
+  typedef value_type (*multfun_type)(const value_type*, int);
+
+  /** \brief Callback type used for functions taking a string as an argument. */
+  typedef value_type (*strfun_type1)(const char_type*);
+
+  /** \brief Callback type used for functions taking a string and a value as arguments. */
+  typedef value_type (*strfun_type2)(const char_type*, value_type);
+
+  /** \brief Callback type used for functions taking a string and two values as arguments. */
+  typedef value_type (*strfun_type3)(const char_type*, value_type, value_type);
+
+  /** \brief Callback used for functions that identify values in a string. */
+  typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal);
+
+  /** \brief Callback used for variable creation factory functions. */
+  typedef value_type* (*facfun_type)(const char_type*, void*);
+} // end of namespace
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserError.h b/ThirdParty/MuParser/include/muParserError.h
new file mode 100644
index 0000000000000000000000000000000000000000..7be257608ca1acaa1fee886fa3c6e409c579ce5b
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserError.h
@@ -0,0 +1,176 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2011 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_ERROR_H
+#define MU_PARSER_ERROR_H
+
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <memory>
+
+#include "muParserDef.h"
+
+/** \file 
+    \brief This file defines the error class used by the parser.
+*/
+
+namespace mu
+{
+
+/** \brief Error codes. */
+enum EErrorCodes
+{
+  // Formula syntax errors
+  ecUNEXPECTED_OPERATOR    = 0,  ///< Unexpected binary operator found
+  ecUNASSIGNABLE_TOKEN     = 1,  ///< Token cant be identified.
+  ecUNEXPECTED_EOF         = 2,  ///< Unexpected end of formula. (Example: "2+sin(")
+  ecUNEXPECTED_ARG_SEP     = 3,  ///< An unexpected comma has been found. (Example: "1,23")
+  ecUNEXPECTED_ARG         = 4,  ///< An unexpected argument has been found
+  ecUNEXPECTED_VAL         = 5,  ///< An unexpected value token has been found
+  ecUNEXPECTED_VAR         = 6,  ///< An unexpected variable token has been found
+  ecUNEXPECTED_PARENS      = 7,  ///< Unexpected Parenthesis, opening or closing
+  ecUNEXPECTED_STR         = 8,  ///< A string has been found at an inapropriate position
+  ecSTRING_EXPECTED        = 9,  ///< A string function has been called with a different type of argument
+  ecVAL_EXPECTED           = 10, ///< A numerical function has been called with a non value type of argument
+  ecMISSING_PARENS         = 11, ///< Missing parens. (Example: "3*sin(3")
+  ecUNEXPECTED_FUN         = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)")
+  ecUNTERMINATED_STRING    = 13, ///< unterminated string constant. (Example: "3*valueof("hello)")
+  ecTOO_MANY_PARAMS        = 14, ///< Too many function parameters
+  ecTOO_FEW_PARAMS         = 15, ///< Too few function parameters. (Example: "ite(1<2,2)")
+  ecOPRT_TYPE_CONFLICT     = 16, ///< binary operators may only be applied to value items of the same type
+  ecSTR_RESULT             = 17, ///< result is a string
+
+  // Invalid Parser input Parameters
+  ecINVALID_NAME           = 18, ///< Invalid function, variable or constant name.
+  ecINVALID_BINOP_IDENT    = 19, ///< Invalid binary operator identifier
+  ecINVALID_INFIX_IDENT    = 20, ///< Invalid function, variable or constant name.
+  ecINVALID_POSTFIX_IDENT  = 21, ///< Invalid function, variable or constant name.
+
+  ecBUILTIN_OVERLOAD       = 22, ///< Trying to overload builtin operator
+  ecINVALID_FUN_PTR        = 23, ///< Invalid callback function pointer 
+  ecINVALID_VAR_PTR        = 24, ///< Invalid variable pointer 
+  ecEMPTY_EXPRESSION       = 25, ///< The Expression is empty
+  ecNAME_CONFLICT          = 26, ///< Name conflict
+  ecOPT_PRI                = 27, ///< Invalid operator priority
+  // 
+  ecDOMAIN_ERROR           = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused)
+  ecDIV_BY_ZERO            = 29, ///< Division by zero (currently unused)
+  ecGENERIC                = 30, ///< Generic error
+  ecLOCALE                 = 31, ///< Conflict with current locale
+
+  ecUNEXPECTED_CONDITIONAL = 32,
+  ecMISSING_ELSE_CLAUSE    = 33, 
+  ecMISPLACED_COLON        = 34,
+
+  ecUNREASONABLE_NUMBER_OF_COMPUTATIONS = 35,
+
+  // internal errors
+  ecINTERNAL_ERROR         = 36, ///< Internal error of any kind.
+  
+  // The last two are special entries 
+  ecCOUNT,                      ///< This is no error code, It just stores just the total number of error codes
+  ecUNDEFINED              = -1  ///< Undefined message, placeholder to detect unassigned error messages
+};
+
+//---------------------------------------------------------------------------
+/** \brief A class that handles the error messages.
+*/
+class ParserErrorMsg
+{
+public:
+    typedef ParserErrorMsg self_type;
+
+    ParserErrorMsg& operator=(const ParserErrorMsg &);
+    ParserErrorMsg(const ParserErrorMsg&);
+    ParserErrorMsg();
+
+   ~ParserErrorMsg();
+
+    static const ParserErrorMsg& Instance();
+    string_type operator[](unsigned a_iIdx) const;
+
+private:
+    std::vector<string_type>  m_vErrMsg;  ///< A vector with the predefined error messages
+    static const self_type m_Instance;    ///< The instance pointer
+};
+
+//---------------------------------------------------------------------------
+/** \brief Error class of the parser. 
+    \author Ingo Berg
+
+  Part of the math parser package.
+*/
+class ParserError
+{
+private:
+
+    /** \brief Replace all ocuurences of a substring with another string. */
+    void ReplaceSubString( string_type &strSource, 
+                           const string_type &strFind,
+                           const string_type &strReplaceWith);
+    void Reset();
+
+public:
+
+    ParserError();
+    explicit ParserError(EErrorCodes a_iErrc);
+    explicit ParserError(const string_type &sMsg);
+    ParserError( EErrorCodes a_iErrc,
+                 const string_type &sTok,
+                 const string_type &sFormula = string_type(),
+                 int a_iPos = -1);
+    ParserError( EErrorCodes a_iErrc, 
+                 int a_iPos, 
+                 const string_type &sTok);
+    ParserError( const char_type *a_szMsg, 
+                 int a_iPos = -1, 
+                 const string_type &sTok = string_type());
+    ParserError(const ParserError &a_Obj);
+    ParserError& operator=(const ParserError &a_Obj);
+   ~ParserError();
+
+    void SetFormula(const string_type &a_strFormula);
+    const string_type& GetExpr() const;
+    const string_type& GetMsg() const;
+    int GetPos() const;
+    const string_type& GetToken() const;
+    EErrorCodes GetCode() const;
+
+private:
+    string_type m_strMsg;     ///< The message string
+    string_type m_strFormula; ///< Formula string
+    string_type m_strTok;     ///< Token related with the error
+    int m_iPos;               ///< Formula position related to the error 
+    EErrorCodes m_iErrc;      ///< Error code
+    const ParserErrorMsg &m_ErrMsg;
+};		
+
+} // namespace mu
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserFixes.h b/ThirdParty/MuParser/include/muParserFixes.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a07237c4c8113f69cf5ffa3d6445fa1fc56d8e0
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserFixes.h
@@ -0,0 +1,62 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_FIXES_H
+#define MU_PARSER_FIXES_H
+
+/** \file
+    \brief This file contains compatibility fixes for some platforms.
+*/
+
+//
+// Compatibility fixes
+//
+
+//---------------------------------------------------------------------------
+//
+// Intel Compiler
+//
+//---------------------------------------------------------------------------
+
+#ifdef __INTEL_COMPILER
+
+// remark #981: operands are evaluated in unspecified order
+// disabled -> completely pointless if the functions do not have side effects
+//
+#pragma warning(disable:981)
+
+// remark #383: value copied to temporary, reference to temporary used
+#pragma warning(disable:383)
+
+// remark #1572: floating-point equality and inequality comparisons are unreliable
+// disabled -> everyone knows it, the parser passes this problem
+//             deliberately to the user
+#pragma warning(disable:1572)
+
+#endif
+
+#endif // include guard
+
+
diff --git a/ThirdParty/MuParser/include/muParserInt.h b/ThirdParty/MuParser/include/muParserInt.h
new file mode 100644
index 0000000000000000000000000000000000000000..4db2be8b6bd0a70ebdd67b1bc9b8a9519424cba3
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserInt.h
@@ -0,0 +1,140 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2013 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_INT_H
+#define MU_PARSER_INT_H
+
+#include "muParserBase.h"
+#include <vector>
+
+
+/** \file
+    \brief Definition of a parser using integer value.
+*/
+
+
+namespace mu
+{
+
+/** \brief Mathematical expressions parser.
+  
+  This version of the parser handles only integer numbers. It disables the built in operators thus it is 
+  slower than muParser. Integer values are stored in the double value_type and converted if needed.
+*/
+class ParserInt : public ParserBase
+{
+private:
+    static int  Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); };
+  
+    static value_type  Abs(value_type);
+    static value_type  Sign(value_type);
+    static value_type  Ite(value_type, value_type, value_type);
+    // !! The unary Minus is a MUST, otherwise you cant use negative signs !!
+    static value_type  UnaryMinus(value_type);
+    // Functions with variable number of arguments
+    static value_type  Sum(const value_type* a_afArg, int a_iArgc);  // sum
+    static value_type  Min(const value_type* a_afArg, int a_iArgc);  // minimum
+    static value_type  Max(const value_type* a_afArg, int a_iArgc);  // maximum
+    // binary operator callbacks
+    static value_type  Add(value_type v1, value_type v2);
+    static value_type  Sub(value_type v1, value_type v2);
+    static value_type  Mul(value_type v1, value_type v2);
+    static value_type  Div(value_type v1, value_type v2);
+    static value_type  Mod(value_type v1, value_type v2);
+    static value_type  Pow(value_type v1, value_type v2);
+    static value_type  Shr(value_type v1, value_type v2);
+    static value_type  Shl(value_type v1, value_type v2);
+    static value_type  LogAnd(value_type v1, value_type v2);
+    static value_type  LogOr(value_type v1, value_type v2);
+    static value_type  And(value_type v1, value_type v2);
+    static value_type  Or(value_type v1, value_type v2);
+    static value_type  Xor(value_type v1, value_type v2);
+    static value_type  Less(value_type v1, value_type v2);
+    static value_type  Greater(value_type v1, value_type v2);
+    static value_type  LessEq(value_type v1, value_type v2);
+    static value_type  GreaterEq(value_type v1, value_type v2);
+    static value_type  Equal(value_type v1, value_type v2);
+    static value_type  NotEqual(value_type v1, value_type v2);
+    static value_type  Not(value_type v1);
+
+    static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
+    static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
+    static int IsVal   (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
+
+    /** \brief A facet class used to change decimal and thousands separator. */
+    template<class TChar>
+    class change_dec_sep : public std::numpunct<TChar>
+    {
+    public:
+      
+      explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
+        :std::numpunct<TChar>()
+        ,m_cDecPoint(cDecSep)
+        ,m_cThousandsSep(cThousandsSep)
+        ,m_nGroup(nGroup)
+      {}
+      
+    protected:
+      
+      virtual char_type do_decimal_point() const
+      {
+        return m_cDecPoint;
+      }
+
+      virtual char_type do_thousands_sep() const
+      {
+        return m_cThousandsSep;
+      }
+
+      virtual std::string do_grouping() const 
+      { 
+        // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
+        // courtesy of Jens Bartsch
+        // original code:
+        //        return std::string(1, (char)m_nGroup); 
+        // new code:
+        return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));
+      }
+
+    private:
+
+      int m_nGroup;
+      char_type m_cDecPoint;  
+      char_type m_cThousandsSep;
+    };
+
+public:
+    ParserInt();
+
+    virtual void InitFun();
+    virtual void InitOprt();
+    virtual void InitConst();
+    virtual void InitCharSets();
+};
+
+} // namespace mu
+
+#endif
+
diff --git a/ThirdParty/MuParser/include/muParserStack.h b/ThirdParty/MuParser/include/muParserStack.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4c20a5c8fad254911803a78d7923ac6ebd2da16
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserStack.h
@@ -0,0 +1,125 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2011 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_STACK_H
+#define MU_PARSER_STACK_H
+
+#include <cassert>
+#include <string>
+#include <stack>
+#include <vector>
+
+#include "muParserError.h"
+#include "muParserToken.h"
+
+/** \file 
+    \brief This file defines the stack used by muparser.
+*/
+
+namespace mu
+{
+
+  /** \brief Parser stack implementation. 
+
+      Stack implementation based on a std::stack. The behaviour of pop() had been
+      slightly changed in order to get an error code if the stack is empty.
+      The stack is used within the Parser both as a value stack and as an operator stack.
+
+      \author (C) 2004-2011 Ingo Berg 
+  */
+  template <typename TValueType>
+  class ParserStack 
+  {
+    private:
+
+      /** \brief Type of the underlying stack implementation. */
+      typedef std::stack<TValueType, std::vector<TValueType> > impl_type;
+      
+      impl_type m_Stack;  ///< This is the actual stack.
+
+    public:	
+  	 
+      //---------------------------------------------------------------------------
+      ParserStack()
+        :m_Stack()
+      {}
+
+      //---------------------------------------------------------------------------
+      virtual ~ParserStack()
+      {}
+
+      //---------------------------------------------------------------------------
+      /** \brief Pop a value from the stack.
+       
+        Unlike the standard implementation this function will return the value that
+        is going to be taken from the stack.
+
+        \throw ParserException in case the stack is empty.
+        \sa pop(int &a_iErrc)
+      */
+	    TValueType pop()
+      {
+        if (empty())
+          throw ParserError( _T("stack is empty.") );
+
+        TValueType el = top();
+        m_Stack.pop();
+        return el;
+      }
+
+      /** \brief Push an object into the stack. 
+
+          \param a_Val object to push into the stack.
+          \throw nothrow
+      */
+      void push(const TValueType& a_Val) 
+      { 
+        m_Stack.push(a_Val); 
+      }
+
+      /** \brief Return the number of stored elements. */
+      unsigned size() const
+      { 
+        return (unsigned)m_Stack.size(); 
+      }
+
+      /** \brief Returns true if stack is empty false otherwise. */
+      bool empty() const
+      {
+        return m_Stack.empty(); 
+      }
+       
+      /** \brief Return reference to the top object in the stack. 
+       
+          The top object is the one pushed most recently.
+      */
+      TValueType& top() 
+      { 
+        return m_Stack.top(); 
+      }
+  };
+} // namespace MathUtils
+
+#endif
diff --git a/ThirdParty/MuParser/include/muParserTemplateMagic.h b/ThirdParty/MuParser/include/muParserTemplateMagic.h
new file mode 100644
index 0000000000000000000000000000000000000000..1caeb4b6de47a3daf5d030deaf671988ca174af1
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserTemplateMagic.h
@@ -0,0 +1,113 @@
+#ifndef MU_PARSER_TEMPLATE_MAGIC_H
+#define MU_PARSER_TEMPLATE_MAGIC_H
+
+#include <cmath>
+#include "muParserError.h"
+
+
+namespace mu
+{
+  //-----------------------------------------------------------------------------------------------
+  //
+  // Compile time type detection
+  //
+  //-----------------------------------------------------------------------------------------------
+
+  /** \brief A class singling out integer types at compile time using 
+             template meta programming.
+  */
+  template<typename T>
+  struct TypeInfo
+  {
+    static bool IsInteger() { return false; }
+  };
+
+  template<>
+  struct TypeInfo<char>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<short>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<int>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<long>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<unsigned char>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<unsigned short>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<unsigned int>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+  template<>
+  struct TypeInfo<unsigned long>
+  {
+    static bool IsInteger() { return true;  }
+  };
+
+
+  //-----------------------------------------------------------------------------------------------
+  //
+  // Standard math functions with dummy overload for integer types
+  //
+  //-----------------------------------------------------------------------------------------------
+
+  /** \brief A template class for providing wrappers for essential math functions.
+
+    This template is spezialized for several types in order to provide a unified interface
+    for parser internal math function calls regardless of the data type.
+  */
+  template<typename T>
+  struct MathImpl
+  {
+    static T Sin(T v)   { return sin(v);  }
+    static T Cos(T v)   { return cos(v);  }
+    static T Tan(T v)   { return tan(v);  }
+    static T ASin(T v)  { return asin(v); }
+    static T ACos(T v)  { return acos(v); }
+    static T ATan(T v)  { return atan(v); }
+    static T ATan2(T v1, T v2) { return atan2(v1, v2); }
+    static T Sinh(T v)  { return sinh(v); }
+    static T Cosh(T v)  { return cosh(v); }
+    static T Tanh(T v)  { return tanh(v); }
+    static T ASinh(T v) { return log(v + sqrt(v * v + 1)); }
+    static T ACosh(T v) { return log(v + sqrt(v * v - 1)); }
+    static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); }
+    static T Log(T v)   { return log(v); } 
+    static T Log2(T v)  { return log(v)/log((T)2); } // Logarithm base 2
+    static T Log10(T v) { return log10(v); }         // Logarithm base 10
+    static T Exp(T v)   { return exp(v);   }
+    static T Abs(T v)   { return (v>=0) ? v : -v; }
+    static T Sqrt(T v)  { return sqrt(v); }
+    static T Rint(T v)  { return floor(v + (T)0.5); }
+    static T Sign(T v)  { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); }
+    static T Pow(T v1, T v2) { return std::pow(v1, v2); }
+  };
+}
+
+#endif
diff --git a/ThirdParty/MuParser/include/muParserTest.h b/ThirdParty/MuParser/include/muParserTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8da872c557c5f7c2921f1fe7a2bcbc7835885c5
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserTest.h
@@ -0,0 +1,214 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_TEST_H
+#define MU_PARSER_TEST_H
+
+#include <string>
+#include <cstdlib>
+#include <numeric> // for accumulate
+#include "muParser.h"
+#include "muParserInt.h"
+
+/** \file
+    \brief This file contains the parser test class.
+*/
+
+namespace mu
+{
+  /** \brief Namespace for test cases. */
+  namespace Test
+  {
+    //------------------------------------------------------------------------------
+    /** \brief Test cases for unit testing.
+
+      (C) 2004-2011 Ingo Berg
+    */
+    class ParserTester // final
+    {
+    private:
+        static int c_iCount;
+
+        // Multiarg callbacks
+        static value_type f1of1(value_type v) { return v;};
+      	
+        static value_type f1of2(value_type v, value_type  ) {return v;};
+        static value_type f2of2(value_type  , value_type v) {return v;};
+
+        static value_type f1of3(value_type v, value_type  , value_type  ) {return v;};
+        static value_type f2of3(value_type  , value_type v, value_type  ) {return v;};
+        static value_type f3of3(value_type  , value_type  , value_type v) {return v;};
+      	
+        static value_type f1of4(value_type v, value_type,   value_type  , value_type  ) {return v;}
+        static value_type f2of4(value_type  , value_type v, value_type  , value_type  ) {return v;}
+        static value_type f3of4(value_type  , value_type,   value_type v, value_type  ) {return v;}
+        static value_type f4of4(value_type  , value_type,   value_type  , value_type v) {return v;}
+
+        static value_type f1of5(value_type v, value_type,   value_type  , value_type  , value_type  ) { return v; }
+        static value_type f2of5(value_type  , value_type v, value_type  , value_type  , value_type  ) { return v; }
+        static value_type f3of5(value_type  , value_type,   value_type v, value_type  , value_type  ) { return v; }
+        static value_type f4of5(value_type  , value_type,   value_type  , value_type v, value_type  ) { return v; }
+        static value_type f5of5(value_type  , value_type,   value_type  , value_type  , value_type v) { return v; }
+
+        static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }
+  	    static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }
+
+        static value_type plus2(value_type v1) { return v1+2; }
+        static value_type times3(value_type v1) { return v1*3; }
+        static value_type sqr(value_type v1) { return v1*v1; }
+        static value_type sign(value_type v) { return -v; }
+        static value_type add(value_type v1, value_type v2) { return v1+v2; }
+        static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; }
+        
+
+        static value_type FirstArg(const value_type* a_afArg, int a_iArgc)
+        {
+          if (!a_iArgc)	
+            throw mu::Parser::exception_type( _T("too few arguments for function FirstArg.") );
+
+          return  a_afArg[0];
+        }
+
+        static value_type LastArg(const value_type* a_afArg, int a_iArgc)
+        {
+          if (!a_iArgc)	
+            throw mu::Parser::exception_type( _T("too few arguments for function LastArg.") );
+
+          return  a_afArg[a_iArgc-1];
+        }
+
+        static value_type Sum(const value_type* a_afArg, int a_iArgc)
+        { 
+          if (!a_iArgc)	
+            throw mu::Parser::exception_type( _T("too few arguments for function sum.") );
+
+          value_type fRes=0;
+          for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
+          return fRes;
+        }
+
+        static value_type Rnd(value_type v)
+        {
+          return (value_type)(1+(v*std::rand()/(RAND_MAX+1.0)));
+        }
+
+        static value_type RndWithString(const char_type*)
+        {
+          return (value_type)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );
+        }
+
+        static value_type Ping()
+        { 
+          return 10; 
+        }
+
+        static value_type ValueOf(const char_type*)      
+        { 
+          return 123; 
+        }
+
+        static value_type StrFun1(const char_type* v1)                               
+        { 
+          int val(0);
+          stringstream_type(v1) >> val;
+          return (value_type)val;
+        }
+
+        static value_type StrFun2(const char_type* v1, value_type v2)                
+        { 
+          int val(0);
+          stringstream_type(v1) >> val;
+          return (value_type)(val + v2);
+        }
+        
+        static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) 
+        { 
+          int val(0);
+          stringstream_type(v1) >> val;
+          return val + v2 + v3;
+        }
+
+        static value_type StrToFloat(const char_type* a_szMsg)
+        {
+          value_type val(0);
+          stringstream_type(a_szMsg) >> val;
+          return val;
+        }
+
+        // postfix operator callback
+        static value_type Mega(value_type a_fVal)  { return a_fVal * (value_type)1e6; }
+        static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; }
+        static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; }
+
+        // Custom value recognition
+        static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal);
+
+        int TestNames();
+        int TestSyntax();
+        int TestMultiArg();
+        int TestPostFix();
+        int TestExpression();
+        int TestInfixOprt();
+        int TestBinOprt();
+        int TestVarConst();
+        int TestInterface();
+        int TestException();
+        int TestStrArg();
+        int TestIfThenElse();
+        int TestBulkMode();
+
+        void Abort() const;
+
+    public:
+        typedef int (ParserTester::*testfun_type)();
+
+	      ParserTester();
+	      void Run();
+
+    private:
+        std::vector<testfun_type> m_vTestFun;
+	      void AddTest(testfun_type a_pFun);
+
+        // Test Double Parser
+        int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);
+        int EqnTestWithVarChange(const string_type& a_str, 
+                                 double a_fRes1, 
+                                 double a_fVar1, 
+                                 double a_fRes2, 
+                                 double a_fVar2);
+        int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);
+
+        // Test Int Parser
+        int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass);
+
+        // Test Bulkmode
+        int EqnTestBulk(const string_type& a_str, double a_fRes[4], bool a_fPass);
+    };
+  } // namespace Test
+} // namespace mu
+
+#endif
+
+
diff --git a/ThirdParty/MuParser/include/muParserToken.h b/ThirdParty/MuParser/include/muParserToken.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff48bce7fc5c16505507513c00c0f51eba3e66ce
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserToken.h
@@ -0,0 +1,401 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2013 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_TOKEN_H
+#define MU_PARSER_TOKEN_H
+
+#include <cassert>
+#include <string>
+#include <stack>
+#include <vector>
+#include <memory>
+
+#include "muParserError.h"
+#include "muParserCallback.h"
+
+/** \file
+    \brief This file contains the parser token definition.
+*/
+
+namespace mu
+{
+  /** \brief Encapsulation of the data for a single formula token. 
+
+    Formula token implementation. Part of the Math Parser Package.
+    Formula tokens can be either one of the following:
+    <ul>
+      <li>value</li>
+      <li>variable</li>
+      <li>function with numerical arguments</li>
+      <li>functions with a string as argument</li>
+      <li>prefix operators</li>
+      <li>infix operators</li>
+	    <li>binary operator</li>
+    </ul>
+
+   \author (C) 2004-2013 Ingo Berg 
+  */
+  template<typename TBase, typename TString>
+  class ParserToken
+  {
+  private:
+
+      ECmdCode  m_iCode;  ///< Type of the token; The token type is a constant of type #ECmdCode.
+      ETypeCode m_iType;
+      void  *m_pTok;      ///< Stores Token pointer; not applicable for all tokens
+      int  m_iIdx;        ///< An otional index to an external buffer storing the token data
+      TString m_strTok;   ///< Token string
+      TString m_strVal;   ///< Value for string variables
+      value_type m_fVal;  ///< the value 
+      std::auto_ptr<ParserCallback> m_pCallback;
+
+  public:
+
+      //---------------------------------------------------------------------------
+      /** \brief Constructor (default).
+        
+          Sets token to an neutral state of type cmUNKNOWN.
+          \throw nothrow
+          \sa ECmdCode
+      */
+      ParserToken()
+        :m_iCode(cmUNKNOWN)
+        ,m_iType(tpVOID)
+        ,m_pTok(0)
+        ,m_iIdx(-1)
+        ,m_strTok()
+		,m_strVal()
+		,m_fVal(0)
+        ,m_pCallback()
+      {}
+
+      //------------------------------------------------------------------------------
+      /** \brief Create token from another one.
+      
+          Implemented by calling Assign(...)
+          \throw nothrow
+          \post m_iType==cmUNKNOWN
+          \sa #Assign
+      */
+      ParserToken(const ParserToken &a_Tok)
+      {
+        Assign(a_Tok);
+      }
+      
+      //------------------------------------------------------------------------------
+      /** \brief Assignement operator. 
+      
+          Copy token state from another token and return this.
+          Implemented by calling Assign(...).
+          \throw nothrow
+      */
+      ParserToken& operator=(const ParserToken &a_Tok)
+      {
+        Assign(a_Tok);
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Copy token information from argument.
+      
+          \throw nothrow
+      */
+      void Assign(const ParserToken &a_Tok)
+      {
+        m_iCode = a_Tok.m_iCode;
+        m_pTok = a_Tok.m_pTok;
+        m_strTok = a_Tok.m_strTok;
+        m_iIdx = a_Tok.m_iIdx;
+        m_strVal = a_Tok.m_strVal;
+        m_iType = a_Tok.m_iType;
+        m_fVal = a_Tok.m_fVal;
+        // create new callback object if a_Tok has one 
+        m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Assign a token type. 
+
+        Token may not be of type value, variable or function. Those have seperate set functions. 
+
+        \pre [assert] a_iType!=cmVAR
+        \pre [assert] a_iType!=cmVAL
+        \pre [assert] a_iType!=cmFUNC
+        \post m_fVal = 0
+        \post m_pTok = 0
+      */
+      ParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
+      {
+        // The following types cant be set this way, they have special Set functions
+        assert(a_iType!=cmVAR);
+        assert(a_iType!=cmVAL);
+        assert(a_iType!=cmFUNC);
+
+        m_iCode = a_iType;
+        m_iType = tpVOID;
+        m_pTok = 0;
+        m_strTok = a_strTok;
+        m_iIdx = -1;
+
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Set Callback type. */
+      ParserToken& Set(const ParserCallback &a_pCallback, const TString &a_sTok)
+      {
+        assert(a_pCallback.GetAddr());
+
+        m_iCode = a_pCallback.GetCode();
+        m_iType = tpVOID;
+        m_strTok = a_sTok;
+        m_pCallback.reset(new ParserCallback(a_pCallback));
+
+        m_pTok = 0;
+        m_iIdx = -1;
+        
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Make this token a value token. 
+      
+          Member variables not necessary for value tokens will be invalidated.
+          \throw nothrow
+      */
+      ParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
+      {
+        m_iCode = cmVAL;
+        m_iType = tpDBL;
+        m_fVal = a_fVal;
+        m_strTok = a_strTok;
+        m_iIdx = -1;
+        
+        m_pTok = 0;
+        m_pCallback.reset(0);
+
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief make this token a variable token. 
+      
+          Member variables not necessary for variable tokens will be invalidated.
+          \throw nothrow
+      */
+      ParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
+      {
+        m_iCode = cmVAR;
+        m_iType = tpDBL;
+        m_strTok = a_strTok;
+        m_iIdx = -1;
+        m_pTok = (void*)a_pVar;
+        m_pCallback.reset(0);
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Make this token a variable token. 
+      
+          Member variables not necessary for variable tokens will be invalidated.
+          \throw nothrow
+      */
+      ParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
+      {
+        m_iCode = cmSTRING;
+        m_iType = tpSTR;
+        m_strTok = a_strTok;
+        m_iIdx = static_cast<int>(a_iSize);
+
+        m_pTok = 0;
+        m_pCallback.reset(0);
+        return *this;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Set an index associated with the token related data. 
+      
+          In cmSTRFUNC - This is the index to a string table in the main parser.
+          \param a_iIdx The index the string function result will take in the bytecode parser.
+          \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
+      */
+      void SetIdx(int a_iIdx)
+      {
+        if (m_iCode!=cmSTRING || a_iIdx<0)
+	        throw ParserError(ecINTERNAL_ERROR);
+        
+        m_iIdx = a_iIdx;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Return Index associated with the token related data. 
+      
+          In cmSTRFUNC - This is the index to a string table in the main parser.
+
+          \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
+          \return The index the result will take in the Bytecode calculatin array (#m_iIdx).
+      */
+      int GetIdx() const
+      {
+        if (m_iIdx<0 || m_iCode!=cmSTRING )
+          throw ParserError(ecINTERNAL_ERROR);
+
+        return m_iIdx;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Return the token type.
+      
+          \return #m_iType
+          \throw nothrow
+      */
+      ECmdCode GetCode() const
+      {
+        if (m_pCallback.get())
+        {
+          return m_pCallback->GetCode();
+        }
+        else
+        {
+          return m_iCode;
+        }
+      }
+
+      //------------------------------------------------------------------------------
+      ETypeCode GetType() const
+      {
+        if (m_pCallback.get())
+        {
+          return m_pCallback->GetType();
+        }
+        else
+        {
+          return m_iType;
+        }
+      }
+      
+      //------------------------------------------------------------------------------
+      int GetPri() const
+      {
+        if ( !m_pCallback.get())
+	        throw ParserError(ecINTERNAL_ERROR);
+            
+        if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)
+	        throw ParserError(ecINTERNAL_ERROR);
+
+        return m_pCallback->GetPri();
+      }
+
+      //------------------------------------------------------------------------------
+      EOprtAssociativity GetAssociativity() const
+      {
+        if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN)
+	        throw ParserError(ecINTERNAL_ERROR);
+
+        return m_pCallback->GetAssociativity();
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Return the address of the callback function assoziated with
+                 function and operator tokens.
+
+          \return The pointer stored in #m_pTok.
+          \throw exception_type if token type is non of:
+                 <ul>
+                   <li>cmFUNC</li>
+                   <li>cmSTRFUNC</li>
+                   <li>cmPOSTOP</li>
+                   <li>cmINFIXOP</li>
+                   <li>cmOPRT_BIN</li>
+                 </ul>
+          \sa ECmdCode
+      */
+      generic_fun_type GetFuncAddr() const
+      {
+        return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \biref Get value of the token.
+        
+          Only applicable to variable and value tokens.
+          \throw exception_type if token is no value/variable token.
+      */
+      TBase GetVal() const
+      {
+        switch (m_iCode)
+        {
+          case cmVAL:  return m_fVal;
+          case cmVAR:  return *((TBase*)m_pTok);
+          default:     throw ParserError(ecVAL_EXPECTED);
+        }
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Get address of a variable token.
+
+        Valid only if m_iType==CmdVar.
+        \throw exception_type if token is no variable token.
+      */
+      TBase* GetVar() const
+      {
+        if (m_iCode!=cmVAR)
+	        throw ParserError(ecINTERNAL_ERROR);
+
+        return (TBase*)m_pTok;
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Return the number of function arguments. 
+
+        Valid only if m_iType==CmdFUNC.
+      */
+      int GetArgCount() const
+      {
+        assert(m_pCallback.get());
+
+        if (!m_pCallback->GetAddr())
+	        throw ParserError(ecINTERNAL_ERROR);
+
+        return m_pCallback->GetArgc();
+      }
+
+      //------------------------------------------------------------------------------
+      /** \brief Return the token identifier. 
+          
+          If #m_iType is cmSTRING the token identifier is the value of the string argument
+          for a string function.
+          \return #m_strTok
+          \throw nothrow
+          \sa m_strTok
+      */
+      const TString& GetAsString() const
+      {
+        return m_strTok;
+      }
+  };
+} // namespace mu
+
+#endif
diff --git a/ThirdParty/MuParser/include/muParserTokenReader.h b/ThirdParty/MuParser/include/muParserTokenReader.h
new file mode 100644
index 0000000000000000000000000000000000000000..654b597693a0f106e2eb12631adac486c05e455a
--- /dev/null
+++ b/ThirdParty/MuParser/include/muParserTokenReader.h
@@ -0,0 +1,161 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2013 Ingo Berg
+
+  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. 
+*/
+
+#ifndef MU_PARSER_TOKEN_READER_H
+#define MU_PARSER_TOKEN_READER_H
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <list>
+#include <map>
+#include <memory>
+#include <stack>
+#include <string>
+
+#include "muParserDef.h"
+#include "muParserToken.h"
+
+/** \file
+    \brief This file contains the parser token reader definition.
+*/
+
+
+namespace mu
+{
+  // Forward declaration
+  class ParserBase;
+
+  /** \brief Token reader for the ParserBase class.
+
+  */
+  class ParserTokenReader 
+  {
+  private:
+
+      typedef ParserToken<value_type, string_type> token_type;
+
+  public:
+
+      ParserTokenReader(ParserBase *a_pParent);
+      ParserTokenReader* Clone(ParserBase *a_pParent) const;
+
+      void AddValIdent(identfun_type a_pCallback);
+      void SetVarCreator(facfun_type a_pFactory, void *pUserData);
+      void SetFormula(const string_type &a_strFormula);
+      void SetArgSep(char_type cArgSep);
+
+      int GetPos() const;
+      const string_type& GetExpr() const;
+      varmap_type& GetUsedVar();
+      char_type GetArgSep() const;
+
+      void IgnoreUndefVar(bool bIgnore);
+      void ReInit();
+      token_type ReadNextToken();
+
+  private:
+
+      /** \brief Syntax codes. 
+  	
+	        The syntax codes control the syntax check done during the first time parsing of 
+          the expression string. They are flags that indicate which tokens are allowed next
+          if certain tokens are identified.
+  	  */
+      enum ESynCodes
+      {
+        noBO      = 1 << 0,  ///< to avoid i.e. "cos(7)(" 
+        noBC      = 1 << 1,  ///< to avoid i.e. "sin)" or "()"
+        noVAL     = 1 << 2,  ///< to avoid i.e. "tan 2" or "sin(8)3.14"
+        noVAR     = 1 << 3,  ///< to avoid i.e. "sin a" or "sin(8)a"
+        noARG_SEP = 1 << 4,  ///< to avoid i.e. ",," or "+," ...
+        noFUN     = 1 << 5,  ///< to avoid i.e. "sqrt cos" or "(1)sin"	
+        noOPT     = 1 << 6,  ///< to avoid i.e. "(+)"
+        noPOSTOP  = 1 << 7,  ///< to avoid i.e. "(5!!)" "sin!"
+	      noINFIXOP = 1 << 8,  ///< to avoid i.e. "++4" "!!4"
+        noEND     = 1 << 9,  ///< to avoid unexpected end of formula
+        noSTR     = 1 << 10, ///< to block numeric arguments on string functions
+        noASSIGN  = 1 << 11, ///< to block assignement to constant i.e. "4=7"
+        noIF      = 1 << 12,
+        noELSE    = 1 << 13,
+        sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP,
+        noANY     = ~0       ///< All of he above flags set
+      };	
+
+      ParserTokenReader(const ParserTokenReader &a_Reader);
+      ParserTokenReader& operator=(const ParserTokenReader &a_Reader);
+      void Assign(const ParserTokenReader &a_Reader);
+
+      void SetParent(ParserBase *a_pParent);
+      int ExtractToken(const char_type *a_szCharSet, 
+                       string_type &a_strTok, 
+                       int a_iPos) const;
+      int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const;
+
+      bool IsBuiltIn(token_type &a_Tok);
+      bool IsArgSep(token_type &a_Tok);
+      bool IsEOF(token_type &a_Tok);
+      bool IsInfixOpTok(token_type &a_Tok);
+      bool IsFunTok(token_type &a_Tok);
+      bool IsPostOpTok(token_type &a_Tok);
+      bool IsOprt(token_type &a_Tok);
+      bool IsValTok(token_type &a_Tok);
+      bool IsVarTok(token_type &a_Tok);
+      bool IsStrVarTok(token_type &a_Tok);
+      bool IsUndefVarTok(token_type &a_Tok);
+      bool IsString(token_type &a_Tok);
+      void Error(EErrorCodes a_iErrc, 
+                 int a_iPos = -1, 
+                 const string_type &a_sTok = string_type() ) const;
+
+      token_type& SaveBeforeReturn(const token_type &tok);
+
+      ParserBase *m_pParser;
+      string_type m_strFormula;
+      int  m_iPos;
+      int  m_iSynFlags;
+      bool m_bIgnoreUndefVar;
+
+      const funmap_type *m_pFunDef;
+      const funmap_type *m_pPostOprtDef;
+      const funmap_type *m_pInfixOprtDef;
+      const funmap_type *m_pOprtDef;
+      const valmap_type *m_pConstDef;
+      const strmap_type *m_pStrVarDef;
+      varmap_type *m_pVarDef;  ///< The only non const pointer to parser internals
+      facfun_type m_pFactory;
+      void *m_pFactoryData;
+      std::list<identfun_type> m_vIdentFun; ///< Value token identification function
+      varmap_type m_UsedVar;
+      value_type m_fZero;      ///< Dummy value of zero, referenced by undefined variables
+      int m_iBrackets;
+      token_type m_lastTok;
+      char_type m_cArgSep;     ///< The character used for separating function arguments
+  };
+} // namespace mu
+
+#endif
+
+
diff --git a/ThirdParty/MuParser/src/muParser.cpp b/ThirdParty/MuParser/src/muParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b536556b6f2dc2c699dd1cb331ba80d9dafd8981
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParser.cpp
@@ -0,0 +1,397 @@
+/* 
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+#include "muParser.h"
+#include "muParserTemplateMagic.h"
+
+//--- Standard includes ------------------------------------------------------------------------
+#include <cmath>
+#include <algorithm>
+#include <numeric>
+
+/** \brief Pi (what else?). */
+#define PARSER_CONST_PI  3.141592653589793238462643
+
+/** \brief The Eulerian number. */
+#define PARSER_CONST_E   2.718281828459045235360287
+
+using namespace std;
+
+/** \file
+    \brief Implementation of the standard floating point parser.
+*/
+
+
+
+/** \brief Namespace for mathematical applications. */
+namespace mu
+{
+
+
+  //---------------------------------------------------------------------------
+  // Trigonometric function
+  value_type Parser::Sin(value_type v)   { return MathImpl<value_type>::Sin(v);  }
+  value_type Parser::Cos(value_type v)   { return MathImpl<value_type>::Cos(v);  }
+  value_type Parser::Tan(value_type v)   { return MathImpl<value_type>::Tan(v);  }
+  value_type Parser::ASin(value_type v)  { return MathImpl<value_type>::ASin(v); }
+  value_type Parser::ACos(value_type v)  { return MathImpl<value_type>::ACos(v); }
+  value_type Parser::ATan(value_type v)  { return MathImpl<value_type>::ATan(v); }
+  value_type Parser::ATan2(value_type v1, value_type v2) { return MathImpl<value_type>::ATan2(v1, v2); }
+  value_type Parser::Sinh(value_type v)  { return MathImpl<value_type>::Sinh(v); }
+  value_type Parser::Cosh(value_type v)  { return MathImpl<value_type>::Cosh(v); }
+  value_type Parser::Tanh(value_type v)  { return MathImpl<value_type>::Tanh(v); }
+  value_type Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }
+  value_type Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }
+  value_type Parser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); }
+
+  //---------------------------------------------------------------------------
+  // Logarithm functions
+
+  // Logarithm base 2
+  value_type Parser::Log2(value_type v)  
+  { 
+    #ifdef MUP_MATH_EXCEPTIONS
+        if (v<=0)
+          throw ParserError(ecDOMAIN_ERROR, _T("Log2"));
+    #endif
+
+    return MathImpl<value_type>::Log2(v);  
+  }  
+
+  // Logarithm base 10
+  value_type Parser::Log10(value_type v) 
+  { 
+    #ifdef MUP_MATH_EXCEPTIONS
+        if (v<=0)
+          throw ParserError(ecDOMAIN_ERROR, _T("Log10"));
+    #endif
+
+    return MathImpl<value_type>::Log10(v); 
+  } 
+
+// Logarithm base e (natural logarithm)
+  value_type Parser::Ln(value_type v)    
+  { 
+    #ifdef MUP_MATH_EXCEPTIONS
+        if (v<=0)
+          throw ParserError(ecDOMAIN_ERROR, _T("Ln"));
+    #endif
+
+    return MathImpl<value_type>::Log(v);   
+  } 
+
+  //---------------------------------------------------------------------------
+  //  misc
+  value_type Parser::Exp(value_type v)  { return MathImpl<value_type>::Exp(v);  }
+  value_type Parser::Abs(value_type v)  { return MathImpl<value_type>::Abs(v);  }
+  value_type Parser::Sqrt(value_type v) 
+  { 
+    #ifdef MUP_MATH_EXCEPTIONS
+        if (v<0)
+          throw ParserError(ecDOMAIN_ERROR, _T("sqrt"));
+    #endif
+
+    return MathImpl<value_type>::Sqrt(v); 
+  }
+  value_type Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }
+  value_type Parser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); }
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for the unary minus operator.
+      \param v The value to negate
+      \return -v
+  */
+  value_type Parser::UnaryMinus(value_type v) 
+  { 
+    return -v; 
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for the unary minus operator.
+      \param v The value to negate
+      \return -v
+  */
+  value_type Parser::UnaryPlus(value_type v) 
+  { 
+    return v; 
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for adding multiple values. 
+      \param [in] a_afArg Vector with the function arguments
+      \param [in] a_iArgc The size of a_afArg
+  */
+  value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)
+  { 
+    if (!a_iArgc)	
+      throw exception_type(_T("too few arguments for function sum."));
+
+    value_type fRes=0;
+    for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
+    return fRes;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for averaging multiple values. 
+      \param [in] a_afArg Vector with the function arguments
+      \param [in] a_iArgc The size of a_afArg
+  */
+  value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)
+  { 
+    if (!a_iArgc)	
+      throw exception_type(_T("too few arguments for function sum."));
+
+    value_type fRes=0;
+    for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
+    return fRes/(value_type)a_iArgc;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for determining the minimum value out of a vector. 
+      \param [in] a_afArg Vector with the function arguments
+      \param [in] a_iArgc The size of a_afArg
+  */
+  value_type Parser::Min(const value_type *a_afArg, int a_iArgc)
+  { 
+    if (!a_iArgc)	
+      throw exception_type(_T("too few arguments for function min."));
+
+    value_type fRes=a_afArg[0];
+    for (int i=0; i<a_iArgc; ++i) 
+      fRes = std::min(fRes, a_afArg[i]);
+
+    return fRes;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Callback for determining the maximum value out of a vector. 
+      \param [in] a_afArg Vector with the function arguments
+      \param [in] a_iArgc The size of a_afArg
+  */
+  value_type Parser::Max(const value_type *a_afArg, int a_iArgc)
+  { 
+    if (!a_iArgc)	
+      throw exception_type(_T("too few arguments for function min."));
+
+    value_type fRes=a_afArg[0];
+    for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
+
+    return fRes;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Default value recognition callback. 
+      \param [in] a_szExpr Pointer to the expression
+      \param [in, out] a_iPos Pointer to an index storing the current position within the expression
+      \param [out] a_fVal Pointer where the value should be stored in case one is found.
+      \return 1 if a value was found 0 otherwise.
+  */
+  int Parser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal)
+  {
+    value_type fVal(0);
+
+    stringstream_type stream(a_szExpr);
+    stream.seekg(0);        // todo:  check if this really is necessary
+    stream.imbue(Parser::s_locale);
+    stream >> fVal;
+    stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
+
+    if (iEnd==(stringstream_type::pos_type)-1)
+      return 0;
+
+    *a_iPos += (int)iEnd;
+    *a_fVal = fVal;
+    return 1;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor. 
+
+    Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
+  */
+  Parser::Parser()
+    :ParserBase()
+  {
+    AddValIdent(IsVal);
+
+    InitCharSets();
+    InitFun();
+    InitConst();
+    InitOprt();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the character sets. 
+      \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
+    
+    This function is used for initializing the default character sets that define
+    the characters to be useable in function and variable names and operators.
+  */
+  void Parser::InitCharSets()
+  {
+    DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
+    DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") );
+    DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") );
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize the default functions. */
+  void Parser::InitFun()
+  {
+    if (mu::TypeInfo<mu::value_type>::IsInteger())
+    {
+      // When setting MUP_BASETYPE to an integer type
+      // Place functions for dealing with integer values here
+      // ...
+      // ...
+      // ...
+    }
+    else
+    {
+      // trigonometric functions
+      DefineFun(_T("sin"), Sin);
+      DefineFun(_T("cos"), Cos);
+      DefineFun(_T("tan"), Tan);
+      // arcus functions
+      DefineFun(_T("asin"), ASin);
+      DefineFun(_T("acos"), ACos);
+      DefineFun(_T("atan"), ATan);
+      DefineFun(_T("atan2"), ATan2);
+      // hyperbolic functions
+      DefineFun(_T("sinh"), Sinh);
+      DefineFun(_T("cosh"), Cosh);
+      DefineFun(_T("tanh"), Tanh);
+      // arcus hyperbolic functions
+      DefineFun(_T("asinh"), ASinh);
+      DefineFun(_T("acosh"), ACosh);
+      DefineFun(_T("atanh"), ATanh);
+      // Logarithm functions
+      DefineFun(_T("log2"), Log2);
+      DefineFun(_T("log10"), Log10);
+      DefineFun(_T("log"), Ln);
+      DefineFun(_T("ln"), Ln);
+      // misc
+      DefineFun(_T("exp"), Exp);
+      DefineFun(_T("sqrt"), Sqrt);
+      DefineFun(_T("sign"), Sign);
+      DefineFun(_T("rint"), Rint);
+      DefineFun(_T("abs"), Abs);
+      // Functions with variable number of arguments
+      DefineFun(_T("sum"), Sum);
+      DefineFun(_T("avg"), Avg);
+      DefineFun(_T("min"), Min);
+      DefineFun(_T("max"), Max);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize constants.
+  
+    By default the parser recognizes two constants. Pi ("pi") and the Eulerian
+    number ("_e").
+  */
+  void Parser::InitConst()
+  {
+    DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI);
+    DefineConst(_T("_e"), (value_type)PARSER_CONST_E);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize operators. 
+  
+    By default only the unary minus operator is added.
+  */
+  void Parser::InitOprt()
+  {
+    DefineInfixOprt(_T("-"), UnaryMinus);
+    DefineInfixOprt(_T("+"), UnaryPlus);
+  }
+
+  //---------------------------------------------------------------------------
+  void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
+  {
+    // this is just sample code to illustrate modifying variable names on the fly.
+    // I'm not sure anyone really needs such a feature...
+    /*
+
+
+    string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
+    string sRepl = std::string("_") + sVar + "_";
+  
+    int nOrigVarEnd = nEnd;
+    cout << "variable detected!\n";
+    cout << "  Expr: " << *pExpr << "\n";
+    cout << "  Start: " << nStart << "\n";
+    cout << "  End: " << nEnd << "\n";
+    cout << "  Var: \"" << sVar << "\"\n";
+    cout << "  Repl: \"" << sRepl << "\"\n";
+    nEnd = nStart + sRepl.length();
+    cout << "  End: " << nEnd << "\n";
+    pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
+    cout << "  New expr: " << *pExpr << "\n";
+    */
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Numerically differentiate with regard to a variable. 
+      \param [in] a_Var Pointer to the differentiation variable.
+      \param [in] a_fPos Position at which the differentiation should take place.
+      \param [in] a_fEpsilon Epsilon used for the numerical differentiation.
+
+    Numerical differentiation uses a 5 point operator yielding a 4th order 
+    formula. The default value for epsilon is 0.00074 which is
+    numeric_limits<double>::epsilon() ^ (1/5) as suggested in the muparser
+    forum:
+
+    http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
+  */
+  value_type Parser::Diff(value_type *a_Var, 
+                          value_type  a_fPos, 
+                          value_type  a_fEpsilon) const
+  {
+    value_type fRes(0), 
+               fBuf(*a_Var),
+               f[4] = {0,0,0,0},
+               fEpsilon(a_fEpsilon);
+
+    // Backwards compatible calculation of epsilon inc case the user doesn't provide
+    // his own epsilon
+    if (fEpsilon==0)
+      fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;
+
+    *a_Var = a_fPos+2 * fEpsilon;  f[0] = Eval();
+    *a_Var = a_fPos+1 * fEpsilon;  f[1] = Eval();
+    *a_Var = a_fPos-1 * fEpsilon;  f[2] = Eval();
+    *a_Var = a_fPos-2 * fEpsilon;  f[3] = Eval();
+    *a_Var = fBuf; // restore variable
+
+    fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
+    return fRes;
+  }
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserBase.cpp b/ThirdParty/MuParser/src/muParserBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bdda6041d76a8117f54d4fc0afc8ff6a1030b9c7
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserBase.cpp
@@ -0,0 +1,1778 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  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. 
+*/
+
+#include "muParserBase.h"
+#include "muParserTemplateMagic.h"
+
+//--- Standard includes ------------------------------------------------------------------------
+#include <cassert>
+#include <algorithm>
+#include <cmath>
+#include <memory>
+#include <vector>
+#include <deque>
+#include <sstream>
+#include <locale>
+
+#ifdef MUP_USE_OPENMP
+  #include <omp.h>
+#endif
+
+using namespace std;
+
+/** \file
+    \brief This file contains the basic implementation of the muparser engine.
+*/
+
+namespace mu
+{
+  std::locale ParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep<char_type>('.'));
+
+  bool ParserBase::g_DbgDumpCmdCode = false;
+  bool ParserBase::g_DbgDumpStack = false;
+
+  //------------------------------------------------------------------------------
+  /** \brief Identifiers for built in binary operators. 
+
+      When defining custom binary operators with #AddOprt(...) make sure not to choose 
+      names conflicting with these definitions. 
+  */
+  const char_type* ParserBase::c_DefaultOprt[] = 
+  { 
+    _T("<="), _T(">="),  _T("!="), 
+    _T("=="), _T("<"),   _T(">"), 
+    _T("+"),  _T("-"),   _T("*"), 
+    _T("/"),  _T("^"),   _T("&&"), 
+    _T("||"), _T("="),   _T("("),  
+    _T(")"),   _T("?"),  _T(":"), 0 
+  };
+
+  //------------------------------------------------------------------------------
+  /** \brief Constructor.
+      \param a_szFormula the formula to interpret.
+      \throw ParserException if a_szFormula is null.
+  */
+  ParserBase::ParserBase()
+    :m_pParseFormula(&ParserBase::ParseString)
+    ,m_vRPN()
+    ,m_vStringBuf()
+    ,m_pTokenReader()
+    ,m_FunDef()
+    ,m_PostOprtDef()
+    ,m_InfixOprtDef()
+    ,m_OprtDef()
+    ,m_ConstDef()
+    ,m_StrVarDef()
+    ,m_VarDef()
+    ,m_bBuiltInOp(true)
+    ,m_sNameChars()
+    ,m_sOprtChars()
+    ,m_sInfixOprtChars()
+    ,m_nIfElseCounter(0)
+    ,m_vStackBuffer()
+    ,m_nFinalResultIdx(0)
+  {
+    InitTokenReader();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+
+    The parser can be safely copy constructed but the bytecode is reset during
+    copy construction.
+  */
+  ParserBase::ParserBase(const ParserBase &a_Parser)
+    :m_pParseFormula(&ParserBase::ParseString)
+    ,m_vRPN()
+    ,m_vStringBuf()
+    ,m_pTokenReader()
+    ,m_FunDef()
+    ,m_PostOprtDef()
+    ,m_InfixOprtDef()
+    ,m_OprtDef()
+    ,m_ConstDef()
+    ,m_StrVarDef()
+    ,m_VarDef()
+    ,m_bBuiltInOp(true)
+    ,m_sNameChars()
+    ,m_sOprtChars()
+    ,m_sInfixOprtChars()
+    ,m_nIfElseCounter(0)
+  {
+    m_pTokenReader.reset(new token_reader_type(this));
+    Assign(a_Parser);
+  }
+
+  //---------------------------------------------------------------------------
+  ParserBase::~ParserBase()
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignment operator. 
+
+    Implemented by calling Assign(a_Parser). Self assignment is suppressed.
+    \param a_Parser Object to copy to this.
+    \return *this
+    \throw nothrow
+  */
+  ParserBase& ParserBase::operator=(const ParserBase &a_Parser)
+  {
+    Assign(a_Parser);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy state of a parser object to this. 
+
+    Clears Variables and Functions of this parser.
+    Copies the states of all internal variables.
+    Resets parse function to string parse mode.
+
+    \param a_Parser the source object.
+  */
+  void ParserBase::Assign(const ParserBase &a_Parser)
+  {
+    if (&a_Parser==this)
+      return;
+
+    // Don't copy bytecode instead cause the parser to create new bytecode
+    // by resetting the parse function.
+    ReInit();
+
+    m_ConstDef        = a_Parser.m_ConstDef;         // Copy user define constants
+    m_VarDef          = a_Parser.m_VarDef;           // Copy user defined variables
+    m_bBuiltInOp      = a_Parser.m_bBuiltInOp;
+    m_vStringBuf      = a_Parser.m_vStringBuf;
+    m_vStackBuffer    = a_Parser.m_vStackBuffer;
+    m_nFinalResultIdx = a_Parser.m_nFinalResultIdx;
+    m_StrVarDef       = a_Parser.m_StrVarDef;
+    m_vStringVarBuf   = a_Parser.m_vStringVarBuf;
+    m_nIfElseCounter  = a_Parser.m_nIfElseCounter;
+    m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this));
+
+    // Copy function and operator callbacks
+    m_FunDef = a_Parser.m_FunDef;             // Copy function definitions
+    m_PostOprtDef = a_Parser.m_PostOprtDef;   // post value unary operators
+    m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation
+    m_OprtDef = a_Parser.m_OprtDef;           // binary operators
+
+    m_sNameChars = a_Parser.m_sNameChars;
+    m_sOprtChars = a_Parser.m_sOprtChars;
+    m_sInfixOprtChars = a_Parser.m_sInfixOprtChars;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Set the decimal separator.
+      \param cDecSep Decimal separator as a character value.
+      \sa SetThousandsSep
+
+      By default muparser uses the "C" locale. The decimal separator of this
+      locale is overwritten by the one provided here.
+  */
+  void ParserBase::SetDecSep(char_type cDecSep)
+  {
+    char_type cThousandsSep = std::use_facet< change_dec_sep<char_type> >(s_locale).thousands_sep();
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));
+  }
+  
+  //---------------------------------------------------------------------------
+  /** \brief Sets the thousands operator. 
+      \param cThousandsSep The thousands separator as a character
+      \sa SetDecSep
+
+      By default muparser uses the "C" locale. The thousands separator of this
+      locale is overwritten by the one provided here.
+  */
+  void ParserBase::SetThousandsSep(char_type cThousandsSep)
+  {
+    char_type cDecSep = std::use_facet< change_dec_sep<char_type> >(s_locale).decimal_point();
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Resets the locale. 
+
+    The default locale used "." as decimal separator, no thousands separator and
+    "," as function argument separator.
+  */
+  void ParserBase::ResetLocale()
+  {
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>('.'));
+    SetArgSep(',');
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize the token reader. 
+
+    Create new token reader object and submit pointers to function, operator,
+    constant and variable definitions.
+
+    \post m_pTokenReader.get()!=0
+    \throw nothrow
+  */
+  void ParserBase::InitTokenReader()
+  {
+    m_pTokenReader.reset(new token_reader_type(this));
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Reset parser to string parsing mode and clear internal buffers.
+
+      Clear bytecode, reset the token reader.
+      \throw nothrow
+  */
+  void ParserBase::ReInit() const
+  {
+    m_pParseFormula = &ParserBase::ParseString;
+    m_vStringBuf.clear();
+    m_vRPN.clear();
+    m_pTokenReader->ReInit();
+    m_nIfElseCounter = 0;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns the version of muparser. 
+      \param eInfo A flag indicating whether the full version info should be 
+                   returned or not.
+
+    Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS
+    are returned only if eInfo==pviFULL.
+  */
+  string_type ParserBase::GetVersion(EParserVersionInfo eInfo) const
+  {
+    stringstream_type ss;
+
+    ss << MUP_VERSION;
+
+    if (eInfo==pviFULL)
+    {
+      ss << _T(" (") << MUP_VERSION_DATE;
+      ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT");
+
+#ifdef _DEBUG
+      ss << _T("; DEBUG");
+#else 
+      ss << _T("; RELEASE");
+#endif
+
+#ifdef _UNICODE
+      ss << _T("; UNICODE");
+#else
+  #ifdef _MBCS
+      ss << _T("; MBCS");
+  #else
+      ss << _T("; ASCII");
+  #endif
+#endif
+
+#ifdef MUP_USE_OPENMP
+      ss << _T("; OPENMP");
+//#else
+//      ss << _T("; NO_OPENMP");
+#endif
+
+#if defined(MUP_MATH_EXCEPTIONS)
+      ss << _T("; MATHEXC");
+//#else
+//      ss << _T("; NO_MATHEXC");
+#endif
+
+      ss << _T(")");
+    }
+
+    return ss.str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a value parsing function. 
+      
+      When parsing an expression muParser tries to detect values in the expression
+      string using different valident callbacks. Thus it's possible to parse
+      for hex values, binary values and floating point values. 
+  */
+  void ParserBase::AddValIdent(identfun_type a_pCallback)
+  {
+    m_pTokenReader->AddValIdent(a_pCallback);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Set a function that can create variable pointer for unknown expression variables. 
+      \param a_pFactory A pointer to the variable factory.
+      \param pUserData A user defined context pointer.
+  */
+  void ParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData)
+  {
+    m_pTokenReader->SetVarCreator(a_pFactory, pUserData);  
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a function or operator callback to the parser. */
+  void ParserBase::AddCallback( const string_type &a_strName,
+                                const ParserCallback &a_Callback, 
+                                funmap_type &a_Storage,
+                                const char_type *a_szCharSet )
+  {
+    if (a_Callback.GetAddr()==0)
+        Error(ecINVALID_FUN_PTR);
+
+    const funmap_type *pFunMap = &a_Storage;
+
+    // Check for conflicting operator or function names
+    if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() )
+      Error(ecNAME_CONFLICT, -1, a_strName);
+
+    if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() )
+      Error(ecNAME_CONFLICT, -1, a_strName);
+
+    if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() )
+      Error(ecNAME_CONFLICT, -1, a_strName);
+
+    if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() )
+      Error(ecNAME_CONFLICT, -1, a_strName);
+
+    CheckOprt(a_strName, a_Callback, a_szCharSet);
+    a_Storage[a_strName] = a_Callback;
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a name contains invalid characters. 
+
+      \throw ParserException if the name contains invalid characters.
+  */
+  void ParserBase::CheckOprt(const string_type &a_sName,
+                             const ParserCallback &a_Callback,
+                             const string_type &a_szCharSet) const
+  {
+    if ( !a_sName.length() ||
+        (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
+        (a_sName[0]>='0' && a_sName[0]<='9'))
+    {
+      switch(a_Callback.GetCode())
+      {
+      case cmOPRT_POSTFIX: Error(ecINVALID_POSTFIX_IDENT, -1, a_sName);
+      case cmOPRT_INFIX:   Error(ecINVALID_INFIX_IDENT, -1, a_sName);
+      default:             Error(ecINVALID_NAME, -1, a_sName);
+      }
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a name contains invalid characters. 
+
+      \throw ParserException if the name contains invalid characters.
+  */
+  void ParserBase::CheckName(const string_type &a_sName,
+                             const string_type &a_szCharSet) const
+  {
+    if ( !a_sName.length() ||
+        (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
+        (a_sName[0]>='0' && a_sName[0]<='9'))
+    {
+      Error(ecINVALID_NAME);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Set the formula. 
+      \param a_strFormula Formula as string_type
+      \throw ParserException in case of syntax errors.
+
+      Triggers first time calculation thus the creation of the bytecode and
+      scanning of used variables.
+  */
+  void ParserBase::SetExpr(const string_type &a_sExpr)
+  {
+    // Check locale compatibility
+    std::locale loc;
+    if (m_pTokenReader->GetArgSep()==std::use_facet<numpunct<char_type> >(loc).decimal_point())
+      Error(ecLOCALE);
+
+    // <ibg> 20060222: Bugfix for Borland-Kylix:
+    // adding a space to the expression will keep Borlands KYLIX from going wild
+    // when calling tellg on a stringstream created from the expression after 
+    // reading a value at the end of an expression. (mu::Parser::IsVal function)
+    // (tellg returns -1 otherwise causing the parser to ignore the value)
+    string_type sBuf(a_sExpr + _T(" ") );
+    m_pTokenReader->SetFormula(sBuf);
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get the default symbols used for the built in operators. 
+      \sa c_DefaultOprt
+  */
+  const char_type** ParserBase::GetOprtDef() const
+  {
+    return (const char_type **)(&c_DefaultOprt[0]);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+             functions, variables, constants.
+  */
+  void ParserBase::DefineNameChars(const char_type *a_szCharset)
+  {
+    m_sNameChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+             binary operators and postfix operators.
+  */
+  void ParserBase::DefineOprtChars(const char_type *a_szCharset)
+  {
+    m_sOprtChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define the set of valid characters to be used in names of
+             infix operators.
+  */
+  void ParserBase::DefineInfixOprtChars(const char_type *a_szCharset)
+  {
+    m_sInfixOprtChars = a_szCharset;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in name identifiers. 
+      \sa #ValidOprtChars, #ValidPrefixOprtChars
+  */ 
+  const char_type* ParserBase::ValidNameChars() const
+  {
+    assert(m_sNameChars.size());
+    return m_sNameChars.c_str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in operator definitions. 
+      \sa #ValidNameChars, #ValidPrefixOprtChars
+  */
+  const char_type* ParserBase::ValidOprtChars() const
+  {
+    assert(m_sOprtChars.size());
+    return m_sOprtChars.c_str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Virtual function that defines the characters allowed in infix operator definitions.
+      \sa #ValidNameChars, #ValidOprtChars
+  */
+  const char_type* ParserBase::ValidInfixOprtChars() const
+  {
+    assert(m_sInfixOprtChars.size());
+    return m_sInfixOprtChars.c_str();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined operator. 
+      \post Will reset the Parser to string parsing mode.
+  */
+  void ParserBase::DefinePostfixOprt(const string_type &a_sName, 
+                                     fun_type1 a_pFun,
+                                     bool a_bAllowOpt)
+  {
+    AddCallback(a_sName, 
+                ParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX),
+                m_PostOprtDef, 
+                ValidOprtChars() );
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize user defined functions. 
+   
+    Calls the virtual functions InitFun(), InitConst() and InitOprt().
+  */
+  void ParserBase::Init()
+  {
+    InitCharSets();
+    InitFun();
+    InitConst();
+    InitOprt();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined operator. 
+      \post Will reset the Parser to string parsing mode.
+      \param [in] a_sName  operator Identifier 
+      \param [in] a_pFun  Operator callback function
+      \param [in] a_iPrec  Operator Precedence (default=prSIGN)
+      \param [in] a_bAllowOpt  True if operator is volatile (default=false)
+      \sa EPrec
+  */
+  void ParserBase::DefineInfixOprt(const string_type &a_sName, 
+                                  fun_type1 a_pFun, 
+                                  int a_iPrec, 
+                                  bool a_bAllowOpt)
+  {
+    AddCallback(a_sName, 
+                ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), 
+                m_InfixOprtDef, 
+                ValidInfixOprtChars() );
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Define a binary operator. 
+      \param [in] a_sName The identifier of the operator.
+      \param [in] a_pFun Pointer to the callback function.
+      \param [in] a_iPrec Precedence of the operator.
+      \param [in] a_eAssociativity The associativity of the operator.
+      \param [in] a_bAllowOpt If this is true the operator may be optimized away.
+      
+      Adds a new Binary operator the the parser instance. 
+  */
+  void ParserBase::DefineOprt( const string_type &a_sName, 
+                               fun_type2 a_pFun, 
+                               unsigned a_iPrec, 
+                               EOprtAssociativity a_eAssociativity,
+                               bool a_bAllowOpt )
+  {
+    // Check for conflicts with built in operator names
+    for (int i=0; m_bBuiltInOp && i<cmENDIF; ++i)
+      if (a_sName == string_type(c_DefaultOprt[i]))
+        Error(ecBUILTIN_OVERLOAD, -1, a_sName);
+
+    AddCallback(a_sName, 
+                ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, a_eAssociativity), 
+                m_OprtDef, 
+                ValidOprtChars() );
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Define a new string constant.
+      \param [in] a_strName The name of the constant.
+      \param [in] a_strVal the value of the constant. 
+  */
+  void ParserBase::DefineStrConst(const string_type &a_strName, const string_type &a_strVal)
+  {
+    // Test if a constant with that names already exists
+    if (m_StrVarDef.find(a_strName)!=m_StrVarDef.end())
+      Error(ecNAME_CONFLICT);
+
+    CheckName(a_strName, ValidNameChars());
+    
+    m_vStringVarBuf.push_back(a_strVal);                // Store variable string in internal buffer
+    m_StrVarDef[a_strName] = m_vStringVarBuf.size()-1;  // bind buffer index to variable name
+
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined variable. 
+      \param [in] a_sName the variable name
+      \param [in] a_pVar A pointer to the variable value.
+      \post Will reset the Parser to string parsing mode.
+      \throw ParserException in case the name contains invalid signs or a_pVar is NULL.
+  */
+  void ParserBase::DefineVar(const string_type &a_sName, value_type *a_pVar)
+  {
+    if (a_pVar==0)
+      Error(ecINVALID_VAR_PTR);
+
+    // Test if a constant with that names already exists
+    if (m_ConstDef.find(a_sName)!=m_ConstDef.end())
+      Error(ecNAME_CONFLICT);
+
+    CheckName(a_sName, ValidNameChars());
+    m_VarDef[a_sName] = a_pVar;
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a user defined constant. 
+      \param [in] a_sName The name of the constant.
+      \param [in] a_fVal the value of the constant.
+      \post Will reset the Parser to string parsing mode.
+      \throw ParserException in case the name contains invalid signs.
+  */
+  void ParserBase::DefineConst(const string_type &a_sName, value_type a_fVal)
+  {
+    CheckName(a_sName, ValidNameChars());
+    m_ConstDef[a_sName] = a_fVal;
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get operator priority.
+      \throw ParserException if a_Oprt is no operator code
+  */
+  int ParserBase::GetOprtPrecedence(const token_type &a_Tok) const
+  {
+    switch (a_Tok.GetCode())
+    {
+    // built in operators
+    case cmEND:      return -5;
+    case cmARG_SEP:  return -4;
+    case cmASSIGN:   return -1;               
+    case cmELSE:
+    case cmIF:       return  0;
+    case cmLAND:     return  prLAND;
+    case cmLOR:      return  prLOR;
+    case cmLT:
+    case cmGT:
+    case cmLE:
+    case cmGE:
+    case cmNEQ:
+    case cmEQ:       return  prCMP; 
+    case cmADD:
+    case cmSUB:      return  prADD_SUB;
+    case cmMUL:
+    case cmDIV:      return  prMUL_DIV;
+    case cmPOW:      return  prPOW;
+
+    // user defined binary operators
+    case cmOPRT_INFIX: 
+    case cmOPRT_BIN: return a_Tok.GetPri();
+    default:  Error(ecINTERNAL_ERROR, 5);
+              return 999;
+    }  
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get operator priority.
+      \throw ParserException if a_Oprt is no operator code
+  */
+  EOprtAssociativity ParserBase::GetOprtAssociativity(const token_type &a_Tok) const
+  {
+    switch (a_Tok.GetCode())
+    {
+    case cmASSIGN:
+    case cmLAND:
+    case cmLOR:
+    case cmLT:
+    case cmGT:
+    case cmLE:
+    case cmGE:
+    case cmNEQ:
+    case cmEQ: 
+    case cmADD:
+    case cmSUB:
+    case cmMUL:
+    case cmDIV:      return oaLEFT;
+    case cmPOW:      return oaRIGHT;
+    case cmOPRT_BIN: return a_Tok.GetAssociativity();
+    default:         return oaNONE;
+    }  
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  const varmap_type& ParserBase::GetUsedVar() const
+  {
+    try
+    {
+      m_pTokenReader->IgnoreUndefVar(true);
+      CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it
+                   // may contain references to nonexisting variables.
+      m_pParseFormula = &ParserBase::ParseString;
+      m_pTokenReader->IgnoreUndefVar(false);
+    }
+    catch(exception_type & /*e*/)
+    {
+      // Make sure to stay in string parse mode, dont call ReInit()
+      // because it deletes the array with the used variables
+      m_pParseFormula = &ParserBase::ParseString;
+      m_pTokenReader->IgnoreUndefVar(false);
+      throw;
+    }
+    
+    return m_pTokenReader->GetUsedVar();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  const varmap_type& ParserBase::GetVar() const
+  {
+    return m_VarDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing all parser constants. */
+  const valmap_type& ParserBase::GetConst() const
+  {
+    return m_ConstDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return prototypes of all parser functions.
+      \return #m_FunDef
+      \sa FunProt
+      \throw nothrow
+      
+      The return type is a map of the public type #funmap_type containing the prototype
+      definitions for all numerical parser functions. String functions are not part of 
+      this map. The Prototype definition is encapsulated in objects of the class FunProt
+      one per parser function each associated with function names via a map construct.
+  */
+  const funmap_type& ParserBase::GetFunDef() const
+  {
+    return m_FunDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Retrieve the formula. */
+  const string_type& ParserBase::GetExpr() const
+  {
+    return m_pTokenReader->GetExpr();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Execute a function that takes a single string argument.
+      \param a_FunTok Function token.
+      \throw exception_type If the function token is not a string function
+  */
+  ParserBase::token_type ParserBase::ApplyStrFunc(const token_type &a_FunTok,
+                                                  const std::vector<token_type> &a_vArg) const
+  {
+    if (a_vArg.back().GetCode()!=cmSTRING)
+      Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());
+
+    token_type  valTok;
+    generic_fun_type pFunc = a_FunTok.GetFuncAddr();
+    assert(pFunc);
+
+    try
+    {
+      // Check function arguments; write dummy value into valtok to represent the result
+      switch(a_FunTok.GetArgCount())
+      {
+      case 0: valTok.SetVal(1); a_vArg[0].GetAsString();  break;
+      case 1: valTok.SetVal(1); a_vArg[1].GetAsString();  a_vArg[0].GetVal();  break;
+      case 2: valTok.SetVal(1); a_vArg[2].GetAsString();  a_vArg[1].GetVal();  a_vArg[0].GetVal();  break;
+      default: Error(ecINTERNAL_ERROR);
+      }
+    }
+    catch(ParserError& )
+    {
+      Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());
+    }
+
+    // string functions won't be optimized
+    m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx());
+    
+    // Push dummy value representing the function result to the stack
+    return valTok;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Apply a function token. 
+      \param iArgCount Number of Arguments actually gathered used only for multiarg functions.
+      \post The result is pushed to the value stack
+      \post The function token is removed from the stack
+      \throw exception_type if Argument count does not match function requirements.
+  */
+  void ParserBase::ApplyFunc( ParserStack<token_type> &a_stOpt,
+                              ParserStack<token_type> &a_stVal, 
+                              int a_iArgCount) const
+  { 
+    assert(m_pTokenReader.get());
+
+    // Operator stack empty or does not contain tokens with callback functions
+    if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 )
+      return;
+
+    token_type funTok = a_stOpt.pop();
+    assert(funTok.GetFuncAddr());
+
+    // Binary operators must rely on their internal operator number
+    // since counting of operators relies on commas for function arguments
+    // binary operators do not have commas in their expression
+    int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount;
+
+    // determine how many parameters the function needs. To remember iArgCount includes the 
+    // string parameter whilst GetArgCount() counts only numeric parameters.
+    int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0);
+
+    // Thats the number of numerical parameters
+    int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0);
+
+    if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1)
+      Error(ecINTERNAL_ERROR);
+
+    if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) 
+      Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
+
+    if (funTok.GetCode()!=cmOPRT_BIN && iArgCount<iArgRequired )
+      Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
+
+    if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired )
+      Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());
+
+    // Collect the numeric function arguments from the value stack and store them
+    // in a vector
+    std::vector<token_type> stArg;  
+    for (int i=0; i<iArgNumerical; ++i)
+    {
+      stArg.push_back( a_stVal.pop() );
+      if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
+        Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
+    }
+
+    switch(funTok.GetCode())
+    {
+    case  cmFUNC_STR:  
+          stArg.push_back(a_stVal.pop());
+          
+          if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
+            Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
+
+          ApplyStrFunc(funTok, stArg); 
+          break;
+
+    case  cmFUNC_BULK: 
+          m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); 
+          break;
+
+    case  cmOPRT_BIN:
+    case  cmOPRT_POSTFIX:
+    case  cmOPRT_INFIX:
+    case  cmFUNC:
+          if (funTok.GetArgCount()==-1 && iArgCount==0)
+            Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString());
+
+          m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical);
+          break;
+    }
+
+    // Push dummy value representing the function result to the stack
+    token_type token;
+    token.SetVal(1);  
+    a_stVal.push(token);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserBase::ApplyIfElse(ParserStack<token_type> &a_stOpt,
+                               ParserStack<token_type> &a_stVal) const
+  {
+    // Check if there is an if Else clause to be calculated
+    while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE)
+    {
+      token_type opElse = a_stOpt.pop();
+      MUP_ASSERT(a_stOpt.size()>0);
+
+      // Take the value associated with the else branch from the value stack
+      token_type vVal2 = a_stVal.pop();
+
+      MUP_ASSERT(a_stOpt.size()>0);
+      MUP_ASSERT(a_stVal.size()>=2);
+
+      // it then else is a ternary operator Pop all three values from the value s
+      // tack and just return the right value
+      token_type vVal1 = a_stVal.pop();
+      token_type vExpr = a_stVal.pop();
+
+      a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2);
+
+      token_type opIf = a_stOpt.pop();
+      MUP_ASSERT(opElse.GetCode()==cmELSE);
+      MUP_ASSERT(opIf.GetCode()==cmIF);
+
+      m_vRPN.AddIfElse(cmENDIF);
+    } // while pending if-else-clause found
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Performs the necessary steps to write code for
+             the execution of binary operators into the bytecode. 
+  */
+  void ParserBase::ApplyBinOprt(ParserStack<token_type> &a_stOpt,
+                                ParserStack<token_type> &a_stVal) const
+  {
+    // is it a user defined binary operator?
+    if (a_stOpt.top().GetCode()==cmOPRT_BIN)
+    {
+      ApplyFunc(a_stOpt, a_stVal, 2);
+    }
+    else
+    {
+      MUP_ASSERT(a_stVal.size()>=2);
+      token_type valTok1 = a_stVal.pop(),
+                 valTok2 = a_stVal.pop(),
+                 optTok  = a_stOpt.pop(),
+                 resTok; 
+
+      if ( valTok1.GetType()!=valTok2.GetType() || 
+          (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) )
+        Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString());
+
+      if (optTok.GetCode()==cmASSIGN)
+      {
+        if (valTok2.GetCode()!=cmVAR)
+          Error(ecUNEXPECTED_OPERATOR, -1, _T("="));
+                      
+        m_vRPN.AddAssignOp(valTok2.GetVar());
+      }
+      else
+        m_vRPN.AddOp(optTok.GetCode());
+
+      resTok.SetVal(1);
+      a_stVal.push(resTok);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Apply a binary operator. 
+      \param a_stOpt The operator stack
+      \param a_stVal The value stack
+  */
+  void ParserBase::ApplyRemainingOprt(ParserStack<token_type> &stOpt,
+                                      ParserStack<token_type> &stVal) const
+  {
+    while (stOpt.size() && 
+           stOpt.top().GetCode() != cmBO &&
+           stOpt.top().GetCode() != cmIF)
+    {
+      token_type tok = stOpt.top();
+      switch (tok.GetCode())
+      {
+      case cmOPRT_INFIX:
+      case cmOPRT_BIN:
+      case cmLE:
+      case cmGE:
+      case cmNEQ:
+      case cmEQ:
+      case cmLT:
+      case cmGT:
+      case cmADD:
+      case cmSUB:
+      case cmMUL:
+      case cmDIV:
+      case cmPOW:
+      case cmLAND:
+      case cmLOR:
+      case cmASSIGN:
+          if (stOpt.top().GetCode()==cmOPRT_INFIX)
+            ApplyFunc(stOpt, stVal, 1);
+          else
+            ApplyBinOprt(stOpt, stVal);
+          break;
+
+      case cmELSE:
+          ApplyIfElse(stOpt, stVal);
+          break;
+
+      default:
+          Error(ecINTERNAL_ERROR);
+      }
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Parse the command code.
+      \sa ParseString(...)
+
+      Command code contains precalculated stack positions of the values and the
+      associated operators. The Stack is filled beginning from index one the 
+      value at index zero is not used at all.
+  */
+  value_type ParserBase::ParseCmdCode() const
+  {
+    return ParseCmdCodeBulk(0, 0);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Evaluate the RPN. 
+      \param nOffset The offset added to variable addresses (for bulk mode)
+      \param nThreadID OpenMP Thread id of the calling thread
+  */
+  value_type ParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
+  {
+    assert(nThreadID<=s_MaxNumOpenMPThreads);
+
+    // Note: The check for nOffset==0 and nThreadID here is not necessary but 
+    //       brings a minor performance gain when not in bulk mode.
+    value_type *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)];
+    value_type buf;
+    int sidx(0);
+    for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok)
+    {
+      switch (pTok->Cmd)
+      {
+      // built in binary operators
+      case  cmLE:   --sidx; Stack[sidx]  = Stack[sidx] <= Stack[sidx+1]; continue;
+      case  cmGE:   --sidx; Stack[sidx]  = Stack[sidx] >= Stack[sidx+1]; continue;
+      case  cmNEQ:  --sidx; Stack[sidx]  = Stack[sidx] != Stack[sidx+1]; continue;
+      case  cmEQ:   --sidx; Stack[sidx]  = Stack[sidx] == Stack[sidx+1]; continue;
+      case  cmLT:   --sidx; Stack[sidx]  = Stack[sidx] < Stack[sidx+1];  continue;
+      case  cmGT:   --sidx; Stack[sidx]  = Stack[sidx] > Stack[sidx+1];  continue;
+      case  cmADD:  --sidx; Stack[sidx] += Stack[1+sidx]; continue;
+      case  cmSUB:  --sidx; Stack[sidx] -= Stack[1+sidx]; continue;
+      case  cmMUL:  --sidx; Stack[sidx] *= Stack[1+sidx]; continue;
+      case  cmDIV:  --sidx;
+
+  #if defined(MUP_MATH_EXCEPTIONS)
+                  if (Stack[1+sidx]==0)
+                    Error(ecDIV_BY_ZERO);
+  #endif
+                  Stack[sidx] /= Stack[1+sidx]; 
+                  continue;
+
+      case  cmPOW: 
+              --sidx; Stack[sidx] = MathImpl<value_type>::Pow(Stack[sidx], Stack[1+sidx]);
+              continue;
+
+      case  cmLAND: --sidx; Stack[sidx]  = Stack[sidx] && Stack[sidx+1]; continue;
+      case  cmLOR:  --sidx; Stack[sidx]  = Stack[sidx] || Stack[sidx+1]; continue;
+
+      case  cmASSIGN: 
+          // Bugfix for Bulkmode:
+          // for details see:
+          //    https://groups.google.com/forum/embed/?place=forum/muparser-dev&showsearch=true&showpopout=true&showtabs=false&parenturl=http://muparser.beltoforion.de/mup_forum.html&afterlogin&pli=1#!topic/muparser-dev/szgatgoHTws
+          --sidx; Stack[sidx] = *(pTok->Oprt.ptr + nOffset) = Stack[sidx + 1]; continue;
+          // original code:
+          //--sidx; Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; continue;
+
+      //case  cmBO:  // unused, listed for compiler optimization purposes
+      //case  cmBC:
+      //      MUP_FAIL(INVALID_CODE_IN_BYTECODE);
+      //      continue;
+
+      case  cmIF:
+            if (Stack[sidx--]==0)
+              pTok += pTok->Oprt.offset;
+            continue;
+
+      case  cmELSE:
+            pTok += pTok->Oprt.offset;
+            continue;
+
+      case  cmENDIF:
+            continue;
+
+      //case  cmARG_SEP:
+      //      MUP_FAIL(INVALID_CODE_IN_BYTECODE);
+      //      continue;
+
+      // value and variable tokens
+      case  cmVAR:    Stack[++sidx] = *(pTok->Val.ptr + nOffset);  continue;
+      case  cmVAL:    Stack[++sidx] =  pTok->Val.data2;  continue;
+      
+      case  cmVARPOW2: buf = *(pTok->Val.ptr + nOffset);
+                       Stack[++sidx] = buf*buf;
+                       continue;
+
+      case  cmVARPOW3: buf = *(pTok->Val.ptr + nOffset);
+                       Stack[++sidx] = buf*buf*buf;
+                       continue;
+
+      case  cmVARPOW4: buf = *(pTok->Val.ptr + nOffset);
+                       Stack[++sidx] = buf*buf*buf*buf;
+                       continue;
+      
+      case  cmVARMUL:  Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;
+                       continue;
+
+      // Next is treatment of numeric functions
+      case  cmFUNC:
+            {
+              int iArgCount = pTok->Fun.argc;
+
+              // switch according to argument count
+              switch(iArgCount)  
+              {
+              case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); continue;
+              case 1:            Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]);   continue;
+              case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue;
+              case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;
+              case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;
+              case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;
+              case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;
+              case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;
+              case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;
+              case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;
+              case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;
+              default:
+                if (iArgCount>0) // function with variable arguments store the number as a negative value
+                  Error(ecINTERNAL_ERROR, 1);
+
+                sidx -= -iArgCount - 1;
+                Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount);
+                continue;
+              }
+            }
+
+      // Next is treatment of string functions
+      case  cmFUNC_STR:
+            {
+              sidx -= pTok->Fun.argc -1;
+
+              // The index of the string argument in the string table
+              int iIdxStack = pTok->Fun.idx;  
+              MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() );
+
+              switch(pTok->Fun.argc)  // switch according to argument count
+              {
+              case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue;
+              case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue;
+              case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue;
+              }
+
+              continue;
+            }
+
+        case  cmFUNC_BULK:
+              {
+                int iArgCount = pTok->Fun.argc;
+
+                // switch according to argument count
+                switch(iArgCount)  
+                {
+                case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); continue;
+                case 1:            Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue;
+                case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue;
+                case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;
+                case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;
+                case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;
+                case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;
+                case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;
+                case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;
+                case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;
+                case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;
+                default:
+                  Error(ecINTERNAL_ERROR, 2);
+                  continue;
+                }
+              }
+
+        default:
+              Error(ecINTERNAL_ERROR, 3);
+              return 0;
+      } // switch CmdCode
+    } // for all bytecode tokens
+
+    return Stack[m_nFinalResultIdx];  
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserBase::CreateRPN() const
+  {
+    if (!m_pTokenReader->GetExpr().length())
+      Error(ecUNEXPECTED_EOF, 0);
+
+    ParserStack<token_type> stOpt, stVal;
+    ParserStack<int> stArgCount;
+    token_type opta, opt;  // for storing operators
+    token_type val, tval;  // for storing value
+
+    ReInit();
+    
+    // The outermost counter counts the number of separated items
+    // such as in "a=10,b=20,c=c+a"
+    stArgCount.push(1);
+    
+    for(;;)
+    {
+      opt = m_pTokenReader->ReadNextToken();
+
+      switch (opt.GetCode())
+      {
+        //
+        // Next three are different kind of value entries
+        //
+        case cmSTRING:
+                opt.SetIdx((int)m_vStringBuf.size());      // Assign buffer index to token 
+                stVal.push(opt);
+		            m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer
+                break;
+   
+        case cmVAR:
+                stVal.push(opt);
+                m_vRPN.AddVar( static_cast<value_type*>(opt.GetVar()) );
+                break;
+
+        case cmVAL:
+		        stVal.push(opt);
+                m_vRPN.AddVal( opt.GetVal() );
+                break;
+
+        case cmELSE:
+                m_nIfElseCounter--;
+                if (m_nIfElseCounter<0)
+                  Error(ecMISPLACED_COLON, m_pTokenReader->GetPos());
+
+                ApplyRemainingOprt(stOpt, stVal);
+                m_vRPN.AddIfElse(cmELSE);
+                stOpt.push(opt);
+                break;
+
+
+        case cmARG_SEP:
+                if (stArgCount.empty())
+                  Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos());
+
+                ++stArgCount.top();
+                // fallthrough intentional (no break!)
+
+        case cmEND:
+                ApplyRemainingOprt(stOpt, stVal);
+                break;
+
+       case cmBC:
+                {
+                  // The argument count for parameterless functions is zero
+                  // by default an opening bracket sets parameter count to 1
+                  // in preparation of arguments to come. If the last token
+                  // was an opening bracket we know better...
+                  if (opta.GetCode()==cmBO)
+                    --stArgCount.top();
+                  
+                  ApplyRemainingOprt(stOpt, stVal);
+
+                  // Check if the bracket content has been evaluated completely
+                  if (stOpt.size() && stOpt.top().GetCode()==cmBO)
+                  {
+                    // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check
+                    // if there is either a function or a sign pending
+                    // neither the opening nor the closing bracket will be pushed back to
+                    // the operator stack
+                    // Check if a function is standing in front of the opening bracket, 
+                    // if yes evaluate it afterwards check for infix operators
+                    assert(stArgCount.size());
+                    int iArgCount = stArgCount.pop();
+                    
+                    stOpt.pop(); // Take opening bracket from stack
+
+                    if (iArgCount>1 && ( stOpt.size()==0 || 
+                                        (stOpt.top().GetCode()!=cmFUNC && 
+                                         stOpt.top().GetCode()!=cmFUNC_BULK && 
+                                         stOpt.top().GetCode()!=cmFUNC_STR) ) )
+                      Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos());
+                    
+                    // The opening bracket was popped from the stack now check if there
+                    // was a function before this bracket
+                    if (stOpt.size() && 
+                        stOpt.top().GetCode()!=cmOPRT_INFIX && 
+                        stOpt.top().GetCode()!=cmOPRT_BIN && 
+                        stOpt.top().GetFuncAddr()!=0)
+                    {
+                      ApplyFunc(stOpt, stVal, iArgCount);
+                    }
+                  }
+                } // if bracket content is evaluated
+                break;
+
+        //
+        // Next are the binary operator entries
+        //
+        //case cmAND:   // built in binary operators
+        //case cmOR:
+        //case cmXOR:
+        case cmIF:
+                m_nIfElseCounter++;
+                // fallthrough intentional (no break!)
+
+        case cmLAND:
+        case cmLOR:
+        case cmLT:
+        case cmGT:
+        case cmLE:
+        case cmGE:
+        case cmNEQ:
+        case cmEQ:
+        case cmADD:
+        case cmSUB:
+        case cmMUL:
+        case cmDIV:
+        case cmPOW:
+        case cmASSIGN:
+        case cmOPRT_BIN:
+
+                // A binary operator (user defined or built in) has been found. 
+                while ( stOpt.size() && 
+                        stOpt.top().GetCode() != cmBO &&
+                        stOpt.top().GetCode() != cmELSE &&
+                        stOpt.top().GetCode() != cmIF)
+                {
+                  int nPrec1 = GetOprtPrecedence(stOpt.top()),
+                      nPrec2 = GetOprtPrecedence(opt);
+
+                  if (stOpt.top().GetCode()==opt.GetCode())
+                  {
+
+                    // Deal with operator associativity
+                    EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt);
+                    if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || 
+                         (eOprtAsct==oaLEFT  && (nPrec1 <  nPrec2)) )
+                    {
+                      break;
+                    }
+                  }
+                  else if (nPrec1 < nPrec2)
+                  {
+                    // In case the operators are not equal the precedence decides alone...
+                    break;
+                  }
+                  
+                  if (stOpt.top().GetCode()==cmOPRT_INFIX)
+                    ApplyFunc(stOpt, stVal, 1);
+                  else
+                    ApplyBinOprt(stOpt, stVal);
+                } // while ( ... )
+
+                if (opt.GetCode()==cmIF)
+                  m_vRPN.AddIfElse(opt.GetCode());
+
+    			      // The operator can't be evaluated right now, push back to the operator stack
+                stOpt.push(opt);
+                break;
+
+        //
+        // Last section contains functions and operators implicitly mapped to functions
+        //
+        case cmBO:
+                stArgCount.push(1);
+                stOpt.push(opt);
+                break;
+
+        case cmOPRT_INFIX:
+        case cmFUNC:
+        case cmFUNC_BULK:
+        case cmFUNC_STR:  
+                stOpt.push(opt);
+                break;
+
+        case cmOPRT_POSTFIX:
+                stOpt.push(opt);
+                ApplyFunc(stOpt, stVal, 1);  // this is the postfix operator
+                break;
+
+        default:  Error(ecINTERNAL_ERROR, 3);
+      } // end of switch operator-token
+
+      opta = opt;
+
+      if ( opt.GetCode() == cmEND )
+      {
+        m_vRPN.Finalize();
+        break;
+      }
+
+      if (ParserBase::g_DbgDumpStack)
+      {
+        StackDump(stVal, stOpt);
+        m_vRPN.AsciiDump();
+      }
+    } // while (true)
+
+    if (ParserBase::g_DbgDumpCmdCode)
+      m_vRPN.AsciiDump();
+
+    if (m_nIfElseCounter>0)
+      Error(ecMISSING_ELSE_CLAUSE);
+
+    // get the last value (= final result) from the stack
+    MUP_ASSERT(stArgCount.size()==1);
+    m_nFinalResultIdx = stArgCount.top();
+    if (m_nFinalResultIdx==0)
+      Error(ecINTERNAL_ERROR, 9);
+
+    if (stVal.size()==0)
+      Error(ecEMPTY_EXPRESSION);
+
+    if (stVal.top().GetType()!=tpDBL)
+      Error(ecSTR_RESULT);
+
+    m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief One of the two main parse functions.
+      \sa ParseCmdCode(...)
+
+    Parse expression from input string. Perform syntax checking and create 
+    bytecode. After parsing the string and creating the bytecode the function 
+    pointer #m_pParseFormula will be changed to the second parse routine the 
+    uses bytecode instead of string parsing.
+  */
+  value_type ParserBase::ParseString() const
+  {
+    try
+    {
+      CreateRPN();
+      m_pParseFormula = &ParserBase::ParseCmdCode;
+      return (this->*m_pParseFormula)(); 
+    }
+    catch(ParserError &exc)
+    {
+      exc.SetFormula(m_pTokenReader->GetExpr());
+      throw;
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Create an error containing the parse error position.
+
+    This function will create an Parser Exception object containing the error text and
+    its position.
+
+    \param a_iErrc [in] The error code of type #EErrorCodes.
+    \param a_iPos [in] The position where the error was detected.
+    \param a_strTok [in] The token string representation associated with the error.
+    \throw ParserException always throws thats the only purpose of this function.
+  */
+  void  ParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const
+  {
+    throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined variables.
+      \throw nothrow
+
+      Resets the parser to string parsing mode by calling #ReInit.
+  */
+  void ParserBase::ClearVar()
+  {
+    m_VarDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Remove a variable from internal storage.
+      \throw nothrow
+
+      Removes a variable if it exists. If the Variable does not exist nothing will be done.
+  */
+  void ParserBase::RemoveVar(const string_type &a_strVarName)
+  {
+    varmap_type::iterator item = m_VarDef.find(a_strVarName);
+    if (item!=m_VarDef.end())
+    {
+      m_VarDef.erase(item);
+      ReInit();
+    }
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all functions.
+      \post Resets the parser to string parsing mode.
+      \throw nothrow
+  */
+  void ParserBase::ClearFun()
+  {
+    m_FunDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined constants.
+
+      Both numeric and string constants will be removed from the internal storage.
+      \post Resets the parser to string parsing mode.
+      \throw nothrow
+  */
+  void ParserBase::ClearConst()
+  {
+    m_ConstDef.clear();
+    m_StrVarDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined postfix operators.
+      \post Resets the parser to string parsing mode.
+      \throw nothrow
+  */
+  void ParserBase::ClearPostfixOprt()
+  {
+    m_PostOprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear all user defined binary operators.
+      \post Resets the parser to string parsing mode.
+      \throw nothrow
+  */
+  void ParserBase::ClearOprt()
+  {
+    m_OprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Clear the user defined Prefix operators. 
+      \post Resets the parser to string parser mode.
+      \throw nothrow
+  */
+  void ParserBase::ClearInfixOprt()
+  {
+    m_InfixOprtDef.clear();
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Enable or disable the formula optimization feature. 
+      \post Resets the parser to string parser mode.
+      \throw nothrow
+  */
+  void ParserBase::EnableOptimizer(bool a_bIsOn)
+  {
+    m_vRPN.EnableOptimizer(a_bIsOn);
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Enable the dumping of bytecode and stack content on the console. 
+      \param bDumpCmd Flag to enable dumping of the current bytecode to the console.
+      \param bDumpStack Flag to enable dumping of the stack content is written to the console.
+
+     This function is for debug purposes only!
+  */
+  void ParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack)
+  {
+    ParserBase::g_DbgDumpCmdCode = bDumpCmd;
+    ParserBase::g_DbgDumpStack   = bDumpStack;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Enable or disable the built in binary operators.
+      \throw nothrow
+      \sa m_bBuiltInOp, ReInit()
+
+    If you disable the built in binary operators there will be no binary operators
+    defined. Thus you must add them manually one by one. It is not possible to
+    disable built in operators selectively. This function will Reinitialize the
+    parser by calling ReInit().
+  */
+  void ParserBase::EnableBuiltInOprt(bool a_bIsOn)
+  {
+    m_bBuiltInOp = a_bIsOn;
+    ReInit();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Query status of built in variables.
+      \return #m_bBuiltInOp; true if built in operators are enabled.
+      \throw nothrow
+  */
+  bool ParserBase::HasBuiltInOprt() const
+  {
+    return m_bBuiltInOp;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Get the argument separator character. 
+  */
+  char_type ParserBase::GetArgSep() const
+  {
+    return m_pTokenReader->GetArgSep();
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Set argument separator. 
+      \param cArgSep the argument separator character.
+  */
+  void ParserBase::SetArgSep(char_type cArgSep)
+  {
+    m_pTokenReader->SetArgSep(cArgSep);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Dump stack content. 
+
+      This function is used for debugging only.
+  */
+  void ParserBase::StackDump(const ParserStack<token_type> &a_stVal, 
+                             const ParserStack<token_type> &a_stOprt) const
+  {
+    ParserStack<token_type> stOprt(a_stOprt), 
+                            stVal(a_stVal);
+
+    mu::console() << _T("\nValue stack:\n");
+    while ( !stVal.empty() ) 
+    {
+      token_type val = stVal.pop();
+      if (val.GetType()==tpSTR)
+        mu::console() << _T(" \"") << val.GetAsString() << _T("\" ");
+      else
+        mu::console() << _T(" ") << val.GetVal() << _T(" ");
+    }
+    mu::console() << "\nOperator stack:\n";
+
+    while ( !stOprt.empty() )
+    {
+      if (stOprt.top().GetCode()<=cmASSIGN) 
+      {
+        mu::console() << _T("OPRT_INTRNL \"")
+                      << ParserBase::c_DefaultOprt[stOprt.top().GetCode()] 
+                      << _T("\" \n");
+      }
+      else
+      {
+        switch(stOprt.top().GetCode())
+        {
+        case cmVAR:   mu::console() << _T("VAR\n");  break;
+        case cmVAL:   mu::console() << _T("VAL\n");  break;
+        case cmFUNC:  mu::console() << _T("FUNC \"") 
+                                    << stOprt.top().GetAsString() 
+                                    << _T("\"\n");   break;
+        case cmFUNC_BULK:  mu::console() << _T("FUNC_BULK \"") 
+                                         << stOprt.top().GetAsString() 
+                                         << _T("\"\n");   break;
+        case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"")
+                                         << stOprt.top().GetAsString() 
+                                         << _T("\"\n");      break;
+        case cmOPRT_BIN:   mu::console() << _T("OPRT_BIN \"") 
+                                         << stOprt.top().GetAsString() 
+                                         << _T("\"\n");           break;
+        case cmFUNC_STR: mu::console() << _T("FUNC_STR\n");       break;
+        case cmEND:      mu::console() << _T("END\n");            break;
+        case cmUNKNOWN:  mu::console() << _T("UNKNOWN\n");        break;
+        case cmBO:       mu::console() << _T("BRACKET \"(\"\n");  break;
+        case cmBC:       mu::console() << _T("BRACKET \")\"\n");  break;
+        case cmIF:       mu::console() << _T("IF\n");  break;
+        case cmELSE:     mu::console() << _T("ELSE\n");  break;
+        case cmENDIF:    mu::console() << _T("ENDIF\n");  break;
+        default:         mu::console() << stOprt.top().GetCode() << _T(" ");  break;
+        }
+      }	
+      stOprt.pop();
+    }
+
+    mu::console() << dec << endl;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Evaluate an expression containing comma separated subexpressions 
+      \param [out] nStackSize The total number of results available
+      \return Pointer to the array containing all expression results
+
+      This member function can be used to retrieve all results of an expression
+      made up of multiple comma separated subexpressions (i.e. "x+y,sin(x),cos(y)")
+  */
+  value_type* ParserBase::Eval(int &nStackSize) const
+  {
+    (this->*m_pParseFormula)(); 
+    nStackSize = m_nFinalResultIdx;
+
+    // (for historic reasons the stack starts at position 1)
+    return &m_vStackBuffer[1];
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the number of results on the calculation stack. 
+  
+    If the expression contains comma separated subexpressions (i.e. "sin(y), x+y"). 
+    There may be more than one return value. This function returns the number of 
+    available results.
+  */
+  int ParserBase::GetNumResults() const
+  {
+    return m_nFinalResultIdx;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Calculate the result.
+
+    A note on const correctness: 
+    I consider it important that Calc is a const function.
+    Due to caching operations Calc changes only the state of internal variables with one exception
+    m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making
+    Calc non const GetUsedVar is non const because it explicitly calls Eval() forcing this update. 
+
+    \pre A formula must be set.
+    \pre Variables must have been set (if needed)
+
+    \sa #m_pParseFormula
+    \return The evaluation result
+    \throw ParseException if no Formula is set or in case of any other error related to the formula.
+  */
+  value_type ParserBase::Eval() const
+  {
+    return (this->*m_pParseFormula)(); 
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserBase::Eval(value_type *results, int nBulkSize)
+  {
+/* <ibg 2014-09-24/> Commented because it is making a unit test impossible
+
+    // Parallelization does not make sense for fewer than 10000 computations 
+    // due to thread creation overhead. If the bulk size is below 2000
+    // computation is refused. 
+    if (nBulkSize<2000)
+    {
+      throw ParserError(ecUNREASONABLE_NUMBER_OF_COMPUTATIONS);
+    }
+*/
+    CreateRPN();
+
+    int i = 0;
+
+#ifdef MUP_USE_OPENMP
+//#define DEBUG_OMP_STUFF
+    #ifdef DEBUG_OMP_STUFF
+    int *pThread = new int[nBulkSize];
+    int *pIdx = new int[nBulkSize];
+    #endif
+
+    int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads);
+	int nThreadID = 0, ct = 0;
+    omp_set_num_threads(nMaxThreads);
+
+    #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID)
+    for (i=0; i<nBulkSize; ++i)
+    {
+      nThreadID = omp_get_thread_num();
+      results[i] = ParseCmdCodeBulk(i, nThreadID);
+
+      #ifdef DEBUG_OMP_STUFF
+      #pragma omp critical
+      {
+        pThread[ct] = nThreadID;  
+        pIdx[ct] = i; 
+        ct++;
+      }
+      #endif
+    }
+
+#ifdef DEBUG_OMP_STUFF
+    FILE *pFile = fopen("bulk_dbg.txt", "w");
+    for (i=0; i<nBulkSize; ++i)
+    {
+      fprintf(pFile, "idx: %d  thread: %d \n", pIdx[i], pThread[i]);
+    }
+    
+    delete [] pIdx;
+    delete [] pThread;
+
+    fclose(pFile);
+#endif
+
+#else
+    for (i=0; i<nBulkSize; ++i)
+    {
+      results[i] = ParseCmdCodeBulk(i, 0);
+    }
+#endif
+
+  }
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserBytecode.cpp b/ThirdParty/MuParser/src/muParserBytecode.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38ae3f933422c779b66807493c8fdd61b2399e95
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserBytecode.cpp
@@ -0,0 +1,588 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  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. 
+*/
+
+#include "muParserBytecode.h"
+
+#include <algorithm>
+#include <cassert>
+#include <string>
+#include <stack>
+#include <vector>
+#include <iostream>
+
+#include "muParserDef.h"
+#include "muParserError.h"
+#include "muParserToken.h"
+#include "muParserStack.h"
+#include "muParserTemplateMagic.h"
+
+
+namespace mu
+{
+  //---------------------------------------------------------------------------
+  /** \brief Bytecode default constructor. */
+  ParserByteCode::ParserByteCode()
+    :m_iStackPos(0)
+    ,m_iMaxStackSize(0)
+    ,m_vRPN()
+    ,m_bEnableOptimizer(true)
+  {
+    m_vRPN.reserve(50);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+    
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
+  */
+  ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode)
+  {
+    Assign(a_ByteCode);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignment operator.
+    
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
+  */
+  ParserByteCode& ParserByteCode::operator=(const ParserByteCode &a_ByteCode)
+  {
+    Assign(a_ByteCode);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::EnableOptimizer(bool bStat)
+  {
+    m_bEnableOptimizer = bStat;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy state of another object to this. 
+    
+      \throw nowthrow
+  */
+  void ParserByteCode::Assign(const ParserByteCode &a_ByteCode)
+  {
+    if (this==&a_ByteCode)    
+      return;
+
+    m_iStackPos = a_ByteCode.m_iStackPos;
+    m_vRPN = a_ByteCode.m_vRPN;
+    m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;
+	m_bEnableOptimizer = a_ByteCode.m_bEnableOptimizer;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a Variable pointer to bytecode. 
+      \param a_pVar Pointer to be added.
+      \throw nothrow
+  */
+  void ParserByteCode::AddVar(value_type *a_pVar)
+  {
+    ++m_iStackPos;
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    // optimization does not apply
+    SToken tok;
+    tok.Cmd       = cmVAR;
+    tok.Val.ptr   = a_pVar;
+    tok.Val.data  = 1;
+    tok.Val.data2 = 0;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a Variable pointer to bytecode. 
+
+      Value entries in byte code consist of:
+      <ul>
+        <li>value array position of the value</li>
+        <li>the operator code according to ParserToken::cmVAL</li>
+        <li>the value stored in #mc_iSizeVal number of bytecode entries.</li>
+      </ul>
+
+      \param a_pVal Value to be added.
+      \throw nothrow
+  */
+  void ParserByteCode::AddVal(value_type a_fVal)
+  {
+    ++m_iStackPos;
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    // If optimization does not apply
+    SToken tok;
+    tok.Cmd = cmVAL;
+    tok.Val.ptr   = NULL;
+    tok.Val.data  = 0;
+    tok.Val.data2 = a_fVal;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::ConstantFolding(ECmdCode a_Oprt)
+  {
+    std::size_t sz = m_vRPN.size();
+    value_type &x = m_vRPN[sz-2].Val.data2,
+               &y = m_vRPN[sz-1].Val.data2;
+    switch (a_Oprt)
+    {
+    case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break;
+    case cmLOR:  x = (int)x || (int)y; m_vRPN.pop_back(); break;
+    case cmLT:   x = x < y;  m_vRPN.pop_back();  break;
+    case cmGT:   x = x > y;  m_vRPN.pop_back();  break;
+    case cmLE:   x = x <= y; m_vRPN.pop_back();  break;
+    case cmGE:   x = x >= y; m_vRPN.pop_back();  break;
+    case cmNEQ:  x = x != y; m_vRPN.pop_back();  break;
+    case cmEQ:   x = x == y; m_vRPN.pop_back();  break;
+    case cmADD:  x = x + y;  m_vRPN.pop_back();  break;
+    case cmSUB:  x = x - y;  m_vRPN.pop_back();  break;
+    case cmMUL:  x = x * y;  m_vRPN.pop_back();  break;
+    case cmDIV: 
+
+#if defined(MUP_MATH_EXCEPTIONS)
+        if (y==0)
+          throw ParserError(ecDIV_BY_ZERO, _T("0"));
+#endif
+
+        x = x / y;   
+        m_vRPN.pop_back();
+        break;
+
+    case cmPOW: x = MathImpl<value_type>::Pow(x, y); 
+                m_vRPN.pop_back();
+                break;
+
+    default:
+        break;
+    } // switch opcode
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add an operator identifier to bytecode. 
+    
+      Operator entries in byte code consist of:
+      <ul>
+        <li>value array position of the result</li>
+        <li>the operator code according to ParserToken::ECmdCode</li>
+      </ul>
+
+      \sa  ParserToken::ECmdCode
+  */
+  void ParserByteCode::AddOp(ECmdCode a_Oprt)
+  {
+    bool bOptimized = false;
+
+    if (m_bEnableOptimizer)
+    {
+      std::size_t sz = m_vRPN.size();
+
+      // Check for foldable constants like:
+      //   cmVAL cmVAL cmADD 
+      // where cmADD can stand fopr any binary operator applied to
+      // two constant values.
+      if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL)
+      {
+        ConstantFolding(a_Oprt);
+        bOptimized = true;
+      }
+      else
+      {
+        switch(a_Oprt)
+        {
+        case  cmPOW:
+              // Optimization for polynomials of low order
+              if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)
+              {
+                if (m_vRPN[sz-1].Val.data2==2)
+                  m_vRPN[sz-2].Cmd = cmVARPOW2;
+                else if (m_vRPN[sz-1].Val.data2==3)
+                  m_vRPN[sz-2].Cmd = cmVARPOW3;
+                else if (m_vRPN[sz-1].Val.data2==4)
+                  m_vRPN[sz-2].Cmd = cmVARPOW4;
+                else
+                  break;
+
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+
+        case  cmSUB:
+        case  cmADD:
+              // Simple optimization based on pattern recognition for a shitload of different
+              // bytecode combinations of addition/subtraction
+              if ( (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAL)    ||
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVAR)    || 
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL)    ||
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )
+              {
+                assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) ||
+                        (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || 
+                        (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );
+
+                m_vRPN[sz-2].Cmd = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));    // variable
+                m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2;  // offset
+                m_vRPN[sz-2].Val.data  += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data;   // multiplicand
+                m_vRPN.pop_back();
+                bOptimized = true;
+              } 
+              break;
+
+        case  cmMUL:
+              if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) ||
+                   (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) 
+              {
+                m_vRPN[sz-2].Cmd        = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
+                m_vRPN[sz-2].Val.data   = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;
+                m_vRPN[sz-2].Val.data2  = 0;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              } 
+              else if ( (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||
+                        (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) )
+              {
+                // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
+                m_vRPN[sz-2].Cmd     = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
+                if (m_vRPN[sz-1].Cmd == cmVAL)
+                {
+                  m_vRPN[sz-2].Val.data  *= m_vRPN[sz-1].Val.data2;
+                  m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2;
+                }
+                else
+                {
+                  m_vRPN[sz-2].Val.data  = m_vRPN[sz-1].Val.data  * m_vRPN[sz-2].Val.data2;
+                  m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2;
+                }
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR &&
+                       m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr)
+              {
+                // Optimization: a*a -> a^2
+                m_vRPN[sz-2].Cmd = cmVARPOW2;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+
+        case cmDIV:
+              if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)
+              {
+                // Optimization: 4*a/2 -> 2*a
+                m_vRPN[sz-2].Val.data  /= m_vRPN[sz-1].Val.data2;
+                m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+              
+        } // switch a_Oprt
+      }
+    }
+
+    // If optimization can't be applied just write the value
+    if (!bOptimized)
+    {
+      --m_iStackPos;
+      SToken tok;
+      tok.Cmd = a_Oprt;
+      m_vRPN.push_back(tok);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::AddIfElse(ECmdCode a_Oprt)
+  {
+    SToken tok;
+    tok.Cmd = a_Oprt;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add an assignment operator
+    
+      Operator entries in byte code consist of:
+      <ul>
+        <li>cmASSIGN code</li>
+        <li>the pointer of the destination variable</li>
+      </ul>
+
+      \sa  ParserToken::ECmdCode
+  */
+  void ParserByteCode::AddAssignOp(value_type *a_pVar)
+  {
+    --m_iStackPos;
+
+    SToken tok;
+    tok.Cmd = cmASSIGN;
+    tok.Oprt.ptr = a_pVar;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add function to bytecode. 
+
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
+      \param a_pFun Pointer to function callback.
+  */
+  void ParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)
+  {
+    if (a_iArgc>=0)
+    {
+      m_iStackPos = m_iStackPos - a_iArgc + 1; 
+    }
+    else
+    {
+      // function with unlimited number of arguments
+      m_iStackPos = m_iStackPos + a_iArgc + 1; 
+    }
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    SToken tok;
+    tok.Cmd = cmFUNC;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a bulk function to bytecode. 
+
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
+      \param a_pFun Pointer to function callback.
+  */
+  void ParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
+  {
+    m_iStackPos = m_iStackPos - a_iArgc + 1; 
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    SToken tok;
+    tok.Cmd = cmFUNC_BULK;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add Strung function entry to the parser bytecode. 
+      \throw nothrow
+
+      A string function entry consists of the stack position of the return value,
+      followed by a cmSTRFUNC code, the function pointer and an index into the 
+      string buffer maintained by the parser.
+  */
+  void ParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
+  {
+    m_iStackPos = m_iStackPos - a_iArgc + 1;
+
+    SToken tok;
+    tok.Cmd = cmFUNC_STR;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.idx = a_iIdx;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add end marker to bytecode.
+      
+      \throw nothrow 
+  */
+  void ParserByteCode::Finalize()
+  {
+    SToken tok;
+    tok.Cmd = cmEND;
+    m_vRPN.push_back(tok);
+    rpn_type(m_vRPN).swap(m_vRPN);     // shrink bytecode vector to fit
+
+    // Determine the if-then-else jump offsets
+    ParserStack<int> stIf, stElse;
+    int idx;
+    for (int i=0; i<(int)m_vRPN.size(); ++i)
+    {
+      switch(m_vRPN[i].Cmd)
+      {
+      case cmIF:
+            stIf.push(i);
+            break;
+
+      case  cmELSE:
+            stElse.push(i);
+            idx = stIf.pop();
+            m_vRPN[idx].Oprt.offset = i - idx;
+            break;
+      
+      case cmENDIF:
+            idx = stElse.pop();
+            m_vRPN[idx].Oprt.offset = i - idx;
+            break;
+
+      default:
+            break;
+      }
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  const SToken* ParserByteCode::GetBase() const
+  {
+    if (m_vRPN.size()==0)
+      throw ParserError(ecINTERNAL_ERROR);
+    else
+      return &m_vRPN[0];
+  }
+
+  //---------------------------------------------------------------------------
+  std::size_t ParserByteCode::GetMaxStackSize() const
+  {
+    return m_iMaxStackSize+1;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns the number of entries in the bytecode. */
+  std::size_t ParserByteCode::GetSize() const
+  {
+    return m_vRPN.size();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Delete the bytecode. 
+  
+      \throw nothrow
+
+      The name of this function is a violation of my own coding guidelines
+      but this way it's more in line with the STL functions thus more 
+      intuitive.
+  */
+  void ParserByteCode::clear()
+  {
+    m_vRPN.clear();
+    m_iStackPos = 0;
+    m_iMaxStackSize = 0;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Dump bytecode (for debugging only!). */
+  void ParserByteCode::AsciiDump()
+  {
+    if (!m_vRPN.size()) 
+    {
+      mu::console() << _T("No bytecode available\n");
+      return;
+    }
+
+    mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n");
+    for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
+    {
+      mu::console() << std::dec << i << _T(" : \t");
+      switch (m_vRPN[i].Cmd)
+      {
+      case cmVAL:   mu::console() << _T("VAL \t");
+                    mu::console() << _T("[") << m_vRPN[i].Val.data2 << _T("]\n");
+                    break;
+
+      case cmVAR:   mu::console() << _T("VAR \t");
+	                  mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                    break;
+
+      case cmVARPOW2: mu::console() << _T("VARPOW2 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARPOW3: mu::console() << _T("VARPOW3 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARPOW4: mu::console() << _T("VARPOW4 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARMUL:  mu::console() << _T("VARMUL \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]"); 
+                      mu::console() << _T(" * [") << m_vRPN[i].Val.data << _T("]");
+                      mu::console() << _T(" + [") << m_vRPN[i].Val.data2 << _T("]\n");
+                      break;
+
+      case cmFUNC:  mu::console() << _T("CALL\t");
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); 
+                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Fun.ptr << _T("]"); 
+                    mu::console() << _T("\n");
+                    break;
+
+      case cmFUNC_STR:
+                    mu::console() << _T("CALL STRFUNC\t");
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]");
+                    mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].Fun.idx << _T("]");
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Fun.ptr << _T("]\n"); 
+                    break;
+
+      case cmLT:    mu::console() << _T("LT\n");  break;
+      case cmGT:    mu::console() << _T("GT\n");  break;
+      case cmLE:    mu::console() << _T("LE\n");  break;
+      case cmGE:    mu::console() << _T("GE\n");  break;
+      case cmEQ:    mu::console() << _T("EQ\n");  break;
+      case cmNEQ:   mu::console() << _T("NEQ\n"); break;
+      case cmADD:   mu::console() << _T("ADD\n"); break;
+      case cmLAND:  mu::console() << _T("&&\n"); break;
+      case cmLOR:   mu::console() << _T("||\n"); break;
+      case cmSUB:   mu::console() << _T("SUB\n"); break;
+      case cmMUL:   mu::console() << _T("MUL\n"); break;
+      case cmDIV:   mu::console() << _T("DIV\n"); break;
+      case cmPOW:   mu::console() << _T("POW\n"); break;
+
+      case cmIF:    mu::console() << _T("IF\t");
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");
+                    break;
+
+      case cmELSE:  mu::console() << _T("ELSE\t");
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");
+                    break;
+
+      case cmENDIF: mu::console() << _T("ENDIF\n"); break;
+
+      case cmASSIGN: 
+                    mu::console() << _T("ASSIGN\t");
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Oprt.ptr << _T("]\n"); 
+                    break; 
+
+      default:      mu::console() << _T("(unknown code: ") << m_vRPN[i].Cmd << _T(")\n"); 
+                    break;
+      } // switch cmdCode
+    } // while bytecode
+
+    mu::console() << _T("END") << std::endl;
+  }
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserCallback.cpp b/ThirdParty/MuParser/src/muParserCallback.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b6aec1ae037823ae519cbe10469162b0b86d0cd9
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserCallback.cpp
@@ -0,0 +1,463 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2004-2011 Ingo Berg
+
+  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. 
+*/
+
+#include "muParserCallback.h"
+
+/** \file
+    \brief Implementation of the parser callback class.
+*/
+
+
+namespace mu
+{
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(0)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(1)
+    ,m_iPri(a_iPrec)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(a_iCode)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor for constructing function callbacks taking two arguments. 
+      \throw nothrow
+  */
+  ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(2)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor for constructing binary operator callbacks. 
+      \param a_pFun Pointer to a static function taking two arguments
+      \param a_bAllowOpti A flag indicating this function can be optimized
+      \param a_iPrec The operator precedence
+      \param a_eOprtAsct The operators associativity
+      \throw nothrow
+  */
+  ParserCallback::ParserCallback(fun_type2 a_pFun, 
+                                 bool a_bAllowOpti, 
+                                 int a_iPrec, 
+                                 EOprtAssociativity a_eOprtAsct)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(2)
+    ,m_iPri(a_iPrec)
+    ,m_eOprtAsct(a_eOprtAsct)
+    ,m_iCode(cmOPRT_BIN)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(3)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(4)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(5)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(6)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(7)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(8)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(9)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(10)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(0)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(1)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor for constructing function callbacks taking two arguments. 
+      \throw nothrow
+  */
+  ParserCallback::ParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(2)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(3)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(4)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(5)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(6)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(7)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(8)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(9)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(10)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_BULK)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(-1)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC)
+    ,m_iType(tpDBL)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(0)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_STR)
+    ,m_iType(tpSTR)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(1)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_STR)
+    ,m_iType(tpSTR)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
+    :m_pFun((void*)a_pFun)
+    ,m_iArgc(2)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmFUNC_STR)
+    ,m_iType(tpSTR)
+    ,m_bAllowOpti(a_bAllowOpti)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Default constructor. 
+      \throw nothrow
+  */
+  ParserCallback::ParserCallback()
+    :m_pFun(0)
+    ,m_iArgc(0)
+    ,m_iPri(-1)
+    ,m_eOprtAsct(oaNONE)
+    ,m_iCode(cmUNKNOWN)
+    ,m_iType(tpVOID)
+    ,m_bAllowOpti(0)
+  {}
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+      \throw nothrow
+  */
+  ParserCallback::ParserCallback(const ParserCallback &ref)
+  {
+    m_pFun       = ref.m_pFun;
+    m_iArgc      = ref.m_iArgc;
+    m_bAllowOpti = ref.m_bAllowOpti;
+    m_iCode      = ref.m_iCode;
+    m_iType      = ref.m_iType;
+    m_iPri       = ref.m_iPri;
+    m_eOprtAsct  = ref.m_eOprtAsct;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Clone this instance and return a pointer to the new instance. */
+  ParserCallback* ParserCallback::Clone() const
+  {
+    return new ParserCallback(*this);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return tru if the function is conservative.
+
+      Conservative functions return always the same result for the same argument.
+      \throw nothrow
+  */
+  bool ParserCallback::IsOptimizable() const  
+  { 
+    return m_bAllowOpti; 
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Get the callback address for the parser function. 
+  
+      The type of the address is void. It needs to be recasted according to the
+      argument number to the right type.
+
+      \throw nothrow
+      \return #pFun
+  */
+  void* ParserCallback::GetAddr() const 
+  { 
+    return m_pFun;  
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the callback code. */
+  ECmdCode  ParserCallback::GetCode() const 
+  { 
+    return m_iCode; 
+  }
+  
+  //---------------------------------------------------------------------------
+  ETypeCode ParserCallback::GetType() const 
+  { 
+    return m_iType; 
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the operator precedence. 
+      \throw nothrown
+
+     Only valid if the callback token is an operator token (binary or infix).
+  */
+  int ParserCallback::GetPri()  const 
+  { 
+    return m_iPri;  
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the operators associativity. 
+      \throw nothrown
+
+     Only valid if the callback token is a binary operator token.
+  */
+  EOprtAssociativity ParserCallback::GetAssociativity() const
+  {
+    return m_eOprtAsct;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns the number of function Arguments. */
+  int ParserCallback::GetArgc() const 
+  { 
+    return m_iArgc; 
+  }
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserDLL.cpp b/ThirdParty/MuParser/src/muParserDLL.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a05476655614bdf5ac9388a8dd237b49e9ac3694
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserDLL.cpp
@@ -0,0 +1,1096 @@
+/*
+                 __________
+                 _____   __ __\______   \_____  _______  ______  ____ _______
+                 /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+                 |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+                 |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|
+                 \/                       \/            \/      \/
+                 Copyright (C) 2004-2011 Ingo Berg
+
+                 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.
+                 */
+#if defined(MUPARSER_DLL) 
+
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "muParserDLL.h"
+#include "muParser.h"
+#include "muParserInt.h"
+#include "muParserError.h"
+
+
+#define MU_TRY  \
+    try     \
+        {
+
+#define MU_CATCH                                                 \
+        }                                                        \
+        catch (muError_t &e)                                      \
+        {                                                        \
+        ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \
+        pTag->exc = e;                                         \
+        pTag->bError = true;                                   \
+if (pTag->errHandler)                                  \
+    (pTag->errHandler)(a_hParser);                       \
+        }                                                        \
+        catch (...)                                               \
+        {                                                        \
+        ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \
+        pTag->exc = muError_t(mu::ecINTERNAL_ERROR);           \
+        pTag->bError = true;                                   \
+if (pTag->errHandler)                                  \
+    (pTag->errHandler)(a_hParser);                       \
+        }
+
+/** \file
+    \brief This file contains the implementation of the DLL interface of muparser.
+    */
+
+//---------------------------------------------------------------------------
+// private types
+typedef mu::ParserBase::exception_type muError_t;
+typedef mu::ParserBase muParser_t;
+
+int g_nBulkSize;
+
+//---------------------------------------------------------------------------
+class ParserTag
+{
+public:
+    ParserTag(int nType)
+        :pParser((nType == muBASETYPE_FLOAT) ? (mu::ParserBase*)new mu::Parser() :
+        (nType == muBASETYPE_INT) ? (mu::ParserBase*)new mu::ParserInt() : NULL)
+        , exc()
+        , errHandler(NULL)
+        , bError(false)
+        , m_nParserType(nType)
+    {}
+
+    ~ParserTag()
+    {
+        delete pParser;
+    }
+
+    mu::ParserBase *pParser;
+    mu::ParserBase::exception_type exc;
+    muErrorHandler_t errHandler;
+    bool bError;
+
+private:
+    ParserTag(const ParserTag &ref);
+    ParserTag& operator=(const ParserTag &ref);
+
+    int m_nParserType;
+};
+
+static muChar_t s_tmpOutBuf[2048];
+
+//---------------------------------------------------------------------------
+//
+//
+//  unexported functions
+//
+//
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+muParser_t* AsParser(muParserHandle_t a_hParser)
+{
+    return static_cast<ParserTag*>(a_hParser)->pParser;
+}
+
+//---------------------------------------------------------------------------
+ParserTag* AsParserTag(muParserHandle_t a_hParser)
+{
+    return static_cast<ParserTag*>(a_hParser);
+}
+
+//---------------------------------------------------------------------------
+#if defined(_WIN32)
+#define _CRT_SECURE_NO_DEPRECATE
+
+BOOL APIENTRY DllMain(HANDLE /*hModule*/,
+    DWORD ul_reason_for_call,
+    LPVOID /*lpReserved*/)
+{
+    switch (ul_reason_for_call)
+    {
+    case  DLL_PROCESS_ATTACH:
+        break;
+
+    case  DLL_THREAD_ATTACH:
+    case  DLL_THREAD_DETACH:
+    case  DLL_PROCESS_DETACH:
+        break;
+    }
+
+    return TRUE;
+}
+
+#endif
+
+//---------------------------------------------------------------------------
+//
+//
+//  exported functions
+//
+//
+//---------------------------------------------------------------------------
+
+API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void *pUserData)
+{
+    MU_TRY
+        muParser_t* p(AsParser(a_hParser));
+    p->SetVarFactory(a_pFactory, pUserData);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Create a new Parser instance and return its handle.
+*/
+API_EXPORT(muParserHandle_t) mupCreate(int nBaseType)
+{
+    switch (nBaseType)
+    {
+    case  muBASETYPE_FLOAT:   return (void*)(new ParserTag(muBASETYPE_FLOAT));
+    case  muBASETYPE_INT:     return (void*)(new ParserTag(muBASETYPE_INT));
+    default:                  return NULL;
+    }
+}
+
+//---------------------------------------------------------------------------
+/** \brief Release the parser instance related with a parser handle.
+*/
+API_EXPORT(void) mupRelease(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        ParserTag* p = static_cast<ParserTag*>(a_hParser);
+    delete p;
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+
+#ifndef _UNICODE
+    sprintf(s_tmpOutBuf, "%s", p->GetVersion().c_str());
+#else
+    wsprintf(s_tmpOutBuf, _T("%s"), p->GetVersion().c_str());
+#endif
+
+    return s_tmpOutBuf;
+    MU_CATCH
+
+        return _T("");
+}
+
+//---------------------------------------------------------------------------
+/** \brief Evaluate the expression.
+*/
+API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    return p->Eval();
+    MU_CATCH
+
+        return 0;
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum)
+{
+    MU_TRY
+        assert(nNum != NULL);
+
+    muParser_t* const p(AsParser(a_hParser));
+    return p->Eval(*nNum);
+    MU_CATCH
+
+        return 0;
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_res, int nSize)
+{
+    MU_TRY
+        muParser_t* p(AsParser(a_hParser));
+    p->Eval(a_res, nSize);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t* a_szExpr)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->SetExpr(a_szExpr);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->RemoveVar(a_szName);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Release all parser variables.
+    \param a_hParser Handle to the parser instance.
+    */
+API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->ClearVar();
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Release all parser variables.
+    \param a_hParser Handle to the parser instance.
+    */
+API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->ClearConst();
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Clear all user defined operators.
+    \param a_hParser Handle to the parser instance.
+    */
+API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->ClearOprt();
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->ClearFun();
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun0_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun1_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun2_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun3_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun4_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun5_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun6_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun7_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun8_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun9_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFun10_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muBulkFun0_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muBulkFun1_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muBulkFun2_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun3_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun4_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun5_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun6_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun7_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun8_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun9_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muBulkFun10_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muStrFun1_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muStrFun2_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muStrFun3_t a_pFun)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, false);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineMultFun(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muMultFun_t a_pFun,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineOprt(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun2_t a_pFun,
+    muInt_t a_nPrec,
+    muInt_t a_nOprtAsct,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineOprt(a_szName,
+        a_pFun,
+        a_nPrec,
+        (mu::EOprtAssociativity)a_nOprtAsct,
+        a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineVar(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFloat_t *a_pVar)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineVar(a_szName, a_pVar);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineBulkVar(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFloat_t *a_pVar)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineVar(a_szName, a_pVar);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineConst(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    muFloat_t a_fVal)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineConst(a_szName, a_fVal);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineStrConst(muParserHandle_t a_hParser,
+    const muChar_t *a_szName,
+    const muChar_t *a_szVal)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineStrConst(a_szName, a_szVal);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+
+    // C# explodes when pMsg is returned directly. For some reason it can't access
+    // the memory where the message lies directly.
+#ifndef _UNICODE
+    sprintf(s_tmpOutBuf, "%s", p->GetExpr().c_str());
+#else
+    wsprintf(s_tmpOutBuf, _T("%s"), p->GetExpr().c_str());
+#endif
+
+    return s_tmpOutBuf;
+
+    MU_CATCH
+
+        return _T("");
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefinePostfixOprt(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun1_t a_pOprt,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefinePostfixOprt(a_szName, a_pOprt, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineInfixOprt(muParserHandle_t a_hParser,
+    const muChar_t* a_szName,
+    muFun1_t a_pOprt,
+    muBool_t a_bAllowOpt)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->DefineInfixOprt(a_szName, a_pOprt, a_bAllowOpt != 0);
+    MU_CATCH
+}
+
+// Define character sets for identifiers
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser,
+    const muChar_t* a_szCharset)
+{
+    muParser_t* const p(AsParser(a_hParser));
+    p->DefineNameChars(a_szCharset);
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser,
+    const muChar_t* a_szCharset)
+{
+    muParser_t* const p(AsParser(a_hParser));
+    p->DefineOprtChars(a_szCharset);
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser,
+    const muChar_t *a_szCharset)
+{
+    muParser_t* const p(AsParser(a_hParser));
+    p->DefineInfixOprtChars(a_szCharset);
+}
+
+//---------------------------------------------------------------------------
+/** \brief Get the number of variables defined in the parser.
+    \param a_hParser [in] Must be a valid parser handle.
+    \return The number of used variables.
+    \sa mupGetExprVar
+    */
+API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::varmap_type VarMap = p->GetVar();
+    return (int)VarMap.size();
+    MU_CATCH
+
+        return 0; // never reached
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return a variable that is used in an expression.
+    \param a_hParser [in] A valid parser handle.
+    \param a_iVar [in] The index of the variable to return.
+    \param a_szName [out] Pointer to the variable name.
+    \param a_pVar [out] Pointer to the variable.
+    \throw nothrow
+
+    Prior to calling this function call mupGetExprVarNum in order to get the
+    number of variables in the expression. If the parameter a_iVar is greater
+    than the number of variables both a_szName and a_pVar will be set to zero.
+    As a side effect this function will trigger an internal calculation of the
+    expression undefined variables will be set to zero during this calculation.
+    During the calculation user defined callback functions present in the expression
+    will be called, this is unavoidable.
+    */
+API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser,
+    unsigned a_iVar,
+    const muChar_t **a_szName,
+    muFloat_t **a_pVar)
+{
+    // A static buffer is needed for the name since i cant return the
+    // pointer from the map.
+    static muChar_t  szName[1024];
+
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::varmap_type VarMap = p->GetVar();
+
+    if (a_iVar >= VarMap.size())
+    {
+        *a_szName = 0;
+        *a_pVar = 0;
+        return;
+    }
+    mu::varmap_type::const_iterator item;
+
+    item = VarMap.begin();
+    for (unsigned i = 0; i < a_iVar; ++i)
+        ++item;
+
+#ifndef _UNICODE
+    strncpy(szName, item->first.c_str(), sizeof(szName));
+#else
+    wcsncpy(szName, item->first.c_str(), sizeof(szName));
+#endif
+
+    szName[sizeof(szName)-1] = 0;
+
+    *a_szName = &szName[0];
+    *a_pVar = item->second;
+    return;
+
+    MU_CATCH
+
+        *a_szName = 0;
+    *a_pVar = 0;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Get the number of variables used in the expression currently set in the parser.
+    \param a_hParser [in] Must be a valid parser handle.
+    \return The number of used variables.
+    \sa mupGetExprVar
+    */
+API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::varmap_type VarMap = p->GetUsedVar();
+    return (int)VarMap.size();
+    MU_CATCH
+
+        return 0; // never reached
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return a variable that is used in an expression.
+
+    Prior to calling this function call mupGetExprVarNum in order to get the
+    number of variables in the expression. If the parameter a_iVar is greater
+    than the number of variables both a_szName and a_pVar will be set to zero.
+    As a side effect this function will trigger an internal calculation of the
+    expression undefined variables will be set to zero during this calculation.
+    During the calculation user defined callback functions present in the expression
+    will be called, this is unavoidable.
+
+    \param a_hParser [in] A valid parser handle.
+    \param a_iVar [in] The index of the variable to return.
+    \param a_szName [out] Pointer to the variable name.
+    \param a_pVar [out] Pointer to the variable.
+    \throw nothrow
+    */
+API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser,
+    unsigned a_iVar,
+    const muChar_t **a_szName,
+    muFloat_t **a_pVar)
+{
+    // A static buffer is needed for the name since i cant return the
+    // pointer from the map.
+    static muChar_t  szName[1024];
+
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::varmap_type VarMap = p->GetUsedVar();
+
+    if (a_iVar >= VarMap.size())
+    {
+        *a_szName = 0;
+        *a_pVar = 0;
+        return;
+    }
+    mu::varmap_type::const_iterator item;
+
+    item = VarMap.begin();
+    for (unsigned i = 0; i < a_iVar; ++i)
+        ++item;
+
+#ifndef _UNICODE
+    strncpy(szName, item->first.c_str(), sizeof(szName));
+#else
+    wcsncpy(szName, item->first.c_str(), sizeof(szName));
+#endif
+
+    szName[sizeof(szName)-1] = 0;
+
+    *a_szName = &szName[0];
+    *a_pVar = item->second;
+    return;
+
+    MU_CATCH
+
+        *a_szName = 0;
+    *a_pVar = 0;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return the number of constants defined in a parser. */
+API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::valmap_type ValMap = p->GetConst();
+    return (int)ValMap.size();
+    MU_CATCH
+
+        return 0; // never reached
+}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->SetArgSep(cArgSep);
+    MU_CATCH
+}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->ResetLocale();
+    MU_CATCH
+}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cDecSep)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->SetDecSep(cDecSep);
+    MU_CATCH
+}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cThousandsSep)
+{
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    p->SetThousandsSep(cThousandsSep);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Retrieve name and value of a single parser constant.
+    \param a_hParser [in] a valid parser handle
+    \param a_iVar [in] Index of the constant to query
+    \param a_pszName [out] pointer to a null terminated string with the constant name
+    \param [out] The constant value
+    */
+API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser,
+    unsigned a_iVar,
+    const muChar_t **a_pszName,
+    muFloat_t *a_fVal)
+{
+    // A static buffer is needed for the name since i cant return the
+    // pointer from the map.
+    static muChar_t szName[1024];
+
+    MU_TRY
+        muParser_t* const p(AsParser(a_hParser));
+    const mu::valmap_type ValMap = p->GetConst();
+
+    if (a_iVar >= ValMap.size())
+    {
+        *a_pszName = 0;
+        *a_fVal = 0;
+        return;
+    }
+
+    mu::valmap_type::const_iterator item;
+    item = ValMap.begin();
+    for (unsigned i = 0; i < a_iVar; ++i)
+        ++item;
+
+#ifndef _UNICODE
+    strncpy(szName, item->first.c_str(), sizeof(szName));
+#else
+    wcsncpy(szName, item->first.c_str(), sizeof(szName));
+#endif
+
+    szName[sizeof(szName)-1] = 0;
+
+    *a_pszName = &szName[0];
+    *a_fVal = item->second;
+    return;
+
+    MU_CATCH
+
+        *a_pszName = 0;
+    *a_fVal = 0;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Add a custom value recognition function.
+*/
+API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser,
+    muIdentFun_t a_pFun)
+{
+    MU_TRY
+        muParser_t* p(AsParser(a_hParser));
+    p->AddValIdent(a_pFun);
+    MU_CATCH
+}
+
+//---------------------------------------------------------------------------
+/** \brief Query if an error occurred.
+
+    After querying the internal error bit will be reset. So a consecutive call
+    will return false.
+    */
+API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser)
+{
+    bool bError(AsParserTag(a_hParser)->bError);
+    AsParserTag(a_hParser)->bError = false;
+    return bError;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Reset the internal error flag.
+*/
+API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser)
+{
+    AsParserTag(a_hParser)->bError = false;
+}
+
+//---------------------------------------------------------------------------
+API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pHandler)
+{
+    AsParserTag(a_hParser)->errHandler = a_pHandler;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return the message associated with the last error.
+*/
+API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser)
+{
+    ParserTag* const p(AsParserTag(a_hParser));
+    const muChar_t *pMsg = p->exc.GetMsg().c_str();
+
+    // C# explodes when pMsg is returned directly. For some reason it can't access
+    // the memory where the message lies directly.
+#ifndef _UNICODE
+    sprintf(s_tmpOutBuf, "%s", pMsg);
+#else
+    wsprintf(s_tmpOutBuf, _T("%s"), pMsg);
+#endif
+
+    return s_tmpOutBuf;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return the message associated with the last error.
+*/
+API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser)
+{
+    ParserTag* const p(AsParserTag(a_hParser));
+    const muChar_t *pToken = p->exc.GetToken().c_str();
+
+    // C# explodes when pMsg is returned directly. For some reason it can't access
+    // the memory where the message lies directly.
+#ifndef _UNICODE
+    sprintf(s_tmpOutBuf, "%s", pToken);
+#else
+    wsprintf(s_tmpOutBuf, _T("%s"), pToken);
+#endif
+
+    return s_tmpOutBuf;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return the code associated with the last error.
+*/
+API_EXPORT(int) mupGetErrorCode(muParserHandle_t a_hParser)
+{
+    return AsParserTag(a_hParser)->exc.GetCode();
+}
+
+//---------------------------------------------------------------------------
+/** \brief Return the position associated with the last error. */
+API_EXPORT(int) mupGetErrorPos(muParserHandle_t a_hParser)
+{
+    return (int)AsParserTag(a_hParser)->exc.GetPos();
+}
+
+////-----------------------------------------------------------------------------------------------------
+//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser)
+//{
+//  return AsParserTag(a_hParser)->exc.GetExpr().c_str();
+//}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(muFloat_t*) mupCreateVar()
+{
+    return new muFloat_t(0);
+}
+
+//-----------------------------------------------------------------------------------------------------
+API_EXPORT(void) mupReleaseVar(muFloat_t *ptr)
+{
+    delete ptr;
+}
+
+#endif      // MUPARSER_DLL
diff --git a/ThirdParty/MuParser/src/muParserError.cpp b/ThirdParty/MuParser/src/muParserError.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30c46484650ea12b1f47e2069d667722fc0f3523
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserError.cpp
@@ -0,0 +1,337 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  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. 
+*/
+#include "muParserError.h"
+
+
+namespace mu
+{
+  const ParserErrorMsg ParserErrorMsg::m_Instance;
+
+  //------------------------------------------------------------------------------
+  const ParserErrorMsg& ParserErrorMsg::Instance()
+  {
+    return m_Instance;
+  }
+
+  //------------------------------------------------------------------------------
+  string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
+  {
+    return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
+  }
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::~ParserErrorMsg()
+  {}
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignement operator is deactivated.
+  */
+  ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )
+  {
+    assert(false);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
+  {}
+
+  //---------------------------------------------------------------------------
+  ParserErrorMsg::ParserErrorMsg()
+    :m_vErrMsg(0)
+  {
+    m_vErrMsg.resize(ecCOUNT);
+
+    m_vErrMsg[ecUNASSIGNABLE_TOKEN]     = _T("Unexpected token \"$TOK$\" found at position $POS$.");
+    m_vErrMsg[ecINTERNAL_ERROR]         = _T("Internal error");
+    m_vErrMsg[ecINVALID_NAME]           = _T("Invalid function-, variable- or constant name: \"$TOK$\".");
+    m_vErrMsg[ecINVALID_BINOP_IDENT]    = _T("Invalid binary operator identifier: \"$TOK$\".");
+    m_vErrMsg[ecINVALID_INFIX_IDENT]    = _T("Invalid infix operator identifier: \"$TOK$\".");
+    m_vErrMsg[ecINVALID_POSTFIX_IDENT]  = _T("Invalid postfix operator identifier: \"$TOK$\".");
+    m_vErrMsg[ecINVALID_FUN_PTR]        = _T("Invalid pointer to callback function.");
+    m_vErrMsg[ecEMPTY_EXPRESSION]       = _T("Expression is empty.");
+    m_vErrMsg[ecINVALID_VAR_PTR]        = _T("Invalid pointer to variable.");
+    m_vErrMsg[ecUNEXPECTED_OPERATOR]    = _T("Unexpected operator \"$TOK$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_EOF]         = _T("Unexpected end of expression at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_ARG_SEP]     = _T("Unexpected argument separator at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_PARENS]      = _T("Unexpected parenthesis \"$TOK$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_FUN]         = _T("Unexpected function \"$TOK$\" at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAL]         = _T("Unexpected value \"$TOK$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_VAR]         = _T("Unexpected variable \"$TOK$\" found at position $POS$");
+    m_vErrMsg[ecUNEXPECTED_ARG]         = _T("Function arguments used without a function (position: $POS$)");
+    m_vErrMsg[ecMISSING_PARENS]         = _T("Missing parenthesis");
+    m_vErrMsg[ecTOO_MANY_PARAMS]        = _T("Too many parameters for function \"$TOK$\" at expression position $POS$");
+    m_vErrMsg[ecTOO_FEW_PARAMS]         = _T("Too few parameters for function \"$TOK$\" at expression position $POS$");
+    m_vErrMsg[ecDIV_BY_ZERO]            = _T("Divide by zero");
+    m_vErrMsg[ecDOMAIN_ERROR]           = _T("Domain error");
+    m_vErrMsg[ecNAME_CONFLICT]          = _T("Name conflict");
+    m_vErrMsg[ecOPT_PRI]                = _T("Invalid value for operator priority (must be greater or equal to zero).");
+    m_vErrMsg[ecBUILTIN_OVERLOAD]       = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator.");
+    m_vErrMsg[ecUNEXPECTED_STR]         = _T("Unexpected string token found at position $POS$.");
+    m_vErrMsg[ecUNTERMINATED_STRING]    = _T("Unterminated string starting at position $POS$.");
+    m_vErrMsg[ecSTRING_EXPECTED]        = _T("String function called with a non string type of argument.");
+    m_vErrMsg[ecVAL_EXPECTED]           = _T("String value used where a numerical argument is expected.");
+    m_vErrMsg[ecOPRT_TYPE_CONFLICT]     = _T("No suitable overload for operator \"$TOK$\" at position $POS$.");
+    m_vErrMsg[ecSTR_RESULT]             = _T("Function result is a string.");
+    m_vErrMsg[ecGENERIC]                = _T("Parser error.");
+    m_vErrMsg[ecLOCALE]                 = _T("Decimal separator is identic to function argument separator.");
+    m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket.");
+    m_vErrMsg[ecMISSING_ELSE_CLAUSE]    = _T("If-then-else operator is missing an else clause");
+    m_vErrMsg[ecMISPLACED_COLON]        = _T("Misplaced colon at position $POS$");
+    m_vErrMsg[ecUNREASONABLE_NUMBER_OF_COMPUTATIONS] = _T("Number of computations to small for bulk mode. (Vectorisation overhead too costly)");
+    
+    #if defined(_DEBUG)
+      for (int i=0; i<ecCOUNT; ++i)
+        if (!m_vErrMsg[i].length())
+          assert(false);
+    #endif
+  }
+
+  //---------------------------------------------------------------------------
+  //
+  //  ParserError class
+  //
+  //---------------------------------------------------------------------------
+
+  /** \brief Default constructor. */
+  ParserError::ParserError()
+    :m_strMsg()
+    ,m_strFormula()
+    ,m_strTok()
+    ,m_iPos(-1)
+    ,m_iErrc(ecUNDEFINED)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief This Constructor is used for internal exceptions only. 
+      
+    It does not contain any information but the error code.
+  */
+  ParserError::ParserError(EErrorCodes a_iErrc) 
+    :m_strMsg()
+    ,m_strFormula()
+    ,m_strTok()
+    ,m_iPos(-1)
+    ,m_iErrc(a_iErrc)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    m_strMsg = m_ErrMsg[m_iErrc];
+    stringstream_type stream;
+    stream << (int)m_iPos;
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an error from a message text. */
+  ParserError::ParserError(const string_type &sMsg) 
+    :m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    Reset();
+    m_strMsg = sMsg;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an error object. 
+      \param [in] a_iErrc the error code.
+      \param [in] sTok The token string related to this error.
+      \param [in] sExpr The expression related to the error.
+      \param [in] a_iPos the position in the expression where the error occurred. 
+  */
+  ParserError::ParserError( EErrorCodes iErrc,
+                            const string_type &sTok,
+                            const string_type &sExpr,
+                            int iPos )
+    :m_strMsg()
+    ,m_strFormula(sExpr)
+    ,m_strTok(sTok)
+    ,m_iPos(iPos)
+    ,m_iErrc(iErrc)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    m_strMsg = m_ErrMsg[m_iErrc];
+    stringstream_type stream;
+    stream << (int)m_iPos;
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an error object. 
+      \param [in] iErrc the error code.
+      \param [in] iPos the position in the expression where the error occurred. 
+      \param [in] sTok The token string related to this error.
+  */
+  ParserError::ParserError(EErrorCodes iErrc, int iPos, const string_type &sTok) 
+    :m_strMsg()
+    ,m_strFormula()
+    ,m_strTok(sTok)
+    ,m_iPos(iPos)
+    ,m_iErrc(iErrc)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    m_strMsg = m_ErrMsg[m_iErrc];
+    stringstream_type stream;
+    stream << (int)m_iPos;
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Construct an error object. 
+      \param [in] szMsg The error message text.
+      \param [in] iPos the position related to the error.
+      \param [in] sTok The token string related to this error.
+  */
+  ParserError::ParserError(const char_type *szMsg, int iPos, const string_type &sTok) 
+    :m_strMsg(szMsg)
+    ,m_strFormula()
+    ,m_strTok(sTok)
+    ,m_iPos(iPos)
+    ,m_iErrc(ecGENERIC)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+    stringstream_type stream;
+    stream << (int)m_iPos;
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Copy constructor. */
+  ParserError::ParserError(const ParserError &a_Obj)
+    :m_strMsg(a_Obj.m_strMsg)
+    ,m_strFormula(a_Obj.m_strFormula)
+    ,m_strTok(a_Obj.m_strTok)
+    ,m_iPos(a_Obj.m_iPos)
+    ,m_iErrc(a_Obj.m_iErrc)
+    ,m_ErrMsg(ParserErrorMsg::Instance())
+  {
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Assignment operator. */
+  ParserError& ParserError::operator=(const ParserError &a_Obj)
+  {
+    if (this==&a_Obj)
+      return *this;
+
+    m_strMsg = a_Obj.m_strMsg;
+    m_strFormula = a_Obj.m_strFormula;
+    m_strTok = a_Obj.m_strTok;
+    m_iPos = a_Obj.m_iPos;
+    m_iErrc = a_Obj.m_iErrc;
+    return *this;
+  }
+
+  //------------------------------------------------------------------------------
+  ParserError::~ParserError()
+  {}
+
+  //------------------------------------------------------------------------------
+  /** \brief Replace all occurrences of a substring with another string. 
+      \param strFind The string that shall be replaced.
+      \param strReplaceWith The string that should be inserted instead of strFind
+  */
+  void ParserError::ReplaceSubString( string_type &strSource,
+                                      const string_type &strFind,
+                                      const string_type &strReplaceWith)
+  {
+    string_type strResult;
+    string_type::size_type iPos(0), iNext(0);
+
+    for(;;)
+    {
+      iNext = strSource.find(strFind, iPos);
+      strResult.append(strSource, iPos, iNext-iPos);
+
+      if( iNext==string_type::npos )
+        break;
+
+      strResult.append(strReplaceWith);
+      iPos = iNext + strFind.length();
+    } 
+
+    strSource.swap(strResult);
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Reset the erro object. */
+  void ParserError::Reset()
+  {
+    m_strMsg = _T("");
+    m_strFormula = _T("");
+    m_strTok = _T("");
+    m_iPos = -1;
+    m_iErrc = ecUNDEFINED;
+  }
+      
+  //------------------------------------------------------------------------------
+  /** \brief Set the expression related to this error. */
+  void ParserError::SetFormula(const string_type &a_strFormula)
+  {
+    m_strFormula = a_strFormula;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief gets the expression related tp this error.*/
+  const string_type& ParserError::GetExpr() const 
+  {
+    return m_strFormula;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Returns the message string for this error. */
+  const string_type& ParserError::GetMsg() const
+  {
+    return m_strMsg;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the formula position related to the error. 
+
+    If the error is not related to a distinct position this will return -1
+  */
+  int ParserError::GetPos() const
+  {
+    return m_iPos;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return string related with this token (if available). */
+  const string_type& ParserError::GetToken() const
+  {
+    return m_strTok;
+  }
+
+  //------------------------------------------------------------------------------
+  /** \brief Return the error code. */
+  EErrorCodes ParserError::GetCode() const
+  {
+    return m_iErrc;
+  }
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserInt.cpp b/ThirdParty/MuParser/src/muParserInt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64a29ad9414071e580d49bb63c604bc2bd223cc8
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserInt.cpp
@@ -0,0 +1,280 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  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. 
+*/
+
+#include "muParserInt.h"
+
+#include <cmath>
+#include <algorithm>
+#include <numeric>
+
+using namespace std;
+
+/** \file
+    \brief Implementation of a parser using integer value.
+*/
+
+/** \brief Namespace for mathematical applications. */
+namespace mu
+{
+value_type ParserInt::Abs(value_type v)  { return (value_type)Round(fabs((double)v)); }
+value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
+value_type ParserInt::Ite(value_type v1, 
+                          value_type v2, 
+                          value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
+value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1)  + Round(v2); }
+value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1)  - Round(v2); }
+value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1)  * Round(v2); }
+value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1)  / Round(v2); }
+value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1)  % Round(v2); }
+value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }
+value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }
+value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }
+value_type ParserInt::LogOr(value_type v1, value_type v2)  { return Round(v1) | Round(v2); }
+value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }
+value_type ParserInt::Or(value_type v1, value_type v2)  { return Round(v1) || Round(v2); }
+value_type ParserInt::Less(value_type v1, value_type v2)      { return Round(v1)  < Round(v2); }
+value_type ParserInt::Greater(value_type v1, value_type v2)   { return Round(v1)  > Round(v2); }
+value_type ParserInt::LessEq(value_type v1, value_type v2)    { return Round(v1) <= Round(v2); }
+value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }
+value_type ParserInt::Equal(value_type v1, value_type v2)     { return Round(v1) == Round(v2); }
+value_type ParserInt::NotEqual(value_type v1, value_type v2)  { return Round(v1) != Round(v2); }
+value_type ParserInt::Not(value_type v) { return !Round(v); }
+
+value_type ParserInt::Pow(value_type v1, value_type v2) 
+{ 
+  return std::pow((double)Round(v1), (double)Round(v2)); 
+}
+
+//---------------------------------------------------------------------------
+// Unary operator Callbacks: Infix operators
+value_type ParserInt::UnaryMinus(value_type v) 
+{ 
+  return -Round(v); 
+}
+
+//---------------------------------------------------------------------------
+value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)
+{ 
+  if (!a_iArgc)	
+    throw ParserError(_T("too few arguments for function sum."));
+
+  value_type fRes=0;
+  for (int i=0; i<a_iArgc; ++i) 
+    fRes += a_afArg[i];
+
+  return fRes;
+}
+
+//---------------------------------------------------------------------------
+value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)
+{ 
+  if (!a_iArgc)	
+    throw ParserError( _T("too few arguments for function min.") );
+
+  value_type fRes=a_afArg[0];
+  for (int i=0; i<a_iArgc; ++i) 
+    fRes = std::min(fRes, a_afArg[i]);
+
+  return fRes;
+}
+
+//---------------------------------------------------------------------------
+value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)
+{ 
+  if (!a_iArgc)	
+    throw ParserError(_T("too few arguments for function min."));
+
+  value_type fRes=a_afArg[0];
+  for (int i=0; i<a_iArgc; ++i) 
+    fRes = std::max(fRes, a_afArg[i]);
+
+  return fRes;
+}
+
+//---------------------------------------------------------------------------
+// Default value recognition callback
+int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
+{
+  string_type buf(a_szExpr);
+  std::size_t pos = buf.find_first_not_of(_T("0123456789"));
+
+  if (pos==std::string::npos)
+    return 0;
+
+  stringstream_type stream( buf.substr(0, pos ) );
+  int iVal(0);
+
+  stream >> iVal;
+  if (stream.fail())
+    return 0;
+      
+  stringstream_type::pos_type iEnd = stream.tellg();   // Position after reading
+  if (stream.fail())
+    iEnd = stream.str().length();  
+
+  if (iEnd==(stringstream_type::pos_type)-1)
+    return 0;
+
+  *a_iPos += (int)iEnd;
+  *a_fVal = (value_type)iVal;
+  return 1;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Check a given position in the expression for the presence of 
+           a hex value. 
+    \param a_szExpr Pointer to the expression string
+    \param [in/out] a_iPos Pointer to an integer value holding the current parsing 
+           position in the expression.
+    \param [out] a_fVal Pointer to the position where the detected value shall be stored.
+
+  Hey values must be prefixed with "0x" in order to be detected properly.
+*/
+int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
+{
+  if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) 
+    return 0;
+
+  unsigned iVal(0);
+
+  // New code based on streams for UNICODE compliance:
+  stringstream_type::pos_type nPos(0);
+  stringstream_type ss(a_szExpr + 2);
+  ss >> std::hex >> iVal;
+  nPos = ss.tellg();
+
+  if (nPos==(stringstream_type::pos_type)0)
+    return 1;
+
+  *a_iPos += (int)(2 + nPos);
+  *a_fVal = (value_type)iVal;
+  return 1;
+}
+
+//---------------------------------------------------------------------------
+int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
+{
+  if (a_szExpr[0]!='#') 
+    return 0;
+
+  unsigned iVal(0), 
+           iBits(sizeof(iVal)*8),
+           i(0);
+
+  for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
+    iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
+
+  if (i==0) 
+    return 0;
+
+  if (i==iBits)
+    throw exception_type(_T("Binary to integer conversion error (overflow)."));
+
+  *a_fVal = (unsigned)(iVal >> (iBits-i) );
+  *a_iPos += i+1;
+
+  return 1;
+}
+
+//---------------------------------------------------------------------------
+/** \brief Constructor. 
+
+  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
+*/
+ParserInt::ParserInt()
+  :ParserBase()
+{
+  AddValIdent(IsVal);    // lowest priority
+  AddValIdent(IsBinVal);
+  AddValIdent(IsHexVal); // highest priority
+
+  InitCharSets();
+  InitFun();
+  InitOprt();
+}
+
+//---------------------------------------------------------------------------
+void ParserInt::InitConst()
+{
+}
+
+//---------------------------------------------------------------------------
+void ParserInt::InitCharSets()
+{
+  DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
+  DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );
+  DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );
+}
+
+//---------------------------------------------------------------------------
+/** \brief Initialize the default functions. */
+void ParserInt::InitFun()
+{
+  DefineFun( _T("sign"), Sign);
+  DefineFun( _T("abs"), Abs);
+  DefineFun( _T("if"), Ite);
+  DefineFun( _T("sum"), Sum);
+  DefineFun( _T("min"), Min);
+  DefineFun( _T("max"), Max);
+}
+
+//---------------------------------------------------------------------------
+/** \brief Initialize operators. */
+void ParserInt::InitOprt()
+{
+  // disable all built in operators, not all of them useful for integer numbers
+  // (they don't do rounding of values)
+  EnableBuiltInOprt(false);
+
+  // Disable all built in operators, they wont work with integer numbers
+  // since they are designed for floating point numbers
+  DefineInfixOprt( _T("-"), UnaryMinus);
+  DefineInfixOprt( _T("!"), Not);
+
+  DefineOprt( _T("&"), LogAnd, prLOGIC);
+  DefineOprt( _T("|"), LogOr, prLOGIC);
+  DefineOprt( _T("&&"), And, prLOGIC);
+  DefineOprt( _T("||"), Or, prLOGIC);
+
+  DefineOprt( _T("<"), Less, prCMP);
+  DefineOprt( _T(">"), Greater, prCMP);
+  DefineOprt( _T("<="), LessEq, prCMP);
+  DefineOprt( _T(">="), GreaterEq, prCMP);
+  DefineOprt( _T("=="), Equal, prCMP);
+  DefineOprt( _T("!="), NotEqual, prCMP);
+
+  DefineOprt( _T("+"), Add, prADD_SUB);
+  DefineOprt( _T("-"), Sub, prADD_SUB);
+
+  DefineOprt( _T("*"), Mul, prMUL_DIV);
+  DefineOprt( _T("/"), Div, prMUL_DIV);
+  DefineOprt( _T("%"), Mod, prMUL_DIV);
+
+  DefineOprt( _T("^"), Pow, prPOW, oaRIGHT);
+  DefineOprt( _T(">>"), Shr, prMUL_DIV+1);
+  DefineOprt( _T("<<"), Shl, prMUL_DIV+1);
+}
+
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserTest.cpp b/ThirdParty/MuParser/src/muParserTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e84e38852f03290392f1d55c2326d02ce2d80785
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserTest.cpp
@@ -0,0 +1,1552 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+
+#include "muParserTest.h"
+
+#include <cstdio>
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+#define PARSER_CONST_PI  3.141592653589793238462643
+#define PARSER_CONST_E   2.718281828459045235360287
+
+using namespace std;
+
+/** \file
+    \brief This file contains the implementation of parser test cases.
+*/
+
+namespace mu
+{
+  namespace Test
+  {
+    int ParserTester::c_iCount = 0;
+
+    //---------------------------------------------------------------------------------------------
+    ParserTester::ParserTester()
+      :m_vTestFun()
+    {
+      AddTest(&ParserTester::TestNames);
+      AddTest(&ParserTester::TestSyntax);
+      AddTest(&ParserTester::TestPostFix);
+      AddTest(&ParserTester::TestInfixOprt);
+      AddTest(&ParserTester::TestVarConst);
+      AddTest(&ParserTester::TestMultiArg);
+      AddTest(&ParserTester::TestExpression);
+      AddTest(&ParserTester::TestIfThenElse);
+      AddTest(&ParserTester::TestInterface);
+      AddTest(&ParserTester::TestBinOprt);
+      AddTest(&ParserTester::TestException);
+      AddTest(&ParserTester::TestStrArg);
+      AddTest(&ParserTester::TestBulkMode);
+
+      ParserTester::c_iCount = 0;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int ParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
+    {
+      if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) 
+        return 0;
+
+      unsigned iVal(0);
+
+      // New code based on streams for UNICODE compliance:
+      stringstream_type::pos_type nPos(0);
+      stringstream_type ss(a_szExpr + 2);
+      ss >> std::hex >> iVal;
+      nPos = ss.tellg();
+
+      if (nPos==(stringstream_type::pos_type)0)
+        return 1;
+
+      *a_iPos += (int)(2 + nPos);
+      *a_fVal = (value_type)iVal;
+      return 1;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int ParserTester::TestInterface()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing member functions...");
+   
+      // Test RemoveVar
+      value_type afVal[3] = {1,2,3};
+      Parser p;
+  
+      try
+      {
+        p.DefineVar( _T("a"), &afVal[0]);
+        p.DefineVar( _T("b"), &afVal[1]);
+        p.DefineVar( _T("c"), &afVal[2]);
+        p.SetExpr( _T("a+b+c") );
+        p.Eval();
+      }
+      catch(...)
+      {
+        iStat += 1;  // this is not supposed to happen 
+      }
+
+      try
+      {
+        p.RemoveVar( _T("c") );
+        p.Eval();
+        iStat += 1;  // not supposed to reach this, nonexisting variable "c" deleted...
+      }
+      catch(...)
+      {
+        // failure is expected...
+      }
+
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int ParserTester::TestStrArg()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing string arguments...");
+ 
+      iStat += EqnTest(_T("valueof(\"\")"), 123, true);   // empty string arguments caused a crash
+      iStat += EqnTest(_T("valueof(\"aaa\")+valueof(\"bbb\")  "), 246, true);
+      iStat += EqnTest(_T("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323, true);
+      // use in expressions with variables
+      iStat += EqnTest(_T("a*(atof(\"10\")-b)"), 8, true);
+      iStat += EqnTest(_T("a-(atof(\"10\")*b)"), -19, true);
+      // string + numeric arguments
+      iStat += EqnTest(_T("strfun1(\"100\")"), 100, true);
+      iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true);
+      iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true);
+      // string constants
+      iStat += EqnTest(_T("atof(str1)+atof(str2)"), 3.33, true);
+
+      if (iStat==0)
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int ParserTester::TestBulkMode()
+    {
+        int iStat = 0;
+        mu::console() << _T("testing bulkmode...");
+
+#define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS) \
+        { \
+          double res[] = { R1, R2, R3, R4 }; \
+          iStat += EqnTestBulk(_T(EXPR), res, (PASS)); \
+        }
+
+        // Bulk Variables for the test:
+        // a: 1,2,3,4
+        // b: 2,2,2,2
+        // c: 3,3,3,3
+        // d: 5,4,3,2
+        EQN_TEST_BULK("a",   1, 1, 1, 1, false)
+        EQN_TEST_BULK("a",   1, 2, 3, 4, true)
+        EQN_TEST_BULK("b=a", 1, 2, 3, 4, true)
+        EQN_TEST_BULK("b=a, b*10", 10, 20, 30, 40, true)
+        EQN_TEST_BULK("b=a, b*10, a", 1, 2, 3, 4, true)
+        EQN_TEST_BULK("a+b", 3, 4, 5, 6, true)
+        EQN_TEST_BULK("c*(a+b)", 9, 12, 15, 18, true)
+#undef EQN_TEST_BULK
+
+        if (iStat == 0)
+            mu::console() << _T("passed") << endl;
+        else
+            mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+        return iStat;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    int ParserTester::TestBinOprt()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing binary operators...");
+   
+      // built in operators
+      // xor operator
+
+      iStat += EqnTest(_T("a++b"), 3, true);
+      iStat += EqnTest(_T("a ++ b"), 3, true);
+      iStat += EqnTest(_T("1++2"), 3, true);
+      iStat += EqnTest(_T("1 ++ 2"), 3, true);
+      iStat += EqnTest(_T("a add b"), 3, true);
+      iStat += EqnTest(_T("1 add 2"), 3, true);
+      iStat += EqnTest(_T("a<b"), 1, true);
+      iStat += EqnTest(_T("b>a"), 1, true);
+      iStat += EqnTest(_T("a>a"), 0, true);
+      iStat += EqnTest(_T("a<a"), 0, true);
+      iStat += EqnTest(_T("a>a"), 0, true);
+      iStat += EqnTest(_T("a<=a"), 1, true);
+      iStat += EqnTest(_T("a<=b"), 1, true);
+      iStat += EqnTest(_T("b<=a"), 0, true);
+      iStat += EqnTest(_T("a>=a"), 1, true);
+      iStat += EqnTest(_T("b>=a"), 1, true);
+      iStat += EqnTest(_T("a>=b"), 0, true);
+
+      // Test logical operators, especially if user defined "&" and the internal "&&" collide
+      iStat += EqnTest(_T("1 && 1"), 1, true); 
+      iStat += EqnTest(_T("1 && 0"), 0, true); 
+      iStat += EqnTest(_T("(a<b) && (b>a)"), 1, true); 
+      iStat += EqnTest(_T("(a<b) && (a>b)"), 0, true); 
+      //iStat += EqnTest(_T("12 and 255"), 12, true); 
+      //iStat += EqnTest(_T("12 and 0"), 0, true); 
+      iStat += EqnTest(_T("12 & 255"), 12, true); 
+      iStat += EqnTest(_T("12 & 0"), 0, true); 
+      iStat += EqnTest(_T("12&255"), 12, true); 
+      iStat += EqnTest(_T("12&0"), 0, true); 
+
+      // Assignment operator
+      iStat += EqnTest(_T("a = b"), 2, true); 
+      iStat += EqnTest(_T("a = sin(b)"), 0.909297, true); 
+      iStat += EqnTest(_T("a = 1+sin(b)"), 1.909297, true);
+      iStat += EqnTest(_T("(a=b)*2"), 4, true);
+      iStat += EqnTest(_T("2*(a=b)"), 4, true);
+      iStat += EqnTest(_T("2*(a=b+1)"), 6, true);
+      iStat += EqnTest(_T("(a=b+1)*2"), 6, true);
+      iStat += EqnTest(_T("a=c, a*10"), 30, true);
+
+      iStat += EqnTest(_T("2^2^3"), 256, true); 
+      iStat += EqnTest(_T("1/2/3"), 1.0/6.0, true); 
+
+      // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3
+      iStat += EqnTest(_T("3+4*2/(1-5)^2^3"), 3.0001220703125, true); 
+
+      // Test user defined binary operators
+      iStat += EqnTestInt(_T("1 | 2"), 3, true);          
+      iStat += EqnTestInt(_T("1 || 2"), 1, true);          
+      iStat += EqnTestInt(_T("123 & 456"), 72, true);          
+      iStat += EqnTestInt(_T("(123 & 456) % 10"), 2, true);
+      iStat += EqnTestInt(_T("1 && 0"), 0, true);          
+      iStat += EqnTestInt(_T("123 && 456"), 1, true);          
+      iStat += EqnTestInt(_T("1 << 3"), 8, true);          
+      iStat += EqnTestInt(_T("8 >> 3"), 1, true);          
+      iStat += EqnTestInt(_T("9 / 4"), 2, true);  
+      iStat += EqnTestInt(_T("9 % 4"), 1, true);  
+      iStat += EqnTestInt(_T("if(5%2,1,0)"), 1, true);
+      iStat += EqnTestInt(_T("if(4%2,1,0)"), 0, true);
+      iStat += EqnTestInt(_T("-10+1"), -9, true);
+      iStat += EqnTestInt(_T("1+2*3"), 7, true);
+      iStat += EqnTestInt(_T("const1 != const2"), 1, true);
+      iStat += EqnTestInt(_T("const1 != const2"), 0, false);
+      iStat += EqnTestInt(_T("const1 == const2"), 0, true);
+      iStat += EqnTestInt(_T("const1 == 1"), 1, true);
+      iStat += EqnTestInt(_T("10*(const1 == 1)"), 10, true);
+      iStat += EqnTestInt(_T("2*(const1 | const2)"), 6, true);
+      iStat += EqnTestInt(_T("2*(const1 | const2)"), 7, false);
+      iStat += EqnTestInt(_T("const1 < const2"), 1, true);
+      iStat += EqnTestInt(_T("const2 > const1"), 1, true);
+      iStat += EqnTestInt(_T("const1 <= 1"), 1, true);
+      iStat += EqnTestInt(_T("const2 >= 2"), 1, true);
+      iStat += EqnTestInt(_T("2*(const1 + const2)"), 6, true);
+      iStat += EqnTestInt(_T("2*(const1 - const2)"), -2, true);
+      iStat += EqnTestInt(_T("a != b"), 1, true);
+      iStat += EqnTestInt(_T("a != b"), 0, false);
+      iStat += EqnTestInt(_T("a == b"), 0, true);
+      iStat += EqnTestInt(_T("a == 1"), 1, true);
+      iStat += EqnTestInt(_T("10*(a == 1)"), 10, true);
+      iStat += EqnTestInt(_T("2*(a | b)"), 6, true);
+      iStat += EqnTestInt(_T("2*(a | b)"), 7, false);
+      iStat += EqnTestInt(_T("a < b"), 1, true);
+      iStat += EqnTestInt(_T("b > a"), 1, true);
+      iStat += EqnTestInt(_T("a <= 1"), 1, true);
+      iStat += EqnTestInt(_T("b >= 2"), 1, true);
+      iStat += EqnTestInt(_T("2*(a + b)"), 6, true);
+      iStat += EqnTestInt(_T("2*(a - b)"), -2, true);
+      iStat += EqnTestInt(_T("a + (a << b)"), 5, true);
+      iStat += EqnTestInt(_T("-2^2"), -4, true);
+      iStat += EqnTestInt(_T("3--a"), 4, true);
+      iStat += EqnTestInt(_T("3+-3^2"), -6, true);
+
+      // Test reading of hex values:
+      iStat += EqnTestInt(_T("0xff"), 255, true);
+      iStat += EqnTestInt(_T("10+0xff"), 265, true);
+      iStat += EqnTestInt(_T("0xff+10"), 265, true);
+      iStat += EqnTestInt(_T("10*0xff"), 2550, true);
+      iStat += EqnTestInt(_T("0xff*10"), 2550, true);
+      iStat += EqnTestInt(_T("10+0xff+1"), 266, true);
+      iStat += EqnTestInt(_T("1+0xff+10"), 266, true);
+
+// incorrect: '^' is yor here, not power
+//    iStat += EqnTestInt("-(1+2)^2", -9, true);
+//    iStat += EqnTestInt("-1^3", -1, true);          
+
+      // Test precedence
+      // a=1, b=2, c=3
+      iStat += EqnTestInt(_T("a + b * c"), 7, true);
+      iStat += EqnTestInt(_T("a * b + c"), 5, true);
+      iStat += EqnTestInt(_T("a<b && b>10"), 0, true);
+      iStat += EqnTestInt(_T("a<b && b<10"), 1, true);
+
+      iStat += EqnTestInt(_T("a + b << c"), 17, true);
+      iStat += EqnTestInt(_T("a << b + c"), 7, true);
+      iStat += EqnTestInt(_T("c * b < a"), 0, true);
+      iStat += EqnTestInt(_T("c * b == 6 * a"), 1, true);
+      iStat += EqnTestInt(_T("2^2^3"), 256, true); 
+
+
+      if (iStat==0)
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------------------------
+    /** \brief Check muParser name restriction enforcement. */
+    int ParserTester::TestNames()
+    {
+      int  iStat= 0,
+           iErr = 0;
+
+      mu::console() << "testing name restriction enforcement...";
+    
+      Parser p;
+
+  #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
+      iErr = 0;                                      \
+      ParserTester::c_iCount++;                      \
+      try                                            \
+      {                                              \
+        p.Define##DOMAIN(EXPR, ARG);                 \
+      }                                              \
+      catch(Parser::exception_type&)                 \
+      {                                              \
+        iErr = (FAIL==false) ? 0 : 1;                \
+      }                                              \
+      iStat += iErr;      
+      
+      // constant names
+      PARSER_THROWCHECK(Const, false, _T("0a"), 1)
+      PARSER_THROWCHECK(Const, false, _T("9a"), 1)
+      PARSER_THROWCHECK(Const, false, _T("+a"), 1)
+      PARSER_THROWCHECK(Const, false, _T("-a"), 1)
+      PARSER_THROWCHECK(Const, false, _T("a-"), 1)
+      PARSER_THROWCHECK(Const, false, _T("a*"), 1)
+      PARSER_THROWCHECK(Const, false, _T("a?"), 1)
+      PARSER_THROWCHECK(Const, true, _T("a"), 1)
+      PARSER_THROWCHECK(Const, true, _T("a_min"), 1)
+      PARSER_THROWCHECK(Const, true, _T("a_min0"), 1)
+      PARSER_THROWCHECK(Const, true, _T("a_min9"), 1)
+      // variable names
+      value_type a;
+      p.ClearConst();
+      PARSER_THROWCHECK(Var, false, _T("123abc"), &a)
+      PARSER_THROWCHECK(Var, false, _T("9a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("0a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("+a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("-a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("?a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("!a"), &a)
+      PARSER_THROWCHECK(Var, false, _T("a+"), &a)
+      PARSER_THROWCHECK(Var, false, _T("a-"), &a)
+      PARSER_THROWCHECK(Var, false, _T("a*"), &a)
+      PARSER_THROWCHECK(Var, false, _T("a?"), &a)
+      PARSER_THROWCHECK(Var, true, _T("a"), &a)
+      PARSER_THROWCHECK(Var, true, _T("a_min"), &a)
+      PARSER_THROWCHECK(Var, true, _T("a_min0"), &a)
+      PARSER_THROWCHECK(Var, true, _T("a_min9"), &a)
+      PARSER_THROWCHECK(Var, false, _T("a_min9"), 0)
+      // Postfix operators
+      // fail
+      PARSER_THROWCHECK(PostfixOprt, false, _T("(k"), f1of1)
+      PARSER_THROWCHECK(PostfixOprt, false, _T("9+"), f1of1)
+      PARSER_THROWCHECK(PostfixOprt, false, _T("+"), 0)
+      // pass
+      PARSER_THROWCHECK(PostfixOprt, true, _T("-a"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?a"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("_"),   f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("#"),   f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("&&"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("||"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("&"),   f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("|"),   f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("++"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("--"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?>"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?<"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("**"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("xor"), f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("and"), f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("or"),  f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("not"), f1of1)
+      PARSER_THROWCHECK(PostfixOprt, true, _T("!"),   f1of1)
+      // Binary operator
+      // The following must fail with builtin operators activated
+      // p.EnableBuiltInOp(true); -> this is the default
+      p.ClearPostfixOprt();
+      PARSER_THROWCHECK(Oprt, false, _T("+"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("-"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("*"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("/"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("^"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("&&"),  f1of2)
+      PARSER_THROWCHECK(Oprt, false, _T("||"),  f1of2)
+      // without activated built in operators it should work
+      p.EnableBuiltInOprt(false);
+      PARSER_THROWCHECK(Oprt, true, _T("+"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("-"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("*"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("/"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("^"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("&&"),  f1of2)
+      PARSER_THROWCHECK(Oprt, true, _T("||"),  f1of2)
+  #undef PARSER_THROWCHECK
+
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestSyntax()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing syntax engine...");
+
+      iStat += ThrowTest(_T("1,"), ecUNEXPECTED_EOF);  // incomplete hex definition
+      iStat += ThrowTest(_T("a,"), ecUNEXPECTED_EOF);  // incomplete hex definition
+      iStat += ThrowTest(_T("sin(8),"), ecUNEXPECTED_EOF);  // incomplete hex definition
+      iStat += ThrowTest(_T("(sin(8)),"), ecUNEXPECTED_EOF);  // incomplete hex definition
+      iStat += ThrowTest(_T("a{m},"), ecUNEXPECTED_EOF);  // incomplete hex definition
+
+      iStat += EqnTest(_T("(1+ 2*a)"), 3, true);   // Spaces within formula
+      iStat += EqnTest(_T("sqrt((4))"), 2, true);  // Multiple brackets
+      iStat += EqnTest(_T("sqrt((2)+2)"), 2, true);// Multiple brackets
+      iStat += EqnTest(_T("sqrt(2+(2))"), 2, true);// Multiple brackets
+      iStat += EqnTest(_T("sqrt(a+(3))"), 2, true);// Multiple brackets
+      iStat += EqnTest(_T("sqrt((3)+a)"), 2, true);// Multiple brackets
+      iStat += EqnTest(_T("order(1,2)"), 1, true); // May not cause name collision with operator "or"
+      iStat += EqnTest(_T("(2+"), 0, false);       // missing closing bracket 
+      iStat += EqnTest(_T("2++4"), 0, false);      // unexpected operator
+      iStat += EqnTest(_T("2+-4"), 0, false);      // unexpected operator
+      iStat += EqnTest(_T("(2+)"), 0, false);      // unexpected closing bracket
+      iStat += EqnTest(_T("--2"), 0, false);       // double sign
+      iStat += EqnTest(_T("ksdfj"), 0, false);     // unknown token
+      iStat += EqnTest(_T("()"), 0, false);        // empty bracket without a function
+      iStat += EqnTest(_T("5+()"), 0, false);      // empty bracket without a function
+      iStat += EqnTest(_T("sin(cos)"), 0, false);  // unexpected function
+      iStat += EqnTest(_T("5t6"), 0, false);       // unknown token
+      iStat += EqnTest(_T("5 t 6"), 0, false);     // unknown token
+      iStat += EqnTest(_T("8*"), 0, false);        // unexpected end of formula
+      iStat += EqnTest(_T(",3"), 0, false);        // unexpected comma
+      iStat += EqnTest(_T("3,5"), 0, false);       // unexpected comma
+      iStat += EqnTest(_T("sin(8,8)"), 0, false);  // too many function args
+      iStat += EqnTest(_T("(7,8)"), 0, false);     // too many function args
+      iStat += EqnTest(_T("sin)"), 0, false);      // unexpected closing bracket
+      iStat += EqnTest(_T("a)"), 0, false);        // unexpected closing bracket
+      iStat += EqnTest(_T("pi)"), 0, false);       // unexpected closing bracket
+      iStat += EqnTest(_T("sin(())"), 0, false);   // unexpected closing bracket
+      iStat += EqnTest(_T("sin()"), 0, false);     // unexpected closing bracket
+
+      if (iStat==0)
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestVarConst()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing variable/constant detection...");
+
+      // Test if the result changes when a variable changes
+      iStat += EqnTestWithVarChange( _T("a"), 1, 1, 2, 2 );
+      iStat += EqnTestWithVarChange( _T("2*a"), 2, 4, 3, 6 );
+
+      // distinguish constants with same basename
+      iStat += EqnTest( _T("const"), 1, true);
+      iStat += EqnTest( _T("const1"), 2, true);
+      iStat += EqnTest( _T("const2"), 3, true);
+      iStat += EqnTest( _T("2*const"), 2, true);
+      iStat += EqnTest( _T("2*const1"), 4, true);
+      iStat += EqnTest( _T("2*const2"), 6, true);
+      iStat += EqnTest( _T("2*const+1"), 3, true);
+      iStat += EqnTest( _T("2*const1+1"), 5, true);
+      iStat += EqnTest( _T("2*const2+1"), 7, true);
+      iStat += EqnTest( _T("const"), 0, false);
+      iStat += EqnTest( _T("const1"), 0, false);
+      iStat += EqnTest( _T("const2"), 0, false);
+
+      // distinguish variables with same basename
+      iStat += EqnTest( _T("a"), 1, true);
+      iStat += EqnTest( _T("aa"), 2, true);
+      iStat += EqnTest( _T("2*a"), 2, true);
+      iStat += EqnTest( _T("2*aa"), 4, true);
+      iStat += EqnTest( _T("2*a-1"), 1, true);
+      iStat += EqnTest( _T("2*aa-1"), 3, true);
+
+      // custom value recognition
+      iStat += EqnTest( _T("0xff"), 255, true);
+      iStat += EqnTest( _T("0x97 + 0xff"), 406, true);
+
+      // Finally test querying of used variables
+      try
+      {
+        int idx;
+        mu::Parser p;
+        mu::value_type vVarVal[] = { 1, 2, 3, 4, 5};
+        p.DefineVar( _T("a"), &vVarVal[0]);
+        p.DefineVar( _T("b"), &vVarVal[1]);
+        p.DefineVar( _T("c"), &vVarVal[2]);
+        p.DefineVar( _T("d"), &vVarVal[3]);
+        p.DefineVar( _T("e"), &vVarVal[4]);
+
+        // Test lookup of defined variables
+        // 4 used variables
+        p.SetExpr( _T("a+b+c+d") );
+        mu::varmap_type UsedVar = p.GetUsedVar();
+        int iCount = (int)UsedVar.size();
+        if (iCount!=4) 
+          throw false;
+        
+        // the next check will fail if the parser 
+        // erroneously creates new variables internally
+        if (p.GetVar().size()!=5)
+          throw false;
+
+        mu::varmap_type::const_iterator item = UsedVar.begin();
+        for (idx=0; item!=UsedVar.end(); ++item)
+        {
+          if (&vVarVal[idx++]!=item->second) 
+            throw false;
+        }
+
+        // Test lookup of undefined variables
+        p.SetExpr( _T("undef1+undef2+undef3") );
+        UsedVar = p.GetUsedVar();
+        iCount = (int)UsedVar.size();
+        if (iCount!=3) 
+          throw false;
+
+        // the next check will fail if the parser 
+        // erroneously creates new variables internally
+        if (p.GetVar().size()!=5)
+          throw false;
+
+        for (item = UsedVar.begin(); item!=UsedVar.end(); ++item)
+        {
+          if (item->second!=0) 
+            throw false; // all pointers to undefined variables must be null
+        }
+
+        // 1 used variables
+        p.SetExpr( _T("a+b") );
+        UsedVar = p.GetUsedVar();
+        iCount = (int)UsedVar.size();
+        if (iCount!=2) throw false;
+        item = UsedVar.begin();
+        for (idx=0; item!=UsedVar.end(); ++item)
+          if (&vVarVal[idx++]!=item->second) throw false;
+
+      }
+      catch(...)
+      {
+        iStat += 1;
+      }
+
+      if (iStat==0)  
+        mu::console() << _T("passed") << endl;
+      else
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestMultiArg()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing multiarg functions...");
+    
+      // Compound expressions
+      iStat += EqnTest( _T("1,2,3"), 3, true);
+      iStat += EqnTest( _T("a,b,c"), 3, true);
+      iStat += EqnTest( _T("a=10,b=20,c=a*b"), 200, true);
+      iStat += EqnTest( _T("1,\n2,\n3"), 3, true);
+      iStat += EqnTest( _T("a,\nb,\nc"), 3, true);
+      iStat += EqnTest( _T("a=10,\nb=20,\nc=a*b"), 200, true);
+      iStat += EqnTest( _T("1,\r\n2,\r\n3"), 3, true);
+      iStat += EqnTest( _T("a,\r\nb,\r\nc"), 3, true);
+      iStat += EqnTest( _T("a=10,\r\nb=20,\r\nc=a*b"), 200, true);
+
+      // picking the right argument
+      iStat += EqnTest( _T("f1of1(1)"), 1, true);
+      iStat += EqnTest( _T("f1of2(1, 2)"), 1, true);
+      iStat += EqnTest( _T("f2of2(1, 2)"), 2, true);
+      iStat += EqnTest( _T("f1of3(1, 2, 3)"), 1, true);
+      iStat += EqnTest( _T("f2of3(1, 2, 3)"), 2, true);
+      iStat += EqnTest( _T("f3of3(1, 2, 3)"), 3, true);
+      iStat += EqnTest( _T("f1of4(1, 2, 3, 4)"), 1, true);
+      iStat += EqnTest( _T("f2of4(1, 2, 3, 4)"), 2, true);
+      iStat += EqnTest( _T("f3of4(1, 2, 3, 4)"), 3, true);
+      iStat += EqnTest( _T("f4of4(1, 2, 3, 4)"), 4, true);
+      iStat += EqnTest( _T("f1of5(1, 2, 3, 4, 5)"), 1, true);
+      iStat += EqnTest( _T("f2of5(1, 2, 3, 4, 5)"), 2, true);
+      iStat += EqnTest( _T("f3of5(1, 2, 3, 4, 5)"), 3, true);
+      iStat += EqnTest( _T("f4of5(1, 2, 3, 4, 5)"), 4, true);
+      iStat += EqnTest( _T("f5of5(1, 2, 3, 4, 5)"), 5, true);
+      // Too few arguments / Too many arguments
+      iStat += EqnTest( _T("1+ping()"), 11, true);
+      iStat += EqnTest( _T("ping()+1"), 11, true);
+      iStat += EqnTest( _T("2*ping()"), 20, true);
+      iStat += EqnTest( _T("ping()*2"), 20, true);
+      iStat += EqnTest( _T("ping(1,2)"), 0, false);
+      iStat += EqnTest( _T("1+ping(1,2)"), 0, false);
+      iStat += EqnTest( _T("f1of1(1,2)"), 0, false);
+      iStat += EqnTest( _T("f1of1()"), 0, false);
+      iStat += EqnTest( _T("f1of2(1, 2, 3)"), 0, false);
+      iStat += EqnTest( _T("f1of2(1)"), 0, false);
+      iStat += EqnTest( _T("f1of3(1, 2, 3, 4)"), 0, false);
+      iStat += EqnTest( _T("f1of3(1)"), 0, false);
+      iStat += EqnTest( _T("f1of4(1, 2, 3, 4, 5)"), 0, false);
+      iStat += EqnTest( _T("f1of4(1)"), 0, false);
+      iStat += EqnTest( _T("(1,2,3)"), 0, false);
+      iStat += EqnTest( _T("1,2,3"), 0, false);
+      iStat += EqnTest( _T("(1*a,2,3)"), 0, false);
+      iStat += EqnTest( _T("1,2*a,3"), 0, false);
+     
+      // correct calculation of arguments
+      iStat += EqnTest( _T("min(a, 1)"),  1, true);
+      iStat += EqnTest( _T("min(3*2, 1)"),  1, true);
+      iStat += EqnTest( _T("min(3*2, 1)"),  6, false);
+      iStat += EqnTest( _T("firstArg(2,3,4)"), 2, true);
+      iStat += EqnTest( _T("lastArg(2,3,4)"), 4, true);
+      iStat += EqnTest( _T("min(3*a+1, 1)"),  1, true);
+      iStat += EqnTest( _T("max(3*a+1, 1)"),  4, true);
+      iStat += EqnTest( _T("max(3*a+1, 1)*2"),  8, true);
+      iStat += EqnTest( _T("2*max(3*a+1, 1)+2"),  10, true);
+
+      // functions with Variable argument count
+      iStat += EqnTest( _T("sum(a)"), 1, true);
+      iStat += EqnTest( _T("sum(1,2,3)"),  6, true);
+      iStat += EqnTest( _T("sum(a,b,c)"),  6, true);
+      iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"),  4, true);
+      iStat += EqnTest( _T("2*sum(1,2,3)"),  12, true);
+      iStat += EqnTest( _T("2*sum(1,2,3)+2"),  14, true);
+      iStat += EqnTest( _T("2*sum(-1,2,3)+2"),  10, true);
+      iStat += EqnTest( _T("2*sum(-1,2,-(-a))+2"),  6, true);
+      iStat += EqnTest( _T("2*sum(-1,10,-a)+2"),  18, true);
+      iStat += EqnTest( _T("2*sum(1,2,3)*2"),  24, true);
+      iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"),  4, true);
+      iStat += EqnTest( _T("sum(1*3, 4, a+2)"),  10, true);
+      iStat += EqnTest( _T("sum(1*3, 2*sum(1,2,2), a+2)"),  16, true);
+      iStat += EqnTest( _T("sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24, true);
+
+      // some failures
+      iStat += EqnTest( _T("sum()"),  0, false);
+      iStat += EqnTest( _T("sum(,)"),  0, false);
+      iStat += EqnTest( _T("sum(1,2,)"),  0, false);
+      iStat += EqnTest( _T("sum(,1,2)"),  0, false);
+
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;
+      else
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+  
+      return iStat;
+    }
+
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestInfixOprt()
+    {
+      int iStat(0);
+      mu::console() << "testing infix operators...";
+
+      iStat += EqnTest( _T("+1"),    +1, true);
+      iStat += EqnTest( _T("-(+1)"), -1, true);
+      iStat += EqnTest( _T("-(+1)*2"),  -2, true);
+      iStat += EqnTest( _T("-(+2)*sqrt(4)"),  -4, true);
+      iStat += EqnTest( _T("3-+a"), 2, true);
+      iStat += EqnTest( _T("+1*3"),  3, true);
+
+      iStat += EqnTest( _T("-1"),    -1, true);
+      iStat += EqnTest( _T("-(-1)"),  1, true);
+      iStat += EqnTest( _T("-(-1)*2"),  2, true);
+      iStat += EqnTest( _T("-(-2)*sqrt(4)"),  4, true);
+      iStat += EqnTest( _T("-_pi"), -PARSER_CONST_PI, true);
+      iStat += EqnTest( _T("-a"),  -1, true);
+      iStat += EqnTest( _T("-(a)"),  -1, true);
+      iStat += EqnTest( _T("-(-a)"),  1, true);
+      iStat += EqnTest( _T("-(-a)*2"),  2, true);
+      iStat += EqnTest( _T("-(8)"), -8, true);
+      iStat += EqnTest( _T("-8"), -8, true);
+      iStat += EqnTest( _T("-(2+1)"), -3, true);
+      iStat += EqnTest( _T("-(f1of1(1+2*3)+1*2)"), -9, true);
+      iStat += EqnTest( _T("-(-f1of1(1+2*3)+1*2)"), 5, true);
+      iStat += EqnTest( _T("-sin(8)"), -0.989358, true);
+      iStat += EqnTest( _T("3-(-a)"), 4, true);
+      iStat += EqnTest( _T("3--a"), 4, true);
+      iStat += EqnTest( _T("-1*3"),  -3, true);
+
+      // Postfix / infix priorities
+      iStat += EqnTest( _T("~2#"), 8, true);
+      iStat += EqnTest( _T("~f1of1(2)#"), 8, true);
+      iStat += EqnTest( _T("~(b)#"), 8, true);
+      iStat += EqnTest( _T("(~b)#"), 12, true);
+      iStat += EqnTest( _T("~(2#)"), 8, true);
+      iStat += EqnTest( _T("~(f1of1(2)#)"), 8, true);
+      //
+      iStat += EqnTest( _T("-2^2"),-4, true);
+      iStat += EqnTest( _T("-(a+b)^2"),-9, true);
+      iStat += EqnTest( _T("(-3)^2"),9, true);
+      iStat += EqnTest( _T("-(-2^2)"),4, true);
+      iStat += EqnTest( _T("3+-3^2"),-6, true);
+      // The following assumes use of sqr as postfix operator ("§") together
+      // with a sign operator of low priority:
+      iStat += EqnTest( _T("-2'"), -4, true);
+      iStat += EqnTest( _T("-(1+1)'"),-4, true);
+      iStat += EqnTest( _T("2+-(1+1)'"),-2, true);
+      iStat += EqnTest( _T("2+-2'"), -2, true);
+      // This is the classic behaviour of the infix sign operator (here: "$") which is
+      // now deprecated:
+      iStat += EqnTest( _T("$2^2"),4, true);
+      iStat += EqnTest( _T("$(a+b)^2"),9, true);
+      iStat += EqnTest( _T("($3)^2"),9, true);
+      iStat += EqnTest( _T("$($2^2)"),-4, true);
+      iStat += EqnTest( _T("3+$3^2"),12, true);
+
+      // infix operators sharing the first few characters
+      iStat += EqnTest( _T("~ 123"),  123+2, true);
+      iStat += EqnTest( _T("~~ 123"),  123+2, true);
+
+      if (iStat==0)
+        mu::console() << _T("passed") << endl;
+      else
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestPostFix()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing postfix operators...");
+
+      // application
+      iStat += EqnTest( _T("3{m}+5"), 5.003, true);
+      iStat += EqnTest( _T("1000{m}"), 1, true);
+      iStat += EqnTest( _T("1000 {m}"), 1, true);
+      iStat += EqnTest( _T("(a){m}"), 1e-3, true);
+      iStat += EqnTest( _T("a{m}"), 1e-3, true);
+      iStat += EqnTest( _T("a {m}"), 1e-3, true);
+      iStat += EqnTest( _T("-(a){m}"), -1e-3, true);
+      iStat += EqnTest( _T("-2{m}"), -2e-3, true);
+      iStat += EqnTest( _T("-2 {m}"), -2e-3, true);
+      iStat += EqnTest( _T("f1of1(1000){m}"), 1, true);
+      iStat += EqnTest( _T("-f1of1(1000){m}"), -1, true);
+      iStat += EqnTest( _T("-f1of1(-1000){m}"), 1, true);
+      iStat += EqnTest( _T("f4of4(0,0,0,1000){m}"), 1, true);
+      iStat += EqnTest( _T("2+(a*1000){m}"), 3, true);
+
+      // can postfix operators "m" und "meg" be told apart properly?
+      iStat += EqnTest( _T("2*3000meg+2"), 2*3e9+2, true);   
+
+      // some incorrect results
+      iStat += EqnTest( _T("1000{m}"), 0.1, false);
+      iStat += EqnTest( _T("(a){m}"), 2, false);
+      // failure due to syntax checking
+      iStat += ThrowTest(_T("0x"), ecUNASSIGNABLE_TOKEN);  // incomplete hex definition
+      iStat += ThrowTest(_T("3+"), ecUNEXPECTED_EOF);
+      iStat += ThrowTest( _T("4 + {m}"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("{m}4"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("sin({m})"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("{m} {m}"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("{m}(8)"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("4,{m}"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("-{m}"), ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest( _T("2(-{m})"), ecUNEXPECTED_PARENS);
+      iStat += ThrowTest( _T("2({m})"), ecUNEXPECTED_PARENS);
+ 
+      iStat += ThrowTest( _T("multi*1.0"), ecUNASSIGNABLE_TOKEN);
+
+      if (iStat==0)
+        mu::console() << _T("passed") << endl;
+      else
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestExpression()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing expression samples...");
+
+      value_type b = 2;
+
+      // Optimization
+      iStat += EqnTest( _T("2*b*5"), 20, true);
+      iStat += EqnTest( _T("2*b*5 + 4*b"), 28, true);
+      iStat += EqnTest( _T("2*a/3"), 2.0/3.0, true);
+
+      // Addition auf cmVARMUL 
+      iStat += EqnTest( _T("3+b"), b+3, true);
+      iStat += EqnTest( _T("b+3"), b+3, true);
+      iStat += EqnTest( _T("b*3+2"), b*3+2, true);
+      iStat += EqnTest( _T("3*b+2"), b*3+2, true);
+      iStat += EqnTest( _T("2+b*3"), b*3+2, true);
+      iStat += EqnTest( _T("2+3*b"), b*3+2, true);
+      iStat += EqnTest( _T("b+3*b"), b+3*b, true);
+      iStat += EqnTest( _T("3*b+b"), b+3*b, true);
+
+      iStat += EqnTest( _T("2+b*3+b"), 2+b*3+b, true);
+      iStat += EqnTest( _T("b+2+b*3"), b+2+b*3, true);
+
+      iStat += EqnTest( _T("(2*b+1)*4"), (2*b+1)*4, true);
+      iStat += EqnTest( _T("4*(2*b+1)"), (2*b+1)*4, true);
+
+      // operator precedences
+      iStat += EqnTest( _T("1+2-3*4/5^6"), 2.99923, true);
+      iStat += EqnTest( _T("1^2/3*4-5+6"), 2.33333333, true);
+      iStat += EqnTest( _T("1+2*3"), 7, true);
+      iStat += EqnTest( _T("1+2*3"), 7, true);
+      iStat += EqnTest( _T("(1+2)*3"), 9, true);
+      iStat += EqnTest( _T("(1+2)*(-3)"), -9, true);
+      iStat += EqnTest( _T("2/4"), 0.5, true);
+
+      iStat += EqnTest( _T("exp(ln(7))"), 7, true);
+      iStat += EqnTest( _T("e^ln(7)"), 7, true);
+      iStat += EqnTest( _T("e^(ln(7))"), 7, true);
+      iStat += EqnTest( _T("(e^(ln(7)))"), 7, true);
+      iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true);
+      iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true);
+      iStat += EqnTest( _T("10^log(5)"), pow(10.0, log(5.0)), true);
+      iStat += EqnTest( _T("10^log10(5)"), 5, true);
+      iStat += EqnTest( _T("2^log2(4)"), 4, true);
+      iStat += EqnTest( _T("-(sin(0)+1)"), -1, true);
+      iStat += EqnTest( _T("-(2^1.1)"), -2.14354692, true);
+
+      iStat += EqnTest( _T("(cos(2.41)/b)"), -0.372056, true);
+      iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160, true);
+      iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120, true);
+      iStat += EqnTest( _T("(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"), 0.00377999, true);
+
+      // long formula (Reference: Matlab)
+      iStat += EqnTest(
+        _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))")
+        _T("/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/")
+        _T("((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-")
+        _T("e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6")
+        _T("+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e")
+        _T("*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549, true);
+
+      // long formula (Reference: Matlab)
+      iStat += EqnTest(
+          _T("(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e")
+          _T(")+a)))*2.77)"), -2.16995656, true);
+
+      // long formula (Reference: Matlab)
+      iStat += EqnTest( _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926, true);
+	  
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;  
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestIfThenElse()
+    {
+      int iStat = 0;
+      mu::console() << _T("testing if-then-else operator...");
+
+      // Test error detection
+      iStat += ThrowTest(_T(":3"), ecUNEXPECTED_CONDITIONAL); 
+      iStat += ThrowTest(_T("? 1 : 2"), ecUNEXPECTED_CONDITIONAL); 
+      iStat += ThrowTest(_T("(a<b) ? (b<c) ? 1 : 2"), ecMISSING_ELSE_CLAUSE); 
+      iStat += ThrowTest(_T("(a<b) ? 1"), ecMISSING_ELSE_CLAUSE); 
+      iStat += ThrowTest(_T("(a<b) ? a"), ecMISSING_ELSE_CLAUSE); 
+      iStat += ThrowTest(_T("(a<b) ? a+b"), ecMISSING_ELSE_CLAUSE); 
+      iStat += ThrowTest(_T("a : b"), ecMISPLACED_COLON); 
+      iStat += ThrowTest(_T("1 : 2"), ecMISPLACED_COLON); 
+      iStat += ThrowTest(_T("(1) ? 1 : 2 : 3"), ecMISPLACED_COLON); 
+      iStat += ThrowTest(_T("(true) ? 1 : 2 : 3"), ecUNASSIGNABLE_TOKEN); 
+
+      iStat += EqnTest(_T("1 ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("1<2 ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("a<b ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("(a<b) ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("(1) ? 10 : 11"), 10, true);
+      iStat += EqnTest(_T("(0) ? 10 : 11"), 11, true);
+      iStat += EqnTest(_T("(1) ? a+b : c+d"), 3, true);
+      iStat += EqnTest(_T("(0) ? a+b : c+d"), 1, true);
+      iStat += EqnTest(_T("(1) ? 0 : 1"), 0, true);
+      iStat += EqnTest(_T("(0) ? 0 : 1"), 1, true);
+      iStat += EqnTest(_T("(a<b) ? 10 : 11"), 10, true);
+      iStat += EqnTest(_T("(a>b) ? 10 : 11"), 11, true);
+      iStat += EqnTest(_T("(a<b) ? c : d"), 3, true);
+      iStat += EqnTest(_T("(a>b) ? c : d"), -2, true);
+
+      iStat += EqnTest(_T("(a>b) ? 1 : 0"), 0, true);
+      iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : 2"), 2, true);
+      iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2, true);
+      iStat += EqnTest(_T("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1, true);
+
+      iStat += EqnTest(_T("sum((a>b) ? 1 : 2)"), 2, true);
+      iStat += EqnTest(_T("sum((1) ? 1 : 2)"), 1, true);
+      iStat += EqnTest(_T("sum((a>b) ? 1 : 2, 100)"), 102, true);
+      iStat += EqnTest(_T("sum((1) ? 1 : 2, 100)"), 101, true);
+      iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)"), 13, true);
+      iStat += EqnTest(_T("sum(3, (a<b) ? 3 : 10)"), 6, true);
+      iStat += EqnTest(_T("10*sum(3, (a>b) ? 3 : 10)"), 130, true);
+      iStat += EqnTest(_T("10*sum(3, (a<b) ? 3 : 10)"), 60, true);
+      iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)*10"), 130, true);
+      iStat += EqnTest(_T("sum(3, (a<b) ? 3 : 10)*10"), 60, true);
+      iStat += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 60, true);
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 99, true);
+      iStat += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 360, true);
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 99, true);
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : sum(3, (a<b) ? 3 : 10)*10"), 60, true);
+
+      // todo: auch für muParserX hinzufügen!
+      iStat += EqnTest(_T("(a<b)&&(a<b) ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("(a>b)&&(a<b) ? 128 : 255"), 255, true);
+      iStat += EqnTest(_T("(1<2)&&(1<2) ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("(1>2)&&(1<2) ? 128 : 255"), 255, true);
+      iStat += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true);
+      iStat += EqnTest(_T("((a<b)&&(a<b)) ? 128 : 255"), 128, true);
+      iStat += EqnTest(_T("((a>b)&&(a<b)) ? 128 : 255"), 255, true);
+
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255, true);
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255, true);
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128, true);
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128, true);
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32, true);
+      iStat += EqnTest(_T("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64, true);
+      iStat += EqnTest(_T("1>0 ? 50 :  1>0 ? 128 : 255"), 50, true);
+      iStat += EqnTest(_T("1>0 ? 50 : (1>0 ? 128 : 255)"), 50, true);
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 50"), 128, true);
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32, true);
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32, true);
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :  1>0 ? 32 :1>2 ? 64 : 16"), 255, true);
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255, true);
+      iStat += EqnTest(_T("1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255, true);
+
+      // assignment operators
+      iStat += EqnTest(_T("a= 0 ? 128 : 255, a"), 255, true);
+      iStat += EqnTest(_T("a=((a>b)&&(a<b)) ? 128 : 255, a"), 255, true);
+      iStat += EqnTest(_T("c=(a<b)&&(a<b) ? 128 : 255, c"), 128, true);
+      iStat += EqnTest(_T("0 ? a=a+1 : 666, a"), 1, true);
+      iStat += EqnTest(_T("1?a=10:a=20, a"), 10, true);
+      iStat += EqnTest(_T("0?a=10:a=20, a"), 20, true);
+      iStat += EqnTest(_T("0?a=sum(3,4):10, a"), 1, true);  // a should not change its value due to lazy calculation
+      
+      iStat += EqnTest(_T("a=1?b=1?3:4:5, a"), 3, true);
+      iStat += EqnTest(_T("a=1?b=1?3:4:5, b"), 3, true);
+      iStat += EqnTest(_T("a=0?b=1?3:4:5, a"), 5, true);
+      iStat += EqnTest(_T("a=0?b=1?3:4:5, b"), 2, true);
+
+      iStat += EqnTest(_T("a=1?5:b=1?3:4, a"), 5, true);
+      iStat += EqnTest(_T("a=1?5:b=1?3:4, b"), 2, true);
+      iStat += EqnTest(_T("a=0?5:b=1?3:4, a"), 3, true);
+      iStat += EqnTest(_T("a=0?5:b=1?3:4, b"), 3, true);
+
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;  
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::TestException()
+    {
+      int  iStat = 0;
+      mu::console() << _T("testing error codes...");
+
+      iStat += ThrowTest(_T("3+"),           ecUNEXPECTED_EOF);
+      iStat += ThrowTest(_T("3+)"),          ecUNEXPECTED_PARENS);
+      iStat += ThrowTest(_T("()"),           ecUNEXPECTED_PARENS);
+      iStat += ThrowTest(_T("3+()"),         ecUNEXPECTED_PARENS);
+      iStat += ThrowTest(_T("sin(3,4)"),     ecTOO_MANY_PARAMS);
+      iStat += ThrowTest(_T("sin()"),        ecTOO_FEW_PARAMS);
+      iStat += ThrowTest(_T("(1+2"),         ecMISSING_PARENS);
+      iStat += ThrowTest(_T("sin(3)3"),      ecUNEXPECTED_VAL);
+      iStat += ThrowTest(_T("sin(3)xyz"),    ecUNASSIGNABLE_TOKEN);
+      iStat += ThrowTest(_T("sin(3)cos(3)"), ecUNEXPECTED_FUN);
+      iStat += ThrowTest(_T("a+b+c=10"),     ecUNEXPECTED_OPERATOR);
+      iStat += ThrowTest(_T("a=b=3"),        ecUNEXPECTED_OPERATOR);
+      
+#if defined(MUP_MATH_EXCEPTIONS)
+      // divide by zero whilst constant folding
+      iStat += ThrowTest(_T("1/0"),          ecDIV_BY_ZERO);
+      // square root of a negative number
+      iStat += ThrowTest(_T("sqrt(-1)"),     ecDOMAIN_ERROR);
+      // logarithms of zero
+      iStat += ThrowTest(_T("ln(0)"),        ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log2(0)"),      ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log10(0)"),     ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log(0)"),       ecDOMAIN_ERROR);
+      // logarithms of negative values
+      iStat += ThrowTest(_T("ln(-1)"),       ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log2(-1)"),     ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log10(-1)"),    ecDOMAIN_ERROR);
+      iStat += ThrowTest(_T("log(-1)"),      ecDOMAIN_ERROR);
+#endif
+
+      // functions without parameter
+      iStat += ThrowTest( _T("3+ping(2)"),    ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("3+ping(a+2)"),  ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("3+ping(sin(a)+2)"),  ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("3+ping(1+sin(a))"),  ecTOO_MANY_PARAMS);
+
+      // String function related
+      iStat += ThrowTest( _T("valueof(\"xxx\")"),  999, false);
+      iStat += ThrowTest( _T("valueof()"),          ecUNEXPECTED_PARENS);
+      iStat += ThrowTest( _T("1+valueof(\"abc\""),  ecMISSING_PARENS);
+      iStat += ThrowTest( _T("valueof(\"abc\""),    ecMISSING_PARENS);
+      iStat += ThrowTest( _T("valueof(\"abc"),      ecUNTERMINATED_STRING);
+      iStat += ThrowTest( _T("valueof(\"abc\",3)"), ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("valueof(3)"),         ecSTRING_EXPECTED);
+      iStat += ThrowTest( _T("sin(\"abc\")"),       ecVAL_EXPECTED);
+      iStat += ThrowTest( _T("valueof(\"\\\"abc\\\"\")"),  999, false);
+      iStat += ThrowTest( _T("\"hello world\""),    ecSTR_RESULT);
+      iStat += ThrowTest( _T("(\"hello world\")"),  ecSTR_RESULT);
+      iStat += ThrowTest( _T("\"abcd\"+100"),       ecOPRT_TYPE_CONFLICT);
+      iStat += ThrowTest( _T("\"a\"+\"b\""),        ecOPRT_TYPE_CONFLICT);
+      iStat += ThrowTest( _T("strfun1(\"100\",3)"),     ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("strfun2(\"100\",3,5)"),   ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("strfun3(\"100\",3,5,6)"), ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("strfun2(\"100\")"),       ecTOO_FEW_PARAMS);
+      iStat += ThrowTest( _T("strfun3(\"100\",6)"),   ecTOO_FEW_PARAMS);
+      iStat += ThrowTest( _T("strfun2(1,1)"),         ecSTRING_EXPECTED);
+      iStat += ThrowTest( _T("strfun2(a,1)"),         ecSTRING_EXPECTED);
+      iStat += ThrowTest( _T("strfun2(1,1,1)"),       ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("strfun2(a,1,1)"),       ecTOO_MANY_PARAMS);
+      iStat += ThrowTest( _T("strfun3(1,2,3)"),         ecSTRING_EXPECTED);
+      iStat += ThrowTest( _T("strfun3(1, \"100\",3)"),  ecSTRING_EXPECTED);
+      iStat += ThrowTest( _T("strfun3(\"1\", \"100\",3)"),  ecVAL_EXPECTED);
+      iStat += ThrowTest( _T("strfun3(\"1\", 3, \"100\")"),  ecVAL_EXPECTED);
+      iStat += ThrowTest( _T("strfun3(\"1\", \"100\", \"100\", \"100\")"),  ecTOO_MANY_PARAMS);
+
+      // assignment operator
+      iStat += ThrowTest( _T("3=4"), ecUNEXPECTED_OPERATOR);
+      iStat += ThrowTest( _T("sin(8)=4"), ecUNEXPECTED_OPERATOR);
+      iStat += ThrowTest( _T("\"test\"=a"), ecUNEXPECTED_OPERATOR);
+
+      // <ibg 20090529>
+      // this is now legal, for reference see:
+      // https://sourceforge.net/forum/message.php?msg_id=7411373
+      //      iStat += ThrowTest( _T("sin=9"), ecUNEXPECTED_OPERATOR);    
+      // </ibg>
+
+      iStat += ThrowTest( _T("(8)=5"), ecUNEXPECTED_OPERATOR);
+      iStat += ThrowTest( _T("(a)=5"), ecUNEXPECTED_OPERATOR);
+      iStat += ThrowTest( _T("a=\"tttt\""), ecOPRT_TYPE_CONFLICT);
+
+      if (iStat==0) 
+        mu::console() << _T("passed") << endl;
+      else 
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;
+
+      return iStat;
+    }
+
+
+    //---------------------------------------------------------------------------
+    void ParserTester::AddTest(testfun_type a_pFun)
+    {
+      m_vTestFun.push_back(a_pFun);
+    }
+
+    //---------------------------------------------------------------------------
+    void ParserTester::Run()
+    {
+      int iStat = 0;
+      try
+      {
+        for (int i=0; i<(int)m_vTestFun.size(); ++i)
+          iStat += (this->*m_vTestFun[i])();
+      }
+      catch(Parser::exception_type &e)
+      {
+        mu::console() << "\n" << e.GetMsg() << endl;
+        mu::console() << e.GetToken() << endl;
+        Abort();
+      }
+      catch(std::exception &e)
+      {
+        mu::console() << e.what() << endl;
+        Abort();
+      }
+      catch(...)
+      {
+        mu::console() << "Internal error";
+        Abort();
+      }
+
+      if (iStat==0) 
+      {
+        mu::console() << "Test passed (" <<  ParserTester::c_iCount << " expressions)" << endl;
+      }
+      else 
+      {
+        mu::console() << "Test failed with " << iStat 
+                  << " errors (" <<  ParserTester::c_iCount 
+                  << " expressions)" << endl;
+      }
+      ParserTester::c_iCount = 0;
+    }
+
+
+    //---------------------------------------------------------------------------
+    int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)
+    {
+      ParserTester::c_iCount++;
+
+      try
+      {
+        value_type fVal[] = {1,1,1};
+        Parser p;
+
+        p.DefineVar( _T("a"), &fVal[0]);
+        p.DefineVar( _T("b"), &fVal[1]);
+        p.DefineVar( _T("c"), &fVal[2]);
+        p.DefinePostfixOprt( _T("{m}"), Milli);
+        p.DefinePostfixOprt( _T("m"), Milli);
+        p.DefineFun( _T("ping"), Ping);
+        p.DefineFun( _T("valueof"), ValueOf);
+        p.DefineFun( _T("strfun1"), StrFun1);
+        p.DefineFun( _T("strfun2"), StrFun2);
+        p.DefineFun( _T("strfun3"), StrFun3);
+        p.SetExpr(a_str);
+        p.Eval();
+      }
+      catch(ParserError &e)
+      {
+        // output the formula in case of an failed test
+        if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) )
+        {
+          mu::console() << _T("\n  ") 
+                        << _T("Expression: ") << a_str 
+                        << _T("  Code:") << e.GetCode() << _T("(") << e.GetMsg() << _T(")")
+                        << _T("  Expected:") << a_iErrc;
+        }
+
+        return (a_iErrc==e.GetCode()) ? 0 : 1;
+      }
+
+      // if a_bFail==false no exception is expected
+      bool bRet((a_bFail==false) ? 0 : 1);
+      if (bRet==1)
+      {
+        mu::console() << _T("\n  ") 
+                      << _T("Expression: ") << a_str 
+                      << _T("  did evaluate; Expected error:") << a_iErrc;
+      }
+
+      return bRet; 
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Evaluate a tet expression. 
+
+        \return 1 in case of a failure, 0 otherwise.
+    */
+    int ParserTester::EqnTestWithVarChange(const string_type &a_str, 
+                                           double a_fVar1, 
+                                           double a_fRes1, 
+                                           double a_fVar2, 
+                                           double a_fRes2)
+    {
+      ParserTester::c_iCount++;
+
+      try
+      {
+        value_type fVal[2] = {-999, -999 }; // should be equal
+	  
+        Parser  p;
+        value_type var = 0;
+
+        // variable
+        p.DefineVar( _T("a"), &var);
+        p.SetExpr(a_str);
+
+        var = a_fVar1;
+        fVal[0] = p.Eval();
+
+        var = a_fVar2;
+        fVal[1] = p.Eval();
+        
+        if ( fabs(a_fRes1-fVal[0]) > 0.0000000001)
+          throw std::runtime_error("incorrect result (first pass)");
+
+        if ( fabs(a_fRes2-fVal[1]) > 0.0000000001)
+          throw std::runtime_error("incorrect result (second pass)");
+      }
+      catch(Parser::exception_type &e)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");
+        return 1;
+      }
+      catch(std::exception &e)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")");
+        return 1;  // always return a failure since this exception is not expected
+      }
+      catch(...)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");
+        return 1;  // exceptions other than ParserException are not allowed
+      }
+
+      return 0;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Evaluate a tet expression. 
+
+        \return 1 in case of a failure, 0 otherwise.
+    */
+    int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
+    {
+      ParserTester::c_iCount++;
+      int iRet(0);
+      value_type fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different
+
+      try
+      {
+        std::auto_ptr<Parser> p1;
+        Parser  p2, p3;   // three parser objects
+                          // they will be used for testing copy and assignment operators
+        // p1 is a pointer since i'm going to delete it in order to test if
+        // parsers after copy construction still refer to members of it.
+        // !! If this is the case this function will crash !!
+      
+        p1.reset(new mu::Parser()); 
+        // Add constants
+        p1->DefineConst( _T("pi"), (value_type)PARSER_CONST_PI);
+        p1->DefineConst( _T("e"), (value_type)PARSER_CONST_E);
+        p1->DefineConst( _T("const"), 1);
+        p1->DefineConst( _T("const1"), 2);
+        p1->DefineConst( _T("const2"), 3);
+        // string constants
+        p1->DefineStrConst( _T("str1"), _T("1.11"));
+        p1->DefineStrConst( _T("str2"), _T("2.22"));
+        // variables
+        value_type vVarVal[] = { 1, 2, 3, -2};
+        p1->DefineVar( _T("a"), &vVarVal[0]);
+        p1->DefineVar( _T("aa"), &vVarVal[1]);
+        p1->DefineVar( _T("b"), &vVarVal[1]);
+        p1->DefineVar( _T("c"), &vVarVal[2]);
+        p1->DefineVar( _T("d"), &vVarVal[3]);
+        
+        // custom value ident functions
+        p1->AddValIdent(&ParserTester::IsHexVal);        
+
+        // functions
+        p1->DefineFun( _T("ping"), Ping);
+        p1->DefineFun( _T("f1of1"), f1of1);  // one parameter
+        p1->DefineFun( _T("f1of2"), f1of2);  // two parameter
+        p1->DefineFun( _T("f2of2"), f2of2);
+        p1->DefineFun( _T("f1of3"), f1of3);  // three parameter
+        p1->DefineFun( _T("f2of3"), f2of3);
+        p1->DefineFun( _T("f3of3"), f3of3);
+        p1->DefineFun( _T("f1of4"), f1of4);  // four parameter
+        p1->DefineFun( _T("f2of4"), f2of4);
+        p1->DefineFun( _T("f3of4"), f3of4);
+        p1->DefineFun( _T("f4of4"), f4of4);
+        p1->DefineFun( _T("f1of5"), f1of5);  // five parameter
+        p1->DefineFun( _T("f2of5"), f2of5);
+        p1->DefineFun( _T("f3of5"), f3of5);
+        p1->DefineFun( _T("f4of5"), f4of5);
+        p1->DefineFun( _T("f5of5"), f5of5);
+
+        // binary operators
+        p1->DefineOprt( _T("add"), add, 0);
+        p1->DefineOprt( _T("++"), add, 0);
+        p1->DefineOprt( _T("&"), land, prLAND);
+
+        // sample functions
+        p1->DefineFun( _T("min"), Min);
+        p1->DefineFun( _T("max"), Max);
+        p1->DefineFun( _T("sum"), Sum);
+        p1->DefineFun( _T("valueof"), ValueOf);
+        p1->DefineFun( _T("atof"), StrToFloat);
+        p1->DefineFun( _T("strfun1"), StrFun1);
+        p1->DefineFun( _T("strfun2"), StrFun2);
+        p1->DefineFun( _T("strfun3"), StrFun3);
+        p1->DefineFun( _T("lastArg"), LastArg);
+        p1->DefineFun( _T("firstArg"), FirstArg);
+        p1->DefineFun( _T("order"), FirstArg);
+
+        // infix / postfix operator
+        // Note: Identifiers used here do not have any meaning 
+        //       they are mere placeholders to test certain features.
+        p1->DefineInfixOprt( _T("$"), sign, prPOW+1);  // sign with high priority
+        p1->DefineInfixOprt( _T("~"), plus2);          // high priority
+        p1->DefineInfixOprt( _T("~~"), plus2);
+        p1->DefinePostfixOprt( _T("{m}"), Milli);
+        p1->DefinePostfixOprt( _T("{M}"), Mega);
+        p1->DefinePostfixOprt( _T("m"), Milli);
+        p1->DefinePostfixOprt( _T("meg"), Mega);
+        p1->DefinePostfixOprt( _T("#"), times3);
+        p1->DefinePostfixOprt( _T("'"), sqr); 
+        p1->SetExpr(a_str);
+
+        // Test bytecode integrity
+        // String parsing and bytecode parsing must yield the same result
+        fVal[0] = p1->Eval(); // result from stringparsing
+        fVal[1] = p1->Eval(); // result from bytecode
+        if (fVal[0]!=fVal[1])
+          throw Parser::exception_type( _T("Bytecode / string parsing mismatch.") );
+
+        // Test copy and assignment operators
+        try
+        {
+          // Test copy constructor
+          std::vector<mu::Parser> vParser;
+          vParser.push_back(*(p1.get()));
+          mu::Parser p2 = vParser[0];   // take parser from vector
+        
+          // destroy the originals from p2
+          vParser.clear();              // delete the vector
+          p1.reset(0);
+
+          fVal[2] = p2.Eval();
+
+          // Test assignment operator
+          // additionally  disable Optimizer this time
+          mu::Parser p3;
+          p3 = p2;
+          p3.EnableOptimizer(false);
+          fVal[3] = p3.Eval();
+
+          // Test Eval function for multiple return values
+          // use p2 since it has the optimizer enabled!
+          int nNum;
+          value_type *v = p2.Eval(nNum);
+          fVal[4] = v[nNum-1];
+        }
+        catch(std::exception &e)
+        {
+          mu::console() << _T("\n  ") << e.what() << _T("\n");
+        }
+
+        // limited floating point accuracy requires the following test
+        bool bCloseEnough(true);
+        for (unsigned i=0; i<sizeof(fVal)/sizeof(value_type); ++i)
+        {
+          bCloseEnough &= (fabs(a_fRes-fVal[i]) <= fabs(fVal[i]*0.00001));
+
+          // The tests equations never result in infinity, if they do thats a bug.
+          // reference:
+          // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825
+          #pragma warning(push)
+          #pragma warning(disable:4127)
+		  if (std::numeric_limits<value_type>::has_infinity)
+          #pragma warning(pop)
+		  {
+            bCloseEnough &= (fabs(fVal[i]) != numeric_limits<value_type>::infinity());
+		  }
+		}
+
+        iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
+        
+        
+        if (iRet==1)
+        {
+          mu::console() << _T("\n  fail: ") << a_str.c_str() 
+                        << _T(" (incorrect result; expected: ") << a_fRes
+                        << _T(" ;calculated: ") << fVal[0] << _T(",") 
+                                                << fVal[1] << _T(",")
+                                                << fVal[2] << _T(",")
+                                                << fVal[3] << _T(",")
+                                                << fVal[4] << _T(").");
+        }
+      }
+      catch(Parser::exception_type &e)
+      {
+        if (a_fPass)
+        {
+          if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)
+            mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (copy construction)");
+          else
+            mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");
+          return 1;
+        }
+      }
+      catch(std::exception &e)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")");
+        return 1;  // always return a failure since this exception is not expected
+      }
+      catch(...)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");
+        return 1;  // exceptions other than ParserException are not allowed
+      }
+
+      return iRet;
+    }
+
+    //---------------------------------------------------------------------------
+    int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPass)
+    {
+      ParserTester::c_iCount++;
+
+      value_type vVarVal[] = {1, 2, 3};   // variable values
+      int iRet(0);
+
+      try
+      {
+        value_type fVal[2] = {-99, -999};   // results: initially should be different
+        ParserInt p;
+        p.DefineConst( _T("const1"), 1);
+        p.DefineConst( _T("const2"), 2);
+        p.DefineVar( _T("a"), &vVarVal[0]);
+        p.DefineVar( _T("b"), &vVarVal[1]);
+        p.DefineVar( _T("c"), &vVarVal[2]);
+
+        p.SetExpr(a_str);
+        fVal[0] = p.Eval(); // result from stringparsing
+        fVal[1] = p.Eval(); // result from bytecode
+
+        if (fVal[0]!=fVal[1])
+          throw Parser::exception_type( _T("Bytecode corrupt.") );
+
+        iRet =  ( (a_fRes==fVal[0] &&  a_fPass) || 
+                  (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;
+        if (iRet==1)
+        {
+          mu::console() << _T("\n  fail: ") << a_str.c_str() 
+                        << _T(" (incorrect result; expected: ") << a_fRes 
+                        << _T(" ;calculated: ") << fVal[0]<< _T(").");
+        }
+      }
+      catch(Parser::exception_type &e)
+      {
+        if (a_fPass)
+        {
+          mu::console() << _T("\n  fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg();
+          iRet = 1;
+        }
+      }
+      catch(...)
+      {
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");
+        iRet = 1;  // exceptions other than ParserException are not allowed
+      }
+
+      return iRet;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Test an expression in Bulk Mode. */
+    int ParserTester::EqnTestBulk(const string_type &a_str, double a_fRes[4], bool a_fPass)
+    {
+        ParserTester::c_iCount++;
+
+        // Define Bulk Variables
+        int nBulkSize = 4;
+        value_type vVariableA[] = { 1, 2, 3, 4 };   // variable values
+        value_type vVariableB[] = { 2, 2, 2, 2 };   // variable values
+        value_type vVariableC[] = { 3, 3, 3, 3 };   // variable values
+        value_type vResults[] = { 0, 0, 0, 0 };   // variable values
+        int iRet(0);
+
+        try
+        {
+            Parser p;
+            p.DefineConst(_T("const1"), 1);
+            p.DefineConst(_T("const2"), 2);
+            p.DefineVar(_T("a"), vVariableA);
+            p.DefineVar(_T("b"), vVariableB);
+            p.DefineVar(_T("c"), vVariableC);
+
+            p.SetExpr(a_str);
+            p.Eval(vResults, nBulkSize);
+
+            bool bCloseEnough(true);
+            for (int i = 0; i < nBulkSize; ++i)
+            {
+                bCloseEnough &= (fabs(a_fRes[i] - vResults[i]) <= fabs(a_fRes[i] * 0.00001));
+            }
+
+            iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
+            if (iRet == 1)
+            {
+                mu::console() << _T("\n  fail: ") << a_str.c_str()
+                    << _T(" (incorrect result; expected: {") << a_fRes[0] << _T(",") << a_fRes[1] << _T(",") << a_fRes[2] << _T(",") << a_fRes[3] << _T("}")
+                    << _T(" ;calculated: ") << vResults[0] << _T(",") << vResults[1] << _T(",") << vResults[2] << _T(",") << vResults[3] << _T("}");
+            }
+        }
+        catch (Parser::exception_type &e)
+        {
+            if (a_fPass)
+            {
+                mu::console() << _T("\n  fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg();
+                iRet = 1;
+            }
+        }
+        catch (...)
+        {
+            mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (unexpected exception)");
+            iRet = 1;  // exceptions other than ParserException are not allowed
+        }
+
+        return iRet;
+    }
+
+    //---------------------------------------------------------------------------
+    /** \brief Internal error in test class Test is going to be aborted. */
+    void ParserTester::Abort() const
+    {
+      mu::console() << _T("Test failed (internal error in test class)") << endl;
+      while (!getchar());
+      exit(-1);
+    }
+  } // namespace test
+} // namespace mu
diff --git a/ThirdParty/MuParser/src/muParserTokenReader.cpp b/ThirdParty/MuParser/src/muParserTokenReader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..de15ff043e6f0ea9133d404fd2375512785a7b8a
--- /dev/null
+++ b/ThirdParty/MuParser/src/muParserTokenReader.cpp
@@ -0,0 +1,958 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2013 Ingo Berg
+
+  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. 
+*/
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <map>
+#include <stack>
+#include <string>
+
+#include "muParserTokenReader.h"
+#include "muParserBase.h"
+
+/** \file
+    \brief This file contains the parser token reader implementation.
+*/
+
+
+namespace mu
+{
+
+  // Forward declaration
+  class ParserBase;
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor.
+
+      \sa Assign
+      \throw nothrow
+  */
+  ParserTokenReader::ParserTokenReader(const ParserTokenReader &a_Reader) 
+  { 
+    Assign(a_Reader);
+  }
+    
+  //---------------------------------------------------------------------------
+  /** \brief Assignment operator.
+
+      Self assignment will be suppressed otherwise #Assign is called.
+
+      \param a_Reader Object to copy to this token reader.
+      \throw nothrow
+  */
+  ParserTokenReader& ParserTokenReader::operator=(const ParserTokenReader &a_Reader) 
+  {
+    if (&a_Reader!=this)
+      Assign(a_Reader);
+
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assign state of a token reader to this token reader. 
+      
+      \param a_Reader Object from which the state should be copied.
+      \throw nothrow
+  */
+  void ParserTokenReader::Assign(const ParserTokenReader &a_Reader)
+  {
+    m_pParser = a_Reader.m_pParser;
+    m_strFormula = a_Reader.m_strFormula;
+    m_iPos = a_Reader.m_iPos;
+    m_iSynFlags = a_Reader.m_iSynFlags;
+    
+    m_UsedVar         = a_Reader.m_UsedVar;
+    m_pFunDef         = a_Reader.m_pFunDef;
+    m_pConstDef       = a_Reader.m_pConstDef;
+    m_pVarDef         = a_Reader.m_pVarDef;
+    m_pStrVarDef      = a_Reader.m_pStrVarDef;
+    m_pPostOprtDef    = a_Reader.m_pPostOprtDef;
+    m_pInfixOprtDef   = a_Reader.m_pInfixOprtDef;
+    m_pOprtDef        = a_Reader.m_pOprtDef;
+    m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar;
+    m_vIdentFun       = a_Reader.m_vIdentFun;
+    m_pFactory        = a_Reader.m_pFactory;
+    m_pFactoryData    = a_Reader.m_pFactoryData;
+    m_iBrackets       = a_Reader.m_iBrackets;
+    m_cArgSep         = a_Reader.m_cArgSep;
+	m_fZero           = a_Reader.m_fZero;
+	m_lastTok         = a_Reader.m_lastTok;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Constructor. 
+      
+      Create a Token reader and bind it to a parser object. 
+
+      \pre [assert] a_pParser may not be NULL
+      \post #m_pParser==a_pParser
+      \param a_pParent Parent parser object of the token reader.
+  */
+  ParserTokenReader::ParserTokenReader(ParserBase *a_pParent)
+    :m_pParser(a_pParent)
+    ,m_strFormula()
+    ,m_iPos(0)
+    ,m_iSynFlags(0)
+    ,m_bIgnoreUndefVar(false)
+    ,m_pFunDef(NULL)
+    ,m_pPostOprtDef(NULL)
+    ,m_pInfixOprtDef(NULL)
+    ,m_pOprtDef(NULL)
+    ,m_pConstDef(NULL)
+    ,m_pStrVarDef(NULL)
+    ,m_pVarDef(NULL)
+    ,m_pFactory(NULL)
+    ,m_pFactoryData(NULL)
+    ,m_vIdentFun()
+    ,m_UsedVar()
+    ,m_fZero(0)
+    ,m_iBrackets(0)
+    ,m_lastTok()
+    ,m_cArgSep(',')
+  {
+    assert(m_pParser);
+    SetParent(m_pParser);
+  }
+    
+  //---------------------------------------------------------------------------
+  /** \brief Create instance of a ParserTokenReader identical with this 
+              and return its pointer. 
+
+      This is a factory method the calling function must take care of the object destruction.
+
+      \return A new ParserTokenReader object.
+      \throw nothrow
+  */
+  ParserTokenReader* ParserTokenReader::Clone(ParserBase *a_pParent) const
+  {
+    std::auto_ptr<ParserTokenReader> ptr(new ParserTokenReader(*this));
+    ptr->SetParent(a_pParent);
+    return ptr.release();
+  }
+
+  //---------------------------------------------------------------------------
+  ParserTokenReader::token_type& ParserTokenReader::SaveBeforeReturn(const token_type &tok)
+  {
+    m_lastTok = tok;
+    return m_lastTok;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTokenReader::AddValIdent(identfun_type a_pCallback)
+  {
+    // Use push_front is used to give user defined callbacks a higher priority than
+    // the built in ones. Otherwise reading hex numbers would not work
+    // since the "0" in "0xff" would always be read first making parsing of 
+    // the rest impossible.
+    // reference:
+    // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956
+    m_vIdentFun.push_front(a_pCallback);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTokenReader::SetVarCreator(facfun_type a_pFactory, void *pUserData)
+  {
+    m_pFactory = a_pFactory;
+    m_pFactoryData = pUserData;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return the current position of the token reader in the formula string. 
+
+      \return #m_iPos
+      \throw nothrow
+  */
+  int ParserTokenReader::GetPos() const
+  {
+    return m_iPos;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a reference to the formula. 
+
+      \return #m_strFormula
+      \throw nothrow
+  */
+  const string_type& ParserTokenReader::GetExpr() const
+  {
+    return m_strFormula;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Return a map containing the used variables only. */
+  varmap_type& ParserTokenReader::GetUsedVar() 
+  {
+    return m_UsedVar;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Initialize the token Reader. 
+  
+      Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.
+      \pre [assert] triggered if a_szFormula==0
+  */
+  void ParserTokenReader::SetFormula(const string_type &a_strFormula)
+  {
+    m_strFormula = a_strFormula;
+    ReInit();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Set Flag that controls behaviour in case of undefined variables being found. 
+  
+    If true, the parser does not throw an exception if an undefined variable is found. 
+    otherwise it does. This variable is used internally only!
+    It suppresses a "undefined variable" exception in GetUsedVar().  
+    Those function should return a complete list of variables including 
+    those the are not defined by the time of it's call.
+  */
+  void ParserTokenReader::IgnoreUndefVar(bool bIgnore)
+  {
+    m_bIgnoreUndefVar = bIgnore;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Reset the token reader to the start of the formula. 
+
+      The syntax flags will be reset to a value appropriate for the 
+      start of a formula.
+      \post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR
+      \throw nothrow
+      \sa ESynCodes
+  */
+  void ParserTokenReader::ReInit()
+  {
+    m_iPos = 0;
+    m_iSynFlags = sfSTART_OF_LINE;
+    m_iBrackets = 0;
+    m_UsedVar.clear();
+    m_lastTok = token_type();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Read the next token from the string. */ 
+  ParserTokenReader::token_type ParserTokenReader::ReadNextToken()
+  {
+    assert(m_pParser);
+
+    const char_type *szFormula = m_strFormula.c_str();
+    token_type tok;
+
+    // Ignore all non printable characters when reading the expression
+    while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) 
+      ++m_iPos;
+
+    if ( IsEOF(tok) )        return SaveBeforeReturn(tok); // Check for end of formula
+    if ( IsOprt(tok) )       return SaveBeforeReturn(tok); // Check for user defined binary operator
+    if ( IsFunTok(tok) )     return SaveBeforeReturn(tok); // Check for function token
+    if ( IsBuiltIn(tok) )    return SaveBeforeReturn(tok); // Check built in operators / tokens
+    if ( IsArgSep(tok) )     return SaveBeforeReturn(tok); // Check for function argument separators
+    if ( IsValTok(tok) )     return SaveBeforeReturn(tok); // Check for values / constant tokens
+    if ( IsVarTok(tok) )     return SaveBeforeReturn(tok); // Check for variable tokens
+    if ( IsStrVarTok(tok) )  return SaveBeforeReturn(tok); // Check for string variables
+    if ( IsString(tok) )     return SaveBeforeReturn(tok); // Check for String tokens
+    if ( IsInfixOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators
+    if ( IsPostOpTok(tok) )  return SaveBeforeReturn(tok); // Check for unary operators
+
+    // Check String for undefined variable token. Done only if a 
+    // flag is set indicating to ignore undefined variables.
+    // This is a way to conditionally avoid an error if 
+    // undefined variables occur. 
+    // (The GetUsedVar function must suppress the error for
+    // undefined variables in order to collect all variable 
+    // names including the undefined ones.)
+    if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )  
+      return SaveBeforeReturn(tok);
+
+    // Check for unknown token
+    // 
+    // !!! From this point on there is no exit without an exception possible...
+    // 
+    string_type strTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
+    if (iEnd!=m_iPos)
+      Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);
+
+    Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos));
+    return token_type(); // never reached
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTokenReader::SetParent(ParserBase *a_pParent)
+  {
+    m_pParser       = a_pParent; 
+    m_pFunDef       = &a_pParent->m_FunDef;
+    m_pOprtDef      = &a_pParent->m_OprtDef;
+    m_pInfixOprtDef = &a_pParent->m_InfixOprtDef;
+    m_pPostOprtDef  = &a_pParent->m_PostOprtDef;
+    m_pVarDef       = &a_pParent->m_VarDef;
+    m_pStrVarDef    = &a_pParent->m_StrVarDef;
+    m_pConstDef     = &a_pParent->m_ConstDef;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Extract all characters that belong to a certain charset.
+
+    \param a_szCharSet [in] Const char array of the characters allowed in the token. 
+    \param a_strTok [out]  The string that consists entirely of characters listed in a_szCharSet.
+    \param a_iPos [in] Position in the string from where to start reading.
+    \return The Position of the first character not listed in a_szCharSet.
+    \throw nothrow
+  */
+  int ParserTokenReader::ExtractToken(const char_type *a_szCharSet, 
+                                      string_type &a_sTok, 
+                                      int a_iPos) const
+  {
+    int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos);
+
+    if (iEnd==(int)string_type::npos)
+        iEnd = (int)m_strFormula.length();
+    
+    // Assign token string if there was something found
+    if (a_iPos!=iEnd)
+      a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd);
+
+    return iEnd;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check Expression for the presence of a binary operator token.
+  
+    Userdefined binary operator "++" gives inconsistent parsing result for
+    the equations "a++b" and "a ++ b" if alphabetic characters are allowed
+    in operator tokens. To avoid this this function checks specifically
+    for operator tokens.
+  */
+  int ParserTokenReader::ExtractOperatorToken(string_type &a_sTok, 
+                                              int a_iPos) const
+  {
+    // Changed as per Issue 6: https://code.google.com/p/muparser/issues/detail?id=6
+    int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidOprtChars(), a_iPos);
+    if (iEnd==(int)string_type::npos)
+      iEnd = (int)m_strFormula.length();
+
+    // Assign token string if there was something found
+    if (a_iPos!=iEnd)
+    {
+      a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
+      return iEnd;
+    }
+    else
+    {
+      // There is still the chance of having to deal with an operator consisting exclusively
+      // of alphabetic characters.
+      return ExtractToken(MUP_CHARS, a_sTok, a_iPos);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a built in operator or other token can be found
+      \param a_Tok  [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
+      \return true if an operator token has been found.
+  */
+  bool ParserTokenReader::IsBuiltIn(token_type &a_Tok)
+  {
+    const char_type **const pOprtDef = m_pParser->GetOprtDef(),
+                     *const szFormula = m_strFormula.c_str();
+
+    // Compare token with function and operator strings
+    // check string for operator/function
+    for (int i=0; pOprtDef[i]; i++)
+    {
+      std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );
+      if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) )
+      {
+        switch(i)
+        {
+        //case cmAND:
+        //case cmOR:
+        //case cmXOR:
+        case cmLAND:
+        case cmLOR:
+        case cmLT:
+        case cmGT:
+        case cmLE:
+        case cmGE:
+        case cmNEQ:  
+        case cmEQ:
+        case cmADD:
+        case cmSUB:
+        case cmMUL:
+        case cmDIV:
+        case cmPOW:
+        case cmASSIGN:
+              //if (len!=sTok.length())
+              //  continue;
+
+              // The assignment operator need special treatment
+              if (i==cmASSIGN && m_iSynFlags & noASSIGN)
+                Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
+
+              if (!m_pParser->HasBuiltInOprt()) continue;
+              if (m_iSynFlags & noOPT) 
+              {
+                // Maybe its an infix operator not an operator
+                // Both operator types can share characters in 
+                // their identifiers
+                if ( IsInfixOpTok(a_Tok) ) 
+                  return true;
+
+                Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);
+              }
+
+              m_iSynFlags  = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE | noEND;
+              break;
+
+		    case cmBO:
+              if (m_iSynFlags & noBO)
+	              Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
+              
+              if (m_lastTok.GetCode()==cmFUNC)
+                m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
+              else
+                m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN| noIF | noELSE;
+
+              ++m_iBrackets;
+              break;
+
+		    case cmBC:
+              if (m_iSynFlags & noBC)
+                Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
+
+              m_iSynFlags  = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
+
+              if (--m_iBrackets<0)
+                Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);
+              break;
+
+        case cmELSE:
+              if (m_iSynFlags & noELSE)
+                Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
+
+              m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
+              break;
+
+        case cmIF:
+              if (m_iSynFlags & noIF)
+                Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
+
+              m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
+              break;
+
+		    default:      // The operator is listed in c_DefaultOprt, but not here. This is a bad thing...
+              Error(ecINTERNAL_ERROR);
+        } // switch operator id
+
+        m_iPos += (int)len;
+        a_Tok.Set( (ECmdCode)i, pOprtDef[i] );
+        return true;
+	    } // if operator string found
+    } // end of for all operator strings
+  
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  bool ParserTokenReader::IsArgSep(token_type &a_Tok)
+  {
+    const char_type* szFormula = m_strFormula.c_str();
+
+    if (szFormula[m_iPos]==m_cArgSep)
+    {
+      // copy the separator into null terminated string
+      char_type szSep[2];
+      szSep[0] = m_cArgSep;
+      szSep[1] = 0;
+
+      if (m_iSynFlags & noARG_SEP)
+        Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep);
+
+      m_iSynFlags  = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;
+      m_iPos++;
+      a_Tok.Set(cmARG_SEP, szSep);
+      return true;
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check for End of Formula.
+
+      \return true if an end of formula is found false otherwise.
+      \param a_Tok [out] If an eof is found the corresponding token will be stored there.
+      \throw nothrow
+      \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok
+  */
+  bool ParserTokenReader::IsEOF(token_type &a_Tok)
+  {
+    const char_type* szFormula = m_strFormula.c_str();
+
+    // check for EOF
+    if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/)
+    {
+      if ( m_iSynFlags & noEND )
+        Error(ecUNEXPECTED_EOF, m_iPos);
+
+      if (m_iBrackets>0)
+        Error(ecMISSING_PARENS, m_iPos, _T(")"));
+
+      m_iSynFlags = 0;
+      a_Tok.Set(cmEND);
+      return true;
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a unary infix operator. 
+      \return true if a function token has been found false otherwise.
+  */
+  bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)
+  {
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    // iterate over all postfix operator strings
+    funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
+    for ( ; it!=m_pInfixOprtDef->rend(); ++it)
+    {
+      if (sTok.find(it->first)!=0)
+        continue;
+
+      a_Tok.Set(it->second, it->first);
+      m_iPos += (int)it->first.length();
+
+      if (m_iSynFlags & noINFIXOP) 
+        Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());
+
+      m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN;
+      return true;
+    }
+
+    return false;
+
+/*
+    a_Tok.Set(item->second, sTok);
+    m_iPos = (int)iEnd;
+
+    if (m_iSynFlags & noINFIXOP) 
+      Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());
+
+    m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; 
+    return true;
+*/
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check whether the token at a given position is a function token.
+      \param a_Tok [out] If a value token is found it will be placed here.
+      \throw ParserException if Syntaxflags do not allow a function at a_iPos
+      \return true if a function token has been found false otherwise.
+      \pre [assert] m_pParser!=0
+  */
+  bool ParserTokenReader::IsFunTok(token_type &a_Tok)
+  {
+    string_type strTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    funmap_type::const_iterator item = m_pFunDef->find(strTok);
+    if (item==m_pFunDef->end())
+      return false;
+
+    // Check if the next sign is an opening bracket
+    const char_type *szFormula = m_strFormula.c_str();
+    if (szFormula[iEnd]!='(')
+      return false;
+
+    a_Tok.Set(item->second, strTok);
+
+    m_iPos = (int)iEnd;
+    if (m_iSynFlags & noFUN)
+      Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
+
+    m_iSynFlags = noANY ^ noBO;
+    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a binary operator.
+      \param a_Tok  [out] Operator token if one is found. This can either be a binary operator or an infix operator token.
+      \return true if an operator token has been found.
+  */
+  bool ParserTokenReader::IsOprt(token_type &a_Tok)
+  {
+    const char_type *const szExpr = m_strFormula.c_str();
+    string_type strTok;
+
+    int iEnd = ExtractOperatorToken(strTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    // Check if the operator is a built in operator, if so ignore it here
+    const char_type **const pOprtDef = m_pParser->GetOprtDef();
+    for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i)
+    {
+      if (string_type(pOprtDef[i])==strTok)
+        return false;
+    }
+
+    // Note:
+    // All tokens in oprt_bin_maptype are have been sorted by their length
+    // Long operators must come first! Otherwise short names (like: "add") that
+    // are part of long token names (like: "add123") will be found instead 
+    // of the long ones.
+    // Length sorting is done with ascending length so we use a reverse iterator here.
+    funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();
+    for ( ; it!=m_pOprtDef->rend(); ++it)
+    {
+      const string_type &sID = it->first;
+      if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) )
+      {
+        a_Tok.Set(it->second, strTok);
+
+        // operator was found
+        if (m_iSynFlags & noOPT) 
+        {
+          // An operator was found but is not expected to occur at
+          // this position of the formula, maybe it is an infix 
+          // operator, not a binary operator. Both operator types
+          // can share characters in their identifiers.
+          if ( IsInfixOpTok(a_Tok) ) 
+            return true;
+          else
+          {
+            // nope, no infix operator
+            return false;
+            //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); 
+          }
+
+        }
+
+        m_iPos += (int)sID.length();
+        m_iSynFlags  = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noASSIGN;
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check if a string position contains a unary post value operator. */
+  bool ParserTokenReader::IsPostOpTok(token_type &a_Tok)
+  {
+    // <ibg 20110629> Do not check for postfix operators if they are not allowed at
+    //                the current expression index.
+    //
+    //  This will fix the bug reported here:  
+    //
+    //  http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979
+    //
+    if (m_iSynFlags & noPOSTOP)
+      return false;
+    // </ibg>
+
+    // Tricky problem with equations like "3m+5":
+    //     m is a postfix operator, + is a valid sign for postfix operators and 
+    //     for binary operators parser detects "m+" as operator string and 
+    //     finds no matching postfix operator.
+    // 
+    // This is a special case so this routine slightly differs from the other
+    // token readers.
+    
+    // Test if there could be a postfix operator
+    string_type sTok;
+    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    // iterate over all postfix operator strings
+    funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
+    for ( ; it!=m_pPostOprtDef->rend(); ++it)
+    {
+      if (sTok.find(it->first)!=0)
+        continue;
+
+      a_Tok.Set(it->second, sTok);
+  	  m_iPos += (int)it->first.length();
+
+      m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
+      return true;
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check whether the token at a given position is a value token.
+
+    Value tokens are either values or constants.
+
+    \param a_Tok [out] If a value token is found it will be placed here.
+    \return true if a value token has been found.
+  */
+  bool ParserTokenReader::IsValTok(token_type &a_Tok)
+  {
+    assert(m_pConstDef);
+    assert(m_pParser);
+
+    string_type strTok;
+    value_type fVal(0);
+    int iEnd(0);
+    
+    // 2.) Check for user defined constant
+    // Read everything that could be a constant name
+    iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
+    if (iEnd!=m_iPos)
+    {
+      valmap_type::const_iterator item = m_pConstDef->find(strTok);
+      if (item!=m_pConstDef->end())
+      {
+        m_iPos = iEnd;
+        a_Tok.SetVal(item->second, strTok);
+
+        if (m_iSynFlags & noVAL)
+          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
+
+        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; 
+        return true;
+      }
+    }
+
+    // 3.call the value recognition functions provided by the user
+    // Call user defined value recognition functions
+    std::list<identfun_type>::const_iterator item = m_vIdentFun.begin();
+    for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
+    {
+      int iStart = m_iPos;
+      if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )
+      {
+        // 2013-11-27 Issue 2:  https://code.google.com/p/muparser/issues/detail?id=2
+        strTok.assign(m_strFormula.c_str(), iStart, m_iPos-iStart);
+
+        if (m_iSynFlags & noVAL)
+          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);
+
+        a_Tok.SetVal(fVal, strTok);
+        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Check wheter a token at a given position is a variable token. 
+      \param a_Tok [out] If a variable token has been found it will be placed here.
+	    \return true if a variable token has been found.
+  */
+  bool ParserTokenReader::IsVarTok(token_type &a_Tok)
+  {
+    if (m_pVarDef->empty())
+      return false;
+
+    string_type strTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    varmap_type::const_iterator item =  m_pVarDef->find(strTok);
+    if (item==m_pVarDef->end())
+      return false;
+
+    if (m_iSynFlags & noVAR)
+      Error(ecUNEXPECTED_VAR, m_iPos, strTok);
+
+    m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd);
+
+    m_iPos = iEnd;
+    a_Tok.SetVar(item->second, strTok);
+    m_UsedVar[item->first] = item->second;  // Add variable to used-var-list
+
+    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR;
+
+//  Zur Info hier die SynFlags von IsVal():
+//    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; 
+    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  bool ParserTokenReader::IsStrVarTok(token_type &a_Tok)
+  {
+    if (!m_pStrVarDef || m_pStrVarDef->empty())
+      return false;
+
+    string_type strTok;
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);
+    if (iEnd==m_iPos)
+      return false;
+
+    strmap_type::const_iterator item =  m_pStrVarDef->find(strTok);
+    if (item==m_pStrVarDef->end())
+      return false;
+
+    if (m_iSynFlags & noSTR)
+      Error(ecUNEXPECTED_VAR, m_iPos, strTok);
+
+    m_iPos = iEnd;
+    if (!m_pParser->m_vStringVarBuf.size())
+      Error(ecINTERNAL_ERROR);
+
+    a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() );
+
+    m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP);
+    return true;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Check wheter a token at a given position is an undefined variable. 
+
+      \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.
+	    \return true if a variable token has been found.
+      \throw nothrow
+  */
+  bool ParserTokenReader::IsUndefVarTok(token_type &a_Tok)
+  {
+    string_type strTok;
+    int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) );
+    if ( iEnd==m_iPos )
+      return false;
+
+    if (m_iSynFlags & noVAR)
+    {
+      // <ibg/> 20061021 added token string strTok instead of a_Tok.GetAsString() as the 
+      //                 token identifier. 
+      // related bug report:
+      // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979
+      Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok);
+    }
+
+    // If a factory is available implicitely create new variables
+    if (m_pFactory)
+    {
+      value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
+      a_Tok.SetVar(fVar, strTok );
+
+      // Do not use m_pParser->DefineVar( strTok, fVar );
+      // in order to define the new variable, it will clear the
+      // m_UsedVar array which will kill previously defined variables
+      // from the list
+      // This is safe because the new variable can never override an existing one
+      // because they are checked first!
+      (*m_pVarDef)[strTok] = fVar;
+      m_UsedVar[strTok] = fVar;  // Add variable to used-var-list
+    }
+    else
+    {
+      a_Tok.SetVar((value_type*)&m_fZero, strTok);
+      m_UsedVar[strTok] = 0;  // Add variable to used-var-list
+    }
+
+    m_iPos = iEnd;
+
+    // Call the variable factory in order to let it define a new parser variable
+    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
+    return true;
+  }
+
+
+  //---------------------------------------------------------------------------
+  /** \brief Check wheter a token at a given position is a string.
+      \param a_Tok [out] If a variable token has been found it will be placed here.
+  	  \return true if a string token has been found.
+      \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok
+      \throw nothrow
+  */
+  bool ParserTokenReader::IsString(token_type &a_Tok)
+  {
+    if (m_strFormula[m_iPos]!='"') 
+      return false;
+
+    string_type strBuf(&m_strFormula[m_iPos+1]);
+    std::size_t iEnd(0), iSkip(0);
+
+    // parser over escaped '\"' end replace them with '"'
+    for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd))
+    {
+      if (strBuf[iEnd-1]!='\\') break;
+      strBuf.replace(iEnd-1, 2, _T("\"") );
+      iSkip++;
+    }
+
+    if (iEnd==string_type::npos)
+      Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") );
+
+    string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);
+
+    if (m_iSynFlags & noSTR)
+      Error(ecUNEXPECTED_STR, m_iPos, strTok);
+
+		m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer
+    a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
+
+    m_iPos += (int)strTok.length() + 2 + (int)iSkip;  // +2 wg Anführungszeichen; +iSkip für entfernte escape zeichen
+    m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
+
+    return true;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Create an error containing the parse error position.
+
+    This function will create an Parser Exception object containing the error text and its position.
+
+    \param a_iErrc [in] The error code of type #EErrorCodes.
+    \param a_iPos [in] The position where the error was detected.
+    \param a_strTok [in] The token string representation associated with the error.
+    \throw ParserException always throws thats the only purpose of this function.
+  */
+  void  ParserTokenReader::Error( EErrorCodes a_iErrc, 
+                                  int a_iPos, 
+                                  const string_type &a_sTok) const
+  {
+    m_pParser->Error(a_iErrc, a_iPos, a_sTok);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserTokenReader::SetArgSep(char_type cArgSep)
+  {
+    m_cArgSep = cArgSep;
+  }
+
+  //---------------------------------------------------------------------------
+  char_type ParserTokenReader::GetArgSep() const
+  {
+    return m_cArgSep;
+  }
+} // namespace mu
+
diff --git a/VirtualFluidsBasics/IncludsList.cmake b/VirtualFluidsBasics/IncludsList.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5655947dded019800743d8de0791848fe45b7366
--- /dev/null
+++ b/VirtualFluidsBasics/IncludsList.cmake
@@ -0,0 +1,6 @@
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics/geometry3d)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics/basics/container)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics/basics/objects)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics/basics/utilities)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsBasics/basics/writer)
\ No newline at end of file
diff --git a/VirtualFluidsBasics/VirtualFluidsBasics.cmake b/VirtualFluidsBasics/VirtualFluidsBasics.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..a0e1b3a2014fc15c09fd1773c4cad64c5646350d
--- /dev/null
+++ b/VirtualFluidsBasics/VirtualFluidsBasics.cmake
@@ -0,0 +1,6 @@
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/geometry3d/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/basics/objects/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/basics/utilities/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/basics/container/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/basics/writer/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/IncludsList.cmake)
\ No newline at end of file
diff --git a/VirtualFluidsBasics/basics/container/CMakePackage.txt b/VirtualFluidsBasics/basics/container/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b2d974b49ca72178a8823a1e2e06fc7087205c88
--- /dev/null
+++ b/VirtualFluidsBasics/basics/container/CMakePackage.txt
@@ -0,0 +1,4 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
+
+
diff --git a/VirtualFluidsBasics/basics/container/CbArray2D.h b/VirtualFluidsBasics/basics/container/CbArray2D.h
new file mode 100644
index 0000000000000000000000000000000000000000..575ef2f5403ea35a40a4f214b32829e3d7c39efc
--- /dev/null
+++ b/VirtualFluidsBasics/basics/container/CbArray2D.h
@@ -0,0 +1,413 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CbArray2D.h
+//! \ingroup container
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef CBARRAY2D_H
+#define CBARRAY2D_H
+
+#include <iomanip>
+
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbEqual.h>
+#include <algorithm>
+#include <typeinfo>
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// IndexClasses
+
+//IndexerX2X1:
+//        4 5 6
+// Array  1 2 3  -->  vector 1 2 3 4 5 6
+//optimaler schleifendurchlauf
+//for(alle X2)
+//  for(alle X1)
+class IndexerX2X1
+{
+public:
+   typedef int size_type;
+public:
+   inline std::size_t getIndex(const size_type& x1, const size_type& x2, const size_type& nx1, const size_type& nx2) const
+   {
+      return nx1* x2 + x1;
+   }
+   inline std::size_t getStartIndexOfSortedArray(const size_type& x1, const size_type& x2, const size_type& nx1, const size_type& nx2) const
+   {
+      return  nx1* x2;
+   }
+};
+
+//IndexerX1X2:
+//        4 5 6
+// Array  1 2 3  -->  vector 1 4 2 5 3 6
+//optimaler schleifendurchlauf
+//for(alle X1)
+//  for(alle X2)
+class IndexerX1X2
+{
+public:
+   typedef int size_type;
+public:
+   inline std::size_t getIndex(const size_type& x1, const size_type& x2, const size_type& nx1,const size_type& nx2) const
+   {
+      return nx2* x1+ x2;
+   }
+   inline std::size_t getStartIndexOfSortedArray(const size_type& x1, const size_type& x2, const size_type& nx1, const size_type& nx2) const
+   {
+      return  nx2* x1;
+   }
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// CbArray2D
+//////////////////////////////////////////////////////////////////////////
+//! \brief 2D Array
+//! \details the data is stored in a vector
+//!
+//! Rangecheck active, if:
+//!
+//! -debug  : not defined "NO_CB_RANGECHECK"
+//!
+//! -release: not defined "NO_CB_RANGECHECK" && defined "CB_RANGECHECK"
+//////////////////////////////////////////////////////////////////////////
+template<typename T, typename IndexClass = IndexerX2X1>
+class CbArray2D
+{
+public:
+   typedef T                                                   value_type;
+   typedef IndexClass                                          indexer_type;
+   typedef typename IndexClass::size_type                      size_type;
+   typedef typename std::vector< value_type >::reference       reference;
+   typedef typename std::vector< value_type >::const_reference const_reference;
+   typedef typename std::vector< value_type >::pointer         pointer;
+   typedef typename std::vector< value_type >::const_pointer   const_pointer;
+
+private:
+   template< typename value_type2, typename IndexClass2 > friend class CbArray2D;
+
+public:
+   /*=======================================================================*/
+   CbArray2D()
+   {
+      this->resize(0,0);
+   }
+   /*=======================================================================*/
+   CbArray2D(const size_type& nx2, const size_type& nx1)
+   {
+      this->resize(nx2,nx1);
+   }
+   /*=======================================================================*/
+   CbArray2D(const size_type& nx2, const size_type& nx1, const value_type& val)
+   {
+      this->resize(nx2,nx1,val);
+   }
+   /*=======================================================================*/
+   CbArray2D(const size_type& uniformDimensionSize /*nx1==nx2*/)
+   {
+      this->resize(uniformDimensionSize,uniformDimensionSize);
+   }
+   /*=======================================================================*/
+   //übernimmt vector als daten vector! (erstellt KEINE kopie!!!, vec ist anschließend leer, da swap verwendet wird)
+   CbArray2D(std::vector<value_type>& vec, const size_type& nx1,const size_type& nx2)
+   {
+      assert( (nx1*nx2)==vec.size() );
+      this->data.swap(vec);
+      this->resize(nx1,nx2);
+   }
+   /*=======================================================================*/
+   CbArray2D(const CbArray2D& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+       , data(src.data)
+   {
+   }
+   /*=======================================================================*/
+   template< typename value_type2 >
+   CbArray2D(const CbArray2D< value_type2 >& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+   {
+      //Sourcedaten kopieren
+      this->data.resize( src.data.size() );
+      for(std::size_t i=0; i<data.size(); ++i)
+         this->data[i] = src.data[i];
+   }
+   /*=======================================================================*/
+   virtual ~CbArray2D()
+   {
+      //vector wird automatisch zerstoert
+   }
+   /*=======================================================================*/
+   CbArray2D& operator= (const CbArray2D& rhs)
+   {
+      if(this == &rhs) return *this;
+
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+
+      //Sourcedaten kopieren
+      this->data  = rhs.data;
+
+      return *this;
+   }
+   /*=======================================================================*/
+   //durch value_type2 kann man z.B. ein float array einem double array zuweisen!
+   template< typename value_type2, typename IndexClass2 >
+   CbArray2D& operator= (const CbArray2D< value_type2, IndexClass2 >& rhs)
+   {
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+
+      //Sourcedaten kopieren (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      //ACHTUNG: für diese Konvertierung muss bei Klassen der demenstrechende operator
+      //         implementiert sein, e.g.: class value_type2 {public: inline operator value_type2() const { return value_type2(); }
+      for(int x1=0; x1<this->nx1; x1++)
+         for(int x2=0; x2<this->nx2; x2++)
+               this->operator()(x1,x2) = static_cast< value_type >( rhs.operator()(x1,x2) );
+
+      return *this;
+   }
+   /*=======================================================================*/
+   bool operator== (const CbArray2D& rhs) const
+   {
+      if( this == &rhs ) return true;
+
+      if(   this->nx1!=rhs.nx1
+         || this->nx2!=rhs.nx2
+         || this->data.size() != rhs.data.size() )
+      {
+         return false;
+      }
+
+      return std::equal( this->data.begin(), this->data.end(), rhs.data.begin(), UbEqual<value_type, value_type >() );
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator== (const CbArray2D< value_type2, IndexClass2 >& rhs) const
+   {
+      if( this->data.size() != rhs.data.size() ) return false;
+
+      //Sourcedaten einzeln checken (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      for(int x1=0; x1<this->nx1; x1++)
+         for(int x2=0; x2<this->nx2; x2++)
+            if( !isUbEqual(this->operator()(x1,x2), rhs.operator()(x1,x2)) )
+               return false;
+
+      return true;
+   }
+   /*=======================================================================*/
+   bool operator!= (const CbArray2D& rhs) const
+   {
+      return !(*this==rhs);
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator!= (const CbArray2D< value_type2, IndexClass2 >& rhs) const
+   {
+      return !(*this==rhs);
+   }
+   /*=======================================================================*/
+   reference operator() (const size_type& x1,const size_type& x2)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+
+      return this->data[indexer.getIndex(x1,x2,nx1,nx2)];
+   }
+   /*=======================================================================*/
+   const_reference operator() (const size_type& x1,const size_type& x2)	const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+
+      return this->data[indexer.getIndex(x1,x2,nx1,nx2)];
+   }
+   /*=======================================================================*/
+   pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,nx1,nx2)];
+   }
+   /*=======================================================================*/
+   const_pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,nx1,nx2)];
+   }
+   /*=======================================================================*/
+   void setObject(const size_type& x1,const size_type& x2,const value_type& value)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+      this->data[indexer.getIndex(x1,x2,nx1,nx2)] = value;
+   }
+   /*=======================================================================*/
+   reference getObject(const size_type& x1, const size_type& x2)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+      return this->data[indexer.getIndex(x1,x2,nx1,nx2)] ;
+   }
+   /*=======================================================================*/
+   typename std::vector<value_type>::const_reference getObject(const size_type& x1, const size_type& x2) const
+   {
+      return this->operator()(x1,x2);
+   }
+   /*=======================================================================*/
+   bool      isEmpty() const { return data.empty(); }
+   size_type getNX1()  const { return this->nx1;    }
+   size_type getNX2()  const { return this->nx2;    }
+   /*=======================================================================*/
+   void reset(const T& val)
+   {
+      std::fill( this->data.begin(), this->data.end(), val );
+   }
+   /*=======================================================================*/
+   std::string toString() const
+   {
+      std::stringstream text;
+      for(size_type x2=0; x2<this->nx2; x2++)
+      {
+         for(size_type x1=0; x1<this->nx1; x1++)
+         {
+            //hier kommts zum Konflikt ab  und an ...
+            text<<this->getObject(x1,x2)<<", ";
+         }
+         text<<"\n";
+      }
+
+      return text.str();
+   }
+   /*=======================================================================*/
+   std::string getInfo() const
+   {
+      std::stringstream text;
+      text<<"CbArray2D< storageType="<<typeid(T).name()<<", indexer="<<typeid(IndexClass).name()<<" >";
+      text<<"( nx1="<<this->nx1<<", nx2="<<this->nx2<<")";
+      return text.str();
+   }
+   /*=======================================================================*/
+   void resize(const size_type& uniformDimensionSize)
+   {
+      this->resize(uniformDimensionSize,uniformDimensionSize);
+   }
+   /*=======================================================================*/
+   void resize(const size_type& nx1,const size_type& nx2)
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->data.resize(nx1*nx2);
+   }
+   /*=======================================================================*/
+   void resize(const size_type& nx1, const size_type& nx2, const value_type& initVal )
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->data.resize(nx1*nx2,initVal);
+   }
+   /*=======================================================================*/
+   void clear()
+   {
+      this->nx1 = 0;
+      this->nx2 = 0;
+      this->data.clear();
+   }
+   /*=======================================================================*/
+   std::vector< value_type >& getDataVector() { return this->data; }
+   /*=======================================================================*/
+   const std::vector< value_type >& getDataVector() const { return this->data; }
+   /*=======================================================================*/
+   inline size_type getDataVectorIndex(const size_type& x1, const size_type& x2) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2)) );
+      #endif
+
+      return indexer.getIndex(x1,x2,nx1,nx2);
+   }
+
+protected:
+   /*=======================================================================*/
+   //success -> true
+   //else    -> false
+   inline bool indicesInRange(const size_type& x1, const size_type& x2) const
+   {
+      if(   x1 < 0 || x1 >= this->nx1
+         || x2 < 0 || x2 >= this->nx2 )
+      {
+         return false;
+      }
+      return true;
+   }
+   /*=======================================================================*/
+   std::string getExceptionErrorString(const size_type& x1, const size_type& x2) const
+   {
+      std::stringstream out("index out of range - ");
+      out<<"("<<x1<<","<<x2<<") not in ("<<nx1<<","<<nx2<<")";
+      return out.str();
+   }
+   /*=======================================================================*/
+
+protected:
+   size_type    nx1;
+   size_type    nx2;
+   indexer_type indexer;
+   std::vector< value_type > data;
+};
+
+#endif //CBARRAY2D_H
diff --git a/VirtualFluidsBasics/basics/container/CbArray3D.h b/VirtualFluidsBasics/basics/container/CbArray3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..575b0cb84019bdd0241698d4f8e861ccd9aa2159
--- /dev/null
+++ b/VirtualFluidsBasics/basics/container/CbArray3D.h
@@ -0,0 +1,468 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CbArray3D.h
+//! \ingroup container
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef CBARRAY3D_H
+#define CBARRAY3D_H
+
+#include <iomanip>
+
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbEqual.h>
+#include <algorithm>
+#include <typeinfo>
+#include "PointerDefinitions.h"
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// IndexClasses
+
+//IndexerX3X2X1:
+//                4 5 6          10 11 12
+// Array  ebene A 1 2 3  ebene B  7  8  9 -->  vector 1 2 3 4 5 6 7 8 9 10 11 12
+//x1-reihen "liegen am stueck" im speicher
+//optimaler schleifendurchlauf
+//for(alle X3)
+//  for(alle X2)
+//    for(alle X1)
+class IndexerX3X2X1// FunctorX1SortedForX1X2Plane
+{
+public:
+   typedef size_t size_type;
+public:
+   inline std::size_t getIndex(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                               , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx1 * ( nx2 * x3 + x2) + x1 ;
+   }
+   inline std::size_t getStartIndexOfSortedArray(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                                                 , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx1 * ( nx2 * x3 + x2);
+   }
+};
+
+//IndexerX1X2X3:
+//                4 5 6          10 11 12
+// Array  ebene A 1 2 3  ebene B  7  8  9 -->
+//optimaler schleifendurchlauf
+//for(alle X1)
+//  for(alle X2)
+//    for(alle X3)
+class IndexerX1X2X3 //FunctorX3SortedForX3X2Plane
+{
+public:
+   typedef size_t size_type;
+public:
+   inline std::size_t getIndex(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                               , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx3 * ( nx2 * x1 + x2) + x3 ;
+   }
+   inline std::size_t getStartIndexOfSortedArray(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                                                 , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx3 * ( nx2 * x1 + x2);
+   }
+};
+
+//IndexerX2X1X3:
+//                4 5 6          10 11 12
+// Array  ebene A 1 2 3  ebene B  7  8  9 -->  vector 1 7 2 8 3 9 4 10 5 11 6 12
+//optimaler schleifendurchlauf
+//for(alle X2)
+//  for(alle X1)
+//    for(alle X3)
+class IndexerX2X1X3
+{
+public:
+   typedef size_t size_type;
+public:
+   inline std::size_t getIndex(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                               , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx3* ( nx1 * x2 + x1) + x3 ;
+   }
+   inline std::size_t getStartIndexOfSortedArray(  const size_type& x1 , const size_type& x2 , const size_type& x3
+                                                 , const size_type& nx1, const size_type& nx2, const size_type& nx3 ) const
+   {
+      return  nx3* ( nx1 * x2 + x1);
+   }
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// CbArray3D
+//////////////////////////////////////////////////////////////////////////
+//! \brief 3D Array
+//! \details The data is stored in a vector
+//!
+//! Rangecheck active, if:
+//!
+//! -debug  : not defined "NO_CB_RANGECHECK"
+//!
+//! -release: not defined "NO_CB_RANGECHECK" && defined "CB_RANGECHECK"
+//////////////////////////////////////////////////////////////////////////
+template<typename T, typename IndexClass = IndexerX3X2X1>
+class CbArray3D
+{
+public:
+   typedef SPtr< CbArray3D <T,IndexClass> > CbArray3DPtr;
+
+   typedef T                                                   value_type;
+   typedef IndexClass                                          indexer_type;
+   typedef typename IndexClass::size_type                      size_type;
+   typedef typename std::vector< value_type >::reference       reference;
+   typedef typename std::vector< value_type >::const_reference const_reference;
+   typedef typename std::vector< value_type >::pointer         pointer;
+   typedef typename std::vector< value_type >::const_pointer   const_pointer;
+
+private:
+   template< typename value_type2, typename IndexClass2 > friend class CbArray3D;
+
+public:
+   /*=======================================================================*/
+   CbArray3D()
+   {
+      this->resize(0,0,0);
+   }
+   /*=======================================================================*/
+   CbArray3D(const size_type& nx1,const size_type& nx2, const size_type& nx3, const value_type& val)
+   {
+      this->resize(nx1,nx2,nx3,val);
+   }
+   /*=======================================================================*/
+    CbArray3D(const size_type& nx1,const size_type& nx2, const size_type& nx3)
+    {
+       this->resize(nx1,nx2,nx3);
+    }
+   /*=======================================================================*/
+   CbArray3D(const size_type& uniformDimensionSize /*nx1==nx2==nx3*/)
+   {
+      this->resize(uniformDimensionSize,uniformDimensionSize,uniformDimensionSize);
+   }
+   /*=======================================================================*/
+   //übernimmt vector als daten vector! (erstellt KEINE kopie!!!, vec ist anschließend leer, da swap verwendet wird)
+   CbArray3D(std::vector<value_type>& vec, const size_type& nx1,const size_type& nx2, const size_type& nx3)
+   {
+      assert( (nx1*nx2*nx3)==vec.size() );
+      this->data.swap(vec);
+      this->resize(nx1,nx2,nx3);
+   }
+   /*=======================================================================*/
+   CbArray3D(const CbArray3D& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+       , nx3(src.nx3)
+       , data(src.data)
+   {
+   }
+   /*=======================================================================*/
+   template< typename value_type2 >
+   CbArray3D(const CbArray3D< value_type2 >& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+       , nx3(src.nx3)
+   {
+      //Sourcedaten kopieren
+      this->data.resize( src.data.size() );
+      for(std::size_t i=0; i<data.size(); ++i)
+         this->data[i] = src.data[i];
+   }
+   /*=======================================================================*/
+   virtual ~CbArray3D()
+   {
+      //vector wird automatisch zerstoert
+   }
+   /*=======================================================================*/
+   CbArray3D& operator= (const CbArray3D& rhs)
+   {
+      if(this == &rhs) return *this;
+
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+      this->nx3 = rhs.nx3;
+
+      //gespeicherte Datenelemente loeschen
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+
+      //Sourcedaten kopieren
+      this->data = rhs.data;
+
+      return *this;
+   }
+   /*=======================================================================*/
+   //durch value_type2 kann man z.B. ein float array einer double array zuweisen!
+   template< typename value_type2, typename IndexClass2 >
+   CbArray3D& operator= (const CbArray3D< value_type2, IndexClass2 >& rhs)
+   {
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+      this->nx3 = rhs.nx3;
+
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+
+      //Sourcedaten kopieren (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      for(int x3=0; x3<this->nx3; x3++)
+         for(int x2=0; x2<this->nx2; x2++)
+            for(int x1=0; x1<this->nx1; x1++)
+               this->operator()(x1,x2,x3) = static_cast< value_type >( rhs.operator()(x1,x2,x3) );
+
+      return *this;
+   }
+   /*=======================================================================*/
+   bool operator== (const CbArray3D& rhs) const
+   {
+      if(this == &rhs) return true;
+
+      if(   this->nx1!=rhs.nx1
+         || this->nx2!=rhs.nx2
+         || this->nx3!=rhs.nx3
+         || this->data.size() != rhs.data.size() )
+      {
+         return false;
+      }
+
+      return std::equal( this->data.begin(), this->data.end(), rhs.data.begin(), UbEqual<value_type, value_type >() );
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator== (const CbArray3D< value_type2, IndexClass2 >& rhs) const
+   {
+      if( this->data.size() != rhs.data.size() ) return false;
+
+      //Sourcedaten einzeln checken (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      for(int x3=0; x3<this->nx3; x3++)
+         for(int x2=0; x2<this->nx2; x2++)
+            for(int x1=0; x1<this->nx1; x1++)
+               if( !isUbEqual(this->operator()(x1,x2,x3), rhs.operator()(x1,x2,x3)) )
+               return false;
+
+      return true;
+   }
+   /*=======================================================================*/
+   bool operator!= (const CbArray3D& src) const
+   {
+      return !(*this==src);
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator!= (const CbArray3D< value_type2, IndexClass2 >& rhs) const
+   {
+      return !(*this==rhs);
+   }
+   /*=======================================================================*/
+   reference operator() (const size_type& x1, const size_type& x2, const size_type& x3)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return this->data[ indexer.getIndex(x1,x2,x3,nx1,nx2,nx3) ];
+   }
+   /*=======================================================================*/
+   const_reference operator() (const size_type& x1, const size_type& x2, const size_type& x3)	const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return this->data[ indexer.getIndex(x1,x2,x3,nx1,nx2,nx3) ];
+   }
+   /*=======================================================================*/
+   pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2, const size_type& x3)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,x3,nx1,nx2,nx3)];
+   }
+   /*=======================================================================*/
+   const_pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2, const size_type& x3)  const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,x3,nx1,nx2,nx3)];
+   }
+   /*=======================================================================*/
+   void setObject(const size_type& x1, const size_type& x2, const size_type& x3, const value_type& value)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      this->data[ indexer.getIndex(x1,x2,x3,nx1,nx2,nx3) ] = value;
+   }
+   /*=======================================================================*/
+   reference getObject(const size_type& x1, const size_type& x2, const size_type& x3)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return this->data[ indexer.getIndex(x1,x2,x3,nx1,nx2,nx3) ] ;
+   }
+   /*=======================================================================*/
+   const_reference getObject(const size_type& x1, const size_type& x2, const size_type& x3) const
+   {
+      return (*this)(x1,x2,x3);
+   }
+   /*=======================================================================*/
+   bool      isEmpty() const { return data.empty(); }
+   size_type getNX1()  const { return this->nx1;    }
+   size_type getNX2()  const { return this->nx2;    }
+   size_type getNX3()  const { return this->nx3;    }
+   /*=======================================================================*/
+   void reset(const value_type& val)
+   {
+      std::fill( this->data.begin(), this->data.end(), val );
+   }
+   /*=======================================================================*/
+   std::string toString() const
+   {
+      std::stringstream text;
+      for(size_type x1=0; x1<this->nx1; x1++)
+      {
+      	for(size_type x2=0; x2<this->nx2; x2++)
+      	{
+         	for(size_type x3=0; x3<this->nx3; x3++)
+         	{
+            	text<<(*this)(x1,x2,x3)<<", ";
+         	}
+         	text<<std::endl;
+      	}
+      	text<<std::endl<<std::endl;
+      }
+
+      return text.str();
+   }
+   /*=======================================================================*/
+   std::string getInfo() const
+   {
+      std::stringstream text;
+      text<<"CbArray3D< storageType="<<typeid(T).name()<<", indexer="<<typeid(IndexClass).name()<<" >";
+      text<<"( nx1="<<this->nx1<<", nx2="<<this->nx2<<", nx3="<<this->nx3<<")";
+      return text.str();
+   }
+   /*=======================================================================*/
+   void resize(const int& uniformDimensionSize)
+   {
+      this->resize(uniformDimensionSize,uniformDimensionSize,uniformDimensionSize);
+   }
+   /*=======================================================================*/
+   void resize(const size_type& nx1,const size_type& nx2, const size_type& nx3)
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->nx3 = nx3;
+      this->data.resize(nx1*nx2*nx3);
+   }
+   /*=======================================================================*/
+   void resize(const size_type& nx1,const size_type& nx2, const size_type& nx3,const value_type& val)
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->nx3 = nx3;
+      this->data.resize(nx1*nx2*nx3,val);
+   }
+   /*=======================================================================*/
+   void clear()
+   {
+      this->nx1 = 0;
+      this->nx2 = 0;
+      this->nx3 = 0;
+      this->data.clear();
+   }
+   /*=======================================================================*/
+   std::vector< value_type >& getDataVector() { return this->data; }
+   /*=======================================================================*/
+   const std::vector< value_type >& getDataVector() const { return this->data; }
+   /*=======================================================================*/
+   inline std::size_t getDataVectorIndex(const size_type& x1, const size_type& x2, const size_type& x3) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3)) );
+      #endif
+
+      return indexer.getIndex(x1,x2,x3,nx1,nx2,nx3);
+   }
+
+
+   /*=======================================================================*/
+   //success -> true
+   //else    -> false
+   inline bool indicesInRange(const size_type& x1, const size_type& x2, const size_type& x3) const
+   {
+      if(   x1 < 0 || x1 >= this->nx1
+         || x2 < 0 || x2 >= this->nx2
+         || x3 < 0 || x3 >= this->nx3 )
+      {
+         return false;
+      }
+      return true;
+   }
+protected:
+   /*=======================================================================*/
+   std::string getExceptionErrorString(const size_type& x1, const size_type& x2, const size_type& x3) const
+   {
+      std::stringstream out("index out of range - ");
+      out<<"("<<x1<<","<<x2<<","<<x3<<") not in ("<<nx1<<","<<nx2<<","<<nx3<<")";
+      return out.str();
+   }
+   /*=======================================================================*/
+
+protected:
+   size_type    nx1;
+   size_type    nx2;
+   size_type    nx3;
+   indexer_type indexer;
+   std::vector< value_type > data;
+
+};
+
+#endif //CBARRAY3D_H
diff --git a/VirtualFluidsBasics/basics/container/CbArray4D.h b/VirtualFluidsBasics/basics/container/CbArray4D.h
new file mode 100644
index 0000000000000000000000000000000000000000..b72a13f0e0489869e69ac722493ddc59e6c469e8
--- /dev/null
+++ b/VirtualFluidsBasics/basics/container/CbArray4D.h
@@ -0,0 +1,451 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CbArray4D.h
+//! \ingroup container
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef CBARRAY4D_H
+#define CBARRAY4D_H
+
+
+
+#include <iomanip>
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbEqual.h>
+#include <algorithm>
+#include <typeinfo>
+#include "PointerDefinitions.h"
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+// IndexClasses
+
+//IndexerX1X2X3X4:
+//x4-reihen "liegen am stueck" im speicher
+//optimaler schleifendurchlauf
+//for(alle X1)
+//  for(alle X2)
+//    for(alle X3)
+//      for(alle X4)
+class IndexerX1X2X3X4
+{
+public:
+   typedef int size_type;
+public:
+   inline std::size_t getIndex( const size_type& x1 , const size_type& x2 , const size_type& x3 , const size_type& x4
+                            , const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4 )  const
+   {
+      return nx4*(nx3*(nx2*x1+ x2)+x3)+x4 ;
+   }
+   inline std::size_t getStartIndexOfSortedArray(  const size_type& x1 , const size_type& x2 , const size_type& x3 , const size_type& x4
+                                               , const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4 )  const
+   {
+      return  nx4*(nx3*(nx2*x1+ x2)+x3);
+   }
+};
+//////////////////////////////////////////////////////////////////////////
+// IndexClasses
+
+//IndexerX4X3X2X1:
+//x1-reihen "liegen am stueck" im speicher
+//optimaler schleifendurchlauf
+//for(alle X4)
+//  for(alle X3)
+//    for(alle X2)
+//      for(alle X1)
+class IndexerX4X3X2X1
+{
+public:
+   typedef size_t size_type;
+public:
+   inline std::size_t getIndex( const size_type& x1 , const size_type& x2 , const size_type& x3 , const size_type& x4
+      , const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4 )  const
+   {
+      return nx1*(nx2*(nx3*x4+ x3)+x2)+x1;
+   }
+   inline std::size_t getStartIndexOfSortedArray(  const size_type& x1 , const size_type& x2 , const size_type& x3 , const size_type& x4
+      , const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4 )  const
+   {
+      return  nx1*(nx2*(nx3*x4+ x3)+x2);
+   }
+};
+//////////////////////////////////////////////////////////////////////////
+// CbArray4D
+//! \brief 4D Array
+//! \details The data is stored in a vector
+//!
+//! Rangecheck active, if:
+//!
+//! -debug  : not defined "NO_CB_RANGECHECK"
+//!
+//! -release: not defined "NO_CB_RANGECHECK" && defined "CB_RANGECHECK"
+//////////////////////////////////////////////////////////////////////////
+template<typename T, typename IndexClass = IndexerX4X3X2X1>
+class CbArray4D
+{
+public:
+   typedef SPtr< CbArray4D <T,IndexClass> > CbArray4DPtr;
+
+   typedef T                                                   value_type;
+   typedef IndexClass                                          indexer_type;
+   typedef typename IndexClass::size_type                      size_type;
+   typedef typename std::vector< value_type >::reference       reference;
+   typedef typename std::vector< value_type >::const_reference const_reference;
+   typedef typename std::vector< value_type >::pointer         pointer;
+   typedef typename std::vector< value_type >::const_pointer   const_pointer;
+
+private:
+   template< typename value_type2, typename IndexClass2 > friend class CbArray4D;
+
+public:
+   /*=======================================================================*/
+   CbArray4D()
+   {
+      this->resize(0,0,0,0);
+   }
+   /*=======================================================================*/
+   CbArray4D(const size_type& nx1,const size_type& nx2, const size_type& nx3, const size_type& nx4)
+   {
+      this->resize(nx1,nx2,nx3,nx4);
+   }
+   /*=======================================================================*/
+   CbArray4D(const size_type& nx1,const size_type& nx2, const size_type& nx3, const size_type& nx4, const value_type& val)
+   {
+      this->resize(nx1,nx2,nx3,nx4,val);
+   }
+   /*=======================================================================*/
+   CbArray4D(const size_type& uniformDimensionSize /*nx1=nx2=nx3=nx4*/)
+   {
+      this->resize(uniformDimensionSize,uniformDimensionSize,uniformDimensionSize,uniformDimensionSize);
+   }
+   /*=======================================================================*/
+   //ubernimmt vector als daten vector! (erstellt KEINE kopie!!!, vec ist anschließend leer, da swap verwendet wird)
+   CbArray4D(std::vector<value_type>& vec, const size_type& nx1,const size_type& nx2, const size_type& nx3, const size_type& nx4)
+   {
+      assert( (nx1*nx2*nx3*nx4)==vec.size() );
+      this->data.swap(vec);
+      this->resize(nx1,nx2,nx3,nx4);
+   }
+   /*=======================================================================*/
+   CbArray4D(const CbArray4D& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+       , nx3(src.nx3)
+       , nx4(src.nx4)
+       , data(src.data)
+   {
+   }
+   /*=======================================================================*/
+   template< typename value_type2 >
+   CbArray4D(const CbArray4D< value_type2 >& src)
+      :  nx1(src.nx1)
+       , nx2(src.nx2)
+       , nx3(src.nx3)
+       , nx4(src.nx4)
+   {
+      //Sourcedaten kopieren
+      this->data.resize( src.data.size() );
+      for(std::size_t i=0; i<data.size(); ++i)
+         this->data[i] = src.data[i];
+   }
+   /*=======================================================================*/
+   virtual ~CbArray4D()
+   {
+      //vector wird automatisch zerstoert
+   }
+   /*=======================================================================*/
+   CbArray4D& operator= (const CbArray4D& rhs)
+   {
+      if(this == &rhs) return *this;
+
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+      this->nx3 = rhs.nx3;
+      this->nx4 = rhs.nx4;
+
+      //gespeicherte Datenelemente loeschen
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+
+      //Sourcedaten kopieren
+      this->data = rhs.data;
+
+      return *this;
+   }
+   /*=======================================================================*/
+   //durch value_type2 kann man z.B. ein float Array einem double Array zuweisen!
+   template< typename value_type2, typename IndexClass2 >
+   CbArray4D& operator= (const CbArray4D< value_type2, IndexClass2 >& rhs)
+   {
+      this->nx1 = rhs.nx1;
+      this->nx2 = rhs.nx2;
+      this->nx3 = rhs.nx3;
+      this->nx4 = rhs.nx4;
+
+      //gespeicherte Datenelemente loeschen
+      this->data.clear();
+      //Laenge anpassen
+      this->data.resize(rhs.data.size());
+
+      //Sourcedaten kopieren (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      for(int x1=0; x1<this->nx1; x1++)
+         for(int x2=0; x2<this->nx2; x2++)
+            for(int x3=0; x3<this->nx3; x3++)
+               for(int x4=0; x4<this->nx4; x4++)
+                  this->operator()(x1,x2,x3,x4) = static_cast< value_type >( rhs.operator()(x1,x2,x3,x4));
+
+      return *this;
+   }
+   /*=======================================================================*/
+   bool operator== (const CbArray4D& rhs) const
+   {
+      if( this == &rhs ) return true;
+
+      if(   this->nx1!=rhs.nx1
+         || this->nx2!=rhs.nx2
+         || this->nx3!=rhs.nx3
+         || this->nx4!=rhs.nx4
+         || this->data.size() != rhs.data.size() )
+      {
+         return false;
+      }
+
+      return std::equal( this->data.begin(), this->data.end(), rhs.data.begin(), UbEqual<value_type, value_type >() );
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator== (const CbArray4D< value_type2, IndexClass2 >& rhs) const
+   {
+      if( this->data.size() != rhs.data.size() ) return false;
+
+      //Sourcedaten einzeln checken (!! koennte anderen Indexer besitzen!!! -> operator() benutzen)
+      for(int x4=0; x4<this->nx4; x4++)
+         for(int x3=0; x3<this->nx3; x3++)
+            for(int x2=0; x2<this->nx2; x2++)
+             for(int x1=0; x1<this->nx1; x1++)
+               if( !isUbEqual(this->operator()(x1,x2,x3,x4), rhs.operator()(x1,x2,x3,x4)) )
+                  return false;
+
+      return true;
+   }
+   /*=======================================================================*/
+   bool operator!= (const CbArray4D& rhs) const
+   {
+      return !(*this==rhs);
+   }
+   /*=======================================================================*/
+   template< typename value_type2, typename IndexClass2 >
+   bool operator!= (const CbArray4D< value_type2, IndexClass2 >& rhs) const
+   {
+      return !(*this==rhs);
+   }
+   /*=======================================================================*/
+   reference operator() (const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return this->data[indexer.getIndex(x1,x2,x3,x4,nx1,nx2,nx3,nx4)];
+   }
+   /*=======================================================================*/
+   const_reference operator() (const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4)	const
+   {
+      #ifdef CbArray4D_RANGECHECKING
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return this->data[indexer.getIndex(x1,x2,x3,x4,nx1,nx2,nx3,nx4)];
+   }
+   /*=======================================================================*/
+   pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,x3,x4,nx1,nx2,nx3,nx4)];
+   }
+   /*=======================================================================*/
+   const_pointer getStartAdressOfSortedArray(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4)  const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return &this->data[indexer.getStartIndexOfSortedArray(x1,x2,x3,x4,nx1,nx2,nx3,nx4)];
+   }
+   /*=======================================================================*/
+   void setObject(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4, const value_type& value)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      this->data[indexer.getIndex(x1,x2,x3,x4,nx1,nx2,nx3,nx4)] = value;
+   }
+   /*=======================================================================*/
+   reference getObject(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return this->data[indexer.getIndex(x1,x2,x3,x4,nx1,nx2,nx3,nx4)];
+   }
+   /*=======================================================================*/
+   const_reference getObject(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+      return (*this)(x1,x2,x3,x4,nx1,nx2,nx3,nx4);
+   }
+   /*=======================================================================*/
+   bool      isEmpty() const { return data.empty(); }
+   size_type getNX1()  const { return this->nx1;    }
+   size_type getNX2()  const { return this->nx2;    }
+   size_type getNX3()  const { return this->nx3;    }
+   size_type getNX4()  const { return this->nx4;    }
+   /*=======================================================================*/
+   void reset(const value_type& val)
+   {
+      std::fill( this->data.begin(), this->data.end(), val );
+   }
+   /*=======================================================================*/
+   std::string toString() const
+   {
+      std::stringstream text;
+      text<<std::setprecision(19);
+      for(size_type x1=0; x1<this->nx1; x1++)
+      {
+      	for(size_type x2=0; x2<this->nx2; x2++)
+      	{
+         	for(size_type x3=0; x3<this->nx3; x3++)
+         	{
+               for(size_type x4=0; x4<this->nx4; x4++)
+               {
+                 	text<<(*this)(x1,x2,x3,x4)<<", ";
+               }
+               text<<std::endl;
+         	}
+         	text<<std::endl;
+      	}
+      	text<<std::endl<<std::endl;
+      }
+
+      return text.str();
+   }
+   /*=======================================================================*/
+   std::string getInfo() const
+   {
+      std::stringstream text;
+      text<<"CbArray4D< storageType="<<typeid(T).name()<<", indexer="<<typeid(IndexClass).name()<<" >";
+      text<<"( nx1="<<this->nx1<<", nx2="<<this->nx2<<", nx3="<<this->nx3<<", nx4="<<this->nx4<<")";
+      return text.str();
+   }
+   /*=======================================================================*/
+   void resize(const size_type& uniformDimensionSize) { this->resize(uniformDimensionSize,uniformDimensionSize,uniformDimensionSize); }
+   /*=======================================================================*/
+   void resize(const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4)
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->nx3 = nx3;
+      this->nx4 = nx4;
+      this->data.resize(nx1*nx2*nx3*nx4);
+   }
+   /*=======================================================================*/
+   void resize(const size_type& nx1, const size_type& nx2, const size_type& nx3, const size_type& nx4, const value_type& val)
+   {
+      this->nx1 = nx1;
+      this->nx2 = nx2;
+      this->nx3 = nx3;
+      this->nx4 = nx4;
+      this->data.resize(nx1*nx2*nx3*nx4,val);
+   }
+   /*=======================================================================*/
+   std::vector< value_type >& getDataVector() { return this->data; }
+   /*=======================================================================*/
+   const std::vector< value_type >& getDataVector() const { return this->data; }
+   /*=======================================================================*/
+   inline std::size_t getDataVectorIndex(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if( !this->indicesInRange(x1,x2,x3,x4) )
+            UB_THROW( UbException(UB_EXARGS,getExceptionErrorString(x1,x2,x3,x4)) );
+      #endif
+
+      return indexer.getIndex(x1,x2,x3,x4,nx1,nx2,nx3,nx4);
+   }
+
+protected:
+   /*=======================================================================*/
+   //success -> true
+   //else    -> false
+   inline bool indicesInRange(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4) const
+   {
+      if(   x1 < 0 || x1 >= this->nx1
+         || x2 < 0 || x2 >= this->nx2
+         || x3 < 0 || x3 >= this->nx3
+         || x4 < 0 || x4 >= this->nx4 )
+      {
+         return false;
+      }
+      return true;
+   }
+   /*=======================================================================*/
+   std::string getExceptionErrorString(const size_type& x1, const size_type& x2, const size_type& x3, const size_type& x4) const
+   {
+      std::stringstream out("index out of range - ");
+      out<<"("<<x1<<","<<x2<<","<<x3<<","<<x4<<") not in ("<<nx1<<","<<nx2<<","<<nx3<<","<<nx4<<")";
+      return out.str();
+   }
+   /*=======================================================================*/
+
+protected:
+   size_type    nx1;
+   size_type    nx2;
+   size_type    nx3;
+   size_type    nx4;
+   indexer_type indexer;
+   std::vector< value_type > data;
+
+};
+
+#endif //CBARRAY4D_H
diff --git a/VirtualFluidsBasics/basics/container/CbVector.h b/VirtualFluidsBasics/basics/container/CbVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..b33ad1a44ea4afa13107326fd68cd0f08adfe10b
--- /dev/null
+++ b/VirtualFluidsBasics/basics/container/CbVector.h
@@ -0,0 +1,307 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CbVector.h
+//! \ingroup container
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef CBVECTOR_H
+#define CBVECTOR_H
+
+#include <vector>
+#include <algorithm> //for std::swap
+#include <typeinfo>  //for typeid
+#include <PointerDefinitions.h>    //for memcopy
+
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbEqual.h>
+
+template< typename T > class CbVectorAllocator;
+template< typename T > class CbVectorAllocatorStd;
+
+//=========================================================================
+//! \brief A class implements a container like a vector
+//! \details
+//! For this class it was required to ave only the type as template argument.
+//! Hence, the allocator must be an abstract class. With out this requirement, 
+//! an allocator as second template argument would have been possible, as in the
+//! STL vector. This would lead to the compiler generating two different classes
+//! for the same data type with different allocators during compile time. Here it
+//! is required that the same class can have different allocators.
+//!
+//! Rangecheck active, if:
+//! -debug  : not defined "NO_CB_RANGECHECK"
+//! -release: not defined "NO_CB_RANGECHECK" && defined "CB_RANGECHECK"
+//=========================================================================
+//////////////////////////////////////////////////////////////////////////
+template< typename T >
+class CbVector
+{
+public:
+   typedef T           value_type;
+   typedef value_type* pointer;
+   typedef std::size_t size_type;
+
+   friend class CbVectorAllocator<value_type>; //um auf ptrData und dataSize zugreifen zu koennen!
+
+public:
+   /*==========================================================*/
+   CbVector( CbVectorAllocator<value_type>* const& allocator = new CbVectorAllocatorStd<value_type> )
+      :  ptrData(NULL)
+       , dataSize(0)
+       , allocator(allocator)
+   {
+      this->allocator->alloc(*this,0,value_type());
+   }
+   /*==========================================================*/
+   CbVector( const size_type size, CbVectorAllocator<value_type>* const& allocator = new CbVectorAllocatorStd<value_type>, const value_type& value=value_type() )
+      :  ptrData(NULL)
+       , dataSize(0)
+       , allocator(allocator)
+   {
+      this->allocator->alloc(*this,size,value);
+   }
+   /*==========================================================*/
+   virtual ~CbVector()
+   {
+      if(allocator)
+      {
+         this->allocator->dealloc(*this);
+         delete allocator;
+         allocator=NULL;
+      }
+   }
+   /*=======================================================================*/
+   CbVector& operator= (const CbVector& src)
+   {
+      if(this == &src) return *this;
+
+      //gespeicherte Datenelemente loeschen
+      //Laenge anpassen
+      this->allocator->resize(*this, src.size());
+
+      //gespeicherte Datenelemente kopieren
+      if( !src.empty() ) 
+      {
+         memcpy( (char*)ptrData, (char*)&src[0], src.size()*sizeof(value_type) ); 
+         //for(size_type i=0; i<src.size(); i++)
+         //   (*this)[i] = src[i];
+      }
+
+      return *this;
+   }
+   /*=======================================================================*/
+   CbVector& operator= (const std::vector< value_type >& src)
+   {
+      //gespeicherte Datenelemente loeschen
+      //Laenge anpassen
+      this->allocator->resize(*this, src.size());
+
+      //gespeicherte Datenelemente kopieren
+      if( !src.empty() ) 
+      {
+         memcpy( (char*)ptrData, (char*)&src[0], src.size()*sizeof(value_type) ); 
+         //for(size_type i=0; i<src.size(); i++)
+         //   (*this)[i] = src[i];
+      }
+      
+      return *this;
+   }
+   /*=======================================================================*/
+   bool operator== (const CbVector& rhs) const
+   {
+      if( this           == &rhs         ) return true;
+      if( this->dataSize != rhs.dataSize ) return false;
+
+      for(size_type i=0; i<rhs.size(); i++)
+         if( !isUbEqual( this->operator[](i), rhs.operator[](i) ) )
+            return false;
+
+      return true;
+   }
+   /*==========================================================*/
+   void setAllocator( CbVectorAllocator<value_type>* const& allocator )
+   {
+      if(this->allocator)
+      {
+         if(this->allocator==allocator) return;
+         this->allocator->dealloc(*this);
+         delete this->allocator;
+      }
+      this->allocator = allocator;
+      this->allocator->alloc(*this,0);
+   }
+   /*==========================================================*/
+   size_type size() const { return dataSize; }
+   /*==========================================================*/
+   bool empty() const { return dataSize==0; }
+   /*==========================================================*/
+   bool resize(const size_type& dataSize)
+   {
+      return allocator->resize(*this, dataSize);
+   }
+   /*==========================================================*/
+   bool resize(const size_type& dataSize, const value_type& value)
+   {
+      return allocator->resize(*this, dataSize, value);
+   }
+   /*==========================================================*/
+   void swap(CbVector& rhs)
+   {
+      if( this == &rhs ) return;
+
+      std::swap( this->ptrData  , rhs.ptrData   );
+      std::swap( this->dataSize , rhs.dataSize  );
+      std::swap( this->allocator, rhs.allocator );
+   }
+   /*==========================================================*/
+   value_type& operator[](const size_type& i)
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if(i>=dataSize) 
+            UB_THROW( UbException(UB_EXARGS,"T="+(std::string)typeid(*this).name()+UbSystem::toString(i)+" out of range (size="+UbSystem::toString(dataSize)+")") );
+      #endif // _DEBUG
+
+      return ptrData[i];
+   }
+   /*==========================================================*/
+   const value_type& operator[](const size_type& i) const
+   {
+      #if !defined(NO_CB_RANGECHECK) && ( defined(_DEBUG) || defined(CB_RANGECHECK) )
+         if(i>=dataSize) 
+            UB_THROW( UbException(UB_EXARGS,"T="+(std::string)typeid(*this).name()+UbSystem::toString(i)+" out of range (size="+UbSystem::toString(dataSize)+")") );
+      #endif // _DEBUG
+
+      return ptrData[i];
+   }
+   /*==========================================================*/
+   CbVectorAllocator<value_type>* getAllocator() const { return allocator; }
+   /*==========================================================*/
+
+private:
+   value_type* ptrData;
+   size_type   dataSize;
+   CbVectorAllocator<value_type>* allocator;
+   CbVector<value_type>(const CbVector<value_type>& src);
+   //CbVector<value_type>& operator=(const CbVector<value_type>& src);
+};
+
+//////////////////////////////////////////////////////////////////////////
+// CbVectorAllocator-Interface
+//////////////////////////////////////////////////////////////////////////
+template< typename T >
+class CbVectorAllocator
+{
+public:
+   typedef typename CbVector<T>::value_type          value_type;
+   typedef typename CbVector<value_type>::size_type  size_type;
+
+public:
+   CbVectorAllocator() {}
+   virtual ~CbVectorAllocator() {}
+
+   virtual bool alloc(CbVector< value_type >& vec, const size_type& dataSize, const value_type& value=value_type()) = 0;
+   virtual bool resize(CbVector< value_type >& vec, const size_type& dataSize, const value_type& value=value_type()) = 0;
+   virtual bool dealloc(CbVector< value_type >& vec) = 0;
+
+protected:
+   //folgende Methoden ersparen eine friend Deklaierung aller moeglichen Allocatoren
+   //denn durch diese beiden Methoden haben sie exklusive Zugriffsrechte!
+   //**********************************************************************************//
+   inline value_type*& ptrDataOf( CbVector< value_type >& vec )
+   {
+      if( vec.getAllocator()!=this ) UB_THROW( UbException(UB_EXARGS,"allocator is not member of vec!") );
+      return vec.ptrData;
+   }
+   //**********************************************************************************//
+   inline size_type& dataSizeOf( CbVector< value_type >& vec )
+   {
+      if( vec.getAllocator()!=this ) UB_THROW( UbException(UB_EXARGS,"allocator is not member of vec!") );
+      return vec.dataSize;
+   }
+};
+
+//////////////////////////////////////////////////////////////////////////
+// CbVectorAllocatorStd
+//////////////////////////////////////////////////////////////////////////
+template< typename T >
+class CbVectorAllocatorStd : public CbVectorAllocator<T>
+{
+public:
+   //typedefs wiederholen, da Basisklasse = template -> "Dependent-Base"-Problem
+   typedef typename CbVector<T>::value_type          value_type;
+   typedef typename CbVector<value_type>::size_type  size_type;
+
+public:
+   CbVectorAllocatorStd() : CbVectorAllocator<value_type>()
+   {
+
+   }
+   /*==========================================================*/
+   bool alloc(CbVector< value_type >& src, const size_type& dataSize, const value_type& value=value_type())
+   {
+      return this->resize(src,dataSize,value);
+   }
+   /*==========================================================*/
+   bool resize(CbVector< value_type >& vec, const size_type& dataSize, const value_type& value=value_type())
+   {
+      if( CbVectorAllocatorStd< value_type >::dataSizeOf(vec) == dataSize) return false;
+
+      //new array
+      value_type* new_data = new value_type[dataSize];
+      //copy existing data to array
+      if( this->ptrDataOf(vec) )
+      {
+         for(size_type i=0; (i<vec.size() && i<dataSize); ++i) new_data[i] = CbVectorAllocatorStd< value_type >::ptrDataOf(vec)[i];
+         delete[] this->ptrDataOf(vec);
+      }
+      this->ptrDataOf(vec) = new_data;
+      //new value for new items
+      for(size_type i=this->dataSizeOf(vec); i<dataSize; ++i) this->ptrDataOf(vec)[i] = value;
+      //assign new dataSize
+      this->dataSizeOf(vec) = dataSize;
+
+      return true;
+   }
+   /*==========================================================*/
+   bool dealloc(CbVector< value_type >& vec)
+   {
+      if( this->ptrDataOf(vec) )
+      {
+         delete[] this->ptrDataOf(vec);
+         this->ptrDataOf(vec) = NULL;
+      }
+      this->dataSizeOf(vec) = 0;
+      return true;
+   }
+   /*==========================================================*/
+
+private:
+};
+
+#endif //CBVECTOR_H
diff --git a/VirtualFluidsBasics/basics/objects/CMakePackage.txt b/VirtualFluidsBasics/basics/objects/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsBasics/basics/objects/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsBasics/basics/objects/ObObject.h b/VirtualFluidsBasics/basics/objects/ObObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fee350654bbdac50e31d70414c2f3bd9cfbe1a6
--- /dev/null
+++ b/VirtualFluidsBasics/basics/objects/ObObject.h
@@ -0,0 +1,61 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file ObObject.h
+//! \ingroup objects
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef OBOBJECT_H
+#define OBOBJECT_H
+
+#include <string>
+
+#include <basics/utilities/UbObservable.h>
+
+class ObObject : public UbObservable
+{
+public:
+   ObObject() : name("") { }
+   ObObject(const std::string& name) : name(name) { }
+
+   virtual ~ObObject() { }
+
+   virtual ObObject*   clone()=0;
+
+   virtual std::string getName()  { return name; }
+   void setName(std::string name) { this->name=name; }
+
+   virtual std::string toString()=0;
+
+
+private:
+   std::string name;
+};
+
+
+#endif
diff --git a/VirtualFluidsBasics/basics/utilities/CMakePackage.txt b/VirtualFluidsBasics/basics/utilities/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0127c6fb70ba58900bfa7e273ffb1e02ece1c37e
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/CMakePackage.txt
@@ -0,0 +1,21 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES outOption)
+
+IF(${outOption})
+   IF(WIN32)
+      ADD_DEFINITIONS( -DNOMINMAX )
+   ENDIF(WIN32) 
+   
+   IF(BOOST_VERSION)
+    OPTION(USE_THREADSAFE_LOGGER "ON=thread safe, OFF=not thread safe" ON)
+    IF(NOT ${outOption})
+      ADD_DEFINITIONS( -DNO_THREADSAFE_LOGGING)
+    ELSE()
+      SET(NECESSARY_BOOST_LIBS ${NECESSARY_BOOST_LIBS} thread)
+    ENDIF()
+   ELSE()
+    #um die thread safe zu machen benoetigt man boost
+    ADD_DEFINITIONS( -DNO_THREADSAFE_LOGGING)
+   ENDIF()
+  
+ENDIF()
\ No newline at end of file
diff --git a/VirtualFluidsBasics/basics/utilities/UbComparators.h b/VirtualFluidsBasics/basics/utilities/UbComparators.h
new file mode 100644
index 0000000000000000000000000000000000000000..11f85e18b1cd63b0a5b0eb1f75e07d9fdb6e7aa6
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbComparators.h
@@ -0,0 +1,231 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbComparators.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBCOMPARATORS_H 
+#define UBCOMPARATORS_H
+
+#include <functional> 
+
+namespace UbComparators
+{
+   //type_traits 
+   template <typename T> struct MemberInfo; //not defined for correct compiler errors!
+
+   // specialization for MemberFunctionsPtr
+   // C - class with return T method
+   template <typename T, typename C> 
+   struct MemberInfo<T C::*> 
+   { 
+      typedef T type; 
+      typedef C class_type; 
+
+      static       T& apply(       C& c, T C::* ptr ) { return c.*ptr; } 
+      static const T& apply( const C& c, T C::* ptr ) { return c.*ptr; } 
+   }; 
+   //specialization for MemberFunctionsPtr
+   //C - class with return T method
+   template <typename T, typename C> 
+   struct MemberInfo<T (C::*)()> 
+   { 
+      typedef T type; 
+      typedef C class_type; 
+
+      static T apply( C& c, T (C::*ptr)() ) { return (c.*ptr)(); } 
+   }; 
+   //specialization for const MemberFunctionsPtr
+   //C - class with return T method
+   template <typename T, typename C> 
+   struct MemberInfo<T (C::*)() const> 
+   { 
+      typedef T type; 
+      typedef C class_type; 
+
+      static T apply( const C& c, T (C::*ptr)() const ) { return (c.*ptr)(); } 
+   }; 
+
+   //MemberComparative-Class
+   template <typename Ptr, typename Comp = std::less<typename MemberInfo<Ptr>::type> > 
+   class MemComp 
+      : private Comp  // -> usage of Empty Base Class Optimization (EBCO) 
+   { 
+      typedef typename MemberInfo<Ptr>::class_type C; 
+
+   public: 
+      MemComp( Ptr ptr, Comp c = Comp() ) 
+         : Comp(c), mp_(ptr) 
+      {} 
+
+      bool operator()(C& lhs, C& rhs) 
+      { 
+         return Comp::operator()( MemberInfo<Ptr>::apply(lhs, mp_), MemberInfo<Ptr>::apply(rhs, mp_) ); 
+      } 
+      bool operator()(C& lhs, C& rhs) const 
+      { 
+         return Comp::operator()( MemberInfo<Ptr>::apply(lhs, mp_), MemberInfo<Ptr>::apply(rhs, mp_) ); 
+      } 
+      bool operator()(const C& lhs, const C& rhs) 
+      { 
+         return Comp::operator()( MemberInfo<Ptr>::apply(lhs, mp_), MemberInfo<Ptr>::apply(rhs, mp_) ); 
+      } 
+      bool operator()(const C& lhs, const C& rhs) const 
+      { 
+         return Comp::operator()( MemberInfo<Ptr>::apply(lhs, mp_), MemberInfo<Ptr>::apply(rhs, mp_) ); 
+      } 
+
+   private: 
+      Ptr mp_; 
+   }; 
+
+   // Factoryfunktionen 
+   template <typename Ptr> 
+   MemComp<Ptr> membercomp(Ptr p) 
+   { 
+      return MemComp<Ptr>(p); 
+   } 
+
+   template<typename Comp, typename Ptr> 
+   MemComp<Ptr, Comp> membercomp(Ptr p, Comp c = Comp()) 
+   { 
+      return MemComp<Ptr, Comp>(p, c); 
+   } 
+
+   template<template<typename> class Comp, typename Ptr> 
+   MemComp<Ptr, Comp<typename MemberInfo<Ptr>::type> > 
+      membercomp(Ptr p, Comp<typename MemberInfo<Ptr>::type> c = Comp<typename MemberInfo<Ptr>::type>()) 
+   {
+      return MemComp<Ptr, Comp<typename MemberInfo<Ptr>::type> >(p, c); 
+   } 
+
+    
+   //////////////////////////////////////////////////////////////////////////
+   //////////////////////////////////////////////////////////////////////////
+   //////////////////////////////////////////////////////////////////////////
+   //andere Variante (alerdings ist hier keine Deduction moeglich!!!)
+   //////////////////////////////////////////////////////////////////////////
+   //Vergleichs-Templates:
+   //Funktor zum "non-const" Methodenvergleich: liste.sort( compareMethods<Klasse, int, &Klasse::getVal1  );
+   template<typename K/*Klasse*/, typename M /*MethodenRueckgabeTyp*/, M (K::*fct)() /*MethodenPointer*/> // Allgemeiner Fall
+   struct compareMethods
+   {
+      bool operator()(K& r, K& l) const // da fct nicht const ist, kann auch K nicht const sein. das const hinter der deklaration besagt dass compareMethods const sein kann
+      { return (r.*fct)() < (l.*fct)();  }
+   };
+   //////////////////////////////////////////////////////////////////////////
+   //Funktor zum "const" Methodenvergleich: liste.sort( compareMethods<Klasse, int, &Klasse::getVal1  );
+   template<typename K/*Klasse*/, typename M /*MethodenRueckgabeTyp*/, M (K::*fct)() const /*MethodenPointer*/> // <- hier const 
+   struct compareConstMethods
+   {
+      bool operator()(const K& r, const K& l) const //hier koennen die K's auch const sein, muessen sie aber nicht (const hinzufuegen geht ja problemlos)
+      { return (r.*fct)() < (l.*fct)();  }
+   };
+   //////////////////////////////////////////////////////////////////////////
+   //Funktor zum Membervergleich: lise.sort( compareMember<Klasse, int, &Klasse::member>() );
+   template<typename K/*Klasse*/, typename M /*MemberTyp*/, M (K::*Member) /*MemberPointer*/> // <- hier const 
+   struct compareMember
+   { 
+      bool operator()(const K& r,const K& l) const
+      { return r.*Member < l.*Member; } 
+   };
+   //Bsp:
+   //class Klasse{ 
+   //public: 
+   //   Klasse(double val1, double val2 ) : val1(val1),val2(val2) {} 
+   //   double getVal1()       { return val1; } 
+   //   double getVal2() const { return val2; } // <- hier const
+   //   double val1, val2; 
+   //}; 
+   //int main(int argc, char** argv){ 
+   //   std::list<Klasse> l; 
+   //   l.push_back( Klasse(10,10) ); 
+   //   l.push_back( Klasse(1,5)   ); 
+   //   l.sort( compareMember<Klasse, double,  &Klasse::val1 >() ); 
+   //   l.sort( compareMethods<Klasse, double,  &Klasse::getVal1 >() ); 
+   //   l.sort( compareConstMethods<Klasse, double,  &Klasse::getVal1 >() ); 
+   //} 
+
+};
+
+#endif //UBCOMPARATOR_H
+
+//example
+// #include <basics/utilities/UbComparators.h" 
+// #include <list> 
+// using namespace std; 
+// using namespace UbComparators; 
+// 
+// struct S { 
+//    S(int i) :x(i) {} 
+//    int x; 
+//    float f() {return x;}; 
+//    double g() const {return x;} 
+// }; 
+// 
+// struct intComp { 
+//    bool operator()(int l, int r) const 
+//    { return l > r; } 
+// }; 
+// 
+// struct dblComp { 
+//    bool operator()(double l,  double r) const 
+//    { return l > r; } 
+// }; 
+// 
+// template <typename T> 
+// struct genComp { 
+//    bool operator()(const T& l, const T& r) const
+//    { return l > r; } 
+// }; 
+// 
+// 
+// int main() 
+// { 
+//    S a(1); 
+//    S b(2); 
+//    list<S> sList; 
+//    sList.push_back(a); 
+//    sList.push_back(b); 
+//    sList.sort(UbComparators::membercomp(&S::x,intComp()));  //calls overload (1) 
+//    sList.sort(UbComparators::membercomp<intComp>(&S::x));   //same 
+//    sList.sort(UbComparators::membercomp(&S::x));            //calls overload (5) 
+//    sList.sort(UbComparators::membercomp<genComp>(&S::x));   //calls overload(3) 
+//    sList.sort(UbComparators::membercomp(&S::x, genComp<int>())); //calls overload(1) 
+//    //same for nonconst function 
+//    sList.sort(UbComparators::membercomp(&S::f, dblComp())); //overload(2) 
+//    sList.sort(UbComparators::membercomp<dblComp>(&S::f));   //same      
+//    sList.sort(UbComparators::membercomp(&S::f));            //overload(6) 
+//    sList.sort(UbComparators::membercomp<genComp>(&S::f));   //overload(4) 
+//    //same for const function 
+//    sList.sort(UbComparators::membercomp(&S::g, dblComp())); //overload(2) 
+//    sList.sort(UbComparators::membercomp<dblComp>(&S::g));   //same      
+//    sList.sort(UbComparators::membercomp(&S::g));            //overload(6) 
+//    sList.sort(UbComparators::membercomp<genComp>(&S::g));   //overload(4) 
+// } 
diff --git a/VirtualFluidsBasics/basics/utilities/UbEqual.h b/VirtualFluidsBasics/basics/utilities/UbEqual.h
new file mode 100644
index 0000000000000000000000000000000000000000..483e50a799c3afd1eab055bba3f243413774472c
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbEqual.h
@@ -0,0 +1,145 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbEqual.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBEQUAL_H
+#define UBEQUAL_H
+
+#include<cmath>
+
+//////////////////////////////////////////////////////////////////////////
+//
+//! \brief isUbEqual<T1,T2>(a,b)
+//! Compares the equality of values a and b.
+//!
+//! By default operator== is used for this.
+//!
+//! Execption: floating-point variables
+//! In these cases the type with higher precision is casted to the type of lower precision
+//! and then the two values are compared.
+//! e.g.: double d=1.2; int i=1; bool check = isUbEqual(d,i); -> true
+//!
+//! For classes operator== must be implemented for const objects!
+//! e.g.: bool operator==(const Test&) const { if(blabla) return true; else return false; }
+//
+//////////////////////////////////////////////////////////////////////////
+
+//std-trait, fuer alle nicht spezifischen typen:
+template < typename T1, typename T2 >
+struct UbEqualTrait
+{
+   typedef T1 High;
+   typedef T1 Low;
+};
+
+//std-trait, fuer gleiche T
+template < typename T >
+struct UbEqualTrait< T, T >
+{
+   typedef T High;
+   typedef T Low;
+};
+
+//spezialisierung für diverse Typen-Tuples
+template<> struct UbEqualTrait< short, int >          { typedef int         High; typedef short  Low; };
+template<> struct UbEqualTrait< short, long >         { typedef long        High; typedef short  Low; };
+template<> struct UbEqualTrait< short, float >        { typedef float       High; typedef short  Low; };
+template<> struct UbEqualTrait< short, double >       { typedef double      High; typedef short  Low; };
+template<> struct UbEqualTrait< short, long double >  { typedef long double High; typedef short  Low; };
+
+template<> struct UbEqualTrait< int, short >          { typedef int         High; typedef short  Low; };
+template<> struct UbEqualTrait< int, long >           { typedef long        High; typedef int    Low; };
+template<> struct UbEqualTrait< int, float >          { typedef float       High; typedef int    Low; };
+template<> struct UbEqualTrait< int, double >         { typedef double      High; typedef int    Low; };
+template<> struct UbEqualTrait< int, long double >    { typedef long double High; typedef int    Low; };
+
+template<> struct UbEqualTrait< long, short >         { typedef long        High; typedef short  Low; };
+template<> struct UbEqualTrait< long, int >           { typedef long        High; typedef int    Low; };
+template<> struct UbEqualTrait< long, float >         { typedef float       High; typedef long   Low; };
+template<> struct UbEqualTrait< long, double >        { typedef double      High; typedef long   Low; };
+template<> struct UbEqualTrait< long, long double >   { typedef long double High; typedef long   Low; };
+
+template<> struct UbEqualTrait< float, short >        { typedef float       High; typedef short  Low; };
+template<> struct UbEqualTrait< float, int >          { typedef float       High; typedef int    Low; };
+template<> struct UbEqualTrait< float, long >         { typedef float       High; typedef long   Low; };
+template<> struct UbEqualTrait< float, double >       { typedef double      High; typedef float  Low; };
+template<> struct UbEqualTrait< float, long double >  { typedef long double High; typedef float  Low; };
+
+template<> struct UbEqualTrait< double, short >       { typedef double      High; typedef short  Low; };
+template<> struct UbEqualTrait< double, int >         { typedef double      High; typedef int    Low; };
+template<> struct UbEqualTrait< double, long >        { typedef double      High; typedef long   Low; };
+template<> struct UbEqualTrait< double, float >       { typedef double      High; typedef float  Low; };
+template<> struct UbEqualTrait< double, long double > { typedef long double High; typedef double Low; };
+
+template<> struct UbEqualTrait< long double, short >  { typedef long double High; typedef short  Low; };
+template<> struct UbEqualTrait< long double, int >    { typedef long double High; typedef int    Low; };
+template<> struct UbEqualTrait< long double, long >   { typedef long double High; typedef long   Low; };
+template<> struct UbEqualTrait< long double, float >  { typedef long double High; typedef float  Low; };
+template<> struct UbEqualTrait< long double, double > { typedef long double High; typedef double Low; };
+
+//////////////////////////////////////////////////////////////////////////
+//fuer Allgmeine-Typen ( operator== ):
+template< typename T1, typename T2 >
+inline bool specific_equal(const T1& a, const T2& b) { return a==b; }
+
+//////////////////////////////////////////////////////////////////////////
+//fuer floating point build-in-type
+//float.float
+template< /*float,float*/>
+inline bool specific_equal< float, float >(const float& a, const float& b) {  return std::fabs( a - b ) < 1E-8; }
+
+template</*double,double*/>
+inline bool specific_equal< double, double >(const double& a, const double& b) { return std::fabs( a - b ) < 1E-13; }
+
+template</*long double,long double*/>
+inline bool specific_equal< long double, long double >(const long double& a, const long double& b) { return std::fabs( a - b ) < 1E-16; }
+
+//////////////////////////////////////////////////////////////////////////
+//globale isUbEqual - Funktion
+template< typename T1, typename T2 >
+inline bool isUbEqual(const T1& a, const T2& b)
+{
+   typedef typename UbEqualTrait<T1,T2>::Low Low;
+   return specific_equal< Low, Low >(static_cast< Low >( a ),static_cast< Low >( b ));
+};
+
+//////////////////////////////////////////////////////////////////////////
+//UbEqual-Functor
+template< typename T1, typename T2 >
+struct UbEqual
+{
+   bool operator()(const T1& a, const T2& b)
+   {
+      return isUbEqual(a,b);
+   }
+};
+
+#endif //UBEQUAL_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbException.h b/VirtualFluidsBasics/basics/utilities/UbException.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb8550c1e0523683440d13fff879111cf09c924f
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbException.h
@@ -0,0 +1,177 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbException.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBEXCEPTION_H
+#define UBEXCEPTION_H
+
+#include <vector>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+
+#include "./UbTuple.h"
+
+//=========================================================================
+//
+//! \brief UbException
+//! usage: UB_THROW( UbException("error message") );
+//!        UB_THROW( UbException(__FILE__, __LINE__,"error message") );
+//!        UB_THROW( UbException(__FILE__, __LINE__,UB_FUNCTION,"error message") );
+//!        UB_THROW( UbException(UB_EXARGS,"error") ); //same as above
+//
+//=========================================================================
+
+//Macro UB_FUNCTION: figures out the method/function name (platform dependant)
+#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600))
+ # define UB_FUNCTION __PRETTY_FUNCTION__
+#elif defined(__DMC__) && (__DMC__ >= 0x810)
+ # define UB_FUNCTION __PRETTY_FUNCTION__
+#elif defined(__FUNCSIG__)
+ # define UB_FUNCTION __FUNCSIG__
+#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
+ # define UB_FUNCTION __FUNCTION__
+#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
+ # define UB_FUNCTION __FUNC__
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
+ # define UB_FUNCTION __func__
+#else
+ # define UB_FUNCTION "(unknown)"
+#endif
+
+//Helper Marco
+#define UB_EXARGS __FILE__,__LINE__,UB_FUNCTION
+
+#ifdef CAB_BOOST
+   #define UB_THROW(e) throw boost::enable_current_exception(e)
+#else
+   #define UB_THROW(e) throw e
+#endif
+
+class UbException : public std::runtime_error
+{
+public:
+   typedef UbTuple< std::string, int, std::string, std::string > ExceptionData;
+public:
+   //////////////////////////////////////////////////////////////////////////
+   //constructors
+   UbException()
+      : std::runtime_error("")
+   { 
+   }
+   /*==========================================================*/
+   UbException(const std::string& str)
+      : std::runtime_error("")
+   {
+      this->addInfo(str);		
+   }
+   /*==========================================================*/
+   UbException(const std::string& file, const int& line, const std::string& err_str)
+      : std::runtime_error("")
+   {
+      this->addInfo(file,line,"unknown",err_str);		
+   }
+   /*==========================================================*/
+   //UbException(const char* file, const int& line, const char* function, const std::string& err_str)
+   UbException(const std::string& file, const int& line, const std::string& function, const std::string& err_str)
+      : std::runtime_error("")
+   {
+      this->addInfo(file,line,function,err_str);		
+   }
+   //////////////////////////////////////////////////////////////////////////
+   //destructor
+   virtual ~UbException() throw() { }
+   //////////////////////////////////////////////////////////////////////////
+   //virtual public methods
+   //returns  exception-string
+   virtual const char* what() const throw()
+   {
+      exceptionString = this->toString();
+      return exceptionString.c_str();  //ansonsten ist das Verhalten anschließend undefiniert!
+   }
+   /*==========================================================*/
+   virtual void addInfo(const std::string& err_str)	 
+   { 
+      exceptionData.push_back( makeUbTuple( (std::string)"-", 0, (std::string)"unknown", err_str) ); 
+   }
+   /*==========================================================*/
+   //add exception
+   virtual void addInfo(const std::string& file, const int& line, const std::string& function, const std::string& err_str)	 
+   { 
+      exceptionData.push_back( makeUbTuple( file, line, function, err_str ) ); 
+   }
+   /*==========================================================*/
+   //returns exception-string with all calles exceptions
+   virtual const std::vector<std::string> getInfo() const
+   { 
+      std::vector<std::string> tmp;
+      for(std::size_t i=0; i<exceptionData.size(); i++)
+      {
+         std::stringstream str;
+         str << val<1>( exceptionData[i] ) << ", " 
+             << val<2>( exceptionData[i] ) << ", " 
+             << val<3>( exceptionData[i] ) << ", " 
+             << val<4>( exceptionData[i] );
+         tmp.push_back( str.str());
+      }
+      return tmp; 
+   }
+   /*==========================================================*/
+   //returns exception-string with all calles exceptions and detailes informations
+   virtual std::string toString() const
+   { 
+      std::stringstream str("UbExeption");
+      
+      for(std::size_t i=0; i<exceptionData.size(); i++)
+         str<<(std::string)"caller[" << i << "]\n"
+            <<"  - file:     "<< val<1>( exceptionData[i] )<<"\n"
+            <<"  - line:     "<< val<2>( exceptionData[i] )<<"\n"
+            <<"  - function: "<< val<3>( exceptionData[i] )<<"\n"
+            <<"  - what:     "<< val<4>( exceptionData[i] )<< std::endl; 
+
+      return str.str();
+   }
+
+protected:
+   //////////////////////////////////////////////////////////////////////////
+   //protected member
+   std::vector< ExceptionData > exceptionData;
+   mutable std::string exceptionString;
+};
+
+//overlading operator <<
+inline std::ostream& operator<<(std::ostream& os, const UbException& e)
+{
+   return os<<e.toString();
+}
+
+#endif //UBEXCEPTION_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbInfinity.h b/VirtualFluidsBasics/basics/utilities/UbInfinity.h
new file mode 100644
index 0000000000000000000000000000000000000000..eebaf14166552ccbe4a23a516d28d2594c87494f
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbInfinity.h
@@ -0,0 +1,210 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbInfinity.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UB_INFINITY_H
+#define UB_INFINITY_H
+#include <limits>
+
+#include <basics/utilities/UbLimits.h>
+#include <basics/utilities/UbSystem.h>
+
+//////////////////////////////////////////////////////////////////////////
+//!
+//!  \brief UbNegInfinity
+//!  \details Note: The UbNegInfinity class cannot be instantiated on its own, but works 
+//!        as a base class for the Infinity class.
+//!
+//////////////////////////////////////////////////////////////////////////
+
+class UbNegInfinity
+{
+ public:
+   //name Conversion operators 
+   inline operator signed char() const { return UbLimits<signed char>::ninf(); }
+   inline operator char()        const { return UbLimits<char>::ninf();        }
+   inline operator wchar_t()     const { return UbLimits<wchar_t>::ninf();     }
+   inline operator short()       const { return UbLimits<short>::ninf();       }
+   inline operator int()         const { return UbLimits<int>::ninf();         }
+   inline operator long()        const { return UbLimits<long>::ninf();        }
+   inline operator float()       const { return UbLimits<float>::ninf();       }
+   inline operator double()      const { return UbLimits<double>::ninf();      }
+   inline operator long double() const { return UbLimits<long double>::ninf(); }
+
+   //! This function compares built-in data types with their largest possible value. The function
+   //! only works for built-in data types. The attempt to compare user-defined class types will
+   //! result in a compile time error.
+   template< typename T >
+   inline bool equal( const T& rhs ) const
+   {
+      UB_STATIC_ASSERT( std::numeric_limits<T>::is_specialized );
+      return UbLimits<T>::ninf() == rhs;
+   }
+ protected:
+    inline UbNegInfinity() {}
+
+ private:
+   UbNegInfinity( const UbNegInfinity& ninf );             //copy constructor (private & undefined)
+   UbNegInfinity& operator=( const UbNegInfinity& ninf );  //copy assignment operator (private & undefined)
+   void* operator&() const;                                //address operator (private & undefined)
+};
+
+//=================================================================================================
+//
+//  GLOBAL OPERATORS
+//
+//=================================================================================================
+template< typename T >
+inline bool operator==( const UbNegInfinity& lhs, const T& rhs )
+{
+   return lhs.equal( rhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator==( const T& lhs, const UbNegInfinity& rhs )
+{
+   return rhs.equal( lhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator!=( const UbNegInfinity& lhs, const T& rhs )
+{
+   return !lhs.equal( rhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator!=( const T& lhs, const UbNegInfinity& rhs )
+{
+   return !rhs.equal( lhs );
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+//  UbInfinity
+//
+//////////////////////////////////////////////////////////////////////////
+class UbInfinity : public UbNegInfinity //um später -UbInfinity leichter zu implementieren!!!
+{
+ public:
+   inline UbInfinity() 
+      : UbNegInfinity()
+    {}
+   
+   inline operator unsigned char()  const  { return UbLimits<unsigned char>::inf();  }
+   inline operator signed char()    const  { return UbLimits<signed char>::inf();    }
+   inline operator char()           const  { return UbLimits<char>::inf();           }
+   inline operator wchar_t()        const  { return UbLimits<wchar_t>::inf();        }
+   inline operator unsigned short() const  { return UbLimits<unsigned short>::inf(); }
+   inline operator short()          const  { return UbLimits<short>::inf();          }
+   inline operator unsigned int()   const  { return UbLimits<unsigned int>::inf();   }
+   inline operator int()            const  { return UbLimits<int>::inf();            }
+   inline operator unsigned long()  const  { return UbLimits<unsigned long>::inf();  }
+   inline operator long()           const  { return UbLimits<long>::inf();           }
+   inline operator float()          const  { return UbLimits<float>::inf();          }
+   inline operator double()         const  { return UbLimits<double>::inf();         }
+   inline operator long double()    const  { return UbLimits<long double>::inf();    }
+
+   inline const UbNegInfinity& operator-() const { return static_cast<const UbNegInfinity&>( *this ); }
+
+   /*==========================================================*/
+   template< typename T >
+   inline bool equal( const T& rhs ) const
+   {
+      UB_STATIC_ASSERT( std::numeric_limits<T>::is_specialized );
+      return UbLimits<T>::inf() == rhs;
+   }
+
+ private:
+   UbInfinity( const UbInfinity& inf );             //Copy constructor (private & undefined)
+   UbInfinity& operator=( const UbInfinity& inf );  //Copy assignment operator (private & undefined)
+   void* operator&() const;                         //Address operator (private & undefined)
+};
+
+//////////////////////////////////////////////////////////////////////////
+//  GLOBAL OPERATORS
+//////////////////////////////////////////////////////////////////////////
+template< typename T >
+inline bool operator==( const UbInfinity& lhs, const T& rhs );
+
+template< typename T >
+inline bool operator==( const T& lhs, const UbInfinity& rhs );
+
+template< typename T >
+inline bool operator!=( const UbInfinity& lhs, const T& rhs );
+
+template< typename T >
+inline bool operator!=( const T& lhs, const UbInfinity& rhs );
+//@}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Equality comparison between an Infinity object and a built-in data type.
+// \ingroup util
+//
+// This operator works only for built-in data types. The attempt to compare user-defined class
+// types will result in a compile time error.
+*/
+template< typename T >
+inline bool operator==( const UbInfinity& lhs, const T& rhs )
+{
+   return lhs.equal( rhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator==( const T& lhs, const UbInfinity& rhs )
+{
+   return rhs.equal( lhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator!=( const UbInfinity& lhs, const T& rhs )
+{
+   return !lhs.equal( rhs );
+}
+//*************************************************************************************************
+template< typename T >
+inline bool operator!=( const T& lhs, const UbInfinity& rhs )
+{
+   return !rhs.equal( lhs );
+}
+//*************************************************************************************************
+
+//////////////////////////////////////////////////////////////////////////
+//  GLOBAL INFINITY VALUE
+//////////////////////////////////////////////////////////////////////////
+namespace Ub
+{
+   //e.g. double x = UbSystem::inf;  float x = -Ub::inf; 
+   const UbInfinity inf; 
+} 
+
+#endif //UB_INFINITY_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbKeys.h b/VirtualFluidsBasics/basics/utilities/UbKeys.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ee57815043ec3a36522e956435db0c78e276bd4
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbKeys.h
@@ -0,0 +1,304 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbKeys.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBKEYS_H
+#define UBKEYS_H
+
+#include <iostream>
+
+
+#ifdef CAB_RCF
+   #include <3rdParty/rcf/RcfSerializationIncludes.h>
+#endif //CAB_RCF
+
+//////////////////////////////////////////////////////////////////////////
+//!
+//!  \brief 
+//!  namespace for global Keys (e.g. for STL-maps)
+//!
+//////////////////////////////////////////////////////////////////////////
+
+namespace UbKeys
+{
+   //nested class
+   template< typename T1, typename T2 = T1 >
+   class Key2 
+   {
+   public:
+      //////////////////////////////////////////////////////////////////////////
+      //Konstruktoren
+      Key2(const T1& t1, const T2& t2) 
+         : t1(t1), t2(t2)
+      { 
+      }
+      /*==========================================================*/
+      Key2& operator=(const Key2& srcKey) 
+      {
+         if(this == &srcKey ) return *this;
+
+         t1    = srcKey.t1;
+         t2    = srcKey.t2;
+
+         return *this;
+      }
+      /*==========================================================*/
+      T1 getT1() const { return t1; }
+      T2 getT2() const { return t2; }
+
+      //////////////////////////////////////////////////////////////////////////
+      //global ueberladene Operatoren
+      friend inline bool operator<(const Key2& lhsKey,const Key2& rhsKey)  
+      {
+         if( lhsKey.t1 < rhsKey.t1 ) return true;
+         if( lhsKey.t1 > rhsKey.t1 ) return false;
+         if( lhsKey.t2 < rhsKey.t2 ) return true;
+
+         return false;
+      }
+      /*==========================================================*/
+      friend inline bool operator==(const Key2& lhsKey, const Key2& rhsKey)  
+      {
+         if(lhsKey.t1 != rhsKey.t1 ) return false;
+         if(lhsKey.t2 != rhsKey.t2 ) return false;
+
+         return true;
+      }
+      //ueberladene Operatoren
+      friend inline bool operator!=(const Key2& lhsKey, const Key2& rhsKey)  
+      {
+         return !(lhsKey == rhsKey); 
+      }
+      //ueberladene Operatoren
+      /*==========================================================*/
+      friend inline std::ostream& operator << (std::ostream& os, const Key2& key) 
+      {
+         os<<"Key2<"<<typeid(T1).name()<<","<<typeid(T2).name()<<">,("<<key.t1<<","<<key.t2<<")";
+         return os;
+      }
+      /*==========================================================*/
+      #ifdef CAB_RCF
+	      template<class Archive>
+	      void serialize(Archive & ar, const unsigned int version)
+	      {
+		      ar & t1;
+		      ar & t2;
+	      }
+      #endif //CAB_RCF
+
+   private:
+      //////////////////////////////////////////////////////////////////////////
+      //private Member
+      T1 t1;
+      T2 t2;
+
+   };
+
+   //////////////////////////////////////////////////////////////////////////
+   //
+   //////////////////////////////////////////////////////////////////////////
+   template< typename T1, typename T2 = T1, typename T3 = T1 >
+   class Key3 
+   {
+   public:
+      //////////////////////////////////////////////////////////////////////////
+      //Konstruktoren
+      Key3() : t1(0), t2(0), t3(0)
+      {
+
+      }
+      Key3(const T1& t1, const T2& t2, const T3& t3) 
+         : t1(t1), t2(t2), t3(t3)
+      { 
+      }
+      /*==========================================================*/
+      T1 getT1() const { return t1; }
+      T2 getT2() const { return t2; }
+      T3 getT3() const { return t3; }
+      /*==========================================================*/
+      Key3& operator=(const Key3& srcKey) 
+      {
+         if(this == &srcKey ) return *this;
+
+         t1    = srcKey.t1;
+         t2    = srcKey.t2;
+         t3    = srcKey.t3;
+
+         return *this;
+      }
+
+      //////////////////////////////////////////////////////////////////////////
+      //global ueberladene Operatoren
+      friend inline bool operator<(const Key3& lhsKey,const Key3& rhsKey)  
+      {
+         if( lhsKey.t1 < rhsKey.t1 ) return true;
+         if( lhsKey.t1 > rhsKey.t1 ) return false;
+         if( lhsKey.t2 < rhsKey.t2 ) return true;
+         if( lhsKey.t2 > rhsKey.t2 ) return false;
+         if( lhsKey.t3 < rhsKey.t3 ) return true;
+
+         return false;
+      }
+      /*==========================================================*/
+      friend inline bool operator==(const Key3& lhsKey,const Key3& rhsKey)  
+      {
+         if(lhsKey.t1 != rhsKey.t1 ) return false;
+         if(lhsKey.t2 != rhsKey.t2 ) return false;
+         if(lhsKey.t3 != rhsKey.t3 ) return false;
+
+         return true;
+      }
+      /*==========================================================*/
+      //ueberladene Operatoren
+      friend inline bool operator!=(const Key3& lhsKey, const Key3& rhsKey) 
+      {
+         return !(lhsKey == rhsKey); 
+      }
+
+      //ueberladene Operatoren
+      /*==========================================================*/
+      friend inline std::ostream& operator << (std::ostream& os, const Key3& key) 
+      {
+         os<<"Key3<"<<typeid(T1).name()<<","<<typeid(T2).name()<<","<<typeid(T3).name();
+         os<<">,("<<key.t1<<","<<key.t2<<","<<key.t3<<")";
+         return os;
+      }
+      /*==========================================================*/
+      #ifdef CAB_RCF
+	      template<class Archive>
+	      void serialize(Archive & ar, const unsigned int version)
+	      {
+		      ar & t1;
+		      ar & t2;
+            ar & t3;
+         }
+      #endif //CAB_RCF
+
+   private:
+      //////////////////////////////////////////////////////////////////////////
+      //private Member
+      T1 t1;
+      T2 t2;
+      T3 t3;
+   };
+
+   //////////////////////////////////////////////////////////////////////////
+   //
+   //////////////////////////////////////////////////////////////////////////
+   template< typename T1, typename T2 = T1, typename T3 = T1, typename T4 = T1 >
+   class Key4 
+   {
+   public:
+      //////////////////////////////////////////////////////////////////////////
+      //Konstruktoren
+      Key4(const T1& t1, const T2& t2, const T3& t3, const T4& t4) 
+         : t1(t1), t2(t2), t3(t3), t4(t4)
+      { 
+      }
+      /*==========================================================*/
+      T1 getT1() const { return t1; }
+      T2 getT2() const { return t2; }
+      T3 getT3() const { return t3; }
+      T4 getT4() const { return t4; }
+      /*==========================================================*/
+      Key4& operator=(const Key4& srcKey) 
+      {
+         if(this == &srcKey ) return *this;
+
+         t1    = srcKey.t1;
+         t2    = srcKey.t2;
+         t3    = srcKey.t3;
+         t4    = srcKey.t4;
+
+         return *this;
+      }
+      //////////////////////////////////////////////////////////////////////////
+      //global ueberladene Operatoren
+      friend inline bool operator<(const Key4& lhsKey,const Key4& rhsKey)  
+      {
+         if( lhsKey.t1 < rhsKey.t1 ) return true;
+         if( lhsKey.t1 > rhsKey.t1 ) return false;
+         if( lhsKey.t2 < rhsKey.t2 ) return true;
+         if( lhsKey.t2 > rhsKey.t2 ) return false;
+         if( lhsKey.t3 < rhsKey.t3 ) return true;
+         if( lhsKey.t3 > rhsKey.t3 ) return false;
+         if( lhsKey.t4 < rhsKey.t4 ) return true;
+
+         return false;
+      }
+      /*==========================================================*/
+      friend inline bool operator==(const Key4& lhsKey,const Key4& rhsKey)  
+      {
+         if(lhsKey.t1 != rhsKey.t1 ) return false;
+         if(lhsKey.t2 != rhsKey.t2 ) return false;
+         if(lhsKey.t3 != rhsKey.t3 ) return false;
+         if(lhsKey.t4 != rhsKey.t4 ) return false;
+
+         return true;
+      }
+
+      //ueberladene Operatoren
+      friend inline bool operator!=(const Key4& lhsKey, const Key4& rhsKey) 
+      {
+         return !(lhsKey == rhsKey); 
+      }
+      //ueberladene Operatoren
+      /*==========================================================*/
+      friend inline std::ostream& operator << (std::ostream& os, const Key4& key) 
+      {
+         os<<"Key4<"<<typeid(T1).name()<<","<<typeid(T2).name()<<","<<typeid(T3).name()<<","<<typeid(T4).name();
+         os<<">,("<<key.t1<<","<<key.t2<<","<<key.t3<<","<<key.t4<<")";
+         return os;
+      }
+      /*==========================================================*/
+      #ifdef CAB_RCF
+	      template<class Archive>
+	      void serialize(Archive & ar, const unsigned int version)
+	      {
+		      ar & t1;
+		      ar & t2;
+            ar & t3;
+            ar & t4;
+         }
+      #endif //CAB_RCF
+
+   private:
+      //////////////////////////////////////////////////////////////////////////
+      //private Member
+      T1 t1;
+      T2 t2;
+      T3 t3;
+      T4 t4;
+
+   };
+}
+
+#endif //UBKEYS_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbLimits.h b/VirtualFluidsBasics/basics/utilities/UbLimits.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a2aa9cdbdf4a290571bad4b96796cd5646f4fb3
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbLimits.h
@@ -0,0 +1,165 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbLimits.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UB_LIMITS_H
+#define UB_LIMITS_H
+
+
+//*************************************************************************************************
+// Includes
+//*************************************************************************************************
+
+#include <limits>
+
+//////////////////////////////////////////////////////////////////////////
+//  CLASS DEFINITION
+//////////////////////////////////////////////////////////////////////////
+template< typename T >
+struct UbLimits  {};
+
+//////////////////////////////////////////////////////////////////////////
+//  SPECIALIZATIONS
+//////////////////////////////////////////////////////////////////////////
+template<>
+struct UbLimits<unsigned char>
+{
+   //return the largest possible positive unsigned char value
+   static inline unsigned char inf() { return std::numeric_limits<unsigned char>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<char>
+{
+   //return the largest possible positive char value. */
+   static inline char inf () { return std::numeric_limits<char>::max(); }
+   //return the largest possible negative char value
+   static inline char ninf() { return std::numeric_limits<char>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<signed char>
+{
+   //return the largest possible positive signed char value
+   static inline signed char inf () { return std::numeric_limits<signed char>::max(); }
+
+   //return The largest possible negative signed char value
+   static inline signed char ninf() { return std::numeric_limits<signed char>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<wchar_t>
+{
+   //return The largest possible positive wchar_t value
+   static inline wchar_t inf () { return std::numeric_limits<wchar_t>::max(); }
+   //return The largest possible negative wchar_t value
+   static inline wchar_t ninf() { return std::numeric_limits<wchar_t>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<unsigned short>
+{
+   //return The largest possible positive unsigned short value
+   static inline unsigned short inf() { return std::numeric_limits<unsigned short>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<short>
+{
+   //return The largest possible positive short value
+   static inline short inf () { return std::numeric_limits<short>::max(); }
+   //return The largest possible negative short value
+   static inline short ninf() { return std::numeric_limits<short>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<unsigned int>
+{
+   //return The largest possible positive unsigned int value
+   static inline unsigned int inf() { return std::numeric_limits<unsigned int>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<int>
+{
+   //return The largest possible positive int value
+   static inline int inf () { return std::numeric_limits<int>::max(); }
+
+   //return The largest possible negative int value
+   static inline int ninf() { return std::numeric_limits<int>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<unsigned long>
+{
+   //return The largest possible positive unsigned long value
+   static inline unsigned long inf() { return std::numeric_limits<unsigned long>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<long>
+{
+   //return The largest possible positive long value
+   static inline long inf () { return std::numeric_limits<long>::max(); }
+
+   //return The largest possible negative long value
+   static inline long ninf() { return std::numeric_limits<long>::min(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<float>
+{
+   //return The largest possible positive float value
+   static inline float inf () { return  std::numeric_limits<float>::max(); }
+
+   //return The largest possible negative float value
+   static inline float ninf() { return -std::numeric_limits<float>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<double>
+{
+   //return The largest possible positive double value
+   static inline double inf () { return  std::numeric_limits<double>::max(); }
+   //return The largest possible negative double value
+   static inline double ninf() { return -std::numeric_limits<double>::max(); }
+};
+//*************************************************************************************************
+template<>
+struct UbLimits<long double>
+{
+   //return The largest possible positive long double value
+   static inline long double inf () { return  std::numeric_limits<long double>::max(); }
+   //return The largest possible negative long double value
+   static inline long double ninf() { return -std::numeric_limits<long double>::max(); }
+};
+
+#endif //UB_LIMITS_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbLogger.cpp b/VirtualFluidsBasics/basics/utilities/UbLogger.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a02a1aa15c28410aadaa25466177f0db620383df
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbLogger.cpp
@@ -0,0 +1,40 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbLogger.cpp
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <basics/utilities/UbLogger.h>
+
+#if defined(CAB_BOOST) && !defined(NO_THREADSAFE_LOGGING)
+
+boost::mutex Output2Stream::mtx;
+
+#endif // CAB_BOOST
+
diff --git a/VirtualFluidsBasics/basics/utilities/UbLogger.h b/VirtualFluidsBasics/basics/utilities/UbLogger.h
new file mode 100644
index 0000000000000000000000000000000000000000..266ac1f6be415dfe05ca3796c1b4fbd6f2790fda
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbLogger.h
@@ -0,0 +1,401 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbLogger.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBLOGGER_H
+#define UBLOGGER_H
+
+#include <sstream>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
+   #include <windows.h>
+#else
+   #include <sys/time.h>
+#endif
+
+#if defined(CAB_BOOST) && !defined(NO_THREADSAFE_LOGGING)
+   #include <boost/thread.hpp>
+#endif // CAB_BOOST
+
+
+
+enum LogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5};
+
+//////////////////////////////////////////////////////////////////////////
+// template <typename OutputPolicy> class Log  - declaration
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//!
+//! \brief 
+//! C++ Logger
+//! \details Functionality:
+//! Per logentry an object of type UbLogger is generated, the log string is passed to this object and
+//! upon destruction of the object the string is written to a file or the screen depending on 
+//! the policy (=template paramter). Multiple log level are supported.
+//!
+//! helpermakro:  UBLOG
+//!
+//! Example 1: 
+//! \code
+//! UBLOG(logINFO) << "Klasse::foo entered"; //endl is not required 
+//! \endcode
+//!
+//! Example 2: 
+//! \code
+//! try
+//! {
+//!    UbLog::reportingLevel() = UbLog::logLevelFromString("DEBUG3");
+//!    //UbLog::output_policy::setStream(&std::cerr); //<- clog is stdandard
+//!    UbLog::output_policy::setStream("c:/temp/out.txt");  //you can not open these -> error message -> log is output in cerr
+//! 
+//!    int count = 3;
+//!    UBLOG(logINFO, "A loop with " << count << " iterations");
+//!    for (int i = 0; i != count; ++i)
+//!    {
+//!        UBLOG(logERROR , "error  - the counter i = " << i );
+//!        UBLOG(logDEBUG1, "debug1 - the counter i = " << i );
+//!        UBLOG(logDEBUG2, "debug2 - the counter i = " << i );
+//!        UBLOG(logDEBUG3, "debug3 - the counter i = " << i );
+//!        //for MultiLine entries: -> formatting in logfile
+//!        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//!        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//!        UBLOG2ML(logDEBUG3,std:cout,"debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//!    }
+//!    return 0;
+//! }
+//! catch(const std::exception& e)
+//! {
+//!    UBLOG(logERROR) << e.what();
+//! }
+//! \endcode
+//! Idee based on: 
+//! Paper by Dr. Dobbs Portal,
+//! September 05, 2007,
+//! Logging In C++
+//!
+//////////////////////////////////////////////////////////////////////////
+template <typename OutputPolicy>
+class UbLogger
+{   
+public:
+   typedef OutputPolicy output_policy;
+public:
+    UbLogger();
+    virtual ~UbLogger();
+    std::ostringstream& get(const LogLevel& level = logINFO);
+public:
+   //static, weil man so später die ObjErstellunge ersparen kann,
+   //falls level kleiner als Level
+   static LogLevel&   reportingLevel();
+    
+    static std::string logLevelToString(const LogLevel& level);
+    static LogLevel    logLevelFromString(const std::string& level);
+
+    static std::string logTimeString();
+
+protected:
+    std::ostringstream os;
+
+private:
+    UbLogger(const UbLogger&);
+    UbLogger& operator =(const UbLogger&);
+};
+
+//////////////////////////////////////////////////////////////////////////
+// template <typename OutputPolicy> class Log  - implementation
+//////////////////////////////////////////////////////////////////////////
+template <typename OutputPolicy>
+UbLogger<OutputPolicy>::UbLogger()
+{
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+std::ostringstream& UbLogger<OutputPolicy>::get(const LogLevel& level) 
+{
+   os << logTimeString() << " " << std::setw(6) 
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+      <<boost::this_thread::get_id() << " "
+#endif
+      << std::setw(8) << std::left << UbLogger<OutputPolicy>::logLevelToString(level) << ": "
+      << std::string(level > logDEBUG ? 3*(level - logDEBUG) : 0, ' '); //<baumartiger output :D
+   
+    return os;
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+UbLogger<OutputPolicy>::~UbLogger()
+{
+    os << std::endl;
+    OutputPolicy::output(os.str());
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+LogLevel& UbLogger<OutputPolicy>::reportingLevel()
+{
+    static LogLevel reportLevel = logINFO;
+    return reportLevel;
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+std::string UbLogger<OutputPolicy>::logLevelToString(const LogLevel& level)
+{
+   static std::string const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
+   return buffer[level];
+}
+/*==========================================================*/
+template <typename OutputPolicy>
+LogLevel UbLogger<OutputPolicy>::logLevelFromString(const std::string& level)
+{
+   if (level == "DEBUG5" ) return logDEBUG5;
+   if (level == "DEBUG4" ) return logDEBUG4;
+   if (level == "DEBUG3" ) return logDEBUG3;
+   if (level == "DEBUG2" ) return logDEBUG2;
+   if (level == "DEBUG1" ) return logDEBUG1;
+   if (level == "DEBUG"  ) return logDEBUG;
+   if (level == "INFO"   ) return logINFO;
+   if (level == "WARNING") return logWARNING;
+   if (level == "ERROR"  ) return logERROR;
+       
+   UbLogger<OutputPolicy>().get(logWARNING) << "UbLogger<OutputPolicy>::logLevelFromString(level) - unknown logging level '" << level << "'. Using INFO level as default.";
+   return logINFO;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// logTimeString
+//////////////////////////////////////////////////////////////////////////
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)  || defined(_WIN64)  || defined(__WIN64__)
+template <typename OutputPolicy>
+inline std::string UbLogger<OutputPolicy>::logTimeString()
+{
+   const int MAX_LEN = 200;
+   char buffer[MAX_LEN];
+   if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0, "HH':'mm':'ss", buffer, MAX_LEN) == 0 )
+   {
+      return "Error in std::string UbLogger<OutputPolicy>::logTimeString()";
+   }
+
+   char result[100] = {0};
+   static DWORD first = GetTickCount();
+   std::sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000); 
+   return result;
+}
+#else
+template <typename OutputPolicy>
+inline std::string UbLogger<OutputPolicy>::logTimeString()
+{
+   char buffer[11];
+   time_t t;
+   time(&t);
+   tm r = {0};
+   strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
+   struct timeval tv;
+   gettimeofday(&tv, 0);
+   char result[100] = {0};
+   std::sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000); 
+   return result;
+}
+#endif 
+
+
+//////////////////////////////////////////////////////////////////////////
+//! Implementation of OutputPolicy)
+//////////////////////////////////////////////////////////////////////////
+class Output2Stream // implementation of OutputPolicy
+{
+public:
+   static std::ostream*& getStream();
+   static void output(const std::string& msg);
+   
+   //!creates output-file-stream (of file opening fails -> stream is set to std::cerr)
+   static void setStream(const std::string& filename);
+   
+   //!direct set outputstream, gcControl = true -> object will be deleted by Output2Stream 
+   static void setStream(std::ostream* pStream, const bool& gcControl = false);
+
+protected:
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   static boost::mutex mtx;
+#endif
+};
+/*==========================================================*/
+inline std::ostream*& Output2Stream::getStream()
+{
+   static std::ostream* pStream = &std::clog;
+   return pStream;
+}
+/*==========================================================*/
+inline void Output2Stream::setStream(std::ostream* pFile, const bool& gcControl)
+{
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   boost::mutex::scoped_lock lock(mtx);
+#endif
+   static bool s_gcControl = false;
+   
+   if( s_gcControl && Output2Stream::getStream() ) 
+   {
+      delete Output2Stream::getStream();
+   }
+   
+   s_gcControl = gcControl;
+   
+   Output2Stream::getStream() = pFile;
+}
+/*==========================================================*/
+inline void Output2Stream::setStream(const std::string& filename)
+{
+   std::ofstream* file = new std::ofstream( filename.c_str() );
+   if( !(*file) ) 
+   {
+      delete file;
+      Output2Stream::setStream(&std::cerr, false);
+      UbLogger<Output2Stream>().get(logERROR) << " Output2Stream::setStream(const std::string& filename) could not open file "
+                                               << filename << " -> std::cerr is used instead " << std::endl;
+      return;
+   }
+   std::cout<<"UbLog writes to "<<filename<<std::endl;
+   Output2Stream::setStream(file,true);
+}
+/*==========================================================*/
+inline void Output2Stream::output(const std::string& msg)
+{
+#if defined(CAB_BOOST) && !defined(NO_MT_LOGGING)
+   boost::mutex::scoped_lock lock(mtx);
+#endif
+   std::ostream* pStream = getStream();
+   if (!pStream) return;
+   (*pStream) << msg << std::flush;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// UbLog
+//////////////////////////////////////////////////////////////////////////
+class UbLog : public UbLogger< Output2Stream > 
+{
+
+};
+
+//Macro to limit compiler-side maxLevel
+#ifndef UBLOG_MAX_LEVEL
+   #define UBLOG_MAX_LEVEL logDEBUG5
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+// example UBLOG(logINFO) << "das ist ein log eintrag";
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG(level, logtext) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else UbLog().get(level) << logtext;                                                             
+   
+//////////////////////////////////////////////////////////////////////////
+//makro 2 fuer korrekten MultiLineOutput (teuer!!)
+// example1: UBLOGML(logINFO, "line1"<<endl<<"line2"<<endl<<"line3" )
+// example2: UBLOGML(logINFO, "line1\nline2\nendl\nline3" )
+//////////////////////////////////////////////////////////////////////////
+#define UBLOGML(level, multiline) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else                                                                                            \
+   {                                                                                               \
+      std::ostringstream output;                                                                   \
+      output << multiline;                                                                         \
+      std::istringstream input( output.str() );                                                    \
+      while(!input.eof())                                                                          \
+      {                                                                                            \
+         std::string dummy;                                                                        \
+         getline(input,dummy,'\n');                                                                \
+         UbLog().get(level) << dummy;                                                              \
+      }                                                                                            \
+   }                                                                                          
+//////////////////////////////////////////////////////////////////////////
+//makro3, falls auch bildschirmausgabe erwünscht
+//   -> es wird sowohl ins logfile als auch auf den "stream" geschrieben
+//      wenn reporting level und level passen :D
+//example1: UBLOG2ML(logINFO, std::cout,  "line1"<<endl<<"line2"<<endl<<"line3" ) 
+//example2: UBLOG2ML(logINFO, std::cout,  "line1\nline2\nendl\nline3" ) 
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG2(level, stream,  text ) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else { stream << text <<std::endl; UbLog().get(level) << text;   }                             
+
+//////////////////////////////////////////////////////////////////////////
+//makro4, wie 3 nur mit multiline
+//example: UBLOG2(logINFO, std::cout,  "test" ) 
+//////////////////////////////////////////////////////////////////////////
+#define UBLOG2ML(level, stream,  multiline ) \
+   if(level > UBLOG_MAX_LEVEL || level > UbLog::reportingLevel() || !Output2Stream::getStream()) ; \
+   else                                                                                            \
+   {                                                                                               \
+      stream << multiline << std::endl;                                                            \
+      std::ostringstream output;                                                                   \
+      output << multiline;                                                                         \
+      std::istringstream input( output.str() );                                                    \
+      while(!input.eof())                                                                          \
+      {                                                                                            \
+         std::string dummy;                                                                        \
+         getline(input,dummy,'\n');                                                                \
+         UbLog().get(level) << dummy;                                                              \
+      }                                                                                            \
+   }                                                                                               
+
+//////////////////////////////////////////////////////////////////////////
+// example 2
+//////////////////////////////////////////////////////////////////////////
+// try
+// {
+//    UbLog::reportingLevel() = UbLog::logLevelFromString("DEBUG3");
+//    //UbLog::output_policy::setStream(&std::cerr); //<- clog ist stdandard
+//    UbLog::output_policy::setStream("c:/temp/out.txt");  //kann man diese nicht oeffnen -> fehlermeldung -> Log wird in cerr ausgegben
+// 
+//    int count = 3;
+//    UBLOG(logINFO, "A loop with " << count << " iterations");
+//    for (int i = 0; i != count; ++i)
+//    {
+//        UBLOG(logERROR , "error  - the counter i = " << i );
+//        UBLOG(logDEBUG1, "debug1 - the counter i = " << i );
+//        UBLOG(logDEBUG2, "debug2 - the counter i = " << i );
+//        UBLOG(logDEBUG3, "debug3 - the counter i = " << i );
+//        //fuer MultiLine Eintraege: --> koerrekte formatierung im logfile
+//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//        UBLOGML(logDEBUG3, "debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//        UBLOG2ML(logDEBUG3,std:cout,"debug3 - the counter i = "<<endl<<" 2 zeile "<< "3. Zeile" << i);
+//    }
+//    return 0;
+// }
+// catch(const std::exception& e)
+// {
+//    UBLOG(logERROR) << e.what();
+// }
+
+
+#endif //UBLOGGER_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbMath.cpp b/VirtualFluidsBasics/basics/utilities/UbMath.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..938360645be1ba72aed2f3f4d56ab9f5027244c9
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbMath.cpp
@@ -0,0 +1,38 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbMath.cpp
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbInfinity.h>
+#include <cstring> //for memcmp
+
+       
+const double UbMath::PI = 4.0* std::atan(1.0);   //3.1415926535897932384626433832795
diff --git a/VirtualFluidsBasics/basics/utilities/UbMath.h b/VirtualFluidsBasics/basics/utilities/UbMath.h
new file mode 100644
index 0000000000000000000000000000000000000000..0261256287952460ba8e1ab8547635f01a203d3b
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbMath.h
@@ -0,0 +1,480 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbMath.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBMATH_H
+#define UBMATH_H
+
+#include <cmath>
+#include <limits>
+#include <iostream>
+#include <cassert>
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbEqual.h>
+
+namespace UbMath 
+{
+   extern const double PI;
+   
+   
+   //////////////////////////////////////////////////////////////////////////
+   //Hilfsfunktion fuer Genauigkeit
+   template< typename T >
+   struct Epsilon {  };
+
+   //////////////////////////////////////////////////////////////////////////
+   //  SPECIALIZATIONS von Epsilon
+   //////////////////////////////////////////////////////////////////////////
+   template<>
+   struct Epsilon<double>        { static inline double      val() { return 1.0E-11; } };
+   template<>
+   struct Epsilon<float>         { static inline float       val() { return 1.0E-7f; } };
+   template<>
+   struct Epsilon<long double>   { static inline long double val() { return 1.0E-15; } };
+   template<>
+   struct Epsilon<int>           { static inline int         val() { return 0;       } };
+
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den Logarithmus einer Zahl z bzgl. der Basis b
+   // -------------------------------------------------------------------------------------------------
+   template<typename T>
+   inline T log(const T& z, const T& base)
+   {
+      if( ::log(base)==0 ) return 1.0f;
+      return ::log(z) / ::log(base);
+   }
+   /*=======================================================*/
+   //double x = UbMath::getNegativeInfinity<double>();
+   template<typename T>
+   inline T getNegativeInfinity()
+   {
+      //assert(std::numeric_limits<T>::has_infinity);
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
+      return -std::numeric_limits<T>::infinity();
+   }
+   /*=======================================================*/
+   //double x = UbMath::getPositiveInfinity<double>();
+   template<typename T>
+   inline T getPositiveInfinity()
+   {
+      //assert(std::numeric_limits<T>::has_infinity);
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_infinity);
+      return std::numeric_limits<T>::infinity();
+   }
+   /*=======================================================*/
+   //double x; bool b = UbMath::isInfinity(x);
+   template<typename T>
+   inline bool isInfinity(const T& value)
+   {
+      if(value==getNegativeInfinity<T>()) return true;
+      if(value==getPositiveInfinity<T>()) return true;
+      return false;
+   }
+   /*=======================================================*/
+   //double x = UbMath::getNaN<double>(x);
+   template<typename T>
+   inline T getNaN()
+   {
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
+      return std::numeric_limits<T>::quiet_NaN();
+   }
+   /*=======================================================*/
+   //double x; bool b = UbMath::isNaN(x);
+   // x!=x liefert bei #QNAN "true"!
+   template<typename T>
+   inline bool isNaN(const T& x)
+   {
+      UB_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN);
+      return (x != x); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T getEqualityEpsilon()		  
+   { 
+      return  Epsilon<T>::val();  
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool zero(const T& value)		  
+   { 
+      return std::fabs( value ) < Epsilon<T>::val();
+      //return value >= -UbMath::EPSILON && value <= UbMath::EPSILON;	
+   }
+   /*=======================================================*/
+   //spezialisierung fuer ints
+   template<>
+   inline bool zero(const int& value)		  
+   { 
+      return value == 0;
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool zero(const T1& value1, const T2& value2)		  
+   { 
+      return !(!UbMath::zero(value1) || !UbMath::zero(value2));	
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool zero(const T1& value1, const T2& value2, const T3& value3)		  
+   { 
+      return !(!UbMath::zero(value1) || !UbMath::zero(value2,value3));	
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool negative(const T& value)    
+   { 
+      return value < -Epsilon<T>::val();  
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool nonPositive(const T& value) 
+   { 
+      return value <= Epsilon<T>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool positive(const T& value)    
+   { 
+      return value > +Epsilon<T>::val();   
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline bool nonNegative(const T& value) 
+   { 
+      return value >= -Epsilon<T>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool equal(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return std::fabs(value-reference) < Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool equal(const T1& val1, const T2& val2, const T3& val3) 
+   { 
+      return ( UbMath::equal(val1,val2) && UbMath::equal(val1,val3) ); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool less(const T1& value, const T2& reference)   
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value < reference - Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool lessEqual(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value <= reference + Epsilon<High>::val();
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool greater(const T1& value, const T2& reference)      
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value > reference + Epsilon<High>::val();  
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2>
+   inline bool greaterEqual(const T1& value, const T2& reference) 
+   { 
+      typedef typename UbEqualTrait<T1,T2>::High High;
+      return value >= reference - Epsilon<High>::val(); 
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T round(const T& value, const int& decimalPlaces) 
+   { 
+      return static_cast<T>(floor(value * pow( 10.0, decimalPlaces) + 0.5 ) * pow(10.0, -decimalPlaces)); 
+   } 
+   /*=======================================================*/
+   template<typename T>
+   inline int integerRounding(const T& value) 
+   { 
+      return static_cast<int>( UbMath::zero(value) ?  0 : ( (value<0.0) ? (value-0.5) : (value+0.5) ) );
+   } 
+   /*=======================================================*/
+   template<typename T>
+   inline T getRad(const T& degrees) 
+   {
+      return degrees*static_cast<T>(UbMath::PI/180.0);
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T getDegrees(const T& rad) 
+   {
+      return rad*static_cast<T>(UbMath::PI/180.0);
+   }
+   /*=======================================================*/
+   //aus wildmagic
+   template<typename T>
+   inline T ACos (const T& fValue)
+   {
+      if ( -1.0 < fValue )
+      {
+         if ( fValue < 1.0 ) return static_cast<T>( acos(fValue) );
+         else                return static_cast<T>( 0.0          );
+      }
+      else return static_cast<T>( PI );
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T ASin(const T& fValue)
+   {
+      double HALF_PI = 0.5*UbMath::PI;
+      if ( -1.0 < fValue )
+      {
+         if ( fValue < 1.0 ) return static_cast<T>( asin(fValue) );
+         else                return static_cast<T>( HALF_PI      );
+      }
+      else return -static_cast<T>( HALF_PI );         
+   }
+   /*=======================================================*/
+   template<typename T>
+   inline T invSqrt(const T& fValue)   
+   { 
+      return static_cast<T>(1.0/sqrt(fValue));
+   }
+
+   /*=======================================================*/
+   /**
+   * Returns true, if specified values a and b are less both values c and d.
+   * @param a the first value to check
+   * @param b the second value to check
+   * @param c the first value to check against
+   * @param d the second value to check against
+   * @return true, if specified values a and b are less both values c and d
+   **/
+   template<typename T1, typename T2, typename T3, typename T4>
+   inline bool less2(const T1& value1, const T2& value2, T3 toBeLessAs1, T4 toBeLessAs2) 
+   {	
+      return (   less(value1,toBeLessAs1)
+              && less(value1,toBeLessAs2)
+              && less(value2,toBeLessAs1)
+              && less(value2,toBeLessAs2) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3, typename T4>
+   inline bool greater2(const T1& value1, const T2& value2, T3 toBeGreaterAs1, T4 toBeGreaterAs2)
+   { 
+      return (   greater(value1,toBeGreaterAs1)
+              && greater(value1,toBeGreaterAs2)
+              && greater(value2,toBeGreaterAs1)
+              && greater(value2,toBeGreaterAs2) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool inClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   { 
+      if(threshold1 < threshold2)
+      {
+         return ( greaterEqual( value, threshold1) && lessEqual( value, threshold2) );
+      }
+
+      return ( greaterEqual( value, threshold2) && lessEqual( value, threshold1) );
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline bool inOpenInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   {	
+      if(threshold1 < threshold2) 
+      {
+         return (greater( value, threshold1) && less( value, threshold2));
+      }
+
+      return (greater( value, threshold2) && less( value, threshold1));
+   }
+   /*=======================================================*/
+   template<typename T1, typename T2, typename T3>
+   inline double adaptToClosedInterval(const T1& value, const T2& threshold1, const T3& threshold2)
+   { 
+      if(threshold1 < threshold2)
+      {
+         if     ( less(   value, threshold1) ) return threshold1;
+         else if( greater(value, threshold2) ) return threshold2;
+      }
+      else
+      {
+         if     ( less(   value, threshold2) ) return threshold2;
+         else if( greater(value, threshold1) ) return threshold1;
+      }
+      return value;
+   }
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den groessten gemeinsamen Teiler zweier Zahlen (MK)
+   // -------------------------------------------------------------------------------------------------
+   /*=======================================================*/
+   inline int calcGgt(int val1, int val2)
+   {
+      if( val1 < val2 ) std::swap(val1,val2);
+      int ggt=val2;
+      while(ggt > 1)
+      {
+         if( (val1%ggt)==0 && (val2%ggt)==0 ) break;
+
+         ggt -=1;
+      }
+      return ggt;
+   }
+   /*=======================================================*/
+   // -------------------------------------------------------------------------------------------------
+   // Funktion berechnet den groessten gemeinsamen Teiler von drei Zahlen (MK)
+   // -------------------------------------------------------------------------------------------------
+   inline int calcGgt(int val1, const int& val2, int val3)
+   {
+      return UbMath::calcGgt( UbMath::calcGgt(val1, val2), val3 );
+   }
+   /*=======================================================*/
+   //returns the max of c2 values
+   //to avoid errors at mixed argument-types use: double myMax = max<double>(2,2.3);
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2) 
+   { 
+     return (a1<a2) ? a2 : a1;
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2, const T& a3) 
+   { 
+      return max(max(a1,a2),a3);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& max(const T& a1, const T& a2, const T& a3, const T& a4)
+   {
+      return max(max(max(a1,a2),a3),a4);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1,const T& a2) 
+   { 
+      return (a1<a2) ? a1 : a2;
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1, const T& a2, const T& a3) 
+   { 
+      return min(min(a1,a2),a3);
+   }
+   /*=======================================================*/
+   template< typename T >
+   inline const T& min(const T& a1, const T& a2, const T& a3, const T& a4)
+   {
+      return min(min(min(a1,a2),a3),a4);
+      
+//       double tmp = a1;
+//       if(tmp>a2) tmp=a2;
+//       if(tmp>a3) tmp=a3;
+//       if(tmp>a4) tmp=a4;
+//       return tmp;
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //
+   //constants
+   //
+   //////////////////////////////////////////////////////////////////////////
+   static const double c8o27 = 8. / 27.;
+   static const double c2o27 = 2. / 27.;
+   static const double c1o54 = 1. / 54.;
+   static const double c1o216 = 1. / 216.;
+   static const double c9o2 = 9. / 2.; //4.5
+   static const double c9o4 = 9. / 4.; //2.25
+   static const double c3o9 = 3. / 9.;
+   static const double c3o54 = 3. / 54.;
+   static const double c3o216 = 3. / 216.;
+
+   static const double c1o27 = 1. / 27.;
+
+   static const double c1o72 = 1. / 72.;          //0.01388888
+   static const double c1o36 = 1. / 36.;          //0.02777777
+   static const double c1o48 = 1. / 48.;          //0.02083333
+   static const double c1o32 = 1. / 32.;          //0.03125
+   static const double c1o24 = 1. / 24.;          //0.04166666
+   static const double c1o20 = 1. / 20.;          //0.05
+   static const double c1o18 = 1. / 18.;          //0.05555555
+   static const double c1o16 = 1. / 16.;          //0.0625
+   static const double c1o12 = 1. / 12.;          //0.08333333
+   static const double c1o9 = 1. / 9.;           //0.11111111
+   static const double c1o8 = 1. / 8.;           //0.125
+   static const double c1o6 = 1. / 6.;           //0.16666666
+   static const double c1o5 = 1. / 5.;           //0.2
+   static const double c1o4 = 1. / 4.;           //0.25
+   static const double c1o100 = 1. / 100.;
+   static const double c5o16 = 5. / 16.;          //0.3125
+   static const double c1o3 = 1. / 3.;           //0.33333333
+   static const double c3o8 = 3. / 8.;           //0.375
+   static const double c4o9 = 4. / 9.;           //0.44444444
+   static const double c1o2 = 1. / 2.;           //0.5
+   static const double c9o16 = 9. / 16.;          //0.5625
+   static const double c2o3 = 2. / 3.;           //0.66666666
+   static const double c3o4 = 3. / 4.;           //0.75
+   static const double c3o2 = 3. / 2.;           //1.5
+   static const double c4o3 = 4. / 3.;           //1.33333333
+   static const double c5o3 = 5. / 3.;           //1.66666666
+   static const double c9o5 = 9. / 5.;           //1.8
+   static const double c2o9 = 2. / 9.;           //0.22222222
+   static const double one_over_sqrt2 = 1.0 / sqrt(2.0); //0.707106781
+   static const double one_over_sqrt3 = 1.0 / sqrt(3.0); //0.577350269
+   static const double sqrt2 = sqrt(2.0); //1.4142135
+   static const double sqrt3 = sqrt(3.0); //1.7320508
+   static const double zeroReal = 0.0;
+   static const double c1 = 1.0;
+   static const double c2 = 2.0;
+   static const double c3 = 3.0;
+   static const double c4 = 4.0;
+   static const double c5 = 5.0;
+   static const double c6 = 6.0;
+   static const double c7 = 7.0;
+   static const double c8 = 8.0;
+   static const double c9 = 9.0;
+   static const double c14 = 14.0;
+   static const double c15 = 15.0;
+   static const double c16 = 16.0;
+   static const double c18 = 18.0;
+   static const double c21 = 21.0;
+   static const double c24 = 24.0;
+   static const double c28 = 28.0;
+   static const double c29 = 29.0;
+   static const double c36 = 36.0;
+   static const double c48 = 48.0;
+   static const double c50 = 50.0;
+   static const double c56 = 56.0;
+   static const double c152 = 152.0;
+   static const double c130 = 130.0;
+}
+
+#endif
diff --git a/VirtualFluidsBasics/basics/utilities/UbObservable.h b/VirtualFluidsBasics/basics/utilities/UbObservable.h
new file mode 100644
index 0000000000000000000000000000000000000000..37cb954ddc16c0f258f553375bd46bab48da23a1
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbObservable.h
@@ -0,0 +1,270 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbObservable.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBOBSERVABLE_H
+#define UBOBSERVABLE_H
+
+#include <list>               
+#include <iostream>
+
+#include <basics/utilities/UbObserver.h>
+
+class UbObserver;
+
+//////////////////////////////////////////////////////////////////////////
+//!
+//! \brief Observable object
+//! \details This class provides Observables. The Observeres which observe this
+//!  Observable are stored in an observerlist.
+//!  IMPORTANT: objectWillBeDeleted is called at UbObserver::~UbObserver
+//!             this destructor is called AFTER the destructor of the
+//!             child classes. if you down_cast the pointer sent with the
+//!             objectWillBeDeleted(UbObserver* objpointer) then have to go this:
+//!               
+//!               if(dynamic_cast<UbObserver*>(observedObj)==objpointer) 
+//!                     (e.g.) observedObj=NULL;
+//!   example: see end of file
+//!
+//!   a copy of an UbservableObject will NOT copy the observerList
+//!  <UL>
+//!    <LI><B>Extending:</B> This UbObservable is the observable object itself. Extending should be used
+//!	where object types can be extended from UbObservable.
+//!    <LI><B>Associating:</B> Initialization is done via the constructor <tt>UbObservable(ObservableObject)</tt>.
+//!	Associating may be used, where object types to be observed could not be extended from UbObservable.
+//!  </UL>
+//!
+//! see UbObserver
+//!
+//////////////////////////////////////////////////////////////////////////
+
+class UbObservable 
+{
+protected:
+   /*======================================================================*/
+   /*  Konstruktoren                                                       */
+   /*                                                                      */
+   /**
+     Creates a UbObservable itself to be the object to be observed.
+     Usually this constructor is used in extended classes.
+   */
+   UbObservable()
+   {
+   }
+   
+   UbObservable(const UbObservable& src)
+   {
+      //no copy of observers !!!
+   }
+   
+   //falls irgendein schlaumeier den =operator von UbObservable aufrufen sollte,
+   //dann macht diesr auch keine kopie! (Allg: zuweisungsoperatoren werden nie vererbt
+   UbObservable& operator=(const UbObservable& src)
+   {
+      return *this;
+   }
+   
+   //   /**
+   //     Creates a UbObservable for the specified Object to be observed.
+   //     Usually this constructor is used in associating UbObservable.
+   //     @param object Object to be observed
+   //   */
+public:
+   /*======================================================================*/
+   /*  Destruktor                                                          */
+   /*                                                                      */
+   /**
+   */
+   virtual ~UbObservable()
+   {
+      this->notifyObserversObjectWillBeDeleted();
+   } 
+
+   /*======================================================================*/
+   /*  methods                                                            */
+   /*                                                                      */
+   
+   /**
+   Adds an UbObserver to the observerlist.
+   @param observer the observer to add to this observable (note that an observer may observe c1 observable more than once)
+   */
+   virtual void addObserver(UbObserver* observer)
+   {
+      if(!observer) return;
+      for(std::list<UbObserver*>::iterator pos=mObserverList.begin();pos!=mObserverList.end();++pos)
+      {
+         if(*pos == observer) return;
+      }
+      this->mObserverList.push_back(observer);
+   }
+   /**
+   Deletes an UbObserver from the observerlist.
+   @param observer the observer to remove from this observable (note that all observers identical are deleted)
+   ( delete means delete Heap... but here we're only removing a pointer)
+   */
+   virtual void removeObserver(UbObserver* observer)
+   {
+      if(!observer) return;
+      this->mObserverList.remove(observer);
+
+   }
+   /**
+   Deletes all Observers from the observerlist.
+   ( delete means delete Heap... but here we're only removing a pointer)
+   */
+   virtual void removeAllObservers()
+   {
+      this->mObserverList.clear();
+   }
+   
+   /**
+     Checks whether the specified UbObserver observes this observable.
+     @param observer the observer to remove from this observable (note that all observers identical are deleted)
+     @return true if the specified observer observes this observable
+   */
+   virtual bool isObservedBy(UbObserver* observer)
+   {
+      if(!observer) return false;
+      for(std::list<UbObserver*>::iterator pos=mObserverList.begin();pos!=mObserverList.end();++pos)
+      {
+         if(*pos == observer) return true;
+      }
+      return false;
+   }
+   /**
+     Notifies all of its observers that something happened. Does nothing, if the observed object is null.
+     Calls the Method UbObserver.objectChanged(Object) with the object of this observable as parameter.
+     The Method UbObserver.objectChanged(Object) must be defined
+     by each class implementing the interface TiObserver
+   */
+   virtual void notifyObserversObjectChanged()
+   {
+      std::list<UbObserver*>::iterator tmp_pos; //es kann sein, dass der aktuelle observer waehrend
+                                           //objectChanged() removed wird...
+      for(std::list<UbObserver*>::iterator pos=mObserverList.begin();pos!=mObserverList.end();)
+      {
+        //cout<<"in notifyObserversObjectChanged\n";
+        //cout<<this->mObserverList.size()<<endl;
+
+         tmp_pos = pos++; // erst tmp_pos=pos und dann pos++
+         (*tmp_pos)->objectChanged(this);
+      }
+   }
+
+   std::list<UbObserver*>* getObserverList() { return &mObserverList;}
+
+   virtual std::string toString() { return "UbObservable - toString()"; }
+
+private:
+   /**
+     Notifies all of its observers that something happened. Does nothing, if the observed object is null.
+     Calls the Method UbObserver.objectChanged(Object) with the object of this observable as parameter.
+     The Method UbObserver.objectChanged(Object) must be defined
+     by each class implementing the interface TiObserver
+   */
+   virtual void notifyObserversObjectWillBeDeleted()
+   {
+      std::list<UbObserver*>::iterator tmp_pos; //es kann sein, dass der aktuelle observer waehrend
+                                          //objectWillBeDeleted() removed wird...
+      for(std::list<UbObserver*>::iterator pos=mObserverList.begin();pos!=mObserverList.end();)
+      {
+         //cout<<"in notifyObserversObjectWillBeDeleted\n";
+         //cout<<this->mObserverList.size()<<endl;
+
+         tmp_pos = pos++;
+         (*tmp_pos)->objectWillBeDeleted(this);
+      }
+   }
+
+   std::list<UbObserver*> mObserverList;
+};
+/*=========================================================================*/
+
+
+#ifdef RCF_USE_SF_SERIALIZATION
+   SF_NO_CTOR(UbObservable);
+#endif //RCF_USE_SF_SERIALIZATION
+
+#endif
+
+////  E X A M P L E 
+////===================
+//class Point : public UbObservable
+//{
+//public:
+//   Point(){x=y=0;}
+//   ~Point(){}
+//   void setXCorrdinates(int x,int y)
+//   {
+//     this->x = x; this->y = y;
+//     this->notifyObserverObjectChanged();
+//   }
+//private:
+//   int x,y;
+//};
+//class VisPoint : public UbObserver
+//{
+//public:
+//   VisPoint(Point* point)
+//   { 
+//      this->point = point;
+//      this->point->addObserver(this);
+//   }
+//   ~VisPoint()
+//   {
+//      if(this->point) point->removeObserver(this);
+//   }
+//   void update() { /* do some actualisation stuff */ }
+//   void objectChanged(UbObservable* changedObject)
+//   {
+//      Point* point = dynamic_cast<Point*>(changedObject);
+//      if( !this->point || this->point != point ) return;
+//      this->repaint();
+//   }
+//   void objectWillBeDeleted(UbObservable* objectForDeletion)
+//   {
+//      if(!this->point) return;
+//      UbObservable* obsobjet = dynamic_cast<UbObservable*>(this->point);
+//      if(obsobjet == objectForDeletion) this->point = NULL;
+//      ///////////////////////////////////////////////////////////////////
+//      //*********************************************************************//
+//      //INGEGEN erster annahmen nicht verwenden, da es nicht immer funktioniert
+//      //z.B. bei mehrfachvererbung haut es nicht hin!
+//      ////      Point* point = reinterpret_cast<point*>(objectForDeletion);
+//      ////if(!this->point || objectForDeletion != this->point) return;
+//      ////this->point = NULL;
+//      //*********************************************************************//
+//      //was hingegen immer moeglich sein sollte:
+//      //if(dynamic_cast<void*>(objectForDeletion)==dynamic_cast<void*>(this->point))
+//   }
+//private:
+//   Point* point;
+//};
diff --git a/VirtualFluidsBasics/basics/utilities/UbObserver.h b/VirtualFluidsBasics/basics/utilities/UbObserver.h
new file mode 100644
index 0000000000000000000000000000000000000000..6aff49a396a3858028799a9c7d5186a1d80ce4a7
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbObserver.h
@@ -0,0 +1,78 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbObserver.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBOBSERVER_H
+#define UBOBSERVER_H
+
+class UbObservable;
+
+//////////////////////////////////////////////////////////////////////////
+//!
+//! \brief Observer
+//! \details This interface must be implemented by classes which want to
+//! observe other objects.
+//! IMPORTANT: if you delete an observer, ensure to remove Observer from
+//!            all his observed observable objects before!!!
+//! example: see end of UbObservable.h-file
+//!
+//////////////////////////////////////////////////////////////////////////
+
+class UbObserver 
+{
+protected:
+
+   UbObserver(){}
+
+public:
+
+   virtual ~UbObserver(){}
+
+   /*======================================================================*/
+   /*  Methods                                                           */
+   /*                                                                      */
+   /*!
+   This function is called when the observable indicated that an object
+   has changed.
+   \param changedObject Object which has changed
+   */
+   virtual void objectChanged(UbObservable* changedObject)=0;
+   /*!
+   This function is called when the observable indicated that an object
+   should be deleted.
+   \param objectForDeletion Object which should be deleted
+   */
+   virtual void objectWillBeDeleted(UbObservable* objectForDeletion)=0;
+};
+
+#endif
+
+
diff --git a/VirtualFluidsBasics/basics/utilities/UbScheduler.h b/VirtualFluidsBasics/basics/utilities/UbScheduler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bb41a94281d73eed670572dd0986de4b24972a5
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbScheduler.h
@@ -0,0 +1,346 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbScheduler.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller, Jan Hegewald
+//=======================================================================================
+#ifndef UBSCHEDULER_H
+#define UBSCHEDULER_H
+
+#include <iostream>
+#include <string>
+#include <limits>
+#include <cassert> 
+#include <sstream>
+#include <iomanip>
+#include <algorithm>
+
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbInfinity.h>
+#include <basics/utilities/UbComparators.h>
+
+//////////////////////////////////////////////////////////////////////////
+//!
+//! \brief A class implements scheduling. 
+//! \details This class is not thread save.
+//!
+//////////////////////////////////////////////////////////////////////////
+
+class UbScheduler
+{
+public:
+   class UbSchedule
+   {
+      friend class UbScheduler;
+   public:
+      UbSchedule() :  step(Ub::inf), begin(Ub::inf), end(Ub::inf) { }
+      UbSchedule(const double& step, const double& begin=0.0, const double& end=Ub::inf) 
+         : step(step), begin(begin), end(end) 
+      {  
+      }
+      double getStep()  const { return this->step;  }
+      double getBegin() const { return this->begin; }
+      double getEnd()   const { return this->end;   }
+      
+      /*==========================================================*/
+      std::string toString() { std::stringstream text; text<<*this; return text.str(); }
+      /*==========================================================*/
+      friend inline std::ostream& operator << (std::ostream& os, const UbSchedule& schedule) 
+      {
+         os<<"Schedule[start,end,step]=["<<schedule.begin<<", "<<schedule.end<<", "<<schedule.step<<"]";
+         return os;
+      }
+
+   private:
+      double step, begin, end;
+   };
+
+public:
+   UbScheduler() 
+   {
+      this->initVals();
+   }
+   /*==========================================================*/                         
+   UbScheduler(const double& step,const double& begin=0, const double& end=Ub::inf ) 
+   {
+      this->initVals();
+      this->addSchedule(step,begin,end);
+   }
+   /*==========================================================*/
+   UbScheduler(const UbSchedule& schedule) 
+   {
+      this->initVals();
+      this->addSchedule(schedule);
+   }
+   /*==========================================================*/
+   virtual ~UbScheduler() {}
+   /*==========================================================*/
+   inline void addSchedule(const UbSchedule& schedule)
+   {
+      this->addSchedule(schedule.step, schedule.begin, schedule.end);
+   }
+   /*==========================================================*/
+   bool addSchedule(const double& step, const double& begin, double end)
+   {
+      if( UbMath::zero(step) || begin>end )
+      { 
+         std::cerr<<"UbScheduler::addSchedule - invalid Schedule:\n\t"<<UbSchedule(step, begin, end)<<std::endl;
+         return false; 
+      }
+      
+      if( UbMath::less( end, (double)Ub::inf )  )
+      {
+         //es kann vorkommen, dass man mit dem intervall nicht genau auf den letzten wert kommt
+         //(z.B. step=2; start=0; end=9; -> ende wird angepasst)
+         //also wenn end-begin>Ub::inf ist, dann geht es halt nicht.. ein cast in long double half hier nichts
+         double multiplier=0.0;
+         double fractpart =  modf( (end-begin)/step, &multiplier);
+         if( !UbMath::zero(fractpart) )
+         {
+            //tmp-speicherung (fuer cerr)
+            fractpart = end;
+            //neues ende
+            end = begin+multiplier*step;
+            
+            std::cerr<<"Warning: UbScheduler::addSchedule - "
+                      <<"end of schedule was adapted to intervall \n\t"
+                      <<"from "<< UbSchedule(step, begin, fractpart) <<" to "<< UbSchedule(step, begin, end) <<std::endl;
+         }
+      }
+
+      //nu aber:
+      schedules.push_back(UbSchedule(step, begin, end));
+
+      if( end>maxT ) maxT = end;
+
+      double potentialDueTime;
+      if(   calcNextDueTimeForSchedule(schedules.back(), lastUsedT, potentialDueTime)
+         && potentialDueTime < nextDueTime   )
+      {
+         nextDueTime = potentialDueTime;
+      }
+
+      return true;
+   }
+   /*==========================================================*/
+   //returns true if scheduler contains schedules
+   bool   hasSchedules() const { return !schedules.empty(); }
+   /*==========================================================*/
+   //time bei dem das letzte mal isDue(time) true war
+   double getLastDueTime() const { return lastDueTime; }
+   /*==========================================================*/
+   //time bei dem das naechste mal isDue(time) true ergibt
+   double getNextDueTime() const { return nextDueTime; }
+   /*==========================================================*/
+   //maxDueTime (maxTime der Schedules!
+   double getMaxDueTime()  const { return this->maxT; }
+   /*==========================================================*/
+   bool isDue(const double& t)
+   {
+      lastUsedT = t;
+      if( UbMath::greaterEqual(t,nextDueTime) ) 
+      {
+         //groesser maxT is nicht
+         if( UbMath::greater(t,maxT) )  return false;
+         
+         //temp var
+         double actDueTime = nextDueTime;
+
+         //um Suche nach nextDueTime bei "Zukunfts-t" zu optimieren, setzt man die "start"-suchzeit auf "t-1":
+         nextDueTime = t-1; //t-1 deshlab, damit falls z.B. while Schleife nicht durchlaufen wird
+                            //die folgende if Abfrage nicht faelschlicher Weise true ist!
+         while( UbMath::greaterEqual(t,nextDueTime) && !UbMath::equal(nextDueTime, maxT) )
+         {
+            double tmpNextDueTime = maxT, potentialDueTime=-1.0;
+            for(std::size_t i=0; i<schedules.size(); i++)
+            {
+               if(   calcNextDueTimeForSchedule(schedules[i], nextDueTime, potentialDueTime)
+                  && potentialDueTime < tmpNextDueTime                 )
+               {
+                  assert( nextDueTime < potentialDueTime );
+                  tmpNextDueTime = potentialDueTime;
+               }
+            }
+            actDueTime  = nextDueTime;
+            nextDueTime = tmpNextDueTime;
+         } 
+
+         //wenn t = der aktuuellen oder gar schon der nächstmöglichen ist (hierbei wurde
+         //zuvor actDueTime und nextDueTime ggf. angepasst)
+         //Bsp.: nextDuTime war 5, aber für t=400 gilt andere schedule -> Bsp actDue=350 und nextDue 405
+         if(    UbMath::equal(t,actDueTime)    
+             || UbMath::equal(t,nextDueTime) ) 
+         {
+            lastDueTime = t;
+            return true;
+         }
+      }
+      else if( UbMath::lessEqual(t, lastDueTime) ) 
+      {
+         if(UbMath::equal(t, lastDueTime) ) return true; //braucht man, wenn man für dasselbe t isDue(t) aufruft
+         else  
+         {
+            //Fall: Zeit liegt faktisch in der Vergangenheit -> neu initialsisieren
+            double tmpNextDueTime = maxT, potentialDueTime=-1.0;
+            for(size_t i=0; i<schedules.size(); i++)
+            {
+               if(   calcNextDueTimeForSchedule(schedules[i], t-1, potentialDueTime)
+                  && potentialDueTime < tmpNextDueTime                 )
+               {
+                  tmpNextDueTime = potentialDueTime;
+               }
+            }
+            nextDueTime = tmpNextDueTime;
+
+            return UbMath::equal(t, nextDueTime);
+         }
+      }
+
+      return false;
+   }
+   /*==========================================================*/
+   inline double getMinBegin( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::min_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getBegin) )->getBegin();
+   }
+   /*==========================================================*/
+   inline double getMaxBegin( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::max_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getBegin) )->getBegin();
+   }
+   /*==========================================================*/
+   inline double getMinEnd( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::min_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getEnd) )->getEnd();
+   }
+   /*==========================================================*/
+   inline double getMaxEnd( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::max_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getEnd) )->getEnd();
+   }
+   /*==========================================================*/
+   inline double getMinStep( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::min_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getStep) )->getStep();
+   }
+   /*==========================================================*/
+   inline double getMaxStep( ) const
+   {
+      if( schedules.empty() ) return Ub::inf;
+      return std::max_element(schedules.begin(), schedules.end(),UbComparators::membercomp(&UbSchedule::getStep) )->getStep();
+   }
+   /*==========================================================*/
+   inline std::string toString() const
+   {
+      std::stringstream text;
+      text<<*this;
+      return text.str();
+   }
+   /*==========================================================*/
+   friend inline std::ostream& operator << (std::ostream& os, const UbScheduler& scheduler) 
+   {
+      os<<"UbScheduler\n";
+      os<<"Schedule |       start       |        end        |     intervall     "<<std::endl;
+      for(std::size_t i=0; i<scheduler.schedules.size(); i++)
+         os<<std::setw(9)<<i<<"|"
+           <<std::setw(19)<<scheduler.schedules[i].getBegin()<<"|"
+           <<std::setw(19)<<scheduler.schedules[i].getEnd()  <<"|"
+           <<std::setw(19)<<scheduler.schedules[i].getStep() <<std::endl;
+      return os;
+   }
+
+protected:
+   /*==========================================================*/
+   void initVals()
+   {
+      lastUsedT   = -Ub::inf; 
+      lastDueTime = -Ub::inf;
+      nextDueTime =  Ub::inf;
+      maxT        = -Ub::inf;
+   }
+   /*==========================================================*/
+   // calculates next due time for a schedule 
+   // with  nextDueTime > searchStart
+   bool calcNextDueTimeForSchedule(const UbSchedule& schedule, const double& searchStart, double& nextDueTime )
+   {
+      if     ( UbMath::greater(searchStart, schedule.end  ) ) return false;
+      else if( UbMath::less(   searchStart, schedule.begin) ) nextDueTime = schedule.begin;
+      else                            
+      {
+         nextDueTime = schedule.begin + ((int)((searchStart-schedule.begin)/schedule.step)+1)*schedule.step;
+         if(   UbMath::less(   nextDueTime, searchStart )
+            || UbMath::greater(nextDueTime, schedule.end) ) 
+         {
+            return false;
+         }
+      }
+      return true;
+   }
+
+protected:
+   double lastUsedT;
+   double lastDueTime;
+   double nextDueTime;
+   double maxT;
+   
+   std::vector<UbSchedule> schedules;
+};
+
+typedef UbScheduler::UbSchedule UbSchedule;
+
+#endif //UBSCHEDULER_H
+
+
+
+//int main(int argc, char** argv)            
+//{   
+//	UbScheduler writeSchedule;
+////	writeSchedule.addSchedule(0,2000,100);
+////	writeSchedule.addSchedule(3005,4500,300);
+////	writeSchedule.addSchedule(0,10,1);
+////	writeSchedule.addSchedule(0,100001,100);
+//	writeSchedule.addSchedule(0,2,1);
+//	writeSchedule.addSchedule(0,100001,200);
+//
+//	for(int t = 0; t < 1001; t++)
+//	{
+//		if(writeSchedule.isDue(t))
+//		{
+//			cout<<"due@ "<<t<<endl;
+//		}
+//	}
+//	return 0;
+//}
+
diff --git a/VirtualFluidsBasics/basics/utilities/UbSystem.h b/VirtualFluidsBasics/basics/utilities/UbSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..2102bc52acffb4f7e94263a070c86fe3f55f563c
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbSystem.h
@@ -0,0 +1,569 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbSystem.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBSYSTEM_H
+#define UBSYSTEM_H
+
+#if defined(_WIN32) || defined(_WIN64)
+   #define UBSYSTEM_WINDOWS
+   #include <process.h>
+   #include <io.h>
+   #include <direct.h>
+   //#ifndef _WINSOCK2API_  //ansonsten gibt es mecker bei #include "Windows.h" und ::Sleep()
+   //   #define _WINSOCK2API_
+   //   #include<WinSock2.h> 
+   //#endif
+  #include <windows.h>
+  //#include <Windows.h>
+  //#include <tchar.h>
+#elif defined(__APPLE__)
+   #define UBSYSTEM_APPLE
+   #include "dirent.h"
+   #include "sys/stat.h"
+   #include <sys/syscall.h>
+   #include <sys/stat.h>
+   #include <unistd.h>
+#elif (defined(__amd64) || defined(__amd64__) || defined(__unix__)) && !defined(__AIX__)
+   #define UBSYSTEM_LINUX
+   #include "dirent.h"
+   #include <sys/stat.h>
+   #include <unistd.h>
+   #include <string.h>
+#elif defined(__AIX__)
+   #define UBSYSTEM_AIX
+   #include "dirent.h"
+   #include <unistd.h>
+   #include <sys/stat.h>
+   #include <sys/types.h>
+#else
+   #error "UbSystem::UnknownMachine"
+#endif
+
+#if defined(__unix__) && defined(__CYGWIN__)
+   #define UBSYSTEM_CYGWIN
+   #include <windows.h>
+#else
+   #include <sys/syscall.h>
+#endif
+
+#if defined(min) || defined(max) //daruch kann man sich spaeter #undef min; #undef max erparen
+#   error add NOMINMAX to preprocessor defines
+#endif
+
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <algorithm>
+#include <typeinfo>
+#include <cctype> //for toupper
+#include <ctime>
+
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbLogger.h>
+
+#if defined(CAB_BOOST)
+#include <boost/thread.hpp>
+#endif // CAB_BOOST
+
+//DEFINE TO STRING
+//e.g. #define FOO hallo
+//     -> QUOTEME(FOO) == "hallo"
+#define _QUOTEME(x) #x
+#define QUOTEME(x) _QUOTEME(x)
+
+//allg.:
+//const int * C1        -> C1 is variable pointer to a constant integer
+//int const * C2        -> C2 is variable pointer to a constant integer (same as above)
+//int * const C3        -> C3 is constant pointer to a variable integer
+//int const * const C4  -> C4 is constant pointer to a constant integer
+
+//////////////////////////////////////////////////////////////////////////
+//UbSystem
+//////////////////////////////////////////////////////////////////////////
+namespace UbSystem
+{
+   template<bool> struct ub_static_assert;     //deklaration (ub_xxx da static_assert in C++0x ein keyword werden wird)
+   template<> struct ub_static_assert<true>{}; //deklaration + definition der spezialisierung fuer "true"
+                                               //ub_static_assert<false> fuehrt zu compiler fehler, da dafuer
+                                               //keine implementierung vorhanden!  //UB_STATIC_ASSERT(false)
+
+   /*==========================================================*/
+   inline void sleepMs(const unsigned int& msec)
+   {
+      #if defined(UBSYSTEM_WINDOWS)
+         ::Sleep(  (msec==0) ? 1 : msec );  // +1 here causes a context switch if SleepMSec(0) is called
+      #elif (defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)) && !defined(UBSYSTEM_CYGWIN)
+         ::usleep(1000*msec);
+      #elif defined(UBSYSTEM_CYGWIN)
+       ::Sleep(  (msec==0) ? 1 : msec );
+      #else
+         #error "UbSystem::sleepMSec - UnknownMachine"
+      #endif
+   }
+   /*==========================================================*/
+   inline void sleepS(const unsigned int& sec)
+   {
+      #if defined(UBSYSTEM_WINDOWS) && defined(UBSYSTEM_CYGWIN)
+         ::Sleep( (sec==0) ? 1 : sec*1000 );  // +1 here causes a context switch if sleepS(0) is called
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX) && !defined(UBSYSTEM_CYGWIN)
+         ::sleep(sec);
+      #else
+         #error "UbSystem::sleepS - UnknownMachine"
+      #endif
+   }
+   /*==========================================================*/
+   //checks if the bits of bitmask are set in value
+   template<typename T>
+   inline bool bitCheck(const T& value, const T& bitmask)
+   {
+      return  ( (value & bitmask) == bitmask);
+   }
+   /*==========================================================*/
+   //checks if the bits of bitmask are set in value
+   template<typename T>
+   inline void setBit(T& value, const T& bitmask)
+   {
+      value |= bitmask;
+   }
+   /*==========================================================*/
+   template<typename T>
+   inline void unsetBit(T& value, const T& bitmask)
+   {
+      value &= ~bitmask;
+   }
+   /*==========================================================*/
+   //returns bitmask as string e.g. 0001 0100 1101
+   template<typename T>
+   inline std::string getBitString(const T& value)
+   {
+      std::stringstream text;
+      for(int i=sizeof(value)*8-1/*8 bits per byte*/; i>=0; i--)
+      {
+         text<<(char) ( ((value>>i) & 1) + '0');
+         if(i%4 == 0 && i>0) text<<' ';
+      }
+      return text.str();
+   }
+   /*==========================================================*/
+   //converts string to type T
+   // usage: int x = stringTo<int>("123");
+   template<typename T>
+   inline T stringTo(const std::string& s)
+   {
+     std::istringstream iss(s);
+     T x;
+     iss >> x;
+     if(!iss)
+        UB_THROW( UbException(UB_EXARGS," cannot convert \""+s+"\" to type <"+static_cast<std::string>(typeid(x).name())+">") );
+
+     return x;
+   }
+   /*==========================================================*/
+   // usage: string s = toString(x);
+   template<typename T>
+   inline std::string toString(const T& x, int precision=15)
+   {
+     std::ostringstream oss;
+     oss<<std::setprecision(precision);
+     oss<<x;
+     return oss.str();
+   }
+   /*==========================================================*/
+   //e.g. str="iHcsnW" -> "IHCSNW"
+   inline std::string toUpperString(const std::string& str)
+   {
+      std::string tmp(str);
+      std::transform(tmp.begin(),tmp.end(),tmp.begin(), static_cast<int (*)(int)>(std::toupper));
+
+      return tmp;
+   }
+   /*==========================================================*/
+   //e.g. str="iHcsnW" -> "ihcsnw"
+   inline std::string toLowerString(const std::string& str)
+   {
+      std::string tmp(str);
+      std::transform(tmp.begin(),tmp.end(),tmp.begin(), static_cast<int (*)(int)>(std::tolower));
+
+      return tmp;
+   }
+   /*==========================================================*/
+   // usage: std::string s = replaceInString(str,"\\","/");
+   //        std::string s = replaceInString(str,"ich","du");
+   static std::string replaceInString(std::string original, const std::string& replace, const std::string& replaceWith )
+   {
+      size_t pos=0;
+      while( (pos=original.find(replace,pos))!=std::string::npos )
+      {
+         original.replace(pos,replace.size(),replaceWith);
+         pos+=replaceWith.size();
+      }
+      return original;
+   }
+   /*==========================================================*/
+   //returns content of an enviroment variable
+   inline std::string getEnv(const std::string& var)
+   {
+      char* str = getenv( var.c_str());
+      if(  str == NULL  ) 
+      {
+         return std::string("");
+      }
+      
+      return static_cast<std::string>( str );
+   }
+   /*==========================================================*/
+   inline bool isDirectory(const std::string& dir, const unsigned& attemptions = 3)
+   {
+      if( dir.empty() ) 
+         UB_THROW( UbException(UB_EXARGS,"dir is empty") );
+      
+      std::string path = UbSystem::replaceInString(dir,"\\","/");
+
+      #if defined UBSYSTEM_WINDOWS
+         #ifndef _UNICODE 
+            if( _access(path.c_str(), 0  ) == -1 ) return false;
+         #else
+            if( _waccess(path.c_str(), 0 ) == -1 ) return false;
+         #endif
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
+         struct stat stFileInfo;
+         if( stat(path.c_str(),&stFileInfo) != 0) 
+         {
+            return false;
+         }
+      #endif
+      
+      return true;
+   }
+   /*==========================================================*/
+   // usage:  makeDirectory("c:/temp");
+   //         makeDirectory("c:/temp/");
+   // return: true  -> successful
+   //         false -> failed
+   #if defined(CAB_BOOST) 
+      static boost::mutex mtx_makeDirectory;
+   #endif
+   inline bool makeDirectory(const std::string& dir, const unsigned& attemptions = 3)
+   {
+      UBLOG(logDEBUG5,"UbSystem::makeDirectory - start, dir="<<dir<<" #attemptions="<<attemptions);
+
+      if( dir.empty() ) UB_THROW( UbException(UB_EXARGS,"dir is empty") );
+      std::string path = UbSystem::replaceInString(dir,"\\","/");
+
+      bool dirCreated = true;
+      #if defined UBSYSTEM_WINDOWS
+         if(path[path.size()-1] != '/') path+="/";
+         size_t  pos = 0;
+         while( ( pos=path.find("/",pos+1) ) != std::string::npos )
+         {
+            std::string tmpdir = path.substr(0,pos);
+            #if defined(CAB_BOOST) 
+            boost::mutex::scoped_lock lock(mtx_makeDirectory);
+            #endif
+            if( 
+                #ifndef _UNICODE 
+                 _access(tmpdir.c_str(), 0 ) == -1 && _mkdir(tmpdir.c_str() ) == -1
+                #else
+                 _waccess(tmpdir.c_str(), 0) == -1 && _wmkdir(tmpdir.c_str()) == -1
+                #endif
+               )
+               {
+                  UBLOG(logDEBUG5,"UbSystem::makeDirectory-  dir=\""<<tmpdir<<"\" doesn't exit or makedir failed");
+                  dirCreated = false;
+                  break;
+               }
+         }
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
+         std::string command = "mkdir -p \""+path+"\"";
+         {
+            #if defined(CAB_BOOST) 
+               boost::mutex::scoped_lock lock(mtx_makeDirectory);
+            #endif
+            if(system(command.c_str())!=0)
+            {
+               UBLOG(logDEBUG5,"UbSystem::makeDirectory-  dir=\""<<path<<"\" doesn't exit or makedir failed");
+               dirCreated = false;
+            }
+         }
+      #else
+         #error "UbSystem::makeDirectory - UnknownMachine"
+      #endif
+
+      if(!dirCreated && attemptions > 1)
+      {
+         UBLOG(logDEBUG5,"UbSystem::makeDirectory - internal call of UbSystem::makeDirectory");
+         UbSystem::sleepMs(500);
+         dirCreated = UbSystem::makeDirectory(path, attemptions-1);
+      }
+      
+      UBLOG(logDEBUG5,"UbSystem::makeDirectory - end (success="<<dirCreated<<", attemptions = "<<attemptions<<")");
+      return dirCreated;
+   }
+   /*==========================================================*/
+#if defined(CAB_BOOST) 
+   static boost::mutex mtx_removeDirectory;
+#endif
+   inline int removeDirectory(const std::string& dir)
+   {
+      #if defined(CAB_BOOST) 
+         boost::mutex::scoped_lock lock(mtx_removeDirectory);
+      #endif
+      std::string command = "rmdir \""+dir+"\"";
+      return std::system(command.c_str());
+   }
+   /*==========================================================*/
+   // usage  : getPathFromString("c:/temp/foo.txt");
+   //returns: "c:/temp"
+   // usage  : getPathFromString("c:\\temp\\foo.txt");
+   //returns: "c:/temp"
+   // usage  : getPathFromString("foo.txt");
+   // returns: ""
+   inline std::string getPathFromString(const std::string& fileStringWithPath)
+   {
+      std::string tmp = UbSystem::replaceInString(fileStringWithPath,"\\","/");
+      std::size_t last = tmp.rfind("/");
+      if(last!=std::string::npos) tmp.resize(last);
+      else                        tmp = "";
+      return tmp;
+   }
+   /*==========================================================*/
+   // usage  : getFilenameFromString("c:/temp/foo.txt");
+   // returns: "foo.txt"
+   // usage  : getFilenameFromString("c:/temp/foo.txt",false);
+   // returns: "foo"
+   // usage  : getFilenameFromString("c:/temp/");
+   // returns: ""
+   inline std::string getFilenameFromString(const std::string& fileStringWithPath, bool withExtension = true)
+   {
+      std::string tmp = UbSystem::replaceInString(fileStringWithPath,"\\","/");
+      
+      //remove path
+      std::size_t last = tmp.rfind("/");
+      if(last!=std::string::npos && (last+1)<tmp.size()) tmp.erase(0,last+1);
+      
+      //remove extension
+      if(!withExtension)
+      {
+         last = tmp.rfind(".");
+         if(last!=std::string::npos) tmp.erase(last);
+      }
+
+      return tmp;
+   }
+   /*==========================================================*/
+   inline int getProcessID()
+   {
+      #if defined UBSYSTEM_WINDOWS
+         return _getpid();
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
+         return getpid();
+      #else
+         #error "int UbSystem::getProcessID() - UnknownMachine"
+      #endif
+   }
+   /*==========================================================*/
+   inline unsigned long getCurrentThreadID()
+   {
+      #if defined UBSYSTEM_WINDOWS
+         return (unsigned long)GetCurrentThreadId();
+      #elif (defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE)) && !defined(UBSYSTEM_CYGWIN)
+         return (unsigned long)syscall(SYS_gettid);
+      #elif defined(UBSYSTEM_CYGWIN)
+         return (unsigned long)GetCurrentThreadId();
+      #elif defined(UBSYSTEM_AIX)
+         return (unsigned long) getpid(); //WORKAROUND for IBM (for get thread id is another function necessary) 
+      #else
+         #error "unsigned long UbSystem::getCurrentThreadID() - UnknownMachine"
+      #endif
+   }
+   /*==========================================================*/
+   inline bool isBigEndian()
+   {
+      short word = 0x4321;
+      if((*(char*)& word) != 0x21 ) return true;
+      else                           return false;
+   }
+   /*==========================================================*/
+   inline bool isLittleEndian()
+   {
+      return !isBigEndian();
+   }
+   /*==========================================================*/
+   inline std::string getTimeStamp()
+   {
+      time_t t = time(NULL);
+      tm* localTime = localtime(&t); 	
+      
+      std::stringstream tmp;
+      tmp.fill('0');
+      
+      tmp << localTime->tm_year+1900 
+          << "." << std::setw(2) <<localTime->tm_mon+1
+          << "." << std::setw(2) << localTime->tm_mday 
+          << "@" << std::setw(2) << localTime->tm_hour  
+          << "." << std::setw(2) << localTime->tm_min   
+          << "." << std::setw(2) << localTime->tm_sec  ;
+
+      return tmp.str();
+   }
+   /*==========================================================*/
+   //swap Byte Order
+   //usage: int test = 8;
+   //       swapByteOrder((unsigned char*)& test, sizeof(int))
+   //#define ByteSwap5(x) ByteSwap((unsigned char *) &x,sizeof(x))
+   inline void swapByteOrder(unsigned char* toSwap, int length)
+   {
+      register int i = 0;
+      register int j = length-1;
+      while(i<j)
+      {
+         std::swap(toSwap[i], toSwap[j]);
+         i++, j--;
+      }
+   }
+   //////////////////////////////////////////////////////////////////////////
+   //get host name
+   inline std::string getMachineName()
+   {
+      char Name[150];
+      int i = 0;
+
+#if defined(UBSYSTEM_WINDOWS)  && defined(UBSYSTEM_CYGWIN)
+      TCHAR infoBuf[150];
+      DWORD bufCharCount = 150;
+      memset(Name, 0, 150);
+      if (GetComputerName(infoBuf, &bufCharCount))
+      {
+         for (i = 0; i<150; i++)
+         {
+            Name[i] = infoBuf[i];
+         }
+      }
+      else
+      {
+         strcpy(Name, "Unknown_Host_Name");
+      }
+#elif (defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)) && !defined(UBSYSTEM_CYGWIN)
+      memset(Name, 0, 150);
+      gethostname(Name, 150);
+#endif
+      return std::string(Name);
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   // generic IfThenElse - start
+   //////////////////////////////////////////////////////////////////////////
+   // primary template: yield second or third argument depending on first argument
+   template<bool C, typename Ta, typename Tb>
+   class IfThenElse;
+
+   // partial specialization: true yields second argument
+   template<typename Ta, typename Tb>
+   class IfThenElse<true, Ta, Tb> {
+   public:
+      typedef Ta ResultT;
+   };
+
+   // partial specialization: false yields third argument
+   template<typename Ta, typename Tb>
+   class IfThenElse<false, Ta, Tb> {
+   public:
+      typedef Tb ResultT;
+   };
+   //////////////////////////////////////////////////////////////////////////
+   // generic IfThenElse - end
+   //////////////////////////////////////////////////////////////////////////
+
+   //////////////////////////////////////////////////////////////////////////
+   //help struct for overloading methods in template classes for specific types
+   //////////////////////////////////////////////////////////////////////////
+   template< typename T>
+   struct type2type
+   {
+      typedef T type;
+   };
+
+
+   //////////////////////////////////////////////////////////////////////////
+   // pair selector
+   //////////////////////////////////////////////////////////////////////////
+   template <typename Pair>
+   struct select1st
+   {
+      typedef Pair argument_type ;
+      typedef typename Pair::first_type result_type ;
+
+      const result_type&  operator()(const argument_type &p) const
+      {
+         return p.first ;
+      }
+   };
+
+   template <typename Pair>
+   struct select2nd
+   {
+      typedef Pair argument_type ;
+      typedef typename Pair::second_type result_type ;
+
+      const result_type& operator()(const argument_type &p) const
+      {
+         return p.second ;
+      }
+   };
+
+};
+
+#define UB_STATIC_ASSERT(expr) static_cast<void>(sizeof( UbSystem::ub_static_assert<expr> ));
+//zum ueberpruefen von STATISCHEN ausdruecken waehrend der compile-zeit
+//--> Ausdruecke muessen schon ZUR compilerzeit auswertbar sein !!!
+//Anwendung z.B. zur Ueberpruefung von Funktionalitaeten, wie z.B. bei UbMath::getNegativeInfinity<double>();
+//
+//Grund fuer macro ist einfach, dass es besser anzuwenden ist in der praxis!
+//ansonsten w�rde es so aussehen:
+//     UbSystem::ub_static_assert< aaa == 1 > test();
+//    da ist  UB_STATIC_ASSERT(aaa == 1); schoener
+//
+//um das zu vermeiden machtman hier diesen static_cast<void>(sizeof(...) )
+//Code-Snippet:
+// struct Test { const static bool m_const_bool = true; bool m_bool; };
+// int main() {
+//  UB_STATIC_ASSERT( Test::m_const_bool == true );
+//  --> okay, assert bestanden
+//  UB_STATIC_ASSERT( Test::m_const_bool == false); //:
+//  --> assert nicht bestanden z.B. error C2027: use of undefined type 'UbSystem::ub_static_assert<__formal> with __formal = false --> funzt nicht. fehler im code
+//  UB_STATIC_ASSERT( Test::m_bool == true );
+//  --> nicht erlaubt, da m_bool nicht statisch und nicht const ist.
+//}
+
+#endif //UBSYSTEM_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbTiming.h b/VirtualFluidsBasics/basics/utilities/UbTiming.h
new file mode 100644
index 0000000000000000000000000000000000000000..d683d07050d9a906adfe3a71d77270d2d8bf034a
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbTiming.h
@@ -0,0 +1,416 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbTiming.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBTIMING_H
+#define UBTIMING_H
+
+#include <string>
+#include <limits>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <ctime>
+
+#ifdef VF_MPI
+   #include <mpi.h>
+   #include <basics/parallel/PbMpi.h>
+#endif //VF_MPI
+
+class UbTiming
+{
+public:
+	UbTiming()
+   {
+      this->duration		= 0.0;
+      this->deltaT		= 0.0;
+      this->startTime	= 0;
+      this->name        = "noname";
+   }
+   /*==========================================================*/
+   UbTiming(const std::string& name)
+   {
+      this->duration		= 0.0;
+      this->deltaT		= 0.0;
+      this->startTime	= 0;
+      this->name        = name;
+   }
+   /*==========================================================*/
+   virtual ~UbTiming() {}  
+   /*==========================================================*/
+   virtual void initTiming()
+   {
+      this->duration = 0.0;	
+   }
+   /*==========================================================*/
+   virtual void startTiming()
+   {
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         this->startTime = PbMpi::Wtime();
+      #else
+         this->startTime = (double)clock();	
+      #endif //VF_MPI 
+   }
+   /*==========================================================*/
+   virtual void initAndStartTiming()
+   {
+      this->initTiming();
+      this->startTiming();
+   }
+   /*==========================================================*/
+   virtual void endTiming()
+   {
+      this->stopTiming();
+   }
+   /*==========================================================*/
+   virtual void stopTiming()
+   {
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+            this->deltaT   = PbMpi::Wtime()-this->startTime;
+      #else
+         this->deltaT   = ((double)clock()-this->startTime)/(double)CLOCKS_PER_SEC;
+      #endif //VF_MPI 
+
+      this->duration += this->deltaT;
+   }
+   /*==========================================================*/
+   virtual double getDuration() const
+   {
+      return this->duration;
+   }
+   /*==========================================================*/
+   virtual void setName(const std::string& name)
+   {
+      this->name = name;
+   }
+   /*==========================================================*/
+   virtual std::string getName() const
+   { 
+      return this->name; 
+   }
+   /*==========================================================*/
+   void start()
+   {
+      this->duration = 0.0;
+
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         this->startTime = PbMpi::Wtime();
+      #else
+         this->startTime = (double)clock();
+      #endif //VF_MPI 
+   }
+   /*==========================================================*/
+   void pause()
+   {
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         this->duration += PbMpi::Wtime()-this->startTime;
+      #else
+         this->duration +=((double)clock()-this->startTime)/(double)CLOCKS_PER_SEC;
+      #endif //VF_MPI 
+   }
+   /*==========================================================*/
+   void unpause()
+   {
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         this->startTime   = PbMpi::Wtime();
+      #else
+         this->startTime = (double)clock();
+      #endif //VF_MPI 
+   }
+   /*==========================================================*/
+   void stop()
+   {
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         this->duration += PbMpi::Wtime()-this->startTime;
+      #else
+         this->duration +=((double)clock()-this->startTime)/(double)CLOCKS_PER_SEC;
+      #endif //VF_MPI 
+   }
+   /*==========================================================*/
+   double getTicks() const            
+   { 
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         return PbMpi::Wtick();
+      #else
+         return double(1.0)/double(CLOCKS_PER_SEC);
+      #endif  //VF_MPI 
+   }
+
+protected:
+   std::string name;
+
+   double startTime;
+   double duration;
+	double deltaT;
+};
+
+#include <basics/utilities/UbSystem.h> //for definitons of system/OS type
+
+#ifdef UBSYSTEM_APPLE   //Apple hack
+   #include <mach/mach_time.h>  
+   #include <time.h>  
+   #include <stdio.h> 
+   inline void mach_absolute_difference(const uint64_t& end, const uint64_t& start, struct timespec *tp) 
+   {  
+         uint64_t difference = end - start;  
+         static mach_timebase_info_data_t info = {0,0};  
+   
+         if (info.denom == 0)  
+                 mach_timebase_info(&info);  
+   
+         uint64_t elapsednano = difference * (info.numer / info.denom);  
+   
+         tp->tv_sec = elapsednano * 1e-9;  
+         tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);  
+   } 
+#elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_AIX)
+   #include <ctime>
+   #include <unistd.h> // for sysconf
+   #include <pthread.h>
+#endif
+
+/*=========================================================================*/
+//! \brief Time Measuring                                              
+//! \details                                                                         
+//! example:
+//! \code
+//! t=0  start 
+//! t=1 
+//! t=2  stop  -> return 2; getLapTime=2; getTotalTime 2; getLapTimes:  2
+//! t=3 
+//! t=4 
+//! t=5  stop  -> return 3; getLapTime=3; getTotalTime 5; getLapTimes:  2,3
+//! t=6  stop  -> return 1; getLapTime=1; getTotalTime 6; getLapTimes:  2,3,1
+//! t=7  
+//! t=8  start ->no consideration of time 7 and 8 
+//! t=9  
+//! t=10 stop  -> return 2; getLapTime=2; getTotalTime 8; getLapTimes:  2,3,1,2
+//! t=11 resetAndStart -> Timer is reset and restarted
+//! t=12
+//! t=13 
+//! t=14 stop  -> return 3; getLapTime=3; getTotalTime 3; getLapTimes:  3
+//! \endcode
+
+class UbTimer
+{
+public:
+   UbTimer(const bool& storeLapTimes = false) 
+      :  name("unamed"), isMeasuring(false), storeLapTimes(storeLapTimes)
+       , startTime(0.0), totalTime(0.0), lapTime(0.0)
+   {
+
+   }
+   /*==========================================================*/
+   UbTimer(const std::string& name, const bool& storeLapTimes = false) 
+      :  name(name), isMeasuring(false), storeLapTimes(storeLapTimes)
+       , startTime(0.0), totalTime(0.0), lapTime(0.0)
+   {
+
+   }
+   /*==========================================================*/
+   virtual ~UbTimer() {}  
+   /*==========================================================*/
+   double              getLapTime() const               { return this->lapTime;  }
+   std::vector<double> getLapTimes() const              { return this->lapTimes; }
+   void                setName(const std::string& name) { this->name = name;     }
+   std::string         getName() const                  { return this->name;     }
+   bool                isRunning() const                { return isMeasuring;    }
+   bool                isStoringLapTimes() const        { return storeLapTimes;  }
+   /*==========================================================*/
+   void setStoreLapTimes(const bool& storeLapTimes) { this->storeLapTimes = storeLapTimes; }
+   /*==========================================================*/
+   void start()
+   {
+      this->isMeasuring = true;
+
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+          this->startTime = PbMpi::Wtime();
+      #elif defined(UBSYSTEM_APPLE)
+    	 this->startTime = mach_absolute_time();  
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_AIX)
+         timespec tp;
+         clock_gettime(CLOCK_REALTIME,&tp);
+         this->startTime = (double)(tp.tv_sec)*1.0e9 + (double)(tp.tv_nsec);
+      #else
+         this->startTime = (double)clock();
+      #endif //VF_MPI
+   }
+   /*==========================================================*/
+   void resetAndStart() { this->reset(); this->start(); }
+   /*==========================================================*/
+   //stop: - stops the calculation and returns the time elapsed since last start/stop
+   //      - timing continues
+   double stop()
+   {
+      //if start() was never activated before:
+      if(!isMeasuring) return 0.0; 
+      
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         double actTime = PbMpi::Wtime();
+         this->lapTime  = actTime-this->startTime;
+      #elif defined(UBSYSTEM_APPLE)
+    	 double actTime = mach_absolute_time();  
+         timespec tp;  
+         mach_absolute_difference(actTime, this->startTime, &tp);
+         this->lapTime  =  tp.tv_sec + tp.tv_nsec*1e-9;
+	  #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_AIX)
+         timespec tp;
+         clock_gettime(CLOCK_REALTIME,&tp);
+         double actTime = (double)(tp.tv_sec)*1.0e9 + (double)(tp.tv_nsec);
+         this->lapTime  = (actTime-this->startTime)*1.0e-9;
+      #else
+         double actTime = (double)clock();
+         this->lapTime  = (actTime-this->startTime)/(double)CLOCKS_PER_SEC;
+      #endif //VF_MPI 
+      
+      this->startTime  = actTime;
+      this->totalTime += this->lapTime;
+      if(storeLapTimes) lapTimes.push_back(this->lapTime);
+
+      return lapTime;
+   }
+   /*==========================================================*/
+   void reset()
+   {
+      this->isMeasuring = false;
+      
+      this->startTime   = 0.0;
+      this->totalTime   = 0.0;
+      this->lapTime     = 0.0;
+
+      lapTimes.resize(0);
+   }
+   /*==========================================================*/
+   double getCurrentLapTime() const
+   {
+     //if start() was never activated before:
+      if(!isMeasuring) return 0.0; 
+      
+      #if defined(VF_MPI) && !defined(CAB_RUBY)
+         return PbMpi::Wtime() - this->startTime;
+      #elif defined(UBSYSTEM_APPLE)
+         timespec tp;  
+         mach_absolute_difference(mach_absolute_time(), this->startTime, &tp);
+         return tp.tv_sec + tp.tv_nsec*1e-9;
+      #elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_AIX)
+         timespec tp;
+         clock_gettime(CLOCK_REALTIME,&tp);
+         return ((double)(tp.tv_sec)*1.0e9 + (double)(tp.tv_nsec) - this->startTime)*1.0e-9;
+      #else
+         return ( (double)clock() - this->startTime ) / (double)CLOCKS_PER_SEC;
+      #endif //VF_MPI 
+      
+   }
+   /*==========================================================*/
+   double getTotalTime() const
+   {
+      return this->totalTime;
+   }
+   /*==========================================================*/
+   std::string toString()
+   {
+      std::stringstream text;
+      text<<*this;
+      return text.str();
+   }
+
+   //ueberladene Operatoren
+   /*==========================================================*/
+   friend inline std::ostream& operator << (std::ostream& os, const UbTimer& timer) 
+   {
+       os<<"UbTimer[totalTime="<<timer.totalTime<<"sec, lapTimes(";
+       for(std::size_t i=0; i<timer.lapTimes.size(); i++) os<<timer.lapTimes[i]<<",";
+       os<<")]";
+       return os;
+   }
+
+
+protected:
+   std::string name;
+   bool        isMeasuring;
+   bool        storeLapTimes;
+
+   double      startTime;
+   double      totalTime;
+   double      lapTime;
+   
+   std::vector<double> lapTimes;
+};
+
+
+/*=========================================================================*/
+//! \brief Time Measuring                                              
+//! 
+//! \details UbProressTimer measures the time from its instantiation to destruction and spend the elapsed time on "os" in [s]
+//! example:
+//! \code
+//!  {
+//!     UbProgressTimer timer;
+//!     UbSystem::sleepS(10);
+//!  } //--> 10s
+//! \endcode
+
+class UbProgressTimer : public UbTimer
+{
+private:
+	UbProgressTimer(const UbProgressTimer& rhs);
+public:
+  explicit UbProgressTimer( std::ostream & os = std::cout )
+     : UbTimer(),os(os) 
+  {
+  	  this->start();
+  }
+  /*==========================================================*/
+  ~UbProgressTimer()
+  {
+  //  A) Throwing an exception from a destructor is a Bad Thing.
+  //  B) The progress_timer destructor does output which may throw.
+  //  C) A progress_timer is usually not critical to the application.
+  //  Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
+    try
+    {
+      // use istream instead of ios_base to workaround GNU problem (Greg Chicares)
+      std::istream::fmtflags old_flags = os.setf( std::istream::fixed,
+                                                  std::istream::floatfield );
+      std::streamsize old_prec = os.precision( 2 );
+      os << stop() << " s" << std::endl;
+      os.flags( old_flags );
+      os.precision( old_prec );
+    }
+    catch (...) {} // eat any exceptions
+  } 
+
+private:
+  std::ostream & os;
+};
+
+
+#endif //UBTIMING_H
diff --git a/VirtualFluidsBasics/basics/utilities/UbTuple.h b/VirtualFluidsBasics/basics/utilities/UbTuple.h
new file mode 100644
index 0000000000000000000000000000000000000000..621b378e12a0b37195ec268ce14581576b7de14b
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/UbTuple.h
@@ -0,0 +1,632 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbTupel.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef UBTUPLE_H
+#define UBTUPLE_H
+
+#include <iostream>
+#include <string>
+#include <ostream>
+
+//////////////////////////////////////////////////////////////////////////
+//! \brief A class implements a tuple
+//! \details
+//! usage: ...<BR>
+//! Advanced UbTuple
+//! Example:
+//! create and use tuple with only c1 field
+//! \code
+//! UbTuple<int,int,int,int,int> t1;
+//! val<1>(t1) += 42;
+//! std::cout << t1.v1() << std::endl;
+//! \endcode
+//! create and use duo:
+//! \code
+//! UbTuple<bool,int> t2;
+//! std::cout << val<1>(t2) << ", ";
+//! std::cout << t2.v1() << std::endl;
+//! \endcode
+//! create and use triple:
+//! \code
+//! UbTuple<bool,int,double> t3;
+//! val<1>(t3) = true;  // new values via: val< pos >(triple) = ...
+//! val<2>(t3) = 42;
+//! val<3>(t3) = 0.2;
+//! t3 = makeUbTuple(false, 23, 13.13);
+//! 
+//! std::cout << val<1>(t3) << ", ";
+//! std::cout << val<2>(t3) << ", ";
+//! std::cout << val<3>(t3) << std::endl;
+//! \endcode
+//! create and use quadruple:
+//! \code
+//! UbType<bool,int,float,double> t4(true,42,13,1.95583);
+//! std::cout << val<4>(t4) << std::endl;        //<- option 2 (std)
+//! std::cout << t4.v2().v2().v2() << std::endl; //<- option 2
+//! \endcode
+
+template <typename T>
+class UbTypeOp    // primary template
+{           
+public:
+   typedef T         ArgT;
+   typedef T         BareT;
+   typedef T const   ConstT;
+   typedef T &       RefT;
+   typedef T &       RefBareT;
+   typedef T const & RefConstT;
+};
+/**** end of typeop1.hpp ****/
+
+// partial specialization for const
+/**********************************
+* typeop2.hpp:
+**********************************/
+template <typename T>
+class UbTypeOp <T const>  // partial specialization for const types
+{
+ public:
+   typedef T const   ArgT;
+   typedef T         BareT;
+   typedef T const   ConstT;
+   typedef T const & RefT;
+   typedef T &       RefBareT;
+   typedef T const & RefConstT;
+};
+/**** end of typeop2.hpp ****/
+
+// partial specialization for references
+/**********************************
+* typeop3.hpp:
+**********************************/
+template <typename T>
+class UbTypeOp <T&>        // partial specialization for references
+{
+public:
+   typedef T &                           ArgT;
+   typedef typename UbTypeOp<T>::BareT   BareT;
+   typedef T const                       ConstT;
+   typedef T &                           RefT;
+   typedef typename UbTypeOp<T>::BareT & RefBareT;
+   typedef T const &                     RefConstT;
+};
+/**** end of typeop3.hpp ****/
+
+// full specialization for void
+/**********************************
+* typeop4.hpp:
+**********************************/
+template<>
+class UbTypeOp <void>      // full specialization for void
+{
+public:
+   typedef void       ArgT;
+   typedef void       BareT;
+   typedef void const ConstT;
+   typedef void       RefT;
+   typedef void       RefBareT;
+   typedef void       RefConstT;
+};
+/**** end of typeop4.hpp ****/
+
+template <typename T1, typename T2>
+class  UbDuo;
+
+template <typename T1, typename T2>
+std::ostream& operator << (std::ostream& os, UbDuo<T1, T2> const& d1);
+
+//duo1.hpp
+template <typename T1, typename T2>
+class UbDuo 
+{
+public:
+   typedef T1 Type1;  // type of first field
+   typedef T2 Type2;  // type of second field
+   enum { N = 2 };    // number of fields
+
+public:
+   // constructors
+   UbDuo() : value1(), value2() {  }
+   UbDuo (T1 const & a, T2 const & b) : value1(a), value2(b)  {  }
+
+   // for implicit type conversion during construction
+   template <typename U1, typename U2>
+   UbDuo (UbDuo<U1,U2> const & d) : value1(d.v1()), value2(d.v2()) {  }
+
+   // for implicit type conversion during assignments
+   template <typename U1, typename U2>
+   UbDuo<T1, T2>& operator = (UbDuo<U1,U2> const & d) 
+   {
+      value1 = d.v1();//value1;
+      value2 = d.v2();//value2;
+      return *this;
+   }
+
+   // field access
+   T1& v1()             { return value1; }
+   T1 const& v1() const { return value1; }
+
+   T2& v2()             { return value2; }
+   T2 const& v2() const { return value2; }
+
+private:
+   T1 value1;         // value of first field
+   T2 value2;         // value of second field
+};
+
+// comparison operators (allow mixed types):
+template <typename T1, typename T2,typename U1, typename U2>
+inline bool operator == (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
+{
+   return d1.v1()==d2.v1() && d1.v2()==d2.v2();
+}
+
+template <typename T1, typename T2,typename U1, typename U2>
+inline bool operator != (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
+{
+   return !(d1==d2);
+}
+
+template <typename T1, typename T2,typename U1, typename U2>
+inline bool operator < (UbDuo<T1,T2> const& d1, UbDuo<U1,U2> const& d2)
+{
+   if     (d1.v1() <  d2.v1() ) return true;
+   else if(d1.v1() == d2.v1() ) return d1.v2() < d2.v2();
+
+   return false;
+}
+
+template <typename T1, typename T2>
+std::ostream& operator << (std::ostream& os, UbDuo<T1, T2> const& d1)
+{
+    os << d1.v1() << ", " << d1.v2();
+    return os;
+}
+
+// convenience function  for creation and initialization
+template <typename T1, typename T2> 
+inline UbDuo<T1,T2> makeUbDuo(T1 const & a, T2 const & b)
+{
+   return UbDuo<T1,T2>(a,b);
+}
+
+//duo2.hpp
+template <typename A, typename B, typename C>
+class UbDuo<A, UbDuo<B,C> > 
+{
+public:
+   typedef A          T1;           // type of first field
+   typedef UbDuo<B,C> T2;           // type of second field
+   enum { N = UbDuo<B,C>::N + 1 };  // number of fields
+ 
+public:
+   // constructors
+   UbDuo() : value1(), value2() { }
+   UbDuo (T1 const & a, T2 const & b) : value1(a), value2(b) { }
+
+   // for implicit type conversion during construction
+   template <typename U1, typename U2>
+   UbDuo (UbDuo<U1,U2> const & d) : value1(d.v1()), value2(d.v2()) { }
+
+   // for implicit type conversion during assignments
+   template <typename U1, typename U2>
+   UbDuo<T1, T2>& operator = (UbDuo<U1,U2> const & d) 
+   { 
+      value1 = d.v1();//value1;     
+      value2 = d.v2();//value2;
+      return *this;
+   }
+
+   // field access
+   T1& v1()             { return value1; }
+   T1 const& v1() const { return value1; }
+
+   T2& v2()             { return value2; }
+   T2 const& v2() const { return value2; }
+
+private:
+   T1 value1;         // value of first field
+   T2 value2;         // value of second field
+};
+
+//duo3.hpp
+// primary template for type of Nth field of (duo) T
+template <int N, typename T>
+class UbDuoT 
+{
+public:
+   typedef void ResultT;    // in general, the result type is void
+};
+
+// specialization for 1st field of a plain duo
+template <typename A, typename B>
+class UbDuoT<1, UbDuo<A,B> > 
+{
+public:
+   typedef A ResultT;
+};
+
+// specialization for 2nd field of a plain duo
+template <typename A, typename B>
+class UbDuoT<2, UbDuo<A,B> > 
+{
+public:
+   typedef B ResultT;
+};
+
+// specialization for Nth field of a recursive duo
+template <int N, typename A, typename B, typename C>
+class UbDuoT<N, UbDuo<A, UbDuo<B,C> > > 
+{
+public:
+   typedef typename UbDuoT<N-1, UbDuo<B,C> >::ResultT ResultT;
+};
+
+// specialization for 1st field of a recursive duo
+template <typename A, typename B, typename C>
+class UbDuoT<1, UbDuo<A, UbDuo<B,C> > > 
+{
+public:
+   typedef A ResultT;
+};
+
+// specialization for 2nd field of a recursive duo
+template <typename A, typename B, typename C>
+class UbDuoT<2, UbDuo<A, UbDuo<B,C> > > 
+{
+public:
+   typedef B ResultT;
+};
+
+//duo4.hpp
+// primary template for value of Nth field of (duo) T
+template <int N, typename T>
+class DuoValue 
+{
+public:
+   static void get(T&) {  }      // in general, we have no value
+   static void get(T const&) { }
+};
+
+// specialization for 1st field of a plain duo
+template <typename A, typename B>
+class DuoValue<1, UbDuo<A, B> > 
+{
+public:
+   static A& get(UbDuo<A, B> &d)             { return d.v1(); }
+   static A const& get(UbDuo<A, B> const &d) { return d.v1(); }
+};
+
+// specialization for 2nd field of a plain duo
+template <typename A, typename B>
+class DuoValue<2, UbDuo<A, B> > 
+{
+public:
+   static B& get(UbDuo<A, B> &d)             { return d.v2(); }
+   static B const& get(UbDuo<A, B> const &d) { return d.v2(); }
+};
+
+// specialization for Nth field of recursive duo
+template <int N, typename A, typename B, typename C>
+struct DuoValue<N, UbDuo<A, UbDuo<B,C> > >
+{
+   static typename UbTypeOp<typename UbDuoT<N-1, UbDuo<B,C> >::ResultT>::RefT  get(UbDuo<A, UbDuo<B,C> > &d)
+   { 
+      return DuoValue<N-1, UbDuo<B,C> >::get(d.v2()); 
+   }
+   static typename UbTypeOp<typename UbDuoT<N-1, UbDuo<B,C> >::ResultT>::RefConstT  get(UbDuo<A, UbDuo<B,C> > const &d)
+   { 
+      return DuoValue<N-1, UbDuo<B,C> >::get(d.v2()); 
+   }
+};
+
+// specialization for 1st field of recursive duo
+template <typename A, typename B, typename C>
+class DuoValue<1, UbDuo<A, UbDuo<B,C> > > 
+{
+public:
+   static A& get(UbDuo<A, UbDuo<B,C> > &d)             { return d.v1(); }
+   static A const& get(UbDuo<A, UbDuo<B,C> > const &d) { return d.v1(); }
+};
+
+// specialization for 2nd field of recursive duo
+template <typename A, typename B, typename C>
+class DuoValue<2, UbDuo<A, UbDuo<B,C> > > 
+{
+public:
+   static B& get(UbDuo<A, UbDuo<B,C> > &d)             { return d.v2().v1(); }
+   static B const& get(UbDuo<A, UbDuo<B,C> > const &d) { return d.v2().v1(); }
+};
+
+//duo5.hpp
+// return Nth value of variable duo
+template <int N, typename A, typename B> 
+inline typename UbTypeOp<typename UbDuoT<N, UbDuo<A, B> >::ResultT>::RefT val(UbDuo<A, B>& d)
+{
+   return DuoValue<N, UbDuo<A, B> >::get(d);
+}
+
+// return Nth value of constant duo
+template <int N, typename A, typename B> 
+inline typename UbTypeOp<typename UbDuoT<N, UbDuo<A, B> >::ResultT>::RefConstT val(UbDuo<A, B> const& d)
+{
+   return DuoValue<N, UbDuo<A, B> >::get(d);
+}
+
+//duo6.hpp
+// partial specialization for UbDuo<> with only c1 field
+template <typename A>
+struct UbDuo<A,void> 
+{
+public:
+   typedef A    T1;  // type of first field
+   typedef void T2;  // type of second field
+   enum { N = 1 };   // number of fields
+
+private:
+   T1 value1;        // value of first field
+
+public:
+   // constructors
+   UbDuo() : value1() { }
+   UbDuo (T1 const & a) : value1(a) { }
+
+   // field access
+   T1& v1()             { return value1; }
+   T1 const& v1() const { return value1; }
+
+   void v2() { }
+   void v2() const { }
+
+};
+
+//tupel1.hpp
+// type that represents unused type parameters
+class UbNullT 
+{
+};
+
+//////////////////////////////////////////////////////////////////////////
+//! \brief A class implements a tuple
+//! \details
+//! usage: ...<BR>
+//! Advanced UbTuple
+//! Example:
+//! create and use tuple with only c1 field
+//! \code
+//! UbTuple<int,int,int,int,int> t1;
+//! val<1>(t1) += 42;
+//! std::cout << t1.v1() << std::endl;
+//! \endcode
+//! create and use duo:
+//! \code
+//! UbTuple<bool,int> t2;
+//! std::cout << val<1>(t2) << ", ";
+//! std::cout << t2.v1() << std::endl;
+//! \endcode
+//! create and use triple:
+//! \code
+//! UbTuple<bool,int,double> t3;
+//! val<1>(t3) = true;  // new values via: val< pos >(triple) = ...
+//! val<2>(t3) = 42;
+//! val<3>(t3) = 0.2;
+//! t3 = makeUbTuple(false, 23, 13.13);
+//! 
+//! std::cout << val<1>(t3) << ", ";
+//! std::cout << val<2>(t3) << ", ";
+//! std::cout << val<3>(t3) << std::endl;
+//! \endcode
+//! create and use quadruple:
+//! \code
+//! UbType<bool,int,float,double> t4(true,42,13,1.95583);
+//! std::cout << val<4>(t4) << std::endl;        //<- option 2 (std)
+//! std::cout << t4.v2().v2().v2() << std::endl; //<- option 2
+//! \endcode
+
+// UbTuple<> in general derives from UbTuple<> with c1 more UbNullT
+template <typename P1,
+          typename P2 = UbNullT,
+          typename P3 = UbNullT,
+          typename P4 = UbNullT,
+          typename P5 = UbNullT,
+          typename P6 = UbNullT,
+          typename P7 = UbNullT,
+          typename P8 = UbNullT >
+class UbTuple : public UbDuo<P1, typename UbTuple<P2,P3,P4,P5,P6,P7,P8,UbNullT>::BaseT> 
+{
+public:
+   typedef UbDuo<P1, typename UbTuple<P2,P3,P4,P5,P6,P7,P8,UbNullT>::BaseT>  BaseT;
+
+   // constructor:
+   UbTuple() {}
+   UbTuple( typename UbTypeOp<P1>::RefConstT a1,
+            typename UbTypeOp<P2>::RefConstT a2,
+            typename UbTypeOp<P3>::RefConstT a3 = UbNullT(),
+            typename UbTypeOp<P4>::RefConstT a4 = UbNullT(),
+            typename UbTypeOp<P5>::RefConstT a5 = UbNullT(),
+            typename UbTypeOp<P6>::RefConstT a6 = UbNullT(),
+            typename UbTypeOp<P7>::RefConstT a7 = UbNullT(),
+            typename UbTypeOp<P8>::RefConstT a8 = UbNullT() )
+      : BaseT(a1, UbTuple<P2,P3,P4,P5,P6,P7,P8,UbNullT>(a2,a3,a4,a5,a6,a7,a8))
+   {
+   }
+
+   // for implicit type conversion during assignments
+   template <typename U1,typename U2, typename U3, typename U4, typename U5, typename U6, typename U7, typename U8 >
+   UbTuple<P1,P2,P3,P4,P5,P6,P7,P8>& operator = ( const UbTuple<U1,U2,U3,U4,U5,U6,U7,U8>& rhs)
+   {
+      this->BaseT::operator=( typename UbTuple<U1,U2,U3,U4,U5,U6,U7,U8>::BaseT(rhs) );
+      return *this;
+   }
+
+};
+
+// specialization to end deriving recursion
+template <typename P1, typename P2>
+class UbTuple<P1,P2,UbNullT,UbNullT,UbNullT,UbNullT,UbNullT,UbNullT> : public UbDuo<P1,P2> {
+public:
+   typedef UbDuo<P1,P2> BaseT;
+   
+   // constructor:
+   UbTuple() {}
+   UbTuple( typename UbTypeOp<P1>::RefConstT a1,
+            typename UbTypeOp<P2>::RefConstT a2,
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT() )
+      : BaseT(a1, a2) 
+   {
+   }
+
+   // for implicit type conversion during assignments
+   template <typename U1,typename U2 >
+   UbTuple<P1,P2>& operator = ( const UbTuple<U1,U2>& rhs)
+   {
+      this->BaseT::operator=( typename UbTuple<U1,U2>::BaseT(rhs) );
+      return *this;
+   }
+
+};
+
+// specialization for singletons
+template <typename P1>
+class UbTuple<P1,UbNullT,UbNullT,UbNullT,UbNullT,UbNullT,UbNullT,UbNullT> : public UbDuo<P1,void>
+{
+public:
+   typedef UbDuo<P1,void> BaseT;
+
+   // constructor:
+   UbTuple() {}
+   UbTuple( typename UbTypeOp<P1>::RefConstT a1,
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT(),
+            typename UbTypeOp<UbNullT>::RefConstT = UbNullT() )
+      : BaseT(a1) 
+   {
+   }
+
+   // for implicit type conversion during assignments
+   template <typename U1 >
+   UbTuple<P1>& operator = ( const UbTuple<U1>& rhs)
+   {
+      this->v1() = rhs.v1();
+      return *this;
+   }
+
+};
+
+// convenience function for 1 argument
+template <typename T1> 
+inline UbTuple<T1> makeUbTuple(T1 const &a1)
+{
+   return UbTuple<T1>(a1);
+}
+
+// convenience function for 2 arguments
+template <typename T1, typename T2>
+inline UbTuple<T1,T2> makeUbTuple(T1 const &a1, T2 const &a2)
+{
+   return UbTuple<T1,T2>(a1,a2);
+}
+
+// convenience function for 3 arguments
+template <typename T1, typename T2, typename T3>
+inline UbTuple<T1,T2,T3> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3)
+{
+   return UbTuple<T1,T2,T3>(a1,a2,a3);
+}
+
+// convenience function for 4 arguments
+template <typename T1, typename T2, typename T3, typename T4>
+inline UbTuple<T1,T2,T3,T4> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4)
+{
+   return UbTuple<T1,T2,T3,T4>(a1,a2,a3,a4);
+}
+
+// convenience function for 5 arguments
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+inline UbTuple<T1,T2,T3,T4,T5> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4,T5 const &a5)
+{
+   return UbTuple<T1,T2,T3,T4,T5>(a1,a2,a3,a4,a5);
+}
+
+// convenience function for 6 arguments
+template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+inline UbTuple<T1,T2,T3,T4,T5,T6> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6)
+{
+   return UbTuple<T1,T2,T3,T4,T5,T6>(a1,a2,a3,a4,a5,a6);
+}
+
+// convenience function for 7 arguments
+template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+inline UbTuple<T1,T2,T3,T4,T5,T6,T7> makeUbTuple(T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7)
+{
+   return UbTuple<T1,T2,T3,T4,T5,T6,T7>(a1,a2,a3,a4,a5,a6,a7);
+}
+
+// convenience function for 8 arguments
+template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
+inline UbTuple<T1,T2,T3,T4,T5,T6,T7,T8> makeUbTuple(T1 const &a1, T2 const &a2,T3 const &a3, T4 const &a4,T5 const &a5, T6 const &a6,T7 const &a7, T8 const &a8 )
+{
+   return UbTuple<T1,T2,T3,T4,T5,T6,T7,T8>(a1,a2,a3,a4,a5,a6,a7,a8);
+}
+
+//some typedefs
+typedef UbTuple<float,float>                               UbTupleFloat2;
+typedef UbTuple<float,float,float>                         UbTupleFloat3;
+typedef UbTuple<int,int>                                   UbTupleInt2;
+typedef UbTuple<int,int,int>                               UbTupleInt3;
+typedef UbTuple<int,int,int,int>                           UbTupleInt4;
+typedef UbTuple<int,int,int,int,int>                       UbTupleInt5;
+typedef UbTuple<int,int,int,int,int,int>                   UbTupleInt6;
+typedef UbTuple<int,int,int,int,int,int,int,int>           UbTupleInt8;
+typedef UbTuple<double,double>                             UbTupleDouble2;
+typedef UbTuple<double,double,double>                      UbTupleDouble3;
+typedef UbTuple<double,double,double,double>               UbTupleDouble4;
+typedef UbTuple<double,double,double,double,double,double> UbTupleDouble6;
+typedef UbTuple<std::string,double,double>                 UbTupleStringDouble2;
+typedef UbTuple<std::string,double,double,double>          UbTupleStringDouble3;
+typedef UbTuple<std::string,int,int,int>                   UbTupleStringInt3;
+typedef UbTuple<short,short,short,short>                   UbTupleShort4;
+typedef UbTuple<bool,bool,bool>                            UbTupleBool3;
+typedef UbTuple<int,double,double>                         UbTupleIntDouble2;
+typedef UbTuple<int, bool>                                 UbTupleIntBool;
+
+
+#endif //UBTUPLE_H
diff --git a/VirtualFluidsBasics/basics/utilities/Vector3D.cpp b/VirtualFluidsBasics/basics/utilities/Vector3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b39ee8a410689d89bc41dfc2ed8291f11bd5bb1
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/Vector3D.cpp
@@ -0,0 +1,642 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbVector3D.cpp
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <basics/utilities/Vector3D.h>
+
+#include <cassert>
+#include <sstream>
+
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbInfinity.h>
+
+
+
+const Vector3D Vector3D::ZERO(0.0,0.0,0.0);
+const Vector3D Vector3D::UNIT_X1(1.0,0.0,0.0);
+const Vector3D Vector3D::UNIT_X2(0.0,1.0,0.0);
+const Vector3D Vector3D::UNIT_X3(0.0,0.0,1.0);
+
+/*=======================================================*/
+Vector3D::Vector3D() 
+{                                      
+   m_afTuple[0] = 0.0;
+   m_afTuple[1] = 0.0;
+   m_afTuple[2] = 0.0;
+}
+/*=======================================================*/
+Vector3D::Vector3D(const double& fX, const double& fY, const double& fZ) 
+{
+   m_afTuple[0] = fX;
+   m_afTuple[1] = fY;
+   m_afTuple[2] = fZ;
+}
+/*=======================================================*/
+Vector3D::Vector3D (const Vector3D& rkV) 
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+}
+/*=======================================================*/
+std::string Vector3D::toString()  const
+{
+   std::stringstream os;
+   os<< "Vector3D["<<m_afTuple[0]<<","<<m_afTuple[1]<<","<<m_afTuple[2]<<"]";
+   return os.str();
+}
+/*=======================================================*/
+Vector3D::operator const double*() const
+{
+   return m_afTuple;
+}
+/*=======================================================*/
+Vector3D::operator double*()
+{
+   return m_afTuple;
+}
+/*=======================================================*/
+double Vector3D::operator[](const int& i) const
+{
+   assert( i >= 0 && i <= 2 );
+   return m_afTuple[i];
+}
+/*=======================================================*/
+double& Vector3D::operator[](const int& i)
+{
+   assert( i >= 0 && i <= 2 );
+   return m_afTuple[i];
+}
+/*=======================================================*/
+double Vector3D::X1() const
+{
+   return m_afTuple[0];
+}
+/*=======================================================*/
+double& Vector3D::X1()
+{
+   return m_afTuple[0];
+}
+/*=======================================================*/
+double Vector3D::X2() const
+{
+   return m_afTuple[1];
+}
+/*=======================================================*/
+double& Vector3D::X2()
+{
+   return m_afTuple[1];
+}
+/*=======================================================*/
+double Vector3D::X3() const
+{
+   return m_afTuple[2];
+}
+/*=======================================================*/
+double& Vector3D::X3()
+{
+   return m_afTuple[2];
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator=(const Vector3D& rkV)
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+int Vector3D::CompareArrays(const Vector3D& rkV) const
+{
+   return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(double));
+}
+/*=======================================================*/
+bool Vector3D::operator==(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) == 0;
+}
+/*=======================================================*/
+bool Vector3D::operator!=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) != 0;
+}
+/*=======================================================*/
+bool Vector3D::operator<(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) < 0;
+}
+/*=======================================================*/
+bool Vector3D::operator<=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) <= 0;
+}
+/*=======================================================*/
+bool Vector3D::operator> (const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) > 0;
+}
+/*=======================================================*/
+bool Vector3D::operator>=(const Vector3D& rkV) const
+{
+   return CompareArrays(rkV) >= 0;
+}
+/*=======================================================*/
+Vector3D Vector3D::operator+(const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[0]+rkV.m_afTuple[0],
+                    m_afTuple[1]+rkV.m_afTuple[1],
+                    m_afTuple[2]+rkV.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::Add(Vector3D& vector)
+{
+   return Vector3D( m_afTuple[0]+vector.m_afTuple[0],
+                    m_afTuple[1]+vector.m_afTuple[1],
+                    m_afTuple[2]+vector.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator- (const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[0]-rkV.m_afTuple[0],
+                    m_afTuple[1]-rkV.m_afTuple[1],
+                    m_afTuple[2]-rkV.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::Subtract(Vector3D& vector)
+{
+   return Vector3D( m_afTuple[0]-vector.m_afTuple[0],
+                    m_afTuple[1]-vector.m_afTuple[1],
+                    m_afTuple[2]-vector.m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator*(const double& fScalar) const
+{
+   return Vector3D( fScalar*m_afTuple[0],
+                    fScalar*m_afTuple[1],
+                    fScalar*m_afTuple[2]  );
+}
+/*=======================================================*/
+Vector3D Vector3D::operator/(const double& fScalar) const
+{
+   Vector3D kQuot;
+
+   if ( fScalar != 0.0 )
+   {
+      double fInvScalar = 1.0/fScalar;
+      kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
+      kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
+      kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
+   }
+   else
+   {
+      kQuot.m_afTuple[0] = Ub::inf;
+      kQuot.m_afTuple[1] = Ub::inf;
+      kQuot.m_afTuple[2] = Ub::inf;
+   }
+
+   return kQuot;
+}
+/*=======================================================*/
+Vector3D Vector3D::operator-() const
+{
+   return Vector3D( -m_afTuple[0],
+                    -m_afTuple[1],
+                    -m_afTuple[2] );
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator+=(const Vector3D& rkV)
+{
+   m_afTuple[0] += rkV.m_afTuple[0];
+   m_afTuple[1] += rkV.m_afTuple[1];
+   m_afTuple[2] += rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator-=(const Vector3D& rkV)
+{
+   m_afTuple[0] -= rkV.m_afTuple[0];
+   m_afTuple[1] -= rkV.m_afTuple[1];
+   m_afTuple[2] -= rkV.m_afTuple[2];
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator*=(const double& fScalar)
+{
+   m_afTuple[0] *= fScalar;
+   m_afTuple[1] *= fScalar;
+   m_afTuple[2] *= fScalar;
+   return *this;
+}
+/*=======================================================*/
+Vector3D& Vector3D::operator/=(const double& fScalar)
+{
+   if ( !UbMath::zero(fScalar) )
+   {
+      double fInvScalar = 1.0/fScalar;
+      m_afTuple[0] *= fInvScalar;
+      m_afTuple[1] *= fInvScalar;
+      m_afTuple[2] *= fInvScalar;
+   }
+   else
+   {
+      m_afTuple[0] = Ub::inf;
+      m_afTuple[1] = Ub::inf;
+      m_afTuple[2] = Ub::inf;
+   }
+
+   return *this;
+}
+/*=======================================================*/
+Vector3D Vector3D::Scale(const double& x)
+{
+   Vector3D PointA(0.0,0.0,0.0);
+   PointA.m_afTuple[0] = x * m_afTuple[0];
+   PointA.m_afTuple[1] = x * m_afTuple[1];
+   PointA.m_afTuple[2] = x * m_afTuple[2];
+   return PointA;	
+}
+/*=======================================================*/
+double Vector3D::Length() const
+{
+   return std::sqrt( m_afTuple[0]*m_afTuple[0] +
+                     m_afTuple[1]*m_afTuple[1] +
+                     m_afTuple[2]*m_afTuple[2] );
+}
+/*=======================================================*/
+double Vector3D::SquaredLength() const
+{
+   return m_afTuple[0]*m_afTuple[0] +
+          m_afTuple[1]*m_afTuple[1] +
+          m_afTuple[2]*m_afTuple[2];
+}
+/*=======================================================*/
+double Vector3D::Dot(const Vector3D& rkV) const
+{
+   return m_afTuple[0]*rkV.m_afTuple[0] +
+          m_afTuple[1]*rkV.m_afTuple[1] +
+          m_afTuple[2]*rkV.m_afTuple[2];
+}
+/*=======================================================*/
+double Vector3D::Normalize()
+{
+   double fLength = Length();
+
+   if( !UbMath::zero(fLength) )
+   {
+      double fInvLength = 1.0/fLength;
+      m_afTuple[0] *= fInvLength;
+      m_afTuple[1] *= fInvLength;
+      m_afTuple[2] *= fInvLength;
+   }
+   else
+   {
+      fLength = 0.0;
+      m_afTuple[0] = 0.0;
+      m_afTuple[1] = 0.0;
+      m_afTuple[2] = 0.0;
+   }
+
+   return fLength;
+}
+/*=======================================================*/
+Vector3D Vector3D::Cross(const Vector3D& rkV) const
+{
+   return Vector3D( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
+}
+/*=======================================================*/
+Vector3D Vector3D::UnitCross(const Vector3D& rkV) const
+{
+   Vector3D kCross( m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+                    m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+                    m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0] );
+   kCross.Normalize();
+   return kCross;
+}
+/*=======================================================*/
+void Vector3D::GetBarycentrics(const Vector3D& rkV0,const Vector3D& rkV1, const Vector3D& rkV2,const Vector3D& rkV3, double afBary[4]) const
+{
+   // compute the vectors relative to V3 of the tetrahedron
+   Vector3D akDiff[4] = { rkV0  - rkV3,
+                          rkV1  - rkV3,
+                          rkV2  - rkV3,
+                          *this - rkV3 };
+
+   // If the vertices have large magnitude, the linear system of
+   // equations for computing barycentric coordinates can be
+   // ill-conditioned.  To avoid this, uniformly scale the tetrahedron
+   // edges to be of order 1.  The scaling of all differences does not
+   // change the barycentric coordinates.
+   double fMax = 0.0,fValue=0.0;
+   for(int i=0; i<3; i++)
+      for (int j=0; j<3; j++)
+      {
+         fValue = std::fabs(akDiff[i][j]);
+         if ( fValue > fMax )  fMax = fValue;
+      }
+   
+   // scale down only large data
+   if(UbMath::greater(fMax,1.0) )
+   {
+      double fInvMax = ((double)1.0)/fMax;
+      for( int i=0; i<4; i++)
+         akDiff[i] *= fInvMax;
+   }
+
+   double     fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
+   Vector3D kE1cE2 = akDiff[1].Cross(akDiff[2]);
+   Vector3D kE2cE0 = akDiff[2].Cross(akDiff[0]);
+   Vector3D kE0cE1 = akDiff[0].Cross(akDiff[1]);
+   
+   if( !UbMath::zero( fDet ) )
+   {
+      double fInvDet = 1.0/fDet;
+      afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
+      afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
+      afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
+      afBary[3] = 1.0 - afBary[0] - afBary[1] - afBary[2];
+   }
+   else
+   {
+      // The tetrahedron is potentially flat.  Determine the face of
+      // maximum area and compute barycentric coordinates with respect
+      // to that face.
+      Vector3D kE02 = rkV0 - rkV2;
+      Vector3D kE12 = rkV1 - rkV2;
+      Vector3D kE02cE12 = kE02.Cross(kE12);
+      double fMaxSqrArea = kE02cE12.SquaredLength();
+      int iMaxIndex = 3;
+      double fSqrArea = kE0cE1.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 0;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE1cE2.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 1;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE2cE0.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 2;
+         fMaxSqrArea = fSqrArea;
+      }
+
+      if (UbMath::greater(fMaxSqrArea,0.0)  )
+      {
+         double fInvSqrArea = 1.0/fMaxSqrArea;
+         Vector3D kTmp;
+         if( iMaxIndex==0 )
+         {
+            kTmp      = akDiff[3].Cross(akDiff[1]);
+            afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            kTmp      = akDiff[0].Cross(akDiff[3]);
+            afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = 0.0;
+            afBary[3] = 1.0 - afBary[0] - afBary[1];
+         }
+         else if( iMaxIndex == 1 )
+         {
+            afBary[0] = 0.0;
+            kTmp      = akDiff[3].Cross(akDiff[2]);
+            afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            kTmp      = akDiff[1].Cross(akDiff[3]);
+            afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = 1.0 - afBary[1] - afBary[2];
+         }
+         else if( iMaxIndex == 2 )
+         {
+            kTmp      = akDiff[2].Cross(akDiff[3]);
+            afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[1] = 0.0;
+            kTmp      = akDiff[3].Cross(akDiff[0]);
+            afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = 1.0 - afBary[0] - afBary[2];
+         }
+         else
+         {
+            akDiff[3] = *this - rkV2;
+            kTmp      = akDiff[3].Cross(kE12);
+            afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            kTmp      = kE02.Cross(akDiff[3]);
+            afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = 1.0 - afBary[0] - afBary[1];
+            afBary[3] = 0.0;
+         }
+      }
+      else
+      {
+         // The tetrahedron is potentially a sliver.  Determine the edge of
+         // maximum length and compute barycentric coordinates with respect
+         // to that edge.
+         double fMaxSqrLength = akDiff[0].SquaredLength();
+         iMaxIndex            = 0;  // <V0,V3>
+         double fSqrLength    = akDiff[1].SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 1;  // <V1,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = akDiff[2].SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 2;  // <V2,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE02.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 3;  // <V0,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE12.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 4;  // <V1,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         
+         Vector3D kE01 = rkV0 - rkV1;
+         fSqrLength    = kE01.SquaredLength();
+         
+         if( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex     = 5;  // <V0,V1>
+            fMaxSqrLength = fSqrLength;
+         }
+
+         if(UbMath::greater(fMaxSqrLength, 0.0) )
+         {
+            double fInvSqrLength = 1.0/fMaxSqrLength;
+            if( iMaxIndex == 0 )
+            {
+               // P-V3 = t*(V0-V3)
+               afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
+               afBary[1] = 0.0;
+               afBary[2] = 0.0;
+               afBary[3] = 1.0 - afBary[0];
+            }
+            else if( iMaxIndex == 1 )
+            {
+               // P-V3 = t*(V1-V3)
+               afBary[0] = 0.0;
+               afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
+               afBary[2] = 0.0;
+               afBary[3] = 1.0 - afBary[1];
+            }
+            else if( iMaxIndex == 2 )
+            {
+               // P-V3 = t*(V2-V3)
+               afBary[0] = 0.0;
+               afBary[1] = 0.0;
+               afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
+               afBary[3] = 1.0 - afBary[2];
+            }
+            else if( iMaxIndex == 3 )
+            {      
+               // P-V2 = t*(V0-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
+               afBary[1] = 0.0;
+               afBary[2] = 1.0 - afBary[0];
+               afBary[3] = 0.0;
+            }
+            else if( iMaxIndex == 4 )
+            {
+               // P-V2 = t*(V1-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = 0.0;
+               afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
+               afBary[2] = 1.0 - afBary[1];
+               afBary[3] = 0.0;
+            }
+            else
+            {
+               // P-V1 = t*(V0-V1)
+               akDiff[3] = *this - rkV1;
+               afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
+               afBary[1] = 1.0 - afBary[0];
+               afBary[2] = 0.0;
+               afBary[3] = 0.0;
+            }
+         }
+         else
+         {
+            // tetrahedron is a nearly a point, just return equal weights
+            afBary[0] = 0.25;
+            afBary[1] = afBary[0];
+            afBary[2] = afBary[0];
+            afBary[3] = afBary[0];
+         }
+      }
+   }
+}
+/*=======================================================*/
+void Vector3D::Orthonormalize(Vector3D& rkU, Vector3D& rkV, Vector3D& rkW)
+{
+   // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
+   // orthonormalization produces vectors u0, u1, and u2 as follows,
+   //
+   //   u0 = v0/|v0|
+   //   u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
+   //   u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
+   //
+   // where |A| indicates length of vector A and A*B indicates dot
+   // product of vectors A and B.
+
+   // compute u0
+   rkU.Normalize();
+
+   // compute u1
+   double fDot0 = rkU.Dot(rkV); 
+   rkV -= fDot0*rkU;
+   rkV.Normalize();
+
+   // compute u2
+   double fDot1 = rkV.Dot(rkW);
+   fDot0 = rkU.Dot(rkW);
+   rkW  -= fDot0*rkU + fDot1*rkV;
+   rkW.Normalize();
+}
+/*=======================================================*/
+void Vector3D::Orthonormalize(Vector3D* akV)
+{
+   Orthonormalize(akV[0],akV[1],akV[2]);
+}
+/*=======================================================*/
+void Vector3D::GenerateOrthonormalBasis(Vector3D& rkU, Vector3D& rkV,Vector3D& rkW, bool bUnitLengthW)
+{
+   if ( !bUnitLengthW )
+      rkW.Normalize();
+
+   double fInvLength;
+
+   if (UbMath::greaterEqual( std::fabs(rkW.m_afTuple[0]),std::fabs(rkW.m_afTuple[1]) ) )
+   {
+      // W.x or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[1] = (double)0.0;
+      rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
+   }
+   else
+   {
+      // W.y or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = (double)0.0;
+      rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
+   }
+
+   rkV = rkW.Cross(rkU);
+}
+/*=======================================================*/
+//globaler operator* 
+Vector3D operator*(const double& fScalar, const Vector3D& rkV)
+{
+   return Vector3D( fScalar*rkV[0],
+                    fScalar*rkV[1],
+                    fScalar*rkV[2] );
+}
+/*=======================================================*/
+std::ostream& operator<< (std::ostream& os, const Vector3D& rkV)
+{
+   os<<rkV.toString();
+   return os;
+}
diff --git a/VirtualFluidsBasics/basics/utilities/Vector3D.h b/VirtualFluidsBasics/basics/utilities/Vector3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e1d5178bdeca3a7d61595e54d1c999941a3ecdd
--- /dev/null
+++ b/VirtualFluidsBasics/basics/utilities/Vector3D.h
@@ -0,0 +1,136 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file UbVector3D.h
+//! \ingroup utilities
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef VECTOR_3D_H
+#define VECTOR_3D_H
+
+#include <string>
+
+   class Vector3D
+   {
+   public:
+      // construction
+      Vector3D(); 
+      Vector3D(const double& fX1, const double& fX2, const double& fX3);
+      Vector3D(const Vector3D& rkV);
+
+      std::string toString() const;
+
+      // coordinate access
+      operator const double*() const;
+      operator double*();
+      double   operator[](const int& i) const;
+      double&  operator[](const int& i);
+      double   X1() const;
+      double&  X1();
+      double   X2() const;
+      double&  X2();                                    
+      double   X3() const;
+      double&  X3();
+
+      // assignment
+      Vector3D& operator=(const Vector3D& rkV);
+
+      // comparison
+      bool operator==(const Vector3D& rkV) const;
+      bool operator!=(const Vector3D& rkV) const;
+      bool operator< (const Vector3D& rkV) const;
+      bool operator<=(const Vector3D& rkV) const;
+      bool operator> (const Vector3D& rkV) const;
+      bool operator>=(const Vector3D& rkV) const;
+
+      // arithmetic operations
+      Vector3D operator+(const Vector3D& rkV) const;
+      Vector3D operator-(const Vector3D& rkV) const;
+      Vector3D operator*(const double& fScalar) const;
+      Vector3D operator/(const double& fScalar) const;
+      Vector3D operator-() const;
+
+      // arithmetic updates
+      Vector3D& operator+= (const Vector3D& rkV);
+      Vector3D& operator-= (const Vector3D& rkV);
+      Vector3D& operator*= (const double& fScalar);
+      Vector3D& operator/= (const double& fScalar);
+
+      Vector3D Add(Vector3D& vector);
+      Vector3D Subtract(Vector3D& vector);
+      Vector3D Scale(const double& x);
+
+      // vector operations
+      double Length () const;
+      double SquaredLength () const;
+      double Dot (const Vector3D& rkV) const;
+      double Normalize ();
+
+      // The cross products are computed using the right-handed rule.  Be aware
+      // that some graphics APIs use a left-handed rule.  If you have to compute
+      // a cross product with these functions and send the result to the API
+      // that expects left-handed, you will need to change sign on the vector
+      // (replace each component value c by -c).
+      Vector3D Cross (const Vector3D& rkV) const;
+      Vector3D UnitCross (const Vector3D& rkV) const;
+
+      // Compute the barycentric coordinates of the point with respect to the
+      // tetrahedron <V0,V1,V2,V3>, P = b0*V0 + b1*V1 + b2*V2 + b3*V3, where
+      // b0 + b1 + b2 + b3 = 1.
+      void GetBarycentrics (const Vector3D& rkV0, const Vector3D& rkV1, const Vector3D& rkV2, const Vector3D& rkV3, double afBary[4]) const;
+
+      // Gram-Schmidt orthonormalization.  Take linearly independent vectors
+      // U, V, and W and compute an orthonormal set (unit length, mutually
+      // perpendicular).
+      static void Orthonormalize (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW);
+      static void Orthonormalize (Vector3D* akV);
+
+      // Input W must be initialized to a nonzero vector, output is {U,V,W},
+      // an orthonormal basis.  A hint is provided about whether or not W
+      // is already unit length.
+      static void GenerateOrthonormalBasis (Vector3D& rkU, Vector3D& rkV, Vector3D& rkW, bool bUnitLengthW);
+
+      // special vectors
+      static const Vector3D ZERO;
+      static const Vector3D UNIT_X1;
+      static const Vector3D UNIT_X2;
+      static const Vector3D UNIT_X3;
+
+   protected:
+      // support for comparisons
+      int CompareArrays (const Vector3D& rkV) const;
+
+      double m_afTuple[3];
+   };
+   
+   //globaler multiplaktor mit skalar
+   Vector3D operator*(const double& fScalar, const Vector3D& rkV);
+   std::ostream& operator<<(std::ostream& os, const Vector3D& rkV);
+
+  
+#endif
diff --git a/VirtualFluidsBasics/basics/writer/CMakePackage.txt b/VirtualFluidsBasics/basics/writer/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ef17942b856d69df194c11f63050e950564927b
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/CMakePackage.txt
@@ -0,0 +1,3 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
+
diff --git a/VirtualFluidsBasics/basics/writer/WbWriter.h b/VirtualFluidsBasics/basics/writer/WbWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6793c5ae9366f48b7b636403b929b411561253b
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/WbWriter.h
@@ -0,0 +1,114 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WbWriter.h
+//! \ingroup writer
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef WBWRITER_H
+#define WBWRITER_H
+
+#include <vector>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include <map>
+
+
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbTuple.h>
+
+class WbWriter
+{
+public:
+   //////////////////////////////////////////////////////////////////////////
+   virtual ~WbWriter() 
+   {
+
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //rein virtuelle Methoden
+   virtual std::string getFileExtension() = 0;
+
+   //////////////////////////////////////////////////////////////////////////
+   //nodes
+   virtual std::string writeNodes(const std::string& filename,std::vector< UbTupleFloat3 >& nodes) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeNodesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeNodesWithNodeDataDouble(const std::string& filename,std::vector< UbTupleDouble3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+
+   //////////////////////////////////////////////////////////////////////////
+   //lines
+   //     0 ---- 1
+   //nodenumbering must start with 0!
+   virtual std::string writeLines(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeLinesWithNodeData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+
+   //////////////////////////////////////////////////////////////////////////
+   //triangles
+   //cell numbering:
+   //                     2
+   //                      
+   //                  0 === 1
+   //nodenumbering must start with 0!
+   virtual std::string writeTriangles(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt3 >& cells){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeTrianglesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt3 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+
+   //////////////////////////////////////////////////////////////////////////
+   //quads
+   //cell numbering:
+   //                  3---2
+   //                  |   |
+   //                  0---1
+   //nodenumbering must start with 0!
+   virtual std::string writeQuads(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeQuadsWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeQuadsWithCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& celldata){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeQuadsWithNodeAndCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, 
+                                                     std::vector< std::string >& nodedatanames, std::vector< std::vector< double > >& nodedata, std::vector< std::string >& celldatanames, std::vector< std::vector< double > >&celldata) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+
+   //////////////////////////////////////////////////////////////////////////
+   //octs
+   //     7 ---- 6
+   //    /|     /|
+   //   4 +--- 5 |
+   //   | |    | |
+   //   | 3 ---+ 2
+   //   |/     |/
+   //   0 ---- 1
+   virtual std::string writeOcts(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt8 >& cells){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeOctsWithCellData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt8 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& celldata){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+   virtual std::string writeOctsWithNodeData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt8 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata){ throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() );  }
+
+private:
+
+};
+
+#endif //WBWRITER_H
diff --git a/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.cpp b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..42b7defd6b5dd7616dc9aeb0e97dd884d18d6db1
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.cpp
@@ -0,0 +1,1221 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WbWriterVtkXmlASCII.cpp
+//! \ingroup writer
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <basics/writer/WbWriterVtkXmlASCII.h>
+#include <basics/utilities/UbLogger.h>
+#include <cstring>
+#include <limits>
+
+using namespace std;
+
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::pvdEndTag ="   </Collection>\n</VTKFile>";
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timeStep, const bool& sepGroups)
+{
+   std::string vtkfilename=filename+".pvd";
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   std::string endian;
+   if(UbSystem::isLittleEndian()) endian = "LittleEndian";
+   else                           endian = "BigEndian";
+   out<<"<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\""<<endian<<"\" >\n";
+   out<<"   <Collection>"<<endl;
+   
+   int group = 0, part=0;
+   for(std::size_t i=0; i<filenames.size(); i++)
+   {
+      out<<"       <DataSet timestep=\""<<timeStep<<"\" group=\""<<group<<"\" part=\""<<part<<"\" file=\""<<filenames[i]<<"\"/>\n";
+      if(sepGroups) group++;
+      else          part++;
+   }
+   out<<pvdEndTag;
+   out.close();
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::addFilesToCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timeStep, const bool& sepGroups)
+{
+   std::string vtkfilename=filename;
+   std::fstream test(vtkfilename.c_str(), ios::in);
+   if(!test)
+   {
+      test.clear();
+      vtkfilename += ".pvd";
+      test.open(vtkfilename.c_str(), ios::in);
+      if(!test) return this->writeCollection(filename,filenames,timeStep,sepGroups);
+   }
+
+   std::fstream out(vtkfilename.c_str(), ios::in | ios::out);
+   out.seekp(-(int)pvdEndTag.size()-1, ios_base::end);
+
+   int group = 0;
+   for(std::size_t i=0; i<filenames.size(); i++)
+   {
+      out<<"       <DataSet timestep=\""<<timeStep<<"\" group=\""<<group<<"\" part=\""<<i<<"\" file=\""<<filenames[i]<<"\"/>\n";
+      if(sepGroups) group++;
+   }
+   out<<pvdEndTag;
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeParallelFile(const string& filename,vector<string>& pieceSources, vector<string>& pointDataNames, vector<string>& cellDataNames)
+{
+   string vtkfilename=filename+".pvtu";
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeParallelFile to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   //VTK FILE
+   out<<"<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
+   out<<"  <PUnstructuredGrid GhostLevel=\"0\">\n";
+   out<<"    <PPoints>\n"; 
+   out<<"      <PDataArray type=\"Float32\" NumberOfComponents=\"3\"/>\n";
+   out<<"    </PPoints>\n";
+   out<<"    <PPointData>\n";
+   for(size_t s=0; s<pointDataNames.size(); s++)
+      out<< "      <PDataArray type=\"Float64\" Name=\""<< pointDataNames[s] <<"\"/>\n";
+   out<<"    </PPointData>\n";
+   if (cellDataNames.size() > 0)
+   {
+      out<<"    <PCellData>\n";
+      for(size_t s=0; s<cellDataNames.size(); s++)
+         out<< "      <PDataArray type=\"Float32\" Name=\""<< cellDataNames[s] <<"\"/>\n";
+      out<<"    </PCellData>\n";
+   }
+
+   for(size_t s=0; s<pieceSources.size(); s++)
+      out<<"    <Piece Source=\""<<pieceSources[s]<<"\"/>\n";
+   out<<"  </PUnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeParallelFile to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeQuads(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuads to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"      <Points>\n"; 
+   out<<"         <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+   out<<"      </Points>\n";
+
+   //CELLS SECTION
+   out<<"      <Cells>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*4<<" " ;
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+
+   out<<"      <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"8 ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"      </Cells>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuads to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeQuadsWithNodeData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, vector< string >& datanames, vector< vector< double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*4<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"8 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write data section
+   out<<"         <PointData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+    }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithNodeData to "<<vtkfilename<<" - end");
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeQuadsWithCellData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, vector< string >& datanames, vector< vector< double > >& celldata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithCellData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*4<<" " ;
+
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"8 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write data section
+   out<<"         <CellData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)celldata[s].size(); d++)
+         out<<celldata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </CellData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+
+   out.close();
+
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlASCII::writeQuadsWithNodeAndCellData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, 
+                                                          vector< string >& nodedatanames, vector< vector< double > >& nodedata, vector< string >& celldatanames,
+                                                          vector< vector< double > >& celldata                                                                       )
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithNodeAndCellData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*4<<" " ;
+
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"8 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+   
+   //write PointData section
+   out<<"         <PointData Scalars=\"PScalars\"> \n";
+   for(int s=0; s<(int)nodedatanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< nodedatanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+
+   //write celldata section
+   out<<"         <CellData Scalars=\"CScalars\"> \n";
+   for(int s=0; s<(int)celldatanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< celldatanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)celldata[s].size(); d++)
+         out<<celldata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </CellData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeQuadsWithNodeAndCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeLines(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt2 >& lines) 
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLines to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofLines = (int)lines.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofLines<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"      <Points>\n"; 
+   out<<"         <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+   out<<"      </Points>\n";
+
+   //CELLS SECTION
+   out<<"      <Cells>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofLines; c++)
+      out<< val<1>(lines[c]) <<" "<< val<2>(lines[c])<<"  ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
+   for(int c=1; c<=nofLines; c++)
+      out<<c*2<<" " ;
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+
+   out<<"      <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofLines; c++)
+      out<<"3 ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"      </Cells>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLines to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeLinesWithNodeData(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt2 >& lines, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLinesWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofLines = (int)lines.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofLines<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"      <Points>\n"; 
+   out<<"         <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+   out<<"      </Points>\n";
+
+   //CELLS SECTION
+   out<<"      <Cells>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofLines; c++)
+      out<< val<1>(lines[c]) <<" "<< val<2>(lines[c])<<"  ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
+   for(int c=1; c<=nofLines; c++)
+      out<<c*2<<" " ;
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+
+   out<<"      <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofLines; c++)
+      out<<"3 ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"      </Cells>\n";
+
+   //write data section
+   out<<"         <PointData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLinesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeTriangles(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt3 >& triangles)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeTriangles to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofTriangles= (int)triangles.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofTriangles<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"      <Points>\n"; 
+   out<<"         <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+   out<<"      </Points>\n";
+
+   //CELLS SECTION
+   out<<"      <Cells>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofTriangles; c++)
+      out<< val<1>(triangles[c]) <<" "<< val<2>(triangles[c])<<" "<< val<3>(triangles[c])<<"  ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
+   for(int c=1; c<nofTriangles+1; c++)
+      out<<c*3<<" " ;
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+
+   out<<"      <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
+
+   for(int c=0; c<nofTriangles; c++)
+      out<<"5 ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"      </Cells>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeTriangles to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeTrianglesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt3 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeTrianglesWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "<< val<2>(cells[c]) <<" "<< val<3>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*3<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"5 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write data section
+   out<<"         <PointData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeTrianglesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeOctsWithCellData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt8 >& cells, vector< string >& datanames, vector< vector< double > >& celldata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOctsWithCellData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<" "
+         << val<5>(cells[c]) <<" "
+         << val<6>(cells[c]) <<" "
+         << val<8>(cells[c]) <<" "
+         << val<7>(cells[c]) <<"  ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*8<<" " ;
+
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"11 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+   
+
+   //write data section
+   out<<"         <CellData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)celldata[s].size(); d++)
+         out<<celldata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </CellData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOctsWithCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeOctsWithNodeData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt8 >& cells, vector< string >& datanames, vector< vector< double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOctsWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<<val<1>(nodes[n])<<" "<<val<2>(nodes[n])<<" "<<val<3>(nodes[n])<<" ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<" "
+         << val<5>(cells[c]) <<" "
+         << val<6>(cells[c]) <<" "
+         << val<8>(cells[c]) <<" "
+         << val<7>(cells[c]) <<"  ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*8<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"11 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write PointData section
+   out<<"         <PointData Scalars=\"PScalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float64\" Name=\""<< datanames[s] <<"\" format=\"ascii\">";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+      {
+         //out<<base64_encode((unsigned char*)(&nodedata[s][d]),sizeof(float));
+         //out.write((char*)&nodedata[s][d],sizeof(float));
+         out<<nodedata[s][d]<<" ";
+      }
+      out<<"</DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOctsWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlASCII::writeOcts(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt8 >& cells)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOcts to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofCells<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<< val<1>(cells[c]) <<" "
+         << val<2>(cells[c]) <<" "
+         << val<4>(cells[c]) <<" "
+         << val<3>(cells[c]) <<" "
+         << val<5>(cells[c]) <<" "
+         << val<6>(cells[c]) <<" "
+         << val<8>(cells[c]) <<" "
+         << val<7>(cells[c]) <<"   ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofCells+1; c++)
+      out<<c*8<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofCells; c++)
+      out<<"11 ";
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Cells>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeOcts to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+std::string WbWriterVtkXmlASCII::writeNodes(const std::string& filename,std::vector< UbTupleFloat3 >& nodes)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLines to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofNodes<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"      <Points>\n"; 
+   out<<"         <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+   out<<"      </Points>\n";
+
+   //CELLS SECTION
+   out<<"      <Cells>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
+   for(int n=0; n<nofNodes; n++)
+      out<< n << "  ";
+   out<<"\n";
+
+   out<<"      </DataArray>\n";
+   out<<"         <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n";
+   for(int n=1; n<=nofNodes; n++)
+      out << n << " ";
+
+   out<<"\n";
+   out<<"         </DataArray>\n";
+
+   out<<"      <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n";
+
+   for(int n=0; n<nofNodes; n++)
+      out<<"1 ";
+   out<<"\n";
+   out<<"      </DataArray>\n";
+   out<<"      </Cells>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeLines to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+std::string WbWriterVtkXmlASCII::writeNodesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeNodesWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofNodes<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofNodes; c++)
+      out << c <<"   ";
+   out<<"\n";
+
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofNodes+1; c++)
+      out<<c<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+   for(int c=0; c<nofNodes; c++)
+      out<<"1 ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write data section
+   out<<"         <PointData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeNodesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+
+//////////////////////////////////////////////////////////////////////////
+std::string WbWriterVtkXmlASCII::writeNodesWithNodeDataDouble(const std::string& filename,std::vector< UbTupleDouble3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata)
+{
+   string vtkfilename=filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeNodesWithNodeData to "<<vtkfilename<<" - start");
+
+   std::ofstream out(vtkfilename.c_str());
+   out.precision (std::numeric_limits<double>::digits10 + 1);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){UbSystem::makeDirectory(path);out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+
+   //VTK FILE
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\"	NumberOfCells=\""<<nofNodes<<"\">   \n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">\n               ";
+   for(int n=0; n<nofNodes; n++)
+      out<< val<1>(nodes[n]) <<" "<< val<2>(nodes[n]) <<" "<< val<3>(nodes[n]) <<"   ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+   out<<"         </Points>\n";
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n              ";
+
+   for(int c=0; c<nofNodes; c++)
+      out << c <<"   ";
+   out<<"\n";
+
+   out<<"            </DataArray>\n";
+   out<<"            <DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">\n              ";
+   for(int c=1; c<nofNodes+1; c++)
+      out<<c<<" " ;
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n              ";
+   for(int c=0; c<nofNodes; c++)
+      out<<"1 ";
+
+   out<<"\n";
+   out<<"            </DataArray>\n";
+
+   out<<"         </Cells>\n";
+
+   //write data section
+   out<<"         <PointData Scalars=\"Scalars\"> \n";
+   for(int s=0; s<(int)datanames.size(); ++s)
+   {
+      out<< "           <DataArray type=\"Float64\" Name=\""<< datanames[s] <<"\" format=\"ascii\"> \n";
+
+      for(int d=0; d<(int)nodedata[s].size(); d++)
+         out<<nodedata[s][d]<<" ";
+
+      out<<"\n          </DataArray>\n";
+   }
+   out<<"         </PointData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlASCII::writeNodesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
diff --git a/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.h b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea76ed3b9c56730934fb8d1f673a05bc23740361
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlASCII.h
@@ -0,0 +1,122 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WbWriterVtkXmlASCII.h
+//! \ingroup writer
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef WBWRITERVTKXMLASCII_H
+#define WBWRITERVTKXMLASCII_H
+
+#include <string>
+
+#include <basics/writer/WbWriter.h>
+
+class WbWriterVtkXmlASCII  : public WbWriter
+{
+public:
+   static WbWriterVtkXmlASCII* getInstance()
+   {
+      static WbWriterVtkXmlASCII instance;
+      return &instance;
+   }
+private:
+   WbWriterVtkXmlASCII() : WbWriter() 
+   {
+      if(sizeof(unsigned char)!=1) throw UbException(UB_EXARGS,"error char  type mismatch");
+      if(sizeof(int)          !=4) throw UbException(UB_EXARGS,"error int   type mismatch");
+      if(sizeof(float)        !=4) throw UbException(UB_EXARGS,"error float type mismatch");
+   }
+   WbWriterVtkXmlASCII( const WbWriterVtkXmlASCII& );                  //no copy allowed 
+   const WbWriterVtkXmlASCII& operator=( const WbWriterVtkXmlASCII& ); //no copy allowed
+
+   static std::string  pvdEndTag;
+
+public:
+   std::string getFileExtension()  { return ".ascii.vtu"; }
+
+   //write a metafile 
+   std::string writeCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timesteps, const bool& sepGroups);//std::vector<double>& groups, std::vector<double>& parts);
+   std::string addFilesToCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timestep, const bool& sepGroups);
+   std::string writeParallelFile(const std::string& filename,std::vector<std::string>& pieceSources, std::vector<std::string>& pointDataNames, std::vector<std::string>& cellDataNames);
+
+   //////////////////////////////////////////////////////////////////////////
+   //nodes
+   std::string writeNodes(const std::string& filename,std::vector< UbTupleFloat3 >& nodes);
+   std::string writeNodesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata);
+   std::string writeNodesWithNodeDataDouble(const std::string& filename,std::vector< UbTupleDouble3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //lines
+   //     0 ---- 1
+   //nodenumbering must start with 0!
+   std::string writeLines(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines);
+   std::string writeLinesWithNodeData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //triangles
+   //                    2
+   //                     
+   //                  0---1
+   //nodenumbering must start with 0!
+   std::string writeTriangles(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt3 >& triangles);
+   std::string writeTrianglesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt3 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //2D
+   //cell numbering:
+   //                  3---2
+   //                  |   |
+   //                  0---1
+   //nodenumbering must start with 0!
+
+   std::string writeQuads(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells);
+   std::string writeQuadsWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+   std::string writeQuadsWithCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& celldata);
+   std::string writeQuadsWithNodeAndCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, 
+                                             std::vector< std::string >& nodedatanames, std::vector< std::vector< double > >& nodedata, std::vector< std::string >& celldatanames,
+                                             std::vector< std::vector< double > >& celldata                                                                       );
+   
+   //////////////////////////////////////////////////////////////////////////
+   //octs
+   //     7 ---- 6
+   //    /|     /|
+   //   4 +--- 5 |
+   //   | |    | |
+   //   | 3 ---+ 2
+   //   |/     |/
+   //   0 ---- 1
+   std::string writeOcts(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt8 >& cells);
+   std::string writeOctsWithCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt8 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& celldata);
+   std::string writeOctsWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt8 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+
+private:
+
+};
+
+#endif //WBWRITERVTKXMLASCII_H
diff --git a/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.cpp b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67bd1f56397d6993e54333a07adb6867e2f6f196
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.cpp
@@ -0,0 +1,1618 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WbWriterVtkXmlBinary.cpp
+//! \ingroup writer
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <basics/writer/WbWriterVtkXmlBinary.h>
+#include <basics/writer/WbWriterVtkXmlASCII.h>
+#include <basics/utilities/UbLogger.h>
+#include <cstring>
+
+using namespace std;
+
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::pvdEndTag ="   </Collection>\n</VTKFile>";
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeCollection(const string& filename, const vector<string>& filenames, const double& timeStep, const bool& sepGroups)
+{
+   string vtkfilename=filename+".pvd";
+   ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   string endian;
+   if(UbSystem::isLittleEndian()) endian = "LittleEndian";
+   else                           endian = "BigEndian";
+   out<<"<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\""<<endian<<"\" >"<<endl;
+   out<<"   <Collection>"<<endl;
+   
+   int group = 0, part=0;
+   for(size_t i=0; i<filenames.size(); i++)
+   {
+      out<<"       <DataSet timestep=\""<<timeStep<<"\" group=\""<<group<<"\" part=\""<<part<<"\" file=\""<<filenames[i]<<"\"/>"<<endl;
+      if(sepGroups) group++;
+      else          part++;
+   }
+   out<<pvdEndTag;
+   out.close();
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::addFilesToCollection(const string& filename, const vector<string>& filenames, const double& timeStep, const bool& sepGroups)
+{
+   string vtkfilename=filename;
+   fstream test(vtkfilename.c_str(), ios::in);
+   if(!test)
+   {
+      test.clear();
+      vtkfilename += ".pvd";
+      test.open(vtkfilename.c_str(), ios::in);
+      if(!test) return this->writeCollection(filename,filenames,timeStep,sepGroups);
+   }
+ 
+   fstream out(vtkfilename.c_str(), ios::in | ios::out);
+   out.seekp(-(int)pvdEndTag.size()-1, ios_base::end);
+
+   int group = 0;
+   for(size_t i=0; i<filenames.size(); i++)
+   {
+      out<<"       <DataSet timestep=\""<<timeStep<<"\" group=\""<<group<<"\" part=\""<<i<<"\" file=\""<<filenames[i]<<"\"/>"<<endl;
+      if(sepGroups) group++;
+   }
+   out<<pvdEndTag;
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeParallelFile(const string& filename,vector<string>& pieceSources, vector<string>& pointDataNames, vector<string>& cellDataNames)
+{
+   string vtkfilename=filename+".pvtu";
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeParallelFile to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str());
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str());}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   //VTK FILE
+   out<<"<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">"<<"\n";
+   out<<"  <PUnstructuredGrid GhostLevel=\"0\">"<<"\n";
+   out<<"    <PPoints>\n"; 
+   out<<"      <PDataArray type=\"Float32\" NumberOfComponents=\"3\"/>\n";
+   out<<"    </PPoints>\n";
+   out<<"    <PPointData>\n";
+   for(size_t s=0; s<pointDataNames.size(); s++)
+      out<< "      <PDataArray type=\"Float32\" Name=\""<< pointDataNames[s] <<"\"/>\n";
+   out<<"    </PPointData>\n";
+   if (cellDataNames.size() > 0)
+   {
+      out<<"    <PCellData>\n";
+      for(size_t s=0; s<cellDataNames.size(); s++)
+         out<< "      <PDataArray type=\"Float32\" Name=\""<< cellDataNames[s] <<"\"/>\n";
+      out<<"    </PCellData>\n";
+   }
+
+   for(size_t s=0; s<pieceSources.size(); s++)
+      out<<"    <Piece Source=\""<<pieceSources[s]<<"\"/>\n";
+   out<<"  </PUnstructuredGrid>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeParallelFile to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeLines(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt2 >& lines)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeLines to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)lines.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 2 /*nodes per line */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per line */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of line */ * nofCells * sizeof(unsigned char);
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(lines[c]), sizeof(int) );
+      out.write( (char*)&val<2>(lines[c]), sizeof(int) );
+      
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 2 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 3;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeLines to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+std::string WbWriterVtkXmlBinary::writeLinesWithNodeData(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt2 >& lines, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeLinesWithNodeData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)lines.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 2 /*nodes per line  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per line */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of line    */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar          */ * nofNodes * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </PointData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(lines[c]), sizeof(int) );
+      out.write( (char*)&val<2>(lines[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 3 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 5;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         float tmp = (float)nodedata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeLinesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeTriangles(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt3 >& triangles)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeTriangles to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)triangles.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3 - coord    */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 3 /*nodes per triangle  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per triangle */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of triangle    */ * nofCells * sizeof(unsigned char);
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(triangles[c]), sizeof(int) );
+      out.write( (char*)&val<2>(triangles[c]), sizeof(int) );
+      out.write( (char*)&val<3>(triangles[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 3 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 5;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out<<flush;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeTriangles to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeTrianglesWithNodeData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt3 >& cells, vector< string >& datanames, vector< vector< double > >& nodedata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeTrianglesWithNodeData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 3 /*nodes per tri   */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per tri  */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of tri     */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar          */ * nofNodes * sizeof(float); 
+   
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </PointData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 3 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 5;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         float tmp = (float)nodedata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeTrianglesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeQuads(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuads to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 4 /*nodes per quad  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per quad */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of quad    */ * nofCells * sizeof(unsigned char);
+  
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 4 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 8;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out<<flush;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuads to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeQuadsWithNodeData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, vector< string >& datanames, vector< vector< double > >& nodedata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithNodeData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 4 /*nodes per quad  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per quad */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of quad    */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar          */ * nofNodes * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float64\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </PointData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 4 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 8;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         float tmp = (float)nodedata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeQuadsWithCellData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, vector< string >& datanames, vector< vector< double > >& celldata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithCellData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 4 /*nodes per quad  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per quad */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of quad    */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar          */ * nofCells * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <CellData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </CellData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 4 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 8;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<celldata[s].size(); ++d)
+      {
+         //loake kopie machen, da in celldata "doubles" sind
+         float tmp = (float)celldata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+
+   out<<"\n</AppendedData>\n";
+
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeQuadsWithNodeAndCellData(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt4 >& cells, 
+                                                                vector< string >& nodedatanames, vector< vector< double > >& nodedata, vector< string >& celldatanames,
+                                                                vector< vector< double > >& celldata                                                                    )
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithNodeAndCellData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 4 /*nodes per quad  */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per quad */ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of quad    */ * nofCells * sizeof(unsigned char);
+   int bytesScalarDataPoint = 1 /*scalar          */ * nofNodes * sizeof(float); 
+   int bytesScalarDataCell  = 1 /*scalar          */ * nofCells * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   // Point DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<nodedatanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< nodedatanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarDataPoint);
+   }
+   out<<"         </PointData>\n";
+
+
+   // Cell DATA SECTION
+   out<<"         <CellData>\n";
+   for(size_t s=0; s<celldatanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< celldatanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarDataCell);
+   }
+   out<<"         </CellData>\n";
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 4 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 8;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //Point DATA SECTION
+   //scalarData
+   for(size_t s=0; s<nodedatanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarDataPoint,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         float tmp = (float)nodedata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   //Cell DATA SECTION
+   //scalarData
+   for(size_t s=0; s<celldatanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarDataCell,bytesPerByteVal);
+      for(size_t d=0; d<celldata[s].size(); ++d)
+      {
+         //loake kopie machen, da in celldata "doubles" sind
+         float tmp = (float)celldata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeQuadsWithNodeAndCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeOctsWithCellData(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt8 >& cells, vector<string >& datanames, vector<vector<double > >& celldata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOctsWithCellData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3      */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 8 /*nodes per oct */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per oct*/ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of oct   */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar        */ * nofCells * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <CellData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float32\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </CellData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<5>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<6>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<8>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<7>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 8 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 11;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<celldata[s].size(); ++d)
+      {
+         //loake kopie machen, da in celldata "doubles" sind
+         float tmp = (float)celldata[s][d];
+         out.write((char*)&tmp,sizeof(float));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOctsWithCellData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeOctsWithNodeData(const string& filename,vector<UbTupleFloat3 >& nodes, vector<UbTupleInt8 >& cells, vector<string >& datanames, vector<vector<double > >& nodedata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOctsWithNodeData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3      */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 8 /*nodes per oct */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per oct*/ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of oct   */ * nofCells * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar        */ * nofNodes * sizeof(double); 
+
+   unsigned long long offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"2.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float64\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </PointData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<5>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<6>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<8>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<7>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 8 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 11;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         //float tmp = (float)nodedata[s][d];
+         //out.write((char*)&tmp,sizeof(float));
+         double tmp = nodedata[s][d];
+         out.write((char*)&tmp,sizeof(double));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOctsWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+/*===============================================================================*/
+string WbWriterVtkXmlBinary::writeOcts(const string& filename,vector< UbTupleFloat3 >& nodes, vector< UbTupleInt8 >& cells)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOcts to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+   int nofCells = (int)cells.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3      */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 8 /*nodes per oct */ * nofCells * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per oct*/ * nofCells * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of oct   */ * nofCells * sizeof(unsigned char);
+   //int bytesScalarData      = 1 /*scalar        */ * nofNodes * sizeof(float); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofCells<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofCells; c++) 
+   {
+      out.write( (char*)&val<1>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<2>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<4>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<3>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<5>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<6>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<8>(cells[c]), sizeof(int) );
+      out.write( (char*)&val<7>(cells[c]), sizeof(int) );
+   }
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   int itmp;
+   for(int c=1; c<=nofCells; c++)
+   {
+      itmp = 8 * c;    
+      out.write( (char*)&itmp, sizeof(int) );
+   }
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 11;
+   for(int c=0; c<nofCells; c++)
+   {
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeOcts to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+std::string WbWriterVtkXmlBinary::writeNodes(const std::string& filename,std::vector< UbTupleFloat3 >& nodes)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeNodes to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3        */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 1 /*nodes per cell  */ * nofNodes * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per cell */ * nofNodes * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of line    */ * nofNodes * sizeof(unsigned char);
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofNodes<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofNodes; c++) 
+      out.write( (char*)&c, sizeof(int) );
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   for(int c=1; c<=nofNodes; c++)
+      out.write( (char*)&c, sizeof(int) );
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 1;
+   for(int c=0; c<nofNodes; c++)
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeNodes to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+}
+std::string WbWriterVtkXmlBinary::writeNodesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata)
+{
+   string vtkfilename = filename+getFileExtension();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeNodesWithNodeData to "<<vtkfilename<<" - start");
+
+   ofstream out(vtkfilename.c_str(),ios::out | ios::binary);
+   if(!out)
+   { 
+      out.clear(); //flags ruecksetzen (ansonsten liefert utern if(!out) weiterhin true!!!
+      string path = UbSystem::getPathFromString(vtkfilename);
+      if(path.size()>0){ UbSystem::makeDirectory(path); out.open(vtkfilename.c_str(),ios::out | ios::binary);}
+      if(!out) throw UbException(UB_EXARGS,"couldn't open file "+vtkfilename);
+   }
+
+   int nofNodes = (int)nodes.size(); 
+
+   int bytesPerByteVal      = 4; //==sizeof(int)
+   int bytesPoints          = 3 /*x1/x2/x3       */ * nofNodes * sizeof(float);
+   int bytesCellConnectivty = 1 /*nodes per cell */ * nofNodes * sizeof(int  );
+   int bytesCellOffsets     = 1 /*offset per cell*/ * nofNodes * sizeof(int  );
+   int bytesCellTypes       = 1 /*type of oct    */ * nofNodes * sizeof(unsigned char);
+   int bytesScalarData      = 1 /*scalar         */ * nofNodes * sizeof(double); 
+
+   int offset = 0;
+   //VTK FILE
+   out<<"<?xml version=\"1.0\"?>\n";
+   out<<"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" >"<<"\n";
+   out<<"   <UnstructuredGrid>"<<"\n";
+   out<<"      <Piece NumberOfPoints=\""<<nofNodes<<"\" NumberOfCells=\""<<nofNodes<<"\">\n";
+
+   //POINTS SECTION
+   out<<"         <Points>\n"; 
+   out<<"            <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"appended\" offset=\""<< offset <<"\"  />\n";
+   out<<"         </Points>\n";
+   offset += (bytesPerByteVal + bytesPoints);
+
+   //CELLS SECTION
+   out<<"         <Cells>\n";
+   out<<"            <DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellConnectivty); 
+   out<<"            <DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\""<< offset <<"\" />\n";
+   offset += (bytesPerByteVal + bytesCellOffsets);
+   out<<"            <DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\""<< offset <<"\" />\n ";
+   offset += (bytesPerByteVal + bytesCellTypes);
+   out<<"         </Cells>\n";
+
+   //DATA SECTION
+   out<<"         <PointData>\n";
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out<< "            <DataArray type=\"Float64\" Name=\""<< datanames[s] <<"\" format=\"appended\" offset=\""<< offset <<"\" /> \n";
+      offset += (bytesPerByteVal + bytesScalarData);
+   }
+   out<<"         </PointData>\n";
+
+   out<<"      </Piece>\n";
+   out<<"   </UnstructuredGrid>\n";
+
+   // AppendedData SECTION
+   out<<"   <AppendedData encoding=\"raw\">\n";
+   out<<"_";
+
+   //POINTS SECTION
+   out.write((char*)&bytesPoints,bytesPerByteVal);
+   for(int n=0; n<nofNodes; n++)
+   {
+      out.write((char*)&val<1>(nodes[n]),sizeof(float));
+      out.write((char*)&val<2>(nodes[n]),sizeof(float));
+      out.write((char*)&val<3>(nodes[n]),sizeof(float));
+   }
+
+   //CELLS SECTION
+   //cellConnectivity
+   out.write( (char*)&bytesCellConnectivty, bytesPerByteVal );  
+   for(int c=0; c<nofNodes; c++) 
+      out.write( (char*)&c, sizeof(int) );
+
+   //cellOffsets
+   out.write( (char*)&bytesCellOffsets, bytesPerByteVal );
+   for(int c=1; c<=nofNodes; c++)
+      out.write( (char*)&c, sizeof(int) );
+
+   //cellTypes
+   out.write( (char*)&bytesCellTypes, bytesPerByteVal );
+   unsigned char vtkCellType = 1;
+   for(int c=0; c<nofNodes; c++)
+      out.write( (char*)&vtkCellType, sizeof(unsigned char) );
+   
+   //DATA SECTION
+   //scalarData
+   for(size_t s=0; s<datanames.size(); ++s)
+   {
+      out.write((char*)&bytesScalarData,bytesPerByteVal);
+      for(size_t d=0; d<nodedata[s].size(); ++d)
+      {
+         //loake kopie machen, da in nodedata "doubles" sind
+         //float tmp = (float)nodedata[s][d];
+         //out.write((char*)&tmp,sizeof(float));
+         double tmp = nodedata[s][d];
+         out.write((char*)&tmp, sizeof(double));
+      }
+   }
+   out<<"\n</AppendedData>\n";
+   out<<"</VTKFile>";
+   out<<endl;
+   out.close();
+   UBLOG(logDEBUG1,"WbWriterVtkXmlBinary::writeNodesWithNodeData to "<<vtkfilename<<" - end");
+
+   return vtkfilename;
+
+}
diff --git a/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.h b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd0182c26aedfa6097602f85ff2e3ccb4bb6d499
--- /dev/null
+++ b/VirtualFluidsBasics/basics/writer/WbWriterVtkXmlBinary.h
@@ -0,0 +1,121 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WbWriterVtkXmlBinary.h
+//! \ingroup writer
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef WBWRITERVTKXMLBINARY_H
+#define WBWRITERVTKXMLBINARY_H
+
+#include <string>
+
+#include <basics/writer/WbWriter.h>
+
+class WbWriterVtkXmlBinary  : public WbWriter
+{
+public:
+   static WbWriterVtkXmlBinary* getInstance()
+   {
+      static WbWriterVtkXmlBinary instance;
+      return &instance;
+   }
+private:
+   WbWriterVtkXmlBinary() : WbWriter() 
+   {
+      if(sizeof(unsigned char)!=1) throw UbException(UB_EXARGS,"machine error char  type mismatch");
+      if(sizeof(int)          !=4) throw UbException(UB_EXARGS,"machine error int   type mismatch");
+      if(sizeof(float)        !=4) throw UbException(UB_EXARGS,"machine error float type mismatch");
+   }
+
+   WbWriterVtkXmlBinary( const WbWriterVtkXmlBinary& );                  //no copy allowed 
+   const WbWriterVtkXmlBinary& operator=( const WbWriterVtkXmlBinary& ); //no copy allowed
+
+   static std::string  pvdEndTag;
+public:
+   std::string getFileExtension() { return ".bin.vtu";   }
+
+   //write a metafile 
+   std::string writeCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timestep, const bool& sepGroups);
+   std::string addFilesToCollection(const std::string& filename, const std::vector<std::string>& filenames, const double& timestep, const bool& sepGroups);
+   std::string writeParallelFile(const std::string& filename,std::vector<std::string>& pieceSources, std::vector<std::string>& pointDataNames, std::vector<std::string>& cellDataNames);
+
+   //////////////////////////////////////////////////////////////////////////
+   //nodes
+   std::string writeNodes(const std::string& filename,std::vector< UbTupleFloat3 >& nodes);
+   std::string writeNodesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //lines
+   //     0 ---- 1
+   //nodenumbering must start with 0!
+   std::string writeLines(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines);
+   std::string writeLinesWithNodeData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //triangles
+   //                    2
+   //                     
+   //                  0---1
+   //nodenumbering must start with 0!
+   std::string writeTriangles(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt3 >& triangles);
+   std::string writeTrianglesWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt3 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata);
+
+   //////////////////////////////////////////////////////////////////////////
+   //2D
+   //cell numbering:
+   //                  3---2
+   //                  |   |
+   //                  0---1
+   //nodenumbering must start with 0!
+
+   std::string writeQuads(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells);
+   std::string writeQuadsWithNodeData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& nodedata);
+   std::string writeQuadsWithCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, std::vector< std::string >& datanames, std::vector< std::vector< double > >& celldata);
+   std::string writeQuadsWithNodeAndCellData(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt4 >& cells, 
+                                             std::vector< std::string >& nodedatanames, std::vector< std::vector< double > >& nodedata, std::vector< std::string >& celldatanames,
+                                             std::vector< std::vector< double > >& celldata                                                                    );
+   
+   //////////////////////////////////////////////////////////////////////////
+   //octs
+   //     7 ---- 6
+   //    /|     /|
+   //   4 +--- 5 |
+   //   | |    | |
+   //   | 3 ---+ 2
+   //   |/     |/
+   //   0 ---- 1
+   std::string writeOcts(const std::string& filename,std::vector< UbTupleFloat3 >& nodes, std::vector< UbTupleInt8 >& cells);
+   std::string writeOctsWithCellData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt8 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& celldata);
+   std::string writeOctsWithNodeData(const std::string& filename,std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt8 >& cells, std::vector<std::string >& datanames, std::vector<std::vector<double > >& nodedata);
+   
+private:
+
+};
+
+#endif //WBWRITERVTKXMLBINARY_H
diff --git a/VirtualFluidsBasics/geometry3d/CMakePackage.txt b/VirtualFluidsBasics/geometry3d/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e3e3f9a387b022a62ecc0d63c3ef0210313e906d
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
\ No newline at end of file
diff --git a/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.cpp b/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d92075c9e7910f59cfe5c9b0cc070083507c5ce2
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.cpp
@@ -0,0 +1,288 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CoordinateTransformation3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <geometry3d/CoordinateTransformation3D.h>
+#include <basics/utilities/UbMath.h>
+
+using namespace std;
+
+CoordinateTransformation3D::CoordinateTransformation3D()
+{
+   this->setTransformationValues(0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0,0.0);
+}
+/*======================================================*/
+CoordinateTransformation3D::CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma) 
+{
+   this->setTransformationValues(originX1, originX2, originX3, dx1, dx2, dx3, alpha, beta, gamma);
+}
+/*======================================================*/
+CoordinateTransformation3D::CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3) 
+{
+   this->setTransformationValues(originX1, originX2, originX3, dx1, dx2, dx3, 0.0, 0.0, 0.0);
+}
+/*======================================================*/
+CoordinateTransformation3D::CoordinateTransformation3D(CoordinateTransformation3D* transformation)
+{
+   this->setTransformationValues(transformation->Tx1 , transformation->Tx2 , transformation->Tx3 , transformation->Sx1 , transformation->Sx2 , transformation->Sx3, transformation->alpha, transformation->beta, transformation->gamma);
+}
+/*======================================================*/
+// void CoordinateTransformation3D::init()
+// {
+//    this->Tx1   = 0.0;      this->Tx2   = 0.0;	this->Tx3   = 0.0;
+//    this->Sx1   = 1.0;      this->Sx2   = 1.0;	this->Sx3   = 1.0;
+//    this->alpha = 0.0;		this->beta = 0.0;		this->gamma = 0.0;
+// 
+//    this->toX1factorX1   = 1.0; this->toX1factorX2   = 0.0; this->toX1factorX3   = 0.0;
+//    this->toX2factorX1   = 0.0; this->toX2factorX2   = 1.0; this->toX2factorX3   = 0.0;
+//    this->toX3factorX1   = 0.0; this->toX3factorX2   = 0.0; this->toX3factorX3   = 1.0;
+//    this->toX1delta      = 0.0; this->toX2delta      = 0.0; this->toX3delta      = 0.0;
+//    this->fromX1factorX1 = 1.0; this->fromX1factorX2 = 0.0; this->fromX1factorX3 = 0.0;
+//    this->fromX2factorX1 = 0.0; this->fromX2factorX2 = 1.0; this->fromX2factorX3 = 0.0;
+//    this->fromX3factorX1 = 0.0; this->fromX3factorX2 = 0.0; this->fromX3factorX3 = 1.0;
+//    
+//    this->active         = false;
+//    this->transformation = false;
+// }
+/*======================================================*/
+
+/**====  Set transformation values  ====**/
+/*!
+\brief Set transformation values
+@param a     transformed coordinate system x0 (in global coordinates)
+@param b     transformed coordinate system y0 (in global coordinates)
+@param c     transformed coordinate system z0 (in global coordinates)
+@param dx1    x coordinate scaling       (dx_transformed/dx_global)
+@param dx2    y coordinate scaling       (dy_transformed/dy_global)
+@param dx3    z coordinate scaling       (dz_transformed/dz_global)
+@param alpha rotation around z angle    (positive FROM global TO transformed coordinate system)
+@param beta  rotation around y angle            
+@param gamma rotation around x angle            
+@exception IllegalArgumentException if c1 of the scale values is between -1.0E-8 and 1.0E-8
+*/
+
+void CoordinateTransformation3D::setTransformationValues(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma)
+{
+   if(UbMath::zero(dx1) || UbMath::zero(dx2) || UbMath::zero(dx3))
+      throw UbException(UB_EXARGS,"error: at least one delta==0.0");
+   
+   this->Tx1   = originX1; this->Tx2  = originX2; this->Tx3   = originX3;
+   this->Sx1   = dx1;	   this->Sx2  = dx2;	     this->Sx3   = dx3;
+   this->alpha = alpha;	   this->beta = beta;     this->gamma = gamma;
+
+   double ra   = UbMath::PI*alpha/180.0;
+   double cosA = cos(ra);
+   double sinA = sin(ra);
+   double rb   = UbMath::PI*beta/180.0;
+   double cosB = cos(rb);
+   double sinB = sin(rb);
+   double rg   = UbMath::PI*gamma/180.0;
+   double cosG = cos(rg);
+   double sinG = sin(rg);
+
+   //Matrix-Werte von T_invers  (indizes: 12 = spalte 1 zeile 2)
+   double divisor = (Sx1*Sx2*Sx3);
+   
+   this->toX1factorX1 = +cosB*cosA*Sx2*Sx3/divisor;
+   this->toX1factorX2 = -cosB*sinA*Sx1*Sx3/divisor;
+   this->toX1factorX3 = +sinB*Sx1*Sx2/divisor;
+   this->toX1delta    = (-Tx3*Sx1*Sx2*sinB       
+                         +Tx2*Sx1*Sx3*sinA*cosB  
+                         -Tx1*Sx2*Sx3*cosB*cosA)/divisor;
+   
+   this->toX2factorX1 = Sx2*Sx3*(sinG*sinB*cosA+cosG*sinA)/divisor;
+   this->toX2factorX2 = Sx1*Sx3*(-sinG*sinB*sinA+cosG*cosA)/divisor;
+   this->toX2factorX3 = -Sx1*Sx2*cosB*sinG/divisor;
+   this->toX2delta    = (-Tx2*Sx1*Sx3*cosG*cosA
+                         +Tx3*Sx1*Sx2*sinG*cosB
+                         +Tx2*Sx1*Sx3*sinG*sinA*sinB
+                         -Tx1*Sx2*Sx3*cosG*sinA
+                         -Tx1*Sx2*Sx3*sinB*sinG*cosA   )/divisor;
+   
+
+   this->toX3factorX1 = Sx2*Sx3*(-cosG*sinB*cosA+sinG*sinA)/divisor;
+   this->toX3factorX2 = Sx1*Sx3*(sinB*cosG*sinA+sinG*cosA)/divisor;
+   this->toX3factorX3 = Sx1*Sx2*cosB*cosG/divisor;
+   this->toX3delta    = (-Tx2*Sx1*Sx3*sinG*cosA
+                         -Tx3*Sx1*Sx2*cosG*cosB
+                         -Tx2*Sx1*Sx3*cosG*sinA*sinB
+                         -Tx1*Sx2*Sx3*sinG*sinA
+                         +Tx1*Sx2*Sx3*sinB*cosG*cosA  )/divisor;
+                        
+   //Matrix-Werte von T_invers  (indizes: 12 = spalte 1 zeile 2)
+   this->fromX1factorX1 =  cosB*cosA*Sx1;
+   this->fromX1factorX2 =  (sinG*sinB*cosA+cosG*sinA)*Sx1;
+   this->fromX1factorX3 =  (-cosG*sinB*cosA+sinG*sinA)*Sx1;
+   this->fromX1delta    =  Tx1;
+
+   this->fromX2factorX1 =  -cosB*sinA*Sx2;
+   this->fromX2factorX2 =  -(sinG*sinB*sinA-cosG*cosA)*Sx2;
+   this->fromX2factorX3 =  (cosG*sinB*sinA+sinG*cosA)*Sx2;
+   this->fromX2delta    =  Tx2;
+   
+   this->fromX3factorX1 =  sinB*Sx3;
+   this->fromX3factorX2 =  -sinG*cosB*Sx3;
+   this->fromX3factorX3 =  cosG*cosB*Sx3;
+   this->fromX3delta    =  Tx3;
+
+   this->active         =  true;
+   
+   this->transformation =  true;
+}
+/*======================================================*/
+/*!
+Set transformation active state (if this IS a transformation)
+@param active true to be active, false otherwise
+**/
+void CoordinateTransformation3D::setActive(const bool& active)
+{
+   if(this->active == active) return;
+   if(this->transformation)   this->active = active;
+}
+/*======================================================*/
+/*!
+Transform FROM global coordinates TO transformed coordinates.
+@param x1  the global x coordinate
+@param x2  the global y coordinate
+@param x3  the global z coordinate
+**/
+double CoordinateTransformation3D::transformForwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->toX1factorX1*x1 + this->toX1factorX2*x2 + this->toX1factorX3*x3 + this->toX1delta;
+   else             return x1;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformForwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->toX2factorX1*x1 + this->toX2factorX2*x2 + this->toX2factorX3*x3 + this->toX2delta;
+   else             return x2;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformForwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->toX3factorX1*x1 + this->toX3factorX2*x2 + this->toX3factorX3*x3 + this->toX3delta;
+   else             return x3;
+}
+/*======================================================*/
+/*!
+Transform FROM global coordinates TO transformed coordinates (ignoring rotation).
+@param x1  the global x coordinate
+**/
+double CoordinateTransformation3D::transformForwardToX1CoordinateIgnoringRotation(const double& x1) const
+{
+   if(this->active) return (x1-this->Tx1)/this->Sx1;
+   else             return x1;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformForwardToX2CoordinateIgnoringRotation(const double& x2) const
+{
+   if(this->active) return (x2-this->Tx2)/this->Sx2;
+   else             return x2;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformForwardToX3CoordinateIgnoringRotation(const double& x3) const
+{
+   if(this->active) return (x3-this->Tx3)/this->Sx3;
+   else             return x3;
+}
+/*======================================================*/
+/*!
+Transform FROM transformed coordinates TO global coordinates.
+@param x1  the transformed x coordinate
+@param x2  the transformed y coordinate
+@param x3  the transformed z coordinate
+**/
+double CoordinateTransformation3D::transformBackwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->fromX1factorX1*x1 + this->fromX1factorX2*x2 + this->fromX1factorX3*x3 + this->fromX1delta;
+   else             return x1;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformBackwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->fromX2factorX1*x1 + this->fromX2factorX2*x2 + this->fromX2factorX3*x3 + this->fromX2delta;
+   else             return x2;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformBackwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const
+{
+   if(this->active) return this->fromX3factorX1*x1 + this->fromX3factorX2*x2 + this->fromX3factorX3*x3 + this->fromX3delta;
+   else             return x3;
+}
+/*======================================================*/
+/*!
+Transform FROM transformed coordinates TO global coordinates (ignoring rotation).
+@param x1  the transformed x coordinate
+**/
+double CoordinateTransformation3D::transformBackwardToX1CoordinateIgnoringRotation(const double& x1) const
+{
+   if(this->active) return x1*this->Sx1+this->Tx1;
+   else             return x1;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformBackwardToX2CoordinateIgnoringRotation(const double& x2) const
+{
+   if(this->active) return x2*this->Sx2+this->Tx2;
+   else             return x2;
+}
+/*======================================================*/
+double CoordinateTransformation3D::transformBackwardToX3CoordinateIgnoringRotation(const double& x3) const
+{
+   if(this->active) return x3*this->Sx3+this->Tx3;
+   else             return x3;
+}
+/*======================================================*/
+/*!
+Returns a string representation of this transformation.
+@return a string representation of this transformation
+**/
+string CoordinateTransformation3D::toString() const
+{
+   stringstream ss;
+    ss<<" CoordinateTransformation3D\n";
+//    ss<<"[isTransformation="<<this->transformation;
+//    ss<<", isActive="<<this->active<<endl;
+    ss<<" ,a="<<this->Tx1<<", b="<<this->Tx2<<", c="<<this->Tx3<<endl;
+    ss<<" , dx1="<<this->Sx1<<", dx2="<<this->Sx2<<", dx2="<<this->Sx3<<endl;
+//    ss<<" , alpha="<<this->alpha<<", beta="<<this->beta<endl;
+//    ss<<"]";
+//    ss<<"[to11="<<this->to11<<", to12="<<this->to12<<", to13="<<this->to13;
+//    ss<<", to21="<<this->to21<<", to22="<<this->to22<<", to23="<<this->to23;
+//    ss<<", to31="<<this->to31<<", to32="<<this->to32<<", to33="<<this->to33;
+//    ss<<", toA="<<this->toA<<", toB="<<this->toB<<", toC="<<this->toC;
+//    ss<<", from11="<<this->from11<<", from12="<<this->from12<<", from13="<<this->from13;
+//    ss<<", from21="<<this->from21<<", from22="<<this->from22<<", from23="<<this->from23;
+//    ss<<", from31="<<this->from31<<", from32="<<this->from32<<", from33="<<this->from33;
+//    ss<<", fromA="<<this->fromA; ss<<", fromB="<<this->fromB; ss<<", fromC="<<this->fromC;
+//    ss<<"]}";
+   return ss.str();
+}
+                                     
diff --git a/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.h b/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f89a5e686efc4e3b0a1c901e0d93d1a25f9a9f4
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/CoordinateTransformation3D.h
@@ -0,0 +1,125 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CoordinateTransformation3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef COORDINATETRANSFORMATION3D_H
+#define COORDINATETRANSFORMATION3D_H
+
+#include <cmath>
+#include <string>
+#include <sstream>
+
+#include <basics/utilities/UbException.h>
+
+#include <PointerDefinitions.h>
+
+///////////////////////////////////////////////////////////////////////////////////////
+//! 
+//! \brief A class provides 3d coordinate transformation
+//! \details
+//! description:     x1/x2/x3 = old, x1*/x2*/x3* = new
+//!    x2      
+//!    ^             x*
+//!    |            /
+//!    |           2*
+//!    4          /
+//!    |         /
+//!    3        1*                     => new coordsys is translated by originX1=originX2=originX3=2
+//!    |       /                          new dx1=dx2=dx2=2 -> scaling by 2 in x1-,x2- und x3-direction
+//!    2      /                           FIRST rotation by alpha around "x1" axis
+//!    |       \                          THEN  rotation by beta  around "x2" axis
+//!    1         \                        THEN  rotation by gamma around "x3" axis
+//!    |           x1*
+//!    |--1--2--3--4--5------------- > x1
+//! 
+//!  Remark: It might be that the rotations around x1 and x3 axis are swapped.
+//! 
+//////////////////////////////////////////////////////////////////////////////////////
+
+class CoordinateTransformation3D
+{
+public:
+   CoordinateTransformation3D();
+   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
+   CoordinateTransformation3D(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3);
+   CoordinateTransformation3D(CoordinateTransformation3D* transformation);
+   
+   void setTransformationValues(const double& originX1, const double& originX2, const double& originX3, const double& dx1, const double& dx2, const double& dx3, const double& alpha, const double& beta, const double& gamma);
+   double getX1CoordinateOffset()  const { return this->Tx1;   }   //Translation
+   double getX2CoordinateOffset()  const { return this->Tx2;   }
+   double getX3CoordinateOffset()  const { return this->Tx3;   }
+   double getX1CoordinateScaling() const { return this->Sx1;   }	 //Scaling
+   double getX2CoordinateScaling() const { return this->Sx2;   }
+   double getX3CoordinateScaling() const { return this->Sx3;   }
+   double getRotationX1Angle()     const { return this->alpha; }
+   double getRotationX2Angle()     const { return this->beta;  }
+   double getRotationX3Angle()     const { return this->gamma; }	 //Rotation
+
+   //Achtung die Winkel passen nicht überein -siehe setTransformationValues 
+   void setRotationX1Angle(double alpha) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, alpha, this->beta, this->gamma); }
+   void setRotationX2Angle(double beta ) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, beta, this->gamma); }
+   void setRotationX3Angle(double gamma) { this->setTransformationValues(this->Tx1, this->Tx2, this->Tx3, this->Sx1, this->Sx2, this->Sx3, this->alpha, this->beta, gamma); }
+
+   void setActive(const bool& active);
+   bool isActive()          const { return this->active; }
+   bool isTransformation()  const { return this->transformation; }
+
+   double transformForwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformForwardToX1CoordinateIgnoringRotation(const double& x1) const;
+   double transformForwardToX2CoordinateIgnoringRotation(const double& x2) const;
+   double transformForwardToX3CoordinateIgnoringRotation(const double& x3) const;
+   double transformBackwardToX1Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX2Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX3Coordinate(const double& x1, const double& x2, const double& x3) const;
+   double transformBackwardToX1CoordinateIgnoringRotation(const double& x1) const;
+   double transformBackwardToX2CoordinateIgnoringRotation(const double& x2) const;
+   double transformBackwardToX3CoordinateIgnoringRotation(const double& x3) const;
+   std::string toString() const;
+
+private:
+   double Tx1, Tx2, Tx3, Sx1, Sx2, Sx3, alpha, beta, gamma;
+
+   double toX1factorX1, toX1factorX2, toX1factorX3, toX1delta;
+   double toX2factorX1, toX2factorX2, toX2factorX3, toX2delta;
+   double toX3factorX1, toX3factorX2, toX3factorX3, toX3delta;
+
+   double fromX1factorX1, fromX1factorX2, fromX1factorX3, fromX1delta;
+   double fromX2factorX1, fromX2factorX2, fromX2factorX3, fromX2delta;
+   double fromX3factorX1, fromX3factorX2, fromX3factorX3, fromX3delta;
+
+   bool   active;
+   bool   transformation;
+
+};
+
+#endif //COORDINATETRANSFORMATION3D_H
diff --git a/VirtualFluidsBasics/geometry3d/GbCuboid3D.cpp b/VirtualFluidsBasics/geometry3d/GbCuboid3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67a7d3d15ea79295fd806b393e002dedfac3c0b9
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbCuboid3D.cpp
@@ -0,0 +1,567 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbCuboid3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbCuboid3D.h>
+#include <GbSystem3D.h>
+#include <GbTriangle3D.h>
+
+#include <basics/utilities/UbMath.h>
+
+using namespace std;
+
+/*=======================================================*/
+// Konstruktor
+GbCuboid3D::GbCuboid3D() : GbObject3D()
+{
+   this->setName("cuboid");
+   this->p1 = new GbPoint3D(0.0, 0.0, 0.0);
+   this->p2 = new GbPoint3D(0.0, 0.0, 0.0);
+   this->p1->addObserver(this);
+   this->p2->addObserver(this);
+}
+/*=======================================================*/
+GbCuboid3D::GbCuboid3D(const double& x1a,const double& x2a, const double& x3a, const double& x1b,const double& x2b, const double& x3b):GbObject3D()
+{
+   this->setName("cuboid");
+   this->p1 = new GbPoint3D(x1a, x2a, x3a);
+   this->p1->addObserver(this);
+	this->p2 = new GbPoint3D(x1b, x2b, x3b);     
+   this->p2->addObserver(this);
+}
+/*=======================================================*/
+GbCuboid3D::GbCuboid3D(GbPoint3D* p1, GbPoint3D* p2) : GbObject3D()
+{
+   this->setName("cuboid");
+	if(!p1 || !p2) throw UbException(UB_EXARGS,"one point ==NULL");
+   this->p1 = p1;
+   this->p1->addObserver(this);
+   this->p2 = p2;
+   this->p2->addObserver(this);
+}
+/*=======================================================*/
+GbCuboid3D::GbCuboid3D(GbCuboid3D* cuboid) : GbObject3D()
+{
+   this->setName("cuboid");
+   if(!cuboid->getPoint1() || !cuboid->getPoint2()) throw UbException(UB_EXARGS,"cuboid ==NULL");
+   this->p1 = cuboid->getPoint1()->clone();
+   this->p1->addObserver(this);
+   this->p2 = cuboid->getPoint2()->clone();
+   this->p2->addObserver(this);
+}
+/*=======================================================*/
+// Destruktor
+GbCuboid3D::~GbCuboid3D()
+{
+   //cout<<"~GbCuboid3D()"<<endl;
+   if(this->p1) this->p1->removeObserver(this);
+   if(this->p2) this->p2->removeObserver(this);
+}
+/*=======================================================*/
+void GbCuboid3D::finalize() 
+{ 
+   if(this->p1) 
+   {
+      this->p1->removeObserver(this);
+      this->p1->finalize();
+      delete this->p1; 
+      this->p1=NULL;
+   } 
+   if(this->p2)
+   {
+      this->p2->removeObserver(this);
+      this->p2->finalize();
+      delete this->p2; 
+      this->p2=NULL;
+   }
+}
+/*=======================================================*/
+void GbCuboid3D::setPoint1(GbPoint3D* point1)
+{ 
+   if(this->p1) this->p1->removeObserver(this);
+   this->p1 = point1;  
+   this->p1->addObserver(this);
+
+   this->notifyObserversObjectChanged();
+}
+/*=======================================================*/
+void GbCuboid3D::setPoint2(GbPoint3D* point2)
+{ 
+   if(this->p2) this->p2->removeObserver(this);
+   this->p2 = point2;  
+   this->p2->addObserver(this);
+
+   this->notifyObserversObjectChanged();
+}
+/*=======================================================*/
+void GbCuboid3D::setPoints(GbPoint3D* point1, GbPoint3D* point2)
+{ 
+   if(this->p1) this->p1->removeObserver(this);
+   if(this->p2) this->p2->removeObserver(this);
+
+   this->p1 = point1; 
+   this->p2 = point2;
+
+   this->p1->addObserver(this);
+   this->p2->addObserver(this);
+
+   this->notifyObserversObjectChanged();
+}
+/*=======================================================*/
+void GbCuboid3D::setCenterCoordinates(const double& x1, const double& x2, const double& x3) 
+{
+   this->translate(x1-getX1Centroid(), x2-getX2Centroid(), x3-getX3Centroid() );
+}
+/*=======================================================*/
+double GbCuboid3D::getX1Centroid()
+{
+   return (0.5*(p1->x1 + p2->x1)); 
+}
+/*=======================================================*/
+double GbCuboid3D::getX1Minimum()   
+{
+	return (this->p1->x1 < this->p2->x1 ? this->p1->x1 : this->p2->x1);
+}
+/*=======================================================*/
+double GbCuboid3D::getX1Maximum()   
+{
+	return (this->p1->x1 > this->p2->x1 ? this->p1->x1 : this->p2->x1);
+}
+/*=======================================================*/
+double GbCuboid3D::getX2Centroid()
+{
+   return (0.5*(p1->x2 + p2->x2)); 
+}
+/*=======================================================*/
+double GbCuboid3D::getX2Minimum()   
+{
+	return (this->p1->x2 < this->p2->x2 ? this->p1->x2 : this->p2->x2);
+}	
+/*=======================================================*/
+double GbCuboid3D::getX2Maximum()   
+{
+	return ( this->p1->x2 > this->p2->x2 ? this->p1->x2 : this->p2->x2);
+}
+/*=======================================================*/
+double GbCuboid3D::getX3Centroid()
+{
+   return (0.5*(p1->x3 + p2->x3)); 
+}
+/*=======================================================*/
+double GbCuboid3D::getX3Minimum()   
+{	
+	return (this->p1->x3 < this->p2->x3 ? this->p1->x3 : this->p2->x3);
+}	
+/*=======================================================*/
+double GbCuboid3D::getX3Maximum()   
+{
+	return (this->p1->x3 > this->p2->x3 ? this->p1->x3 : this->p2->x3);
+}
+/*=======================================================*/
+double GbCuboid3D::getLengthX1() 
+{ 
+   return (this->getX1Maximum() - this->getX1Minimum() ); 
+}
+/*=======================================================*/
+double GbCuboid3D::getLengthX2() 
+{ 
+   return (this->getX2Maximum() - this->getX2Minimum());  
+}
+/*=======================================================*/
+double GbCuboid3D::getLengthX3() 
+{ 
+   return (this->getX3Maximum() - this->getX3Minimum()); 
+}
+/*=======================================================*/
+bool GbCuboid3D::isPointInGbObject3D(const double& x1p, const double& x2p, const double& x3p)
+{
+   //true, wenn 'in Object' oder 'auf Boundary'!
+   if     (UbMath::less(x1p,this->getX1Minimum()))    return false;
+   else if(UbMath::less(x2p,this->getX2Minimum()))    return false;
+   else if(UbMath::less(x3p,this->getX3Minimum()))    return false;
+   else if(UbMath::greater(x1p,this->getX1Maximum())) return false;
+   else if(UbMath::greater(x2p,this->getX2Maximum())) return false;
+   else if(UbMath::greater(x3p,this->getX3Maximum())) return false;
+
+   return true;
+}
+/*=======================================================*/
+bool GbCuboid3D::isPointInGbObject3D(const double& x1p, const double& x2p, const double& x3p, bool& pointIsOnBoundary)
+{
+   pointIsOnBoundary = false;
+   
+   //true, wenn 'in Object' oder 'auf Boundary'!
+   if     (UbMath::less(x1p,this->getX1Minimum()))    return false;
+	else if(UbMath::less(x2p,this->getX2Minimum()))    return false;
+	else if(UbMath::less(x3p,this->getX3Minimum()))    return false;
+	else if(UbMath::greater(x1p,this->getX1Maximum())) return false;
+	else if(UbMath::greater(x2p,this->getX2Maximum())) return false;
+	else if(UbMath::greater(x3p,this->getX3Maximum())) return false;
+	
+   if     (UbMath::equal(x1p,this->getX1Minimum())) pointIsOnBoundary = true;
+   else if(UbMath::equal(x2p,this->getX2Minimum())) pointIsOnBoundary = true;
+   else if(UbMath::equal(x3p,this->getX3Minimum())) pointIsOnBoundary = true;
+   else if(UbMath::equal(x1p,this->getX1Maximum())) pointIsOnBoundary = true;
+   else if(UbMath::equal(x2p,this->getX2Maximum())) pointIsOnBoundary = true;
+   else if(UbMath::equal(x3p,this->getX3Maximum())) pointIsOnBoundary = true;
+   
+   return true;
+}
+/*=======================================================*/
+bool GbCuboid3D::isCellInsideGbObject3D(const double& x1p1,const double& x2p1,const double& x3p1,const double& x1p2,const double& x2p2,const double& x3p2)
+{
+   if     ( UbMath::less   (x1p1, this->getX1Minimum() ) ) return false;
+   else if( UbMath::less   (x2p1, this->getX2Minimum() ) ) return false;
+   else if( UbMath::less   (x3p1, this->getX3Minimum() ) ) return false;
+   else if( UbMath::greater(x1p2, this->getX1Maximum() ) ) return false;
+   else if( UbMath::greater(x2p2, this->getX2Maximum() ) ) return false;
+   else if( UbMath::greater(x3p2, this->getX3Maximum() ) ) return false;
+
+   return true;
+}
+/*=======================================================*/
+bool GbCuboid3D::isCellCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b)
+//Merksatz: cell oder deren Volumen schneidet oder beinhaltet komplette oder Teile der CuboidUmrandung
+//returns true:
+//  - cell cuts  cuboid3D
+//  - cell boxes cuboid3D
+//returns false:
+//  - cell completely inside cuboid3D ( = cuboid3D boxes cell)
+//  - cell und cuboid3D haben kein gemeinsames Volumen
+{
+   //erstmal die dumm Loesung
+   if(   !this->isCellInsideGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b) 
+      && this->isCellInsideOrCuttingGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b) )
+   {
+      return true;
+   }
+
+   return false;
+
+   //GbCuboid3D* cube = GbSystem3D::clipRectangle3D(*this->p1, *this->p2, x1a,x2a,x3a,x1b,x2b,x3b);
+   //if(cube) 
+   //{
+   //   cube->finalize();
+   //   delete cube;
+   //   return true;
+   //}
+
+   //return false;
+}
+/*=======================================================*/
+bool GbCuboid3D::isCellInsideOrCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b)
+//returns true:
+//  - cell completely inside cuboid3D ( = cuboid3D boxes cell)
+//  - cell cuts  cuboid3D
+//  - cell boxes cuboid3D
+//returns false:
+//  - cell und cuboid3D haben kein gemeinsames Volumen
+{
+    //simpler check, da unser GbCuboid3D ein AABB is:
+   //  anfA        midA         endA             anfB    midB    endB
+   //   |            x<-- dxA -->|                 |<-dxB->x       |
+   //                |<----------------- T --------------->|
+   //ist |T| <= dxA + dxB -> overlap!
+
+   if(     UbMath::lessEqual(  std::fabs( this->getX1Centroid() - 0.5*(x1b+x1a)      /*Tx1*/      )
+                             , 0.5*( this->getLengthX1()        + std::fabs(x1b-x1a) /*dx1A+dx1B*/) )
+
+        && UbMath::lessEqual(  std::fabs( this->getX2Centroid() - 0.5*(x2b+x2a)      /*Tx2*/      )
+                             , 0.5*( this->getLengthX2()        + std::fabs(x2b-x2a) /*dx2A+dx2B*/) )
+
+        && UbMath::lessEqual(  std::fabs( this->getX3Centroid() - 0.5*(x3b+x3a)      /*Tx3*/      )
+                             , 0.5*( this->getLengthX3()        + std::fabs(x3b-x3a) /*dx3A+dx3B*/) ) )
+    {
+       return true;
+    }
+
+    return false;
+
+    // if(   this->isCellInsideGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b)
+   //    || this->isCellCuttingGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b) ) return true;
+   //
+   //return false;
+}
+/*=======================================================*/
+vector<GbTriangle3D*> GbCuboid3D::getSurfaceTriangleSet()
+{
+   vector<GbTriangle3D*> triangles;
+   GbPoint3D p1(getX1Minimum(),getX2Minimum(),getX3Minimum());
+   GbPoint3D p2(getX1Maximum(),getX2Minimum(),getX3Minimum());
+   GbPoint3D p3(getX1Maximum(),getX2Maximum(),getX3Minimum());
+   GbPoint3D p4(getX1Minimum(),getX2Maximum(),getX3Minimum());
+   GbPoint3D p5(getX1Minimum(),getX2Minimum(),getX3Maximum());
+   GbPoint3D p6(getX1Maximum(),getX2Minimum(),getX3Maximum());
+   GbPoint3D p7(getX1Maximum(),getX2Maximum(),getX3Maximum());
+   GbPoint3D p8(getX1Minimum(),getX2Maximum(),getX3Maximum());
+
+   GbPoint3D pUnten(getX1Centroid(),getX2Centroid(),getX3Minimum());
+   GbPoint3D pOben(getX1Centroid(),getX2Centroid(),getX3Maximum());
+   GbPoint3D pLinks(getX1Minimum(), getX2Centroid(),getX3Centroid());
+   GbPoint3D pRechts(getX1Maximum(), getX2Centroid(),getX3Centroid());
+   GbPoint3D pVorne(getX1Centroid(),getX2Minimum(),getX3Centroid());
+   GbPoint3D pHinten(getX1Centroid(),getX2Maximum(),getX3Centroid());
+
+   //"unten"
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p2),new GbPoint3D(pUnten),new GbPoint3D(p3)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p2),new GbPoint3D(p1),new GbPoint3D(pUnten)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p3),new GbPoint3D(pUnten),new GbPoint3D(p4)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p1),new GbPoint3D(p4),new GbPoint3D(pUnten)));
+   //"oben"
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p5),new GbPoint3D(p6),new GbPoint3D(pOben)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p6),new GbPoint3D(p7),new GbPoint3D(pOben)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p5),new GbPoint3D(pOben),new GbPoint3D(p8)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pOben),new GbPoint3D(p7),new GbPoint3D(p8)));
+   //"links"
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p4),new GbPoint3D(p1),new GbPoint3D(pLinks)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p4),new GbPoint3D(pLinks),new GbPoint3D(p8)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p8),new GbPoint3D(pLinks),new GbPoint3D(p5)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pLinks),new GbPoint3D(p1),new GbPoint3D(p5)));
+   //"rechts"                                                               
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p2),new GbPoint3D(p3),new GbPoint3D(pRechts)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pRechts),new GbPoint3D(p3),new GbPoint3D(p7)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p2),new GbPoint3D(pRechts),new GbPoint3D(p6)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pRechts),new GbPoint3D(p7),new GbPoint3D(p6)));
+   //"hinten"                                                                       
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p3),new GbPoint3D(p4),new GbPoint3D(pHinten)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p3),new GbPoint3D(pHinten),new GbPoint3D(p7)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p7),new GbPoint3D(pHinten),new GbPoint3D(p8)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pHinten),new GbPoint3D(p4),new GbPoint3D(p8)));
+   //"vorne"                                                                        
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p1),new GbPoint3D(p2),new GbPoint3D(pVorne)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pVorne),new GbPoint3D(p2),new GbPoint3D(p6)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p1),new GbPoint3D(pVorne),new GbPoint3D(p5)));
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(pVorne),new GbPoint3D(p6),new GbPoint3D(p5)));
+   return triangles;
+}
+/*=======================================================*/
+void GbCuboid3D::addSurfaceTriangleSet(vector<UbTupleFloat3>& nodes, vector<UbTupleInt3>& triangles)
+{
+   /*0*/nodes.push_back( makeUbTuple((float)getX1Minimum(),(float)getX2Minimum(),(float)getX3Minimum()));
+   /*1*/nodes.push_back( makeUbTuple((float)getX1Maximum(),(float)getX2Minimum(),(float)getX3Minimum()));
+   /*2*/nodes.push_back( makeUbTuple((float)getX1Maximum(),(float)getX2Maximum(),(float)getX3Minimum()));
+   /*3*/nodes.push_back( makeUbTuple((float)getX1Minimum(),(float)getX2Maximum(),(float)getX3Minimum()));
+   
+   /*4*/nodes.push_back( makeUbTuple((float)getX1Minimum(),(float)getX2Minimum(),(float)getX3Maximum()));
+   /*5*/nodes.push_back( makeUbTuple((float)getX1Maximum(),(float)getX2Minimum(),(float)getX3Maximum()));
+   /*6*/nodes.push_back( makeUbTuple((float)getX1Maximum(),(float)getX2Maximum(),(float)getX3Maximum()));
+   /*7*/nodes.push_back( makeUbTuple((float)getX1Minimum(),(float)getX2Maximum(),(float)getX3Maximum()));
+
+   //"unten"
+   triangles.push_back( makeUbTuple( 0, 1, 2) );
+   triangles.push_back( makeUbTuple( 0, 2, 3) );
+   //"oben"
+   triangles.push_back( makeUbTuple( 4, 5, 6) );
+   triangles.push_back( makeUbTuple( 4, 6, 7) );
+   //"links"
+   triangles.push_back( makeUbTuple( 0, 3, 7) );
+   triangles.push_back( makeUbTuple( 0, 7, 4) );
+   //"rechts"                                                               
+   triangles.push_back( makeUbTuple( 1, 2, 6) );
+   triangles.push_back( makeUbTuple( 1, 6, 5) );
+   //"hinten"                                                                       
+   triangles.push_back( makeUbTuple( 3, 2, 7) );  
+   triangles.push_back( makeUbTuple( 2, 7, 6) );
+   //"vorne"                                                                        
+   triangles.push_back( makeUbTuple( 0, 1, 5) );
+   triangles.push_back( makeUbTuple( 0, 5, 4) );
+}
+/*=======================================================*/
+string GbCuboid3D::toString() 
+{
+   stringstream ss;
+   ss<<"GbCuboid3D[";
+   ss<<"p1="<<this->p1->toString();
+   ss<<", p2="<<this->p2->toString();
+   ss<<"]";
+   return ss.str();
+}
+/*=======================================================*/
+GbPoint3D* GbCuboid3D::calculateInterSectionPoint3D(GbPoint3D& point1, GbPoint3D& point2)
+{
+   throw UbException(UB_EXARGS,"not correct implemented");
+}
+/*=======================================================*/
+GbLine3D* GbCuboid3D::createClippedLine3D(GbPoint3D& point1, GbPoint3D& point2)
+{
+   return GbSystem3D::createClipLine3D(point1, point2,
+                                       p1->getX1Coordinate(),p1->getX2Coordinate(),p1->getX3Coordinate(),
+                                       p2->getX1Coordinate(),p2->getX2Coordinate(),p2->getX3Coordinate() );
+}
+/*==========================================================*/
+void GbCuboid3D::objectChanged(UbObservable* changedObject)
+{
+   GbPoint3D* point = dynamic_cast<GbPoint3D*>(changedObject);
+   if(!point || (this->p1!=point && this->p2!=point)) return;
+
+   this->notifyObserversObjectChanged();
+}
+/*==========================================================*/
+void GbCuboid3D::objectWillBeDeleted(UbObservable* objectForDeletion)
+{
+   if(this->p1)
+   {
+      UbObservable* observedObj = dynamic_cast<UbObservable*>(this->p1);
+      if(objectForDeletion == observedObj) { this->p1 = NULL; }
+   }
+   if(this->p2)
+   {
+      UbObservable* observedObj = dynamic_cast<UbObservable*>(this->p2);
+      if(objectForDeletion == observedObj) { this->p2 = NULL; }
+   }
+   //ACHTUNG: eigentlich muessten in allen methoden von GbLine if abfragen fuer NULL pointer hin... toDo
+}
+/*=======================================================*/
+void GbCuboid3D::translate(const double& tx1, const double& tx2, const double& tx3)
+{  
+   this->p1->translate(tx1, tx2, tx3);
+   this->p2->translate(tx1, tx2, tx3);
+   this->notifyObserversObjectChanged();
+}
+/*=======================================================*/
+void GbCuboid3D::scale(const double& sx1, const double& sx2, const double& sx3)
+{  
+   double lenX1 = this->getLengthX1();
+   double lenX2 = this->getLengthX2();
+   double lenX3 = this->getLengthX3();
+
+   double deltaX1 = lenX1*sx1 - lenX1;
+   double deltaX2 = lenX2*sx2 - lenX2;
+   double deltaX3 = lenX3*sx3 - lenX3;
+
+   double p1X1 = this->p1->getX1Coordinate();
+   double p1X2 = this->p1->getX2Coordinate();
+   double p1X3 = this->p1->getX3Coordinate();
+
+   double p2X1 = this->p2->getX1Coordinate();
+   double p2X2 = this->p2->getX2Coordinate();
+   double p2X3 = this->p2->getX3Coordinate();
+
+   this->p1->setCoordinates(p1X1 - 0.5*deltaX1
+                           ,p1X2 - 0.5*deltaX2
+                           ,p1X3 - 0.5*deltaX3);
+
+   this->p2->setCoordinates(p2X1 + 0.5*deltaX1
+                           ,p2X2 + 0.5*deltaX2
+                           ,p2X3 + 0.5*deltaX3);
+}
+/*==========================================================*/
+double GbCuboid3D::getCellVolumeInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b)
+{
+   if( this->isCellInsideGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b) )       return 1.0*(x1b-x1a)*(x2b-x2a)*(x3b-x3a);
+   if( !(this->isCellCuttingGbObject3D(x1a,x2a,x3a,x1b,x2b,x3b)) )   return 0.0;
+
+   GbCuboid3D* cube = GbSystem3D::clipRectangle3D(*this->p1, *this->p2, x1a,x2a,x3a,x1b,x2b,x3b);
+
+   if(cube) 
+   {
+      double eps;
+      eps  = (cube->getLengthX1())*(cube->getLengthX2())*(cube->getLengthX3());
+      cube->finalize();
+      delete cube;
+      return eps;
+   }
+   return 0.0;
+}
+/*==========================================================*/
+double GbCuboid3D::getIntersectionRaytraceFactor(const double& x1, const double& x2, const double& x3, const double& rx1, const double& rx2, const double& rx3)
+{
+   double minB[3]   = { this->getX1Minimum(), this->getX2Minimum(), this->getX3Minimum() };
+   double maxB[3]   = { this->getX1Maximum(), this->getX2Maximum(), this->getX3Maximum() };
+   double origin[3] = { x1,  x2,  x3  }; //point
+   double dir[3]    = { rx1, rx2, rx3 }; //ray 
+
+   bool inside = true;
+   char quadrant[3];
+   int  whichPlane;
+   double maxT[3];
+   double candidatePlane[3];
+
+   /* Find candidate planes; this loop can be avoided if
+   rays cast all from the eye(assume perpsective view) */
+   for(int i=0; i<3; i++)
+   {
+      if(origin[i] < minB[i])
+      {
+         quadrant[i] = 1/*LEFT*/;
+         candidatePlane[i] = minB[i];
+         inside = false;
+      }
+      else if(origin[i] > maxB[i]) 
+      {
+         quadrant[i] = 0/*RIGHT*/;
+         candidatePlane[i] = maxB[i];
+         inside = false;
+      }
+      else	
+      {
+         quadrant[i] = 2/*MIDDLE*/;
+      }
+   }
+   /* Ray origin inside bounding box */
+   if(inside)
+   {
+      //throw UbException(UB_EXARGS,"not done");
+      return 0.0;
+   }
+
+   /* Calculate T distances to candidate planes */
+   for(int i=0; i<3; i++)
+   {
+      if( quadrant[i]!=2/*MIDDLE*/ && fabs(dir[i])>1.E-10 )
+      {
+         maxT[i] = (candidatePlane[i]-origin[i])/dir[i];
+      }
+      else maxT[i] = -1.0;
+   }
+
+   /* Get largest of the maxT's for final choice of intersection */
+   whichPlane = 0;
+   for(int i=1; i<3; i++)
+      if (maxT[whichPlane] < maxT[i])
+            whichPlane = i;
+   
+   /* Check final candidate actually inside box */
+   if(maxT[whichPlane]< -1.E-10) return -1.0;
+   double dummy;
+   for(int i= 0; i<3; i++)
+   {
+      if( whichPlane!= i) 
+      {
+         dummy = origin[i] + maxT[whichPlane]*dir[i];
+         if(dummy < minB[i] || dummy > maxB[i])
+            return -1.0;
+      } 
+   }
+
+   return maxT[whichPlane] ;				/* ray hits box */
+}	
+
diff --git a/VirtualFluidsBasics/geometry3d/GbCuboid3D.h b/VirtualFluidsBasics/geometry3d/GbCuboid3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..db7e0245dbd7b6da344bd26d07a93f8e58c3282d
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbCuboid3D.h
@@ -0,0 +1,145 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbCuboid3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBCUBOID3D_H
+#define GBCUBOID3D_H
+
+#include <vector>
+#include <cmath>
+
+#include <GbPoint3D.h>
+#include <basics/utilities/UbObserver.h>
+#include <basics/utilities/UbMath.h>
+
+class GbLine3D;
+class GbObject3DCreator;
+
+#include <PointerDefinitions.h>
+class GbCuboid3D;
+typedef SPtr<GbCuboid3D> GbCuboid3DPtr;
+
+//! \brief This Class provides basic 3D box objects.
+class GbCuboid3D : public GbObject3D, public UbObserver
+{
+public:              
+   GbCuboid3D();
+   GbCuboid3D(const double& minX1,const double& minX2, const double& minX3, const double& maxX1,const double& maxX2, const double& maxX3);
+   GbCuboid3D(GbPoint3D *p1, GbPoint3D *p2);
+   GbCuboid3D(GbCuboid3D *cuboid);
+   ~GbCuboid3D();   
+
+   GbCuboid3D* clone()    { return new GbCuboid3D(this); }
+   void finalize();
+
+   GbPoint3D* getPoint1() { return this->p1; }
+   GbPoint3D* getPoint2() { return this->p2; }
+
+   void setPoint1(GbPoint3D* point1);
+   void setPoint2(GbPoint3D* point2);
+   void setPoints(GbPoint3D* point1, GbPoint3D* point2);
+
+   double getX1Centroid();
+   double getX1Minimum();
+   double getX1Maximum();
+   double getX2Centroid();
+   double getX2Minimum();
+   double getX2Maximum();
+   double getX3Centroid();
+   double getX3Minimum();
+   double getX3Maximum();
+   void setCenterCoordinates(const double& x1, const double& x2, const double& x3);
+
+   void translate(const double& x1, const double& x2, const double& x3);
+   void rotate(const double& rx1, const double& rx2, const double& rx3) {}
+   void scale(const double& sx1, const double& sx2, const double& sx3);
+
+   double getLengthX1();
+   double getLengthX2();
+   double getLengthX3();
+
+   bool isPointInGbObject3D(const double& x1p, const double& x2p, const double& x3p, bool& pointIsOnBoundary);
+   bool isPointInGbObject3D(const double& x1p, const double& x2p, const double& x3p); 
+   bool isCellInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   bool isCellCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   bool isCellInsideOrCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   double getCellVolumeInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+
+   GbPoint3D*  calculateInterSectionPoint3D(GbPoint3D& point1, GbPoint3D &point2);
+   //GbCuboid3D* createClippedRectangle3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   GbLine3D*   createClippedLine3D(GbPoint3D& point1, GbPoint3D& point2);
+
+   std::vector<GbTriangle3D*> getSurfaceTriangleSet();
+   void addSurfaceTriangleSet(std::vector<UbTupleFloat3>& nodes, std::vector<UbTupleInt3>& triangles);
+
+   bool hasRaytracing() { return true; }
+   /*|r| must be 1! einheitsvector!!*/
+   double getIntersectionRaytraceFactor(const double& x1, const double& x2, const double& x3, const double& rx1, const double& rx2, const double& rx3);
+
+
+   double getDistance(GbPoint3D* p)
+   {
+      return this->getDistance( p->getX1Coordinate(), p->getX2Coordinate(), p->getX3Coordinate() );
+   } 
+   double getDistance(const double& x1p, const double& x2p, const double& x3p)
+   {
+      throw UbException( UB_EXARGS, "not implemented" );
+
+      // falls punkt innerhalt ist: minimalen abstand ausrechnen
+      if( this->isPointInGbObject3D(x1p,x2p,x3p) )
+      {
+         double x1Dist = UbMath::min( std::abs(x1p-this->getX1Minimum()),std::abs(x1p-this->getX1Maximum()) );
+         double x2Dist = UbMath::min( std::abs(x2p-this->getX2Minimum()),std::abs(x2p-this->getX2Maximum()) );
+         double x3Dist = UbMath::min( std::abs(x3p-this->getX3Minimum()),std::abs(x3p-this->getX3Maximum()) );
+
+         return UbMath::min( x1Dist, x2Dist, x3Dist );
+      }
+      else
+      {
+
+      }
+   }
+
+   std::string toString();
+
+   //virtuelle Methoden von UbObserver
+   void objectChanged(UbObservable* changedObject);
+   void objectWillBeDeleted(UbObservable* objectForDeletion);
+
+
+   using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
+
+protected:
+   GbPoint3D* p1;
+   GbPoint3D* p2;
+};
+
+#endif   
diff --git a/VirtualFluidsBasics/geometry3d/GbLine3D.cpp b/VirtualFluidsBasics/geometry3d/GbLine3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4626eaccbf9c5056ddb0136282aedd9e32d7bd5b
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbLine3D.cpp
@@ -0,0 +1,246 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbLine3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbLine3D.h>
+#include <GbSystem3D.h>
+#include <GbCuboid3D.h>
+#include <GbTriangle3D.h>
+
+using namespace std;
+
+/*=======================================================*/
+GbLine3D::GbLine3D()
+{
+   p1     = NULL;
+   p2     = NULL;                       
+   length = 0.0;
+}
+/*=======================================================*/
+GbLine3D::GbLine3D(GbPoint3D* point1, GbPoint3D* point2)
+{
+   this->p1 = point1;
+   this->p2 = point2;
+   this->p1->addObserver(this);
+   this->p2->addObserver(this);
+   this->calculateValues();
+}
+/*=======================================================*/
+GbLine3D::GbLine3D(GbLine3D* line)
+{
+   this->p1 = line->p1->clone();            
+   this->p2 = line->p2->clone();
+   this->p1->addObserver(this);
+   this->p2->addObserver(this);
+   this->calculateValues();
+}
+/*=======================================================*/
+GbLine3D::~GbLine3D() 
+{
+   if(this->p1) this->p1->removeObserver(this);
+   if(this->p2) this->p2->removeObserver(this);
+}
+/*=======================================================*/
+void GbLine3D::finalize() 
+{
+   if(this->p1) 
+   {
+      this->p1->removeObserver(this);
+      this->p1->finalize();
+      delete this->p1;
+      this->p1 = NULL;
+   }
+   if(this->p2)
+   {
+      this->p2->removeObserver(this);
+      this->p2->finalize();
+      delete this->p2;
+      this->p2 = NULL;
+   }
+}
+/*=======================================================*/
+vector<GbTriangle3D*> GbLine3D::getSurfaceTriangleSet()
+{
+   vector<GbTriangle3D*> triangles;
+   GbPoint3D p1(getX1Minimum(),getX2Minimum(),getX3Minimum());
+   GbPoint3D p2(getX1Centroid(),getX2Centroid(),getX3Centroid());
+   GbPoint3D p3(getX1Maximum(),getX2Maximum(),getX3Maximum());
+ 
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(p1),new GbPoint3D(p2),new GbPoint3D(p3)));
+   
+   return triangles;
+}
+/*=======================================================*/
+void GbLine3D::setPoint1(GbPoint3D* point1)
+{ 
+   if(this->p1) this->p1->removeObserver(this);
+   this->p1 = point1;  
+   this->p1->addObserver(this);
+
+   if(this->p1 && this->p2) this->calculateValues(); 
+}
+/*=======================================================*/
+void GbLine3D::setPoint2(GbPoint3D* point2)
+{ 
+   if(this->p2) this->p2->removeObserver(this);
+   this->p2 = point2;  
+   this->p2->addObserver(this);
+
+   if(this->p1 && this->p2) this->calculateValues(); 
+}
+/*=======================================================*/
+void GbLine3D::setPoints(GbPoint3D* point1, GbPoint3D* point2)
+{ 
+   if(this->p1) this->p1->removeObserver(this);
+   if(this->p2) this->p2->removeObserver(this);
+
+   this->p1 = point1; 
+   this->p2 = point2;
+
+   this->p1->addObserver(this);
+   this->p2->addObserver(this);
+
+   this->calculateValues(); 
+}
+/*=======================================================*/
+string GbLine3D::toString()
+{
+   stringstream ss;
+   ss<<"GbLine3D[p1=";
+   ss<<this->p1->toString()<<",p2="<<this->p2->toString()<<",l="<<this->getLength()<<"]";
+   return(ss.str());
+}
+/*=======================================================*/
+GbPoint3D* GbLine3D::calculateIntersectionPoint3D(GbLine3D* line)
+{
+   throw UbException(UB_EXARGS," not implemented");
+   //return(GbSystem::calculateIntersectionPoint3D(*this->p1, *this->p2, *line->p1, *line->p2));
+}
+/*======================================================================*/
+GbLine3D* GbLine3D::createClippedLine3D(GbCuboid3D* cuboid)
+{
+   return GbSystem3D::createClipLine3D(*this->p1, *this->p2, cuboid->getPoint1()->x1, cuboid->getPoint1()->x2, cuboid->getPoint1()->x3, cuboid->getPoint2()->x1, cuboid->getPoint2()->x2, cuboid->getPoint2()->x3);
+}                           
+/*======================================================================*/
+GbLine3D* GbLine3D::createClippedLine3D(GbPoint3D* pA, GbPoint3D* pE)
+{
+   return GbSystem3D::createClipLine3D(*this->p1, *this->p2, pA->x1, pA->x2, pA->x3, pE->x1, pE->x2, pE->x3);
+}
+/*======================================================================*/
+double GbLine3D::getDistance(const GbPoint3D& point)
+{
+   return this->getDistance(point.x1,point.x2,point.x3);
+}
+/*======================================================================*/
+double GbLine3D::getDistance(const double& x1,const double& x2,const double& x3)
+{
+   double dx1 = this->p2->x1 - this->p1->x1;
+   double dx2 = this->p2->x2 - this->p1->x2;
+   double dx3 = this->p2->x3 - this->p1->x3;
+
+   //double vec[3];
+   double a0 = x1 - p1->x1;
+   double a1 = x2 - p1->x2;
+   double a2 = x3 - p1->x3;
+
+   double kreuzProd0 = a1 * dx3 - a2 * dx2;
+   double kreuzProd1 = a2 * dx1 - a0 * dx3;
+   double kreuzProd2 = a0 * dx2 - a1 * dx1;
+
+   return (std::sqrt(kreuzProd0*kreuzProd0+kreuzProd1*kreuzProd1+kreuzProd2*kreuzProd2))/length;
+}
+/*=======================================================*/
+void GbLine3D::calculateValues()
+{
+   double dx1 = this->p2->x1 - this->p1->x1;
+   double dx2 = this->p2->x2 - this->p1->x2;
+   double dx3 = this->p2->x3 - this->p1->x3;
+   this->length = std::sqrt(dx1*dx1+dx2*dx2+dx3*dx3);
+}
+/*==========================================================*/
+void GbLine3D::objectChanged(UbObservable* changedObject)
+{
+   GbPoint3D* point = dynamic_cast<GbPoint3D*>(changedObject);
+   if(!point || (this->p1!=point && this->p2!=point)) return;
+
+   this->calculateValues();
+}
+/*==========================================================*/
+void GbLine3D::objectWillBeDeleted(UbObservable* objectForDeletion)
+{
+   if(this->p1)
+   {
+      UbObservable* observedObj = dynamic_cast<UbObservable*>(this->p1);
+      if(objectForDeletion == observedObj) { this->p1 = NULL; length = 0.0; }
+   }
+   if(this->p2)
+   {
+      UbObservable* observedObj = dynamic_cast<UbObservable*>(this->p2);
+      if(objectForDeletion == observedObj) { this->p2 = NULL; length = 0.0; }
+   }
+   //ACHTUNG: eigentlich muessten in allen methoden von GbLine if abfragen fuer NULL pointer hin... toDo
+}
+/*==========================================================*/
+void GbLine3D::scale(const double& sx1, const double& sx2, const double& sx3)
+{  
+   double p1X1 = this->p1->getX1Coordinate();
+   double p1X2 = this->p1->getX2Coordinate();
+   double p1X3 = this->p1->getX3Coordinate();
+
+   double p2X1 = this->p2->getX1Coordinate();
+   double p2X2 = this->p2->getX2Coordinate();
+   double p2X3 = this->p2->getX3Coordinate();
+
+   double lenX1 = fabs( p1X1 - p2X1 );
+   double lenX2 = fabs( p1X2 - p2X2 );
+   double lenX3 = fabs( p1X3 - p2X3 );
+
+   double deltaX1 = lenX1*sx1 - lenX1;
+   double deltaX2 = lenX2*sx2 - lenX2;
+   double deltaX3 = lenX3*sx3 - lenX3;
+
+   if(p1X1<p2X1) { p1X1 -=  0.5*deltaX1;   p2X1 +=  0.5*deltaX1; }
+   else          { p1X1 +=  0.5*deltaX1;   p2X1 -=  0.5*deltaX1; }
+   if(p1X2<p2X2) { p1X2 -=  0.5*deltaX2;   p2X2 +=  0.5*deltaX2; }
+   else          { p1X2 +=  0.5*deltaX2;   p2X2 -=  0.5*deltaX2; }
+   if(p1X3<p2X3) { p1X3 -=  0.5*deltaX3;   p2X3 +=  0.5*deltaX3; }
+   else          { p1X3 +=  0.5*deltaX3;   p2X3 -=  0.5*deltaX3; }
+
+   this->p1->setCoordinates(p1X1,p1X2,p1X3);
+   this->p2->setCoordinates(p2X1,p2X2,p2X3);
+}
+/*=======================================================*/
+void GbLine3D::translate(const double& tx1, const double& tx2, const double& tx3)
+{  
+   this->p1->translate(tx1, tx2, tx3);
+   this->p2->translate(tx1, tx2, tx3);
+   //this->notifyObserversObjectChanged();
+}
diff --git a/VirtualFluidsBasics/geometry3d/GbLine3D.h b/VirtualFluidsBasics/geometry3d/GbLine3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..69d6de96d3516d89a0faabcd47ef62d4a30a48e9
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbLine3D.h
@@ -0,0 +1,135 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbLine3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBLINE3D_H
+#define GBLINE3D_H
+
+#include <sstream>
+#include <cmath>
+          
+#include <basics/utilities/UbObserver.h>
+
+#include <GbObject3D.h>
+#include <GbPoint3D.h>
+
+class GbCuboid3D;
+
+#include <PointerDefinitions.h>
+
+//////////////////////////////////////////////////////////////////////////
+//! 
+//!  \class GbLine3D
+//! 
+//! \brief This Class provides basic 3D line objects.
+//! \details The describing points are observed by 3D line objects.
+//!
+//////////////////////////////////////////////////////////////////////////
+
+class GbLine3D	: public GbObject3D , public UbObserver
+{
+public:
+   GbLine3D();
+	GbLine3D(GbPoint3D* point1, GbPoint3D* point2);
+	GbLine3D(GbLine3D* line);
+   ~GbLine3D(); 
+
+   GbLine3D* clone() { return new GbLine3D(this); }
+   void finalize();
+
+   void setPoint1(GbPoint3D* point1);
+   void setPoint2(GbPoint3D* point2);
+   void setPoints(GbPoint3D* point1, GbPoint3D* point2);
+
+   void deletePoint1() { if(this->p1) {this->p1->removeObserver(this); delete this->p1; this->p1=NULL;} }
+   void deletePoint2() { if(this->p2) {this->p2->removeObserver(this); delete this->p2; this->p2=NULL;} }
+   void deletePoints() { this->deletePoint1(); this->deletePoint2(); }
+
+   GbPoint3D* getPoint1() { return this->p1; }
+   GbPoint3D* getPoint2() { return this->p2; }    
+   
+   double getLength()     { return(this->length); }
+	
+   double getX1Centroid() { return((this->p1->x1+this->p2->x1)*0.5);}
+   double getX2Centroid() { return((this->p1->x2+this->p2->x2)*0.5); };
+   double getX3Centroid() { return((this->p1->x3+this->p2->x3)*0.5); }
+   
+   double getX1Minimum()  { return(this->p1->x1 < this->p2->x1 ? this->p1->x1 : this->p2->x1); }
+   double getX2Minimum()  { return(this->p1->x2 < this->p2->x2 ? this->p1->x2 : this->p2->x2); }
+   double getX3Minimum()  { return(this->p1->x3 < this->p2->x3 ? this->p1->x3 : this->p2->x3); }
+   
+   double getX1Maximum()  { return(this->p1->x1 > this->p2->x1 ? this->p1->x1 : this->p2->x1); }
+   double getX2Maximum()  { return(this->p1->x2 > this->p2->x2 ? this->p1->x2 : this->p2->x2); }
+   double getX3Maximum()  { return(this->p1->x3 > this->p2->x3 ? this->p1->x3 : this->p2->x3); }
+	                                               
+   void scale(const double& sx1, const double& sx2, const double& sx3);
+   void translate(const double& tx1, const double& tx2, const double& tx3);
+
+   GbPoint3D* calculateIntersectionPoint3D(GbLine3D* line);
+   GbLine3D*  createClippedLine3D(GbCuboid3D* cuboid);
+   GbLine3D*  createClippedLine3D(GbPoint3D* pA, GbPoint3D* pE);
+   
+   double     getDistance(const GbPoint3D& point);
+   double     getDistance(const double& x1,const double& x2,const double& x3);
+
+   std::vector<GbTriangle3D*> getSurfaceTriangleSet();
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3)
+   {
+      throw UbException(UB_EXARGS,"not implemented");
+   }
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)
+   {
+      throw UbException(UB_EXARGS,"not implemented");
+   }
+   bool isCellInsideGbObject3D(const double& x11,const double& x21,const double& x31,const double& x12,const double& x22,const double& x32) { return false; }
+
+   GbLine3D* createClippedLine3D (GbPoint3D& point1, GbPoint3D& point2)
+   {
+      throw UbException(UB_EXARGS,"not implemented");
+   }
+
+   //virtuelle Methoden von UbObserver
+   void objectChanged(UbObservable* changedObject);
+   void objectWillBeDeleted(UbObservable* objectForDeletion);
+
+   std::string toString();
+
+   using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
+protected:
+   GbPoint3D* p1;
+	GbPoint3D* p2;
+	double     length;
+
+private:
+   void calculateValues();
+};
+
+#endif
diff --git a/VirtualFluidsBasics/geometry3d/GbObject3D.cpp b/VirtualFluidsBasics/geometry3d/GbObject3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77a17ac1505ebe72ae9a7d88221fd47c4a9731ef
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbObject3D.cpp
@@ -0,0 +1,115 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbObject3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbObject3D.h>
+#include <GbPoint3D.h>
+#include <basics/utilities/UbMath.h>                 
+
+using namespace std;
+
+/*======================================================================*/
+bool GbObject3D::isPointInGbObject3D(GbPoint3D* p)
+{
+   return this->isPointInGbObject3D(p->getX1Centroid(),p->getX2Coordinate(),p->getX3Coordinate());
+} 
+/*======================================================================*/
+bool GbObject3D::isCellInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b) 
+{
+
+   if(   this->isPointInGbObject3D(x1a, x2a, x3a) 
+      && this->isPointInGbObject3D(x1b, x2a, x3a) 
+      && this->isPointInGbObject3D(x1b, x2b, x3a)
+      && this->isPointInGbObject3D(x1a, x2b, x3a) 
+      && this->isPointInGbObject3D(x1a, x2a, x3b)
+      && this->isPointInGbObject3D(x1b, x2a, x3b)
+      && this->isPointInGbObject3D(x1b, x2b, x3b)
+      && this->isPointInGbObject3D(x1a, x2b, x3b))
+   {
+      return true;
+   }
+
+   return false;
+}
+/*======================================================================*/
+bool GbObject3D::isCellCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b) 
+{
+   if(   this->isPointInGbObject3D(x1a, x2a, x3a)      
+      || this->isPointInGbObject3D(x1b, x2a, x3a)      
+      || this->isPointInGbObject3D(x1b, x2b, x3a)      
+      || this->isPointInGbObject3D(x1a, x2b, x3a)      
+      || this->isPointInGbObject3D(x1a, x2a, x3b)      
+      || this->isPointInGbObject3D(x1b, x2a, x3b)      
+      || this->isPointInGbObject3D(x1b, x2b, x3b)      
+      || this->isPointInGbObject3D(x1a, x2b, x3b) )    
+   {
+      if(   !this->isPointInGbObject3D(x1a, x2a, x3a) 
+         || !this->isPointInGbObject3D(x1b, x2a, x3a) 
+         || !this->isPointInGbObject3D(x1b, x2b, x3a) 
+         || !this->isPointInGbObject3D(x1a, x2b, x3a)
+         || !this->isPointInGbObject3D(x1a, x2a, x3b)
+         || !this->isPointInGbObject3D(x1b, x2a, x3b)
+         || !this->isPointInGbObject3D(x1b, x2b, x3b)
+         || !this->isPointInGbObject3D(x1a, x2b, x3b)) return true;
+   }
+   return false;
+}
+/*======================================================================*/
+bool GbObject3D::isCellInsideOrCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b)
+{
+   if(   this->isPointInGbObject3D(x1a, x2a, x3a)   
+      || this->isPointInGbObject3D(x1b, x2a, x3a)   
+      || this->isPointInGbObject3D(x1b, x2b, x3a)   
+      || this->isPointInGbObject3D(x1a, x2b, x3a)   
+      || this->isPointInGbObject3D(x1a, x2a, x3b)   
+      || this->isPointInGbObject3D(x1b, x2a, x3b)   
+      || this->isPointInGbObject3D(x1b, x2b, x3b)   
+      || this->isPointInGbObject3D(x1a, x2b, x3b))  
+   {
+      return true;
+   }
+
+   return false;
+}
+/*=======================================================*/
+bool GbObject3D::isInsideCell(const double& minX1,const double& minX2,const double& minX3,const double& maxX1,const double& maxX2,const double& maxX3)
+{
+   if(   UbMath::greaterEqual(this->getX1Minimum(),minX1)
+      && UbMath::greaterEqual(this->getX2Minimum(),minX2)
+      && UbMath::greaterEqual(this->getX3Minimum(),minX3)
+      && UbMath::lessEqual(this->getX1Maximum(),maxX1) 
+      && UbMath::lessEqual(this->getX2Maximum(),maxX2)   
+      && UbMath::lessEqual(this->getX2Maximum(),maxX3)     ) return true;
+
+   return false;
+}
+
+
diff --git a/VirtualFluidsBasics/geometry3d/GbObject3D.h b/VirtualFluidsBasics/geometry3d/GbObject3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..dcb27c94ea1390c4458e05fe397a9377846ae5ec
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbObject3D.h
@@ -0,0 +1,152 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbObject3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBOBJECT3D_H
+#define GBOBJECT3D_H
+
+#include <string>
+#include <vector>
+
+
+#include <basics/utilities/UbSystem.h>
+#include <basics/utilities/UbException.h>
+#include <basics/utilities/UbObservable.h>
+#include <basics/utilities/UbTuple.h>
+#include <basics/objects/ObObject.h>
+
+class GbPoint3D;
+class GbLine3D;
+class GbTriangle3D;
+class GbObject3DCreator;
+
+#include <PointerDefinitions.h>
+
+//////////////////////////////////////////////////////////////////////////
+//! 
+//! \class GbObject3D
+//! 
+//! \brief This Interface provides basic 3D geometry objects methods.
+//! 
+//////////////////////////////////////////////////////////////////////////
+
+class GbObject3D : public ObObject
+{
+public:
+   virtual ~GbObject3D(){}
+
+   //abstract Methods
+   virtual void finalize() =0 ; //detroys also all dynamic objects (e.g. GbPoints in GbLine)
+   /**
+    * Returns the centroid x1 coordinate of this 3D object.
+    * @return the centroid x1 coordinate of this 3D object
+    */
+   virtual double getX1Centroid()=0;
+   /**
+    * Returns the minimum x1 coordinate of this 3D object.
+    * @return the minimum x1 coordinate of this 3D object
+    */
+   virtual double getX1Minimum()=0;
+   /**
+    * Returns the maximum x1 coordinate of this 3D object.
+    * @return the maximum x1 coordinate of this 3D object
+    */
+   virtual double getX1Maximum()=0;
+   /**
+    * Returns the centroid x2 coordinate of this 3D object.
+    * @return the centroid x2 coordinate of this 3D object
+    */
+   virtual double getX2Centroid()=0;
+   /**
+    * Returns the minimum x2 coordinate of this 3D object.
+    * @return the minimum x2 coordinate of this 3D object
+    */
+   virtual double getX2Minimum()=0;
+   /**
+    * Returns the maximum x2 coordinate of this 3D object.
+    * @return the maximum x2 coordinate of this 3D object
+    */
+   virtual double getX2Maximum()=0;
+
+	virtual double getX3Centroid()=0;
+   /**
+    * Returns the minimum x2 coordinate of this 3D object.
+    * @return the minimum x2 coordinate of this 3D object
+    */
+   virtual double getX3Minimum()=0;
+   /**
+    * Returns the maximum x2 coordinate of this 3D object.
+    * @return the maximum x2 coordinate of this 3D object
+    */
+   virtual double getX3Maximum()=0;
+
+   /*=======================================================*/
+   double getLengthX1() { return (getX1Maximum()-getX1Minimum()); }
+   double getLengthX2() { return (getX2Maximum()-getX2Minimum()); }
+   double getLengthX3() { return (getX3Maximum()-getX3Minimum()); }
+
+   virtual void setCenterX1Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void setCenterX2Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void setCenterX3Coordinate(const double& value) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void setCenterCoordinates(const double& x1, const double& x2, const double& x3) { throw UbException(UB_EXARGS, "not implemented for " + (std::string)typeid(*this).name()); }
+   virtual void setCenterCoordinates(const UbTupleDouble3& position) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+
+   //Rotates the Point in relation to the origen.
+   //Parameters must be radian measure.
+   virtual void rotate(const double& rx1, const double& rx2, const double& rx3) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void translate(const double& x1, const double& x2, const double& x3) { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+   virtual void scale(const double& sx1, const double& sx2, const double& sx3)  { throw UbException(UB_EXARGS,"not implemented for "+(std::string)typeid(*this).name() ); }
+
+   virtual bool isPointInGbObject3D(GbPoint3D* p);
+   virtual bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)=0;
+   virtual bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3)=0;
+
+   virtual bool isCellInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   virtual bool isCellCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   virtual bool isCellInsideOrCuttingGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b);
+   virtual double getCellVolumeInsideGbObject3D(const double& x1a,const double& x2a,const double& x3a,const double& x1b,const double& x2b,const double& x3b){ return -1.0;};
+
+   virtual bool isInsideCell(const double& minX1,const double& minX2,const double& minX3,const double& maxX1,const double& maxX2,const double& maxX3);
+
+   virtual GbLine3D* createClippedLine3D (GbPoint3D &point1, GbPoint3D &point2)=0;
+   virtual std::vector<GbTriangle3D*> getSurfaceTriangleSet()=0;
+
+   virtual void addSurfaceTriangleSet(std::vector<UbTupleFloat3>& nodes, std::vector<UbTupleInt3>& triangles) { throw UbException("GbObject3D::addSurfaceTriangleSet - not implemented for "+(std::string)typeid(*this).name()); }
+
+   virtual bool hasRaytracing() { return false; }
+   virtual bool raytracingSupportsPointsInside() { return false; }
+   //|r| must be 1! einheitsvector!!
+   //return negativ value oder zero if no intersection
+   virtual double getIntersectionRaytraceFactor(const double& x1, const double& x2, const double& x3, const double& rx1, const double& rx2, const double& rx3) { throw UbException("GbObject3D::getIntersectionRaytraceFactor - not implemented"); }
+};
+/*=========================================================================*/
+
+#endif
diff --git a/VirtualFluidsBasics/geometry3d/GbPoint3D.cpp b/VirtualFluidsBasics/geometry3d/GbPoint3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0a179e695bf7b70c3dbc650ca9466ac3f3ee76f
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbPoint3D.cpp
@@ -0,0 +1,150 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbPoint3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbPoint3D.h>
+using namespace std;
+
+/*=======================================================*/
+GbPoint3D::GbPoint3D()
+{ 
+   this->x1=0.0; 
+   this->x2=0.0; 
+   this->x3=0.0;
+}                                             
+/*=======================================================*/
+GbPoint3D::GbPoint3D(const double& x1, const double& x2, const double& x3)
+{ 
+   this->x1=x1; 
+   this->x2=x2; 
+   this->x3=x3;
+}
+/*=======================================================*/
+GbPoint3D::GbPoint3D(GbPoint3D* point)
+{
+   this->x1 = point->x1;                                             
+   this->x2 = point->x2;
+   this->x3 = point->x3;
+} 
+/*=======================================================*/
+double GbPoint3D::getDistance(GbPoint3D* p)
+{
+   double dx1 = this->x1 - p->x1;
+   double dx2 = this->x2 - p->x2;
+   double dx3 = this->x3 - p->x3;
+   return std::sqrt(dx1*dx1 + dx2*dx2 + dx3*dx3);
+}
+/*=======================================================*/
+bool GbPoint3D::equals(const GbPoint3D* point) const
+{
+   if(fabs(this->x1-point->x1)>1.E-10) return false;
+   if(fabs(this->x2-point->x2)>1.E-10) return false;
+   if(fabs(this->x3-point->x3)>1.E-10) return false;
+
+   return true;
+}
+/*=======================================================*/
+void GbPoint3D::transform(const double matrix[4][4])
+{
+   double tempX1 = x1;
+   double tempX2 = x2;
+   double tempX3 = x3;
+   x1 = matrix[0][0] * tempX1 + matrix[0][1] * tempX2 + matrix[0][2] * tempX3 + matrix[0][3] * 1.;
+   x2 = matrix[1][0] * tempX1 + matrix[1][1] * tempX2 + matrix[1][2] * tempX3 + matrix[1][3] * 1.;
+   x3 = matrix[2][0] * tempX1 + matrix[2][1] * tempX2 + matrix[2][2] * tempX3 + matrix[2][3] * 1.;
+}
+/*=======================================================*/
+bool GbPoint3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3)
+{
+   return (fabs(x1)<1.E-13 && fabs(x2)<1.E-13 && fabs(x3)<1.E-13 );
+}
+/*=======================================================*/
+bool GbPoint3D::isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)
+{
+   pointIsOnBoundary = (fabs(x1)<1.E-13 && fabs(x2)<1.E-13 && fabs(x3)<1.E-13 );
+   return pointIsOnBoundary;
+}
+/*=======================================================*/
+vector<GbTriangle3D*> GbPoint3D::getSurfaceTriangleSet()
+{            
+   cout<<"GbPoint3D::getSurfaceTriangleSet() - test ... if no exception occurs, everything is fine\n";
+   vector<GbTriangle3D*> triangles;
+   return triangles; //<-empty vector! is okay!
+   
+   //old:
+   //to avoid unnecessary exceptions a point will generate a triangle with
+   //c3 point with same coordinates
+   //vector<GbTriangle3D*> triangles;
+   //GbPoint3D p1(getX1Coordinate(),getX2Coordinate(),getX3Coordinate());
+   //triangles.push_back(new GbTriangle3D(new GbPoint3D(p1),new GbPoint3D(p1),new GbPoint3D(p1)));
+}
+/*=======================================================*/
+GbLine3D* GbPoint3D::createClippedLine3D (GbPoint3D& point1, GbPoint3D& point2)
+{
+   throw UbException(UB_EXARGS,"not implemented");
+} 
+/*=======================================================*/
+string GbPoint3D::toString()
+{
+   stringstream ss;
+   ss<<"GbPoint3D["<<this->x1<<","<<this->x2<<","<<this->x3<<"]";
+   return((ss.str()).c_str());
+}
+/*=======================================================*/
+void GbPoint3D::translate(const double& dx1, const double& dx2, const double& dx3)
+{  
+   this->x1 += dx1;
+   this->x2 += dx2;
+   this->x3 += dx3;
+   this->notifyObserversObjectChanged(); 
+}
+/*=======================================================*/
+void GbPoint3D::rotate(const double& rx1, const double& rx2, const double& rx3)
+{  
+   double newX1 = cos(rx3)*cos(rx2)*x1-x2*sin(rx3)*cos(rx1)+x2*cos(rx3)*sin(rx2)*sin(rx1)+x3*sin(rx3)*sin(rx1)+x3*cos(rx3)*sin(rx2)*cos(rx1);
+   double newX2 =  sin(rx3)*cos(rx2)*x1+x2*cos(rx3)*cos(rx1)+x2*sin(rx3)*sin(rx2)*sin(rx1)-x3*cos(rx3)*sin(rx1)+x3*sin(rx3)*sin(rx2)*cos(rx1);
+   double newX3 = -sin(rx2)*x1+cos(rx2)*sin(rx1)*x2+cos(rx2)*cos(rx1)*x3;
+
+   this->x1 = newX1;
+   this->x2 = newX2;
+   this->x3 = newX3;
+   this->notifyObserversObjectChanged(); 
+}
+/*=======================================================*/
+void GbPoint3D::scale(const double& sx1, const double& sx2, const double& sx3)
+{  
+   this->x1 *= sx1;
+   this->x2 *= sx2;
+   this->x3 *= sx3;
+   this->notifyObserversObjectChanged(); 
+}
+/*=======================================================*/
+
diff --git a/VirtualFluidsBasics/geometry3d/GbPoint3D.h b/VirtualFluidsBasics/geometry3d/GbPoint3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..956f10461a8715ee4b80597ecf2a4e702b320fb2
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbPoint3D.h
@@ -0,0 +1,109 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbPoint3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBPOINT3D_H
+#define GBPOINT3D_H
+
+#include <string>
+#include <sstream>
+#include <cmath>
+
+#include <GbObject3D.h>
+
+#include <PointerDefinitions.h>
+
+class GbTriangle3D;
+
+//! \brief This Class provides basic 3D point objects.
+class GbPoint3D : public GbObject3D
+{
+public:
+   GbPoint3D();
+   GbPoint3D(const double& x1, const double& x2, const double& x3);
+   GbPoint3D(GbPoint3D *point);                
+   ~GbPoint3D() {}
+
+   GbPoint3D* clone() {return new GbPoint3D(this);}
+   void finalize() {}
+
+   void setCoordinates(const double& x1, const double& x2, const double& x3)
+   {
+       this->x1=x1;
+       this->x2=x2;
+       this->x3=x3;
+       this->notifyObserversObjectChanged();
+   }
+   void setX1(const double& x1) { this->x1=x1; this->notifyObserversObjectChanged(); }
+   void setX2(const double& x2) { this->x2=x2; this->notifyObserversObjectChanged(); }
+   void setX3(const double& x3) { this->x3=x3; this->notifyObserversObjectChanged(); }
+
+   double getX1Coordinate() const  { return this->x1; }
+   double getX2Coordinate() const  { return this->x2; }
+   double getX3Coordinate() const  { return this->x3; }
+
+   void transform(const double matrix[4][4]);
+ 
+   double getX1Centroid()  { return this->x1; }
+   double getX1Minimum()   { return this->x1; }
+   double getX1Maximum()   { return this->x1; }
+   double getX2Centroid()  { return this->x2; }
+   double getX2Minimum()   { return this->x2; }
+   double getX2Maximum()   { return this->x2; }
+   double getX3Centroid()  { return this->x3; }
+   double getX3Minimum()   { return this->x3; }
+   double getX3Maximum()   { return this->x3; }        
+ 
+   void translate(const double& x1, const double& x2, const double& x3);
+   void rotate(const double& rx1, const double& rx2, const double& rx3);
+   void scale(const double& sx1, const double& sx2, const double& sx3);
+
+   double getDistance(GbPoint3D *p);
+   bool equals(const GbPoint3D* point) const;
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary);
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3);
+   bool isCellInsideGbObject3D(const double& x11,const double& x21,const double& x31,const double& x12,const double& x22,const double& x23) { return false; }
+
+   std::vector<GbTriangle3D*> getSurfaceTriangleSet();
+   GbLine3D* createClippedLine3D(GbPoint3D &point1, GbPoint3D &point2);
+   virtual std::string toString();
+
+   using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren
+                                          //, welche sonst hier "ueberdeckt" waere,da es dieselbe methode mit anderen args gibt!
+
+   //member
+   double x1;
+   double x2;
+   double x3;      
+};
+
+
+#endif
diff --git a/VirtualFluidsBasics/geometry3d/GbPolygon3D.cpp b/VirtualFluidsBasics/geometry3d/GbPolygon3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ba04de82d36371c7939a1a6582d291bd39a03f0
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbPolygon3D.cpp
@@ -0,0 +1,356 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbPolygon3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbPolygon3D.h>
+
+using namespace std;
+
+int GbPolygon3D::counter = 0;
+
+GbPolygon3D::GbPolygon3D()
+{
+   init();
+   counter++;
+   this->ps = new GbSystem3D::PointSet3(0);
+}
+void GbPolygon3D::init()
+{
+   x1s        = 0.0;
+   x2s        = 0.0;
+   x1min      = 0.0;
+   x1max      = 0.0;
+   x2min      = 0.0;
+   x2max      = 0.0;
+   //		points   = NULL;
+   consistent = false;
+   ps         = NULL;
+}
+
+/*!
+* Creates an empty 3D polygon with the specified capacity.
+* @param capacity the initial capacity
+*/
+GbPolygon3D::GbPolygon3D(int capacity)
+{
+   init();
+   counter++;
+   this->ps = new GbSystem3D::PointSet3(capacity);
+   //     this.po = new PointObserver(this);
+}
+/**
+* Creates a 3D polygon with the specified points.
+* @param points the initial points of the polygon
+*/
+GbPolygon3D::GbPolygon3D(vector<GbPoint3D>& points)
+{
+   init();
+   counter++;
+   this->ps = new GbSystem3D::PointSet3((int)points.size());
+   this->addPoints(points);
+}
+/**
+* Creates a 3D polygon as clone of the specified 3D polygon.
+* @param polygon the 3D polygon to be cloned
+*/
+GbPolygon3D::GbPolygon3D(GbPolygon3D* polygon)
+{
+   this->init();
+   counter++;
+   this->ps = new GbSystem3D::PointSet3((int)polygon->size());
+   vector<GbPoint3D> temp = polygon->getPoints();
+   this->addPoints( temp  );
+}
+
+GbPolygon3D::~GbPolygon3D()
+{
+   counter--;
+   //if(points)
+   //for(unsigned u=0; u<points->size(); u++)
+   //{
+   //	delete (*points)[u];
+   //}
+   //		delete this->points;
+   delete this->ps;
+}
+
+/*======================================================================*/
+/**
+* Returns the number of points.
+* @return the number of points
+*/
+int GbPolygon3D::size()
+{
+   return(this->ps->size());
+}
+/**
+* Returns the number of times this 3D polygon contains the specified point.
+* @param point the point
+* @return the number of times this 3D polygon contains the specified point
+*/
+int GbPolygon3D::contains(GbPoint3D* point)
+{
+   return(this->ps->contains(point));
+}
+/**
+* Returns the number of times this 3D polygon contains a point equal to the specified point.
+* @param point the point
+* @return the number of times this 3D polygon contains a point equal to the specified point
+*/
+int GbPolygon3D::containsEqual(GbPoint3D* point)
+{
+   return(this->ps->containsEqual(point));
+}
+/**
+* Returns true, if this 3D polygon contains the specified line.
+* @param point1 the first point
+* @param point2 the second point
+* @return true, if this 3D polygon contains the specified line
+*/
+bool GbPolygon3D::containsLine(GbPoint3D* point1, GbPoint3D* point2)
+{
+   return(this->ps->containsLine(point1, point2));
+}
+/**
+* Returns true, if this 3D polygon contains the specified line.
+* @param line the line
+* @return true, if this 3D polygon contains the specified line
+*/
+bool GbPolygon3D::containsLine(GbLine3D* line)
+{
+   return(this->ps->containsLine(line->getPoint1(), line->getPoint2()));
+}
+/**
+* Returns the first point.
+* @return the first point
+*/
+GbPoint3D* GbPolygon3D::getFirstPoint()
+{
+   return(this->ps->getFirstPoint());
+}
+/**
+* Returns the last point.
+* @return the last point
+*/
+GbPoint3D* GbPolygon3D::getLastPoint()
+{
+   return(this->ps->getLastPoint());
+}
+/**
+* Returns the specified point.
+* @param index the index
+* @return the specified point
+* @exception ArrayIndexOutOfBoundsException if the specified index is not valid
+*/
+GbPoint3D* GbPolygon3D::getPoint(const int& index) 
+{
+   if(index < 0 || index > this->ps->size()) throw UbException(UB_EXARGS,"ArrayIndexOutOfBoundsException-GbPolygon3D.getPoint()");
+   return(this->ps->getPoint(index));
+}
+/**
+* Returns the points.
+* @return the points
+*/
+vector<GbPoint3D> GbPolygon3D::getPoints()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->points);
+}
+/**
+* Returns the points within the specified rectangle.
+* @param p1 the 1st point of the rectangle
+* @param p2 the 2nd point of the rectangle
+* @return the points within the specified rectangle
+*/
+vector<GbPoint3D> GbPolygon3D::getPoints(GbPoint3D* p1, GbPoint3D* p2)
+{
+   return(this->getPoints(p1->x1, p1->x2, p1->x3, p2->x1, p2->x2, p2->x3));
+}
+/**
+* Returns the points within the specified rectangle.
+* @param p1x1 the 1st x1 coordinate of the rectangle
+* @param p1x2 the 1st x2 coordinate of the rectangle
+* @param p1x3 the 1st x3 coordinate of the rectangle
+* @param p2x1 the 2nd x1 coordinate of the rectangle
+* @param p2x2 the 2nd x2 coordinate of the rectangle
+* @param p2x3 the 2nd x3 coordinate of the rectangle
+* @return the points within the specified rectangle
+*/
+vector<GbPoint3D> GbPolygon3D::getPoints(const double& p1x1, const double& p1x2, const double& p1x3, const double& p2x1, const double& p2x2, const double& p2x3)
+{
+   double x1min, x1max, x2min, x2max, x3min, x3max;
+
+   if(UbMath::less(p1x1, p2x1)) { x1min = p1x1; x1max = p2x1; }
+   else                           { x1min = p2x1; x1max = p1x1; }
+   if(UbMath::less(p1x2, p2x2)) { x2min = p1x2; x2max = p2x2; }
+   else                           { x2min = p2x2; x2max = p1x2; }
+   if(UbMath::less(p1x3, p2x3)) { x3min = p1x3; x3max = p2x3; }
+   else                           { x3min = p2x3; x3max = p1x3; }
+
+   GbSystem3D::PointSet3 *pts = new GbSystem3D::PointSet3(1);
+
+   if(!this->consistent) this->calculateValues();
+   for(int i=this->size()-1; i>=0; i--)
+   {
+      if(UbMath::lessEqual(x1min, (this->points)[i].x1) && UbMath::greaterEqual(x1max, (this->points)[i].x1) &&
+         UbMath::lessEqual(x2min, (this->points)[i].x2) && UbMath::greaterEqual(x2max, (this->points)[i].x2) &&
+         UbMath::lessEqual(x3min, (this->points)[i].x3) && UbMath::greaterEqual(x3max, (this->points)[i].x3))     pts->add((this->points)[i]);
+   }
+   return(pts->getPoints());
+}
+/**
+* Returns the area of this polygon.
+* The area is positive for positive ordered points, otherwise negative.
+* @return the area of this polygon
+*/
+//double getArea()
+//{
+//   if(!this.consistent) this.calculateValues();
+//   return(this.area);
+//}
+double GbPolygon3D::getX1Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1s);
+}
+double GbPolygon3D::getX1Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1min);
+}
+double GbPolygon3D::getX1Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1max);
+}
+double GbPolygon3D::getX2Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2s);
+}
+double GbPolygon3D::getX2Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2min);
+}
+double GbPolygon3D::getX2Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2max);
+}
+double GbPolygon3D::getX3Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3s);
+}
+double GbPolygon3D::getX3Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3min);
+}
+double GbPolygon3D::getX3Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3max);
+}
+
+/**
+* Adds a point to the end of this polygon. Notifies the observers of this 3D polygon.
+* @param point the point
+*/
+void GbPolygon3D::addPoint(GbPoint3D* point)
+{
+   //if((this instanceof GbPolygon3D) && !(point instanceof GbPoint3D)) throw new IllegalArgumentException("GbPolygon3D.addPoint(): points of 3D polygons have to be 3D points!");
+
+   this->ps->add(point);
+   //point.addObserver(this.po);
+   this->consistent = false;
+   //super.notifyObservers();
+}
+/**
+* Adds a number of points to the end of this polygon. Notifies the observers of this 3D polygon.
+* @param points the points
+*/
+void GbPolygon3D::addPoints(vector<GbPoint3D>& points)
+{
+   //if((this instanceof GbPolygon3D) && (points.getClass().getComponentType() != GbPoint3D.class)) throw new IllegalArgumentException("GbPolygon3D.addPoints(): points of 3D polygons have to be 3D points!");
+
+   this->ps->add(points);
+   //for(int i=0; i<points.length; i++) points[i].addObserver(this.po);
+   this->consistent = false;
+   //super.notifyObservers();
+}
+/**
+* Removes all points from this polygon. Notifies the observers of this 3D polygon.
+*/
+void GbPolygon3D::clear()
+{
+   //		delete this->points;
+   this->ps->clearAndTrim();
+   delete this->ps;
+
+   //for(int i=points.length-1; i>=0; i--) points[i].removeObserver(this.po);
+   this->consistent = false;
+   //super.notifyObservers();
+}
+/**
+* Returns a string representation of this 3D polygon.
+* @return a string representation of this 3D polygon
+*/
+string GbPolygon3D::toString()
+{
+   stringstream ss;
+   ss<<"GbPolygon3D[";
+   ss<<this->size()<<" points";
+   ss<<"]"<<endl;
+   for(int u=0; u<this->size(); u++)
+      ss<<this->ps->getPoint(u)->toString()<<endl;
+
+   return(ss.str());
+}
+/*======================================================================*/
+
+void GbPolygon3D::calculateValues()
+{
+   this->x1s        = 0.0;
+   this->x2s        = 0.0;
+   this->x3s        = 0.0;
+   this->x1min      = 0.0;
+   this->x1max      = 0.0;
+   this->x2min      = 0.0;
+   this->x2max      = 0.0;
+   this->x3min      = 0.0;
+   this->x3max      = 0.0;
+   throw UbException(UB_EXARGS,"should be implemented");
+}
+/*======================================================================*/
+
+
diff --git a/VirtualFluidsBasics/geometry3d/GbPolygon3D.h b/VirtualFluidsBasics/geometry3d/GbPolygon3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..e94f2227d1c6ef8fed69dc4d1a5dbe27c2c70c87
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbPolygon3D.h
@@ -0,0 +1,285 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbPolygon3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBPOLYGON3D_H
+#define GBPOLYGON3D_H
+
+#include <sstream>
+#include <iostream>
+
+
+#include <GbObject3D.h>
+#include <GbLine3D.h>
+#include <GbTriangle3D.h>
+#include <GbSystem3D.h>
+
+#include <PointerDefinitions.h>
+
+
+/*=========================================================================*/
+//! \class GbPolygon2D                                         
+/*                                                                         */
+//! \brief This Class provides basic 3D polygon objects.
+
+class GbPolygon3D : public GbObject3D
+{
+public:
+   using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
+private:
+   /*======================================================================*/
+   double            x1s  ;
+   double            x2s  ;
+   double            x3s  ;
+   double            x1min;
+   double            x1max;
+   double            x2min;
+   double            x2max;
+   double            x3min;
+   double            x3max;
+
+   std::vector<GbPoint3D> points;
+   bool                   consistent;
+
+   GbSystem3D::PointSet3 *ps;
+   //private PointObserver     po         = null;
+
+   void init();
+
+   /*======================================================================*/
+
+
+   /*======================================================================*/
+   /*  Construcrors                                                       */
+   /*                                                                      */
+   /*
+   * Creates an empty 2D polygon.
+   */
+public:
+   static int counter;
+   GbPolygon3D();
+   /*
+   * Creates an empty 2D polygon with the specified capacity.
+   * @param capacity the initial capacity
+   */
+   GbPolygon3D(int capacity);
+   /*
+   * Creates a 2D polygon with the specified points.
+   * @param points the initial points of the polygon
+   */
+   GbPolygon3D(std::vector<GbPoint3D> &points);
+   /*
+   * Creates a 2D polygon as clone of the specified 2D polygon.
+   * @param polygon the 2D polygon to be cloned
+   */
+   GbPolygon3D(GbPolygon3D *polygon);
+
+   ~GbPolygon3D();
+
+   /*======================================================================*/
+
+
+   /*======================================================================*/
+   /*  Methoden                                                            */
+   /*                                                                      */
+   /*
+   * Creates a 2D polygon as clone of this 2D polygon.
+   */
+   GbPolygon3D* clone() {   return(new GbPolygon3D(this)); }
+   void finalize()
+   {
+      throw UbException(UB_EXARGS,"toDo");
+   }
+
+   /*
+   * Returns the number of points.
+   * @return the number of points
+   */
+   int size();
+   /*
+   * Returns the number of times this 2D polygon contains the specified point.
+   * @param point the point
+   * @return the number of times this 2D polygon contains the specified point
+   */
+   int contains(GbPoint3D *point);
+   /*
+   * Returns the number of times this 2D polygon contains a point equal to the specified point.
+   * @param point the point
+   * @return the number of times this 2D polygon contains a point equal to the specified point
+   */
+   int containsEqual(GbPoint3D* point);
+   /*
+   * Returns true, if this 2D polygon contains the specified line.
+   * @param point1 the first point
+   * @param point2 the second point
+   * @return true, if this 2D polygon contains the specified line
+   */
+   bool containsLine(GbPoint3D* point1, GbPoint3D* point2);
+   /*
+   * Returns true, if this 2D polygon contains the specified line.
+   * @param line the line
+   * @return true, if this 2D polygon contains the specified line
+   */
+   bool containsLine(GbLine3D* line);
+   /*
+   * Returns the first point.
+   * @return the first point
+   */
+   GbPoint3D* getFirstPoint();
+   /*
+   * Returns the last point.
+   * @return the last point
+   */
+   GbPoint3D* getLastPoint();
+   /*
+   * Returns the specified point.
+   * @param index the index
+   * @return the specified point
+   * @exception ArrayIndexOutOfBoundsException if the specified index is not valid
+   */
+   GbPoint3D* getPoint(const int& index);
+   /*
+   * Returns the points.
+   * @return the points
+   */
+   std::vector<GbPoint3D> getPoints();
+   /*
+   * Returns the points within the specified rectangle.
+   * @param p1 the 1st point of the rectangle
+   * @param p2 the 2nd point of the rectangle
+   * @return the points within the specified rectangle
+   */
+   std::vector<GbPoint3D> getPoints(GbPoint3D* p1, GbPoint3D* p2);
+   /*
+   * Returns the points within the specified rectangle.
+   * @param p1x1 the 1st x1 coordinate of the rectangle
+   * @param p1x2 the 1st x2 coordinate of the rectangle
+   * @param p2x1 the 2nd x1 coordinate of the rectangle
+   * @param p2x2 the 2nd x2 coordinate of the rectangle
+   * @return the points within the specified rectangle
+   */
+   std::vector<GbPoint3D> getPoints(const double& p1x1, const double& p1x2, const double& p1x3, const double& p2x1, const double& p2x2, const double& p2x3);
+   /*
+   * Returns the area of this polygon.
+   * The area is positive for positive ordered points, otherwise negative.
+   * @return the area of this polygon
+   */
+   //double getArea()
+   //{
+   //   if(!this.consistent) this.calculateValues();
+   //   return(this.area);
+   //}
+   double getX1Centroid();
+   double getX1Minimum();
+   double getX1Maximum();
+   double getX2Centroid();
+   double getX2Minimum();
+   double getX2Maximum();
+   double getX3Centroid();
+   double getX3Minimum();
+   double getX3Maximum();
+
+   /*
+   * Adds a point to the end of this polygon. Notifies the observers of this 2D polygon.
+   * @param point the point
+   */
+   void addPoint(GbPoint3D* point);
+   /*
+   * Adds a number of points to the end of this polygon. Notifies the observers of this 2D polygon.
+   * @param points the points
+   */
+   void addPoints(std::vector<GbPoint3D>& points);
+   /*
+   * Removes all points from this polygon. Notifies the observers of this 2D polygon.
+   */
+   void clear();
+
+   /*
+   * Returns true if this 2D polygon equals the specified object.
+   * Two polygon are equal, if their points are equal.
+   * <BR>Note that the order of points is recognized!
+   * @return true if this 2D polygon equals the specified object
+   * @see GbPoint2D#equals(java.lang.Object)
+   * @see GbPoint3D#equals(java.lang.Object)
+   */
+   // bool equals(Object object)
+   // {
+   //    try
+   //    {
+   //	GbPolygon2D polygon = (GbPolygon2D) object;
+   //int         n       = this.size();
+
+   //if(n != polygon.size()) return(false);
+   //for(int i=0; i<n; i++) if(!this.getPoint(i).equals(polygon.getPoint(i))) return(false);
+   //return(true);
+   //    }
+   //    catch(Exception e){ return(false); }
+   // }
+   std::vector<GbTriangle3D*> getSurfaceTriangleSet()
+   {
+      std::cout<<"GbPolygon3D::getSurfaceTriangleSet() - not implemented\n";
+      std::vector<GbTriangle3D*> tmp;
+      return tmp;
+   }
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3)
+   {
+      throw UbException(__FILE__, __LINE__, "GbPolygon3D::isPointInObject3D- not implemented");
+   }
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)
+   {
+      throw UbException(__FILE__, __LINE__, "GbPolygon3D::isPointInObject3D- not implemented");
+   }
+   bool isCellInsideGbObject3D(double x11,double x21,double x31,double x12,double x22,double x32) { return false; }
+
+   GbLine3D* createClippedLine3D (GbPoint3D& point1, GbPoint3D &point2)
+   {
+      throw UbException(__FILE__, __LINE__, "GbPolygon3D::createClippedLine3D - not implemented");
+   }                        
+/*
+   * Returns a string representation of this 2D polygon.
+   * @return a string representation of this 2D polygon
+   */
+   std::string toString();
+
+   /*======================================================================*/
+   /*  Private Methoden                                                    */
+   /*                                                                      */
+   void calculateValues();
+   /*======================================================================*/
+};
+/*=========================================================================*/
+#endif
+
+
+
+
+
+
diff --git a/VirtualFluidsBasics/geometry3d/GbSystem3D.cpp b/VirtualFluidsBasics/geometry3d/GbSystem3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3afca818f5b917bc8012ad552a894b52b5282b1e
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbSystem3D.cpp
@@ -0,0 +1,1218 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbSystem3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbSystem3D.h>
+#include <GbPolygon3D.h>
+#include <GbCuboid3D.h>
+
+using namespace std;
+
+double GbSystem3D::getDistance(const GbPoint3D& p11, const GbPoint3D& p12)
+{
+   double dx1 = p11.x1 - p12.x1;
+   double dx2 = p11.x2 - p12.x2;
+   double dx3 = p11.x3 - p12.x3;
+   return std::sqrt(dx1*dx1+dx2*dx2+dx3*dx3);
+}
+
+GbPoint3D* GbSystem3D::calculateIntersectionPoint3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22)
+{
+   if(UbMath::less2(p11.x1, p12.x1, p21.x1, p22.x1))    return NULL;
+   if(UbMath::less2(p11.x2, p12.x2, p21.x2, p22.x2))    return NULL;
+   if(UbMath::less2(p11.x3, p12.x3, p21.x3, p22.x3))    return NULL;
+   if(UbMath::greater2(p11.x1, p12.x1, p21.x1, p22.x1)) return NULL;
+   if(UbMath::greater2(p11.x2, p12.x2, p21.x2, p22.x2)) return NULL;
+   if(UbMath::greater2(p11.x3, p12.x3, p21.x3, p22.x3)) return NULL;
+
+   double a11 = p12.x1 - p11.x1;                       //..HOW PARAMETERS ARE USED.........
+   double a12 = p12.x2 - p11.x2;                       //
+   double a13 = p12.x3 - p11.x3;                       //  p11 and p12 represent line 1
+   double a21 = p21.x1 - p22.x1;                       //  p21 and p22 represent line 2
+   double a22 = p21.x2 - p22.x2;                       //
+   double a23 = p21.x3 - p22.x3;                       //..................................
+   double b1  = p21.x1 - p11.x1;
+   double b2  = p21.x2 - p11.x2;
+   double b3  = p21.x3 - p11.x3;
+   double d1  = a11*a22 - a12*a21;
+   double d2  = a11*a23 - a13*a21;
+   double d3  = a12*a23 - a13*a22;
+   double t;
+
+   if(UbMath::zero(d1) && UbMath::zero(d2) && UbMath::zero(d3)) return NULL;
+   if(UbMath::zero(d1))
+   {
+   	if(!UbMath::zero(d2)) t = (a23*b1-a21*b3)/d2;
+      else          t = (a23*b2-a22*b3)/d3;
+   }
+   else if(UbMath::zero(d2))
+   {
+   	if(!UbMath::zero(d1)) t = (a22*b1-a21*b2)/d1;
+      else          t = (a23*b2-a22*b3)/d3;
+   }
+   else if(UbMath::zero(d3))
+   {
+   	if(!UbMath::zero(d1)) t = (a22*b1-a21*b2)/d1;
+      else          t = (a23*b1-a21*b3)/d2;
+   }
+   else return NULL;
+
+   double x1 = p11.x1 + t*a11;
+   double x2 = p11.x2 + t*a12;
+   double x3 = p11.x3 + t*a13;
+
+   if(UbMath::inClosedInterval(x1, p11.x1, p12.x1) && UbMath::inClosedInterval(x1, p21.x1, p22.x1) &&
+      UbMath::inClosedInterval(x2, p11.x2, p12.x2) && UbMath::inClosedInterval(x2, p21.x2, p22.x2) &&
+      UbMath::inClosedInterval(x3, p11.x3, p12.x3) && UbMath::inClosedInterval(x3, p21.x3, p22.x3)    ) return new GbPoint3D(x1, x2, x3);
+
+   return NULL;
+}
+/*=================================================================*/
+//Line1: p11 -> p12 and Line2: p21 -> p22
+bool GbSystem3D::hasIntersectionPoint3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22)
+{
+   if(UbMath::less2(p11.x1, p12.x1, p21.x1, p22.x1))    return false; 
+   if(UbMath::less2(p11.x2, p12.x2, p21.x2, p22.x2))    return false; 
+   if(UbMath::less2(p11.x3, p12.x3, p21.x3, p22.x3))    return false; 
+   if(UbMath::greater2(p11.x1, p12.x1, p21.x1, p22.x1)) return false; 
+   if(UbMath::greater2(p11.x2, p12.x2, p21.x2, p22.x2)) return false; 
+   if(UbMath::greater2(p11.x3, p12.x3, p21.x3, p22.x3)) return false; 
+
+   double a11 = p12.x1 - p11.x1;                       //..HOW PARAMETERS ARE USED.........
+   double a12 = p12.x2 - p11.x2;                       //
+   double a13 = p12.x3 - p11.x3;                       //  p11 and p12 represent line 1
+   double a21 = p21.x1 - p22.x1;                       //  p21 and p22 represent line 2
+   double a22 = p21.x2 - p22.x2;                       //
+   double a23 = p21.x3 - p22.x3;                       //..................................
+   double b1  = p21.x1 - p11.x1;
+   double b2  = p21.x2 - p11.x2;
+   double b3  = p21.x3 - p11.x3;
+   double d1  = a11*a22 - a12*a21;
+   double d2  = a11*a23 - a13*a21;
+   double d3  = a12*a23 - a13*a22;
+   double t;
+
+   if(UbMath::zero(d1) && UbMath::zero(d2) && UbMath::zero(d3)) return false; 
+   if(UbMath::zero(d1))
+   {
+      if(!UbMath::zero(d2)) t = (a23*b1-a21*b3)/d2;
+      else          t = (a23*b2-a22*b3)/d3;
+   }
+   else if(UbMath::zero(d2))
+   {
+      if(!UbMath::zero(d1)) t = (a22*b1-a21*b2)/d1;
+	   else          t = (a23*b2-a22*b3)/d3;
+   }
+   else if(UbMath::zero(d3))
+   {
+      if(!UbMath::zero(d1)) t = (a22*b1-a21*b2)/d1;
+      else          t = (a23*b1-a21*b3)/d2;
+   }
+   else return false; 
+
+   double x1 = p11.x1 + t*a11;
+   double x2 = p11.x2 + t*a12;
+   double x3 = p11.x3 + t*a13;
+
+   if(UbMath::inClosedInterval(x1, p11.x1, p12.x1) && UbMath::inClosedInterval(x1, p21.x1, p22.x1) &&
+	   UbMath::inClosedInterval(x2, p11.x2, p12.x2) && UbMath::inClosedInterval(x2, p21.x2, p22.x2) &&
+	   UbMath::inClosedInterval(x3, p11.x3, p12.x3) && UbMath::inClosedInterval(x3, p21.x3, p22.x3)) return true; 
+   return false; 
+}
+ /*======================================================================*/
+//
+//
+//   /*======================================================================*/
+//   /*  Private Methoden (Parallelism)                                      */
+//   /*                                                                      */
+bool GbSystem3D::isParallelIn3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22)
+{
+   double a11 = p12.x1 - p11.x1;                       //..HOW PARAMETERS ARE USED.........
+   double a12 = p12.x2 - p11.x2;                       //
+   double a13 = p12.x3 - p11.x3;                       //  p11 and p12 represent line 1
+   double a21 = p21.x1 - p22.x1;                       //  p21 and p22 represent line 2
+   double a22 = p21.x2 - p22.x2;                       //
+   double a23 = p21.x3 - p22.x3;                       //..................................
+
+   return (UbMath::zero(a11*a22 - a12*a21) && UbMath::zero(a11*a23 - a13*a21) && UbMath::zero(a12*a23 - a13*a22));
+}
+/*======================================================================*/
+
+
+/*======================================================================*/
+/*  General Clipping Methods                                            */
+//......................................................................*/
+//
+//  Method       Parameters                                       Result      Remarks
+//  ---------    ---------------------------------------------    ---------   -------------------
+//  clip###2D   (2D objects to be clipped, 2+2 clipping values)   2D object   clipping x1, x2
+//  clip###3D   (3D objects to be clipped, 2+2 clipping values)   3D object   clipping x1, x2
+//  clip###3D   (3D objects to be clipped, 3+3 clipping values)   3D object   clipping x1, x2, x3
+//  clip###3D   (3D objects to be clipped, 1+1 clipping values)   3D object   clipping x3
+//
+/*======================================================================*/
+/*  Private Methoden (Clipping Lines)                                   */
+/*                                                                      */
+GbLine3D* GbSystem3D::createClipLine3D(GbPoint3D &pA, GbPoint3D &pB, double x1a, double x2a, double x3a, double x1b, double x2b, double x3b)
+{
+   GbPoint3D *p1 = new GbPoint3D(pA);
+   GbPoint3D *p2 = new GbPoint3D(pB);
+
+   if(UbMath::greater(x1a, x1b)) { double x1 = x1a; x1a = x1b; x1b = x1; }
+   if(UbMath::greater(x2a, x2b)) { double x2 = x2a; x2a = x2b; x2b = x2; }
+   if(UbMath::greater(x3a, x3b)) { double x3 = x3a; x3a = x3b; x3b = x3; }
+
+   double f;
+
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an vorderer Kante                                      */
+   /*                                                                   */
+   if(UbMath::less(p1->x3, x3a))
+   {
+      if(UbMath::less(p2->x3, x3a)) { delete p1; delete p2; return NULL; }
+
+      f       = (x3a-p1->x3)/(p1->x3-p2->x3);
+      p1->x1 += (p1->x1-p2->x1)*f;
+      p1->x2 += (p1->x2-p2->x2)*f;
+      p1->x3  = x3a;
+   }
+   else if(UbMath::less(p2->x3, x3a))
+   {
+      f      = (x3a-p2->x3)/(p2->x3-p1->x3);
+      p2->x1 += (p2->x1-p1->x1)*f;
+      p2->x2 += (p2->x2-p1->x2)*f;
+      p2->x3  = x3a;
+   }     
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an unterer Kante                                       */
+   /*                                                                   */
+   if(UbMath::less(p1->x2, x2a))
+   {
+      if(UbMath::less(p2->x2, x2a)) { delete p1; delete p2; return NULL;
+      }
+
+      f      = (x2a-p1->x2)/(p1->x2-p2->x2);
+      p1->x1 += (p1->x1-p2->x1)*f;
+      p1->x3 += (p1->x3-p2->x3)*f;
+      p1->x2  = x2a;
+   }
+   else if(UbMath::less(p2->x2, x2a))
+   {
+      f      = (x2a-p2->x2)/(p2->x2-p1->x2);
+      p2->x1 += (p2->x1-p1->x1)*f;
+      p2->x3 += (p2->x3-p1->x3)*f;
+      p2->x2  = x2a;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an rechter Kante                                       */
+   /*                                                                   */
+   if(UbMath::greater(p1->x1, x1b))
+   {
+      if(UbMath::greater(p2->x1, x1b))  { delete p1;delete p2; return NULL;}
+
+      f      = (x1b-p1->x1)/(p1->x1-p2->x1);
+      p1->x2 += (p1->x2-p2->x2)*f;
+      p1->x3 += (p1->x3-p2->x3)*f;
+      p1->x1  = x1b;
+   }
+   else if(UbMath::greater(p2->x1, x1b))
+   {
+      f      = (x1b-p2->x1)/(p2->x1-p1->x1);
+      p2->x2 += (p2->x2-p1->x2)*f;
+      p2->x3 += (p2->x3-p1->x3)*f;
+      p2->x1  = x1b;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an hinterer Kante                                      */
+   /*                                                                   */
+   if(UbMath::greater(p1->x3, x3b))
+   {
+      if(UbMath::greater(p2->x3, x3b))  { delete p1;delete p2; return NULL;}
+
+      f      = (x3b-p1->x3)/(p1->x3-p2->x3);
+      p1->x1 += (p1->x1-p2->x1)*f;
+      p1->x2 += (p1->x2-p2->x2)*f;
+      p1->x3  = x3b;
+   }
+   else if(UbMath::greater(p2->x3, x3b))
+   {
+      f      = (x3b-p2->x3)/(p2->x3-p1->x3);
+      p2->x1 += (p2->x1-p1->x1)*f;
+      p2->x2 += (p2->x2-p1->x2)*f;
+      p2->x3  = x3b;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an oberer Kante                                        */
+   /*                                                                   */
+   if(UbMath::greater(p1->x2, x2b))
+   {
+      if(UbMath::greater(p2->x2, x2b))  { delete p1;delete p2; return NULL;}
+
+      f      = (x2b-p1->x2)/(p1->x2-p2->x2);
+      p1->x1 += (p1->x1-p2->x1)*f;
+      p1->x3 += (p1->x3-p2->x3)*f;
+      p1->x2  = x2b;
+   }
+   else if(UbMath::greater(p2->x2, x2b))
+   {
+      f      = (x2b-p2->x2)/(p2->x2-p1->x2);
+      p2->x1 += (p2->x1-p1->x1)*f;
+      p2->x3 += (p2->x3-p1->x3)*f;
+      p2->x2  = x2b;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an linker Kante                                        */
+   /*                                                                   */
+   if(UbMath::less(p1->x1, x1a))
+   {
+      if(UbMath::less(p2->x1, x1a))  { delete p1;delete p2; return NULL;}
+
+      f      = (x1a-p1->x1)/(p1->x1-p2->x1);
+      p1->x2 += (p1->x2-p2->x2)*f;
+      p1->x3 += (p1->x3-p2->x3)*f;
+      p1->x1  = x1a;
+   }
+   else if(UbMath::less(p2->x1, x1a))
+   {
+      f      = (x1a-p2->x1)/(p2->x1-p1->x1);
+      p2->x2 += (p2->x2-p1->x2)*f;
+      p2->x3 += (p2->x3-p1->x3)*f;
+      p2->x1  = x1a;
+   }
+   /*-------------------------------------------------------------------*/
+   return new GbLine3D(p1, p2);
+}
+//   /*======================================================================*/
+//   /*  Private Methoden (Clipping Rectangles)                              */
+//   /*                                                                      */
+//   final static GbPolygon3D clipPolygon3D(GbPoint3D points[], double x11, double x12, double x21, double x22)
+//   {
+//      GbPoint3D last = null;
+//      PointSet3 ps   = new PointSet3(points);
+//      boolean   flag = false;
+//      int       n    = points.length;
+//      int       i;
+//      double    f;
+//
+//      if(n == 0)              return(null);
+//      if(greater(x11, x21)) { double ax = x11; x11 = x21; x21 = ax; }
+//      if(greater(x12, x22)) { double ay = x12; x12 = x22; x22 = ay; }
+//
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an unterer Kante                                       */
+//      /*                                                                   */
+//      if(less(ps.getX2Minimum(), x12))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(less((*points)[0]->x2, x12)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(less((*points)[i]->x2, x12))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x12-(*points)[i]->x2)/((*points)[i]->x2-last->x2);
+//	          ps.add(new GbPoint3D((*points)[i]->x1 + ((*points)[i]->x1-last->x1)*f, x12, (*points)[i]->x3 + ((*points)[i]->x3-last->x3)*f));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x12-(*points)[i]->x2)/((*points)[i]->x2-last->x2);
+//	          ps.add(new GbPoint3D((*points)[i]->x1 + ((*points)[i]->x1-last->x1)*f, x12, (*points)[i]->x3 + ((*points)[i]->x3-last->x3)*f));
+//	       }
+//	       ps.add((*points)[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((less(points[0].x2, x12)) ^ flag))
+//	 {
+//	    f = (x12-points[0].x2)/(points[0].x2-last->x2);
+//	    ps.add(new GbPoint3D(points[0].x1 + (points[0].x1-last->x1)*f, x12, points[0].x3 + (points[0].x3-last->x3)*f));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an rechter Kante                                       */
+//      /*                                                                   */
+//      if(greater(ps.getX1Maximum(), x21))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(greater(points[0].x1, x21)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(greater((*points)[i]->x1, x21))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x21-(*points)[i]->x1)/((*points)[i]->x1-last->x1);
+//	          ps.add(new GbPoint3D(x21, (*points)[i]->x2 + ((*points)[i]->x2-last->x2)*f, (*points)[i]->x3 + ((*points)[i]->x3-last->x3)*f));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x21-(*points)[i]->x1)/((*points)[i]->x1-last->x1);
+//	          ps.add(new GbPoint3D(x21, (*points)[i]->x2 + ((*points)[i]->x2-last->x2)*f, (*points)[i]->x3 + ((*points)[i]->x3-last->x3)*f));
+//	       }
+//	       ps.add(points[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((greater(points[0].x1, x21)) ^ flag))
+//	 {
+//	    f = (x21-points[0].x1)/(points[0].x1-last.x1);
+//	    ps.add(new GbPoint3D(x21, points[0].x2 + (points[0].x2-last.x2)*f, points[0].x3 + (points[0].x3-last.x3)*f));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an oberer Kante                                        */
+//      /*                                                                   */
+//      if(greater(ps.getX2Maximum(), x22))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(greater(points[0].x2, x22)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(greater((*points)[i]->x2, x22))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x22-(*points)[i]->x2)/(points[i].x2-last.x2);
+//	          ps.add(new GbPoint3D(points[i].x1 + (points[i].x1-last.x1)*f, x22, points[i].x3 + (points[i].x3-last.x3)*f));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x22-points[i].x2)/(points[i].x2-last.x2);
+//	          ps.add(new GbPoint3D(points[i].x1 + (points[i].x1-last.x1)*f, x22, points[i].x3 + (points[i].x3-last.x3)*f));
+//	       }
+//	       ps.add(points[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((greater(points[0].x2, x22)) ^ flag))
+//	 {
+//	    f = (x22-points[0].x2)/(points[0].x2-last.x2);
+//	    ps.add(new GbPoint3D(points[0].x1 + (points[0].x1-last.x1)*f, x22, points[0].x3 + (points[0].x3-last.x3)*f));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an linker Kante                                        */
+//      /*                                                                   */
+//      if(less(ps.getX1Minimum(), x11))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(less(points[0].x1, x11)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(less(points[i].x1, x11))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x11-points[i].x1)/(points[i].x1-last.x1);
+//	          ps.add(new GbPoint3D(x11, points[i].x2 + (points[i].x2-last.x2)*f, points[i].x3 + (points[i].x3-last.x3)*f));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x11-points[i].x1)/(points[i].x1-last.x1);
+//	          ps.add(new GbPoint3D(x11, points[i].x2 + (points[i].x2-last.x2)*f, points[i].x3 + (points[i].x3-last.x3)*f));
+//	       }
+//	       ps.add(points[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((less(points[0].x1, x11)) ^ flag))
+//	 {
+//	    f = (x11-points[0].x1)/(points[0].x1-last.x1);
+//	    ps.add(new GbPoint3D(x11, points[0].x2 + (points[0].x2-last.x2)*f, points[0].x3 + (points[0].x3-last.x3)*f));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      GbPolygon3D polygon = new GbPolygon3D(points);
+//
+//      if(n > 2)
+//      {
+//	 for(i=2; i<n; i++) if(zero(i_TA(points[i-2], points[i-1], points[i]))) polygon.deletePoint(points[i-1]);
+//	 if(zero(i_TA(points[n-2], points[n-1], points[0]))) polygon.deletePoint(points[n-1]);
+//	 if(zero(i_TA(points[n-1], points[0],   points[1]))) polygon.deletePoint(points[0]);
+//      }
+//      return(polygon);
+//   }
+//   final static GbPolygon3D clipPolygon3D(GbPoint3D points[], double x13, double x23)
+//   {
+//      GbPoint3D last = null;
+//      PointSet3 ps   = new PointSet3(points);
+//      boolean   flag = false;
+//      int       n    = points.length;
+//      int       i;
+//      double    f;
+//
+//      if(n == 0)              return(null);
+//      if(greater(x13, x23)) { double az = x13; x13 = x23; x23 = az; }
+//
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an vorderer Kante                                      */
+//      /*                                                                   */
+//      if(less(ps.getX3Minimum(), x13))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(less(points[0].x3, x13)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(less(points[i].x3, x13))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x13-points[i].x3)/(points[i].x3-last.x3);
+//	          ps.add(new GbPoint3D(points[i].x1 + (points[i].x1-last.x1)*f, points[i].x2 + (points[i].x2-last.x2)*f, x13));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x13-points[i].x3)/(points[i].x3-last.x3);
+//	          ps.add(new GbPoint3D(points[i].x1 + (points[i].x1-last.x1)*f, points[i].x2 + (points[i].x2-last.x2)*f, x13));
+//	       }
+//	       ps.add(points[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((less(points[0].x3, x13)) ^ flag))
+//	 {
+//	    f = (x13-points[0].x3)/(points[0].x3-last.x3);
+//	    ps.add(new GbPoint3D(points[0].x1 + (points[0].x1-last.x1)*f, points[0].x2 + (points[0].x2-last.x2)*f, x13));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      /*  Schneiden an hinterer Kante                                      */
+//      /*                                                                   */
+//      if(greater(ps.getX3Maximum(), x23))
+//      {
+//	 ps.clear();
+//	 last = points[0];
+//	 if(greater(points[0].x3, x23)) flag = false;
+//	 else
+//	 {
+//	    ps.add(points[0]);
+//	    flag = true;
+//	 }
+//	 for(i=1; i<n; i++)
+//	 {
+//	    if(greater(points[i].x3, x23))
+//	    {
+//	       if(flag)
+//	       {
+//	          f = (x23-points[i].x3)/(points[i].x3-last.x3);
+//	          ps.add(new GbPoint3D(points[i].x1 + (points[i].x1-last.x1)*f, points[i].x2 + (points[i].x2-last.x2)*f, x23));
+//	       }
+//	       flag = false;
+//	    }
+//	    else
+//	    {
+//	       if(!flag)
+//	       {
+//	          f = (x23-points[i].x3)/(points[i].x3-last.x3);
+//	          ps.add(new GbPoint3D(points[i].x1 + ((*points)[i]->x1-last.x1)*f, (*points)[i]->x2 + ((*points)[i]->x2-last.x2)*f, x23));
+//	       }
+//	       ps.add(points[i]);
+//	       flag = true;
+//	    }
+//	    last = points[i];
+//	 }
+//	 if(!((greater(points[0].x3, x23)) ^ flag))
+//	 {
+//	    f = (x23-points[0].x3)/(points[0].x3-last.x3);
+//	    ps.add(new GbPoint3D(points[0].x1 + (points[0].x1-last.x1)*f, points[0].x2 + (points[0].x2-last.x2)*f, x23));
+//	 }
+//
+//	 points = ps.getPoints();
+//	 n      = points.length;
+//
+//	 if(n == 0) return(null);
+//      }
+//      /*-------------------------------------------------------------------*/
+//      GbPolygon3D polygon = new GbPolygon3D(points);
+//
+//      return(polygon);
+//   }
+GbPolygon3D* GbSystem3D::clipPolygon3D(vector<GbPoint3D> points, double x11, double x12, double x13, double x21, double x22, double x23)
+{
+   GbPoint3D last;
+   PointSet3 ps(points);
+   bool   flag = false;
+   int    n    = (int)points.size();
+	int       i;
+   double    f;
+
+   if(n == 0)              return NULL;
+   if(UbMath::greater(x11, x21)) { double ax = x11; x11 = x21; x21 = ax; }
+   if(UbMath::greater(x12, x22)) { double ay = x12; x12 = x22; x22 = ay; }
+   if(UbMath::greater(x13, x23)) { double az = x13; x13 = x23; x23 = az; }
+
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an vorderer Kante                                      */
+   /*                                                                   */
+   if(UbMath::less(ps.getX3Minimum(), x13))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::less((points)[0].x3, x13)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::less((points)[i].x3, x13))
+			{
+				if(flag)
+				{
+					f = (x13-(points)[i].x3)/((points)[i].x3-last.x3);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, (points)[i].x2 + ((points)[i].x2-last.x2)*f, x13));
+				}
+				flag = false;
+			}
+			else
+			{
+				if(!flag)
+				{
+					f = (x13-(points)[i].x3)/((points)[i].x3-last.x3);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, (points)[i].x2 + ((points)[i].x2-last.x2)*f, x13));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::less((points)[0].x3, x13)) ^ flag))
+		{
+			f = (x13-(points)[0].x3)/((points)[0].x3-last.x3);
+			ps.add(GbPoint3D((points)[0].x1 + ((points)[0].x1-last.x1)*f, (points)[0].x2 + ((points)[0].x2-last.x2)*f, x13));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+
+		if(n == 0) return NULL;
+   }
+	
+	/*-------------------------------------------------------------------*/
+   /*  Schneiden an unterer Kante                                       */
+   /*                                                                   */
+   if(UbMath::less(ps.getX2Minimum(), x12))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::less((points)[0].x2, x12)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::less((points)[i].x2, x12))
+			{
+				if(flag)
+				{
+					f = (x12-(points)[i].x2)/((points)[i].x2-last.x2);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, x12, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				flag = false;
+			}
+		   else
+			{
+				if(!flag)
+				{
+					f = (x12-(points)[i].x2)/((points)[i].x2-last.x2);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, x12, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::less((points)[0].x2, x12)) ^ flag))
+		{
+			f = (x12-(points)[0].x2)/((points)[0].x2-last.x2);
+			ps.add(GbPoint3D((points)[0].x1 + ((points)[0].x1-last.x1)*f, x12, (points)[0].x3 + ((points)[0].x3-last.x3)*f));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+
+		if(n == 0) return NULL;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an rechter Kante                                       */
+   /*                                                                   */
+	
+	if(UbMath::greater(ps.getX1Maximum(), x21))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::greater((points)[0].x1, x21)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::greater((points)[i].x1, x21))
+			{
+				if(flag)
+				{
+					f = (x21-(points)[i].x1)/((points)[i].x1-last.x1);
+					ps.add(GbPoint3D(x21, (points)[i].x2 + ((points)[i].x2-last.x2)*f, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				flag = false;
+			}
+			else
+			{
+				if(!flag)
+				{
+					f = (x21-(points)[i].x1)/((points)[i].x1-last.x1);
+					ps.add(GbPoint3D(x21, (points)[i].x2 + ((points)[i].x2-last.x2)*f, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::greater((points)[0].x1, x21)) ^ flag))
+		{
+			f = (x21-(points)[0].x1)/((points)[0].x1-last.x1);
+			ps.add(GbPoint3D(x21, (points)[0].x2 + ((points)[0].x2-last.x2)*f, (points)[0].x3 + ((points)[0].x3-last.x3)*f));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+
+		if(n == 0) return NULL;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an hinterer Kante                                      */
+   /*                                                                   */
+   if(UbMath::greater(ps.getX3Maximum(), x23))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::greater((points)[0].x3, x23)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::greater((points)[i].x3, x23))
+			{
+				if(flag)
+				{
+					f = (x23-(points)[i].x3)/((points)[i].x3-last.x3);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, (points)[i].x2 + ((points)[i].x2-last.x2)*f, x23));
+				}
+				flag = false;
+			}
+			else
+			{
+				if(!flag)
+				{
+					f = (x23-(points)[i].x3)/((points)[i].x3-last.x3);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, (points)[i].x2 + ((points)[i].x2-last.x2)*f, x23));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::greater((points)[0].x3, x23)) ^ flag))
+		{
+			f = (x23-(points)[0].x3)/((points)[0].x3-last.x3);
+			ps.add(GbPoint3D((points)[0].x1 + ((points)[0].x1-last.x1)*f, (points)[0].x2 + ((points)[0].x2-last.x2)*f, x23));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+
+		if(n == 0) return NULL;
+	}
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an oberer Kante                                        */
+   /*                                                                   */
+
+	if(UbMath::greater(ps.getX2Maximum(), x22))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::greater((points)[0].x2, x22)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::greater((points)[i].x2, x22))
+			{
+				if(flag)
+				{
+					f = (x22-(points)[i].x2)/((points)[i].x2-last.x2);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, x22, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				flag = false;
+			}
+			else
+			{
+				if(!flag)
+				{
+					f = (x22-(points)[i].x2)/((points)[i].x2-last.x2);
+					ps.add(GbPoint3D((points)[i].x1 + ((points)[i].x1-last.x1)*f, x22, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::greater((points)[0].x2, x22)) ^ flag))
+		{
+			f = (x22-(points)[0].x2)/((points)[0].x2-last.x2);
+			ps.add(GbPoint3D((points)[0].x1 + ((points)[0].x1-last.x1)*f, x22, (points)[0].x3 + ((points)[0].x3-last.x3)*f));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+
+		if(n == 0) return NULL;
+   }
+   /*-------------------------------------------------------------------*/
+   /*  Schneiden an linker Kante                                        */
+   /*                                                                   */
+	if(UbMath::less(ps.getX1Minimum(), x11))
+   {
+		ps.clear();
+		last = (points)[0];
+		if(UbMath::less((points)[0].x1, x11)) flag = false;
+		else
+		{
+			ps.add((points)[0]);
+			flag = true;
+		}
+		for(i=1; i<n; i++)
+		{
+			if(UbMath::less((points)[i].x1, x11))
+			{
+				if(flag)
+				{
+					f = (x11-(points)[i].x1)/((points)[i].x1-last.x1);
+					ps.add(GbPoint3D(x11, (points)[i].x2 + ((points)[i].x2-last.x2)*f, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+
+				}
+				flag = false;
+			}
+			else
+			{
+				if(!flag)
+				{
+					f = (x11-(points)[i].x1)/((points)[i].x1-last.x1);
+					ps.add(GbPoint3D(x11, (points)[i].x2 + ((points)[i].x2-last.x2)*f, (points)[i].x3 + ((points)[i].x3-last.x3)*f));
+				}
+				ps.add((points)[i]);
+				flag = true;
+			}
+			last = (points)[i];
+		}
+		if(!((UbMath::less((points)[0].x1, x11)) ^ flag))
+		{
+			f = (x11-(points)[0].x1)/((points)[0].x1-last.x1);
+			ps.add(GbPoint3D(x11, (points)[0].x2 + ((points)[0].x2-last.x2)*f, (points)[0].x3 + ((points)[0].x3-last.x3)*f));
+		}
+
+		points = ps.getPoints();
+		n      = (int)points.size();
+		
+		if(n == 0) return NULL;
+   }
+   /*-------------------------------------------------------------------*/
+	return new GbPolygon3D(points);
+}
+/*=========================================================================*/
+GbCuboid3D* GbSystem3D::clipRectangle3D(GbPoint3D& p1, GbPoint3D& p2, double x11, double x12, double x13, double x21, double x22, double x23)
+{
+   double r11 = p1.x1;
+   double r12 = p1.x2;
+   double r13 = p1.x3;
+   double r21 = p2.x1;
+   double r22 = p2.x2;
+   double r23 = p2.x3;
+
+   if(UbMath::greater(x11, x21)) { double ax = x11; x11 = x21; x21 = ax; }
+   if(UbMath::greater(x12, x22)) { double ay = x12; x12 = x22; x22 = ay; }
+   if(UbMath::greater(x13, x23)) { double az = x13; x13 = x23; x23 = az; }
+   if(UbMath::greater(r11, r21)) { double bx = r11; r11 = r21; r21 = bx; }
+   if(UbMath::greater(r12, r22)) { double by = r12; r12 = r22; r22 = by; }
+   if(UbMath::greater(r13, r23)) { double bz = r13; r13 = r23; r23 = bz; }
+
+   double m11 = UbMath::greater(x11, r11) ? x11 : r11;
+   double m12 = UbMath::greater(x12, r12) ? x12 : r12;
+   double m13 = UbMath::greater(x13, r13) ? x13 : r13;
+   double m21 = UbMath::greater(x21, r21) ? r21 : x21;
+   double m22 = UbMath::greater(x22, r22) ? r22 : x22;
+   double m23 = UbMath::greater(x23, r23) ? r23 : x23;
+
+   if(UbMath::lessEqual(m11, m21) && UbMath::lessEqual(m12, m22) && UbMath::lessEqual(m13, m23)) 
+      return(new GbCuboid3D(new GbPoint3D(m11, m12, m13), new GbPoint3D(m21, m22, m23)));
+   else  
+      return(NULL);
+}
+
+/*=========================================================================*/
+/*=========================================================================*/
+/*=========================================================================*/
+
+
+GbSystem3D::PointSet3::PointSet3(int n)
+{
+   this->init();
+   this->points.reserve(n); //reserves n elements! but the size of the vector ist still "0"
+}
+/*=======================================================*/
+GbSystem3D::PointSet3::PointSet3(const vector<GbPoint3D>& points)
+{
+   this->init();
+   this->add(points);
+}
+/*=======================================================*/
+void GbSystem3D::PointSet3::add(const GbPoint3D& point)
+{
+   //is point equal to last point in points then return
+   if(!this->points.empty() && point.equals(&this->points.back())) return;    //WHY???
+
+   //push point to vector
+   this->points.push_back(point);
+
+   this->consistent = false;
+}
+/*=======================================================*/
+void GbSystem3D::PointSet3::addUnequal(const GbPoint3D& point)
+{
+   if(this->containsEqual(point) > 0) return;
+   
+   this->points.push_back(point);
+   this->consistent = false;
+}
+/*=======================================================*/
+void GbSystem3D::PointSet3::add(const vector<GbPoint3D>& pointVector)
+{
+   for(int pos=0; pos<(int)pointVector.size(); pos++ )
+      this->points.push_back(pointVector[pos]);
+
+   this->consistent = false;
+}
+/*=======================================================*/
+void GbSystem3D::PointSet3::insert(const GbPoint3D& point, int index)
+{
+   if(index<0 || index>=(int)this->points.size()) 
+      throw UbException(UB_EXARGS,"index out of range");
+
+   //get iterator for index-position
+   vector<GbPoint3D>::iterator pos=this->points.begin();
+   for(int i=1; i<=index; i++) ++pos;
+
+   //insert point
+   this->points.insert(pos,point);
+
+   this->consistent    = false;
+}
+/*=======================================================*/
+//void delete(GbPoint3D point)
+//{
+//   for(int i=this.size-1; i>=0; i--) if(this.points[i] == point) this.delete(i);
+//}
+/*=======================================================*/
+//void delete(int index)
+//{
+//   int j = this.size - index - 1;
+//   if(j > 0) System.arraycopy(this.points, index + 1, this.points, index, j);
+//   this.consistent = false;
+//   this.size--;
+//}
+/*=======================================================*/
+void GbSystem3D::PointSet3::clear()
+{
+   //clears points (size==0 but capacity is the old c1)
+   this->points.clear();
+   this->consistent = false;
+}
+/*=======================================================*/
+void GbSystem3D::PointSet3::clearAndTrim()
+{
+   //clears points (size==0 AND capacity==0)
+   this->points.resize(0);
+   this->consistent = false;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX1Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x1min;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX1Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x1max;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX2Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x2min;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX2Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x2max;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX3Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x3min;
+}
+/*=======================================================*/
+double GbSystem3D::PointSet3::getX3Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return this->x3max;
+}
+/*=======================================================*/
+int GbSystem3D::PointSet3::contains(GbPoint3D* point)
+{
+   //returns number of points which has the same adress (this should be 0 or 1!!!)
+   int n=0;
+
+   for(int pos=(int)this->points.size()-1; pos>=0; pos--) 
+      if(&this->points[pos]==point) n++;
+
+   return n;
+}
+/*=======================================================*/
+int GbSystem3D::PointSet3::containsEqual(const GbPoint3D& point)
+{
+   //returns number of points which have the same coordinates with point (could be 0,1 or even more)
+   int n=0;
+
+   for(int pos=(int)this->points.size()-1; pos>=0; pos--) 
+      if(this->points[pos].equals(&point)) n++;
+
+   return n;
+}
+/*=======================================================*/
+bool GbSystem3D::PointSet3::containsLine(GbPoint3D *point1, GbPoint3D *point2)
+{
+   //returns true if pointset has c2 in "this->points"vector  neighboured points 
+   //wich have the same adress as point1 or point2
+   vector<GbPoint3D>::iterator pos1=this->points.begin();
+   vector<GbPoint3D>::iterator pos2;
+
+   for(pos2=pos1++; pos2!=this->points.end(); ++pos2) 
+   {
+      if     (&(*pos1)==point1 && &(*pos2)==point2) return true;
+      else if(&(*pos1)==point2 && &(*pos2)==point1) return true;
+
+      pos1=pos2;
+   }
+
+   return false;
+}
+/*=======================================================*/
+bool GbSystem3D::PointSet3::containsEqualLine(const GbPoint3D& point1, const GbPoint3D& point2)
+{
+   //returns true if pointset has c2 in "this->points"vector  neighboured points 
+   //wich have the same coordinates as point1 or point2
+   vector<GbPoint3D>::iterator pos1=this->points.begin();
+   vector<GbPoint3D>::iterator pos2;
+
+   for(pos2=pos1++; pos2!=this->points.end(); ++pos2) 
+   {
+      if     ((*pos1).equals(&point1) && (*pos2).equals(&point2)) return true;
+      else if((*pos1).equals(&point2) && (*pos2).equals(&point1)) return true;
+
+      pos1=pos2;
+   }
+
+   return false;
+}
+/*=======================================================*/
+GbPoint3D* GbSystem3D::PointSet3::getPoint(int index)
+{
+   if(index<0 || index>=(int)this->points.size()) throw UbException(UB_EXARGS,"index out of range");
+   return &(this->points)[index];
+}
+/*=======================================================*/
+GbPoint3D* GbSystem3D::PointSet3::getFirstPoint()
+{
+   return &(this->points.front());
+}
+/*=======================================================*/
+GbPoint3D* GbSystem3D::PointSet3::getLastPoint() 
+{ 
+   return &(this->points.back()); 
+}
+/*=======================================================*/
+int GbSystem3D::PointSet3::size()
+{ 
+   return (int)this->points.size();      
+}
+/*=======================================================*/
+vector<GbPoint3D> GbSystem3D::PointSet3::getPoints()
+{
+   //is this right? it's another effect as at GbPoint3D* getNode(index)!!!
+   //or do we want to have the next uncommented getPoints() funktion
+   return this->points;
+}
+///*=======================================================*/
+//vector<GbPoint3D*> GbSystem3D::PointSet3::getPoints()
+//{
+//   vector<GbPoint3D*> tmp;
+//   for(int pos=0; pos<(int)this->points.size();pos++) tmp.push_back(&this->points[pos]);
+//   
+//   return tmp;
+//}
+/*=======================================================*/
+void GbSystem3D::PointSet3::calculateValues()
+{
+   if(this->points.empty()) 
+   {
+      this->x1min = this->x2min = this->x3min = 0.0;
+      this->x1max = this->x2max = this->x3max = 0.0;
+   }
+   else
+   {
+      this->x1min = (this->points)[0].x1;
+      this->x1max = (this->points)[0].x1;
+      this->x2min = (this->points)[0].x2;
+      this->x2max = (this->points)[0].x2;
+      this->x3min = (this->points)[0].x3;
+      this->x3max = (this->points)[0].x3;
+
+      for(int i=(int)this->points.size()-1; i>0; --i)
+      {
+         if((this->points)[i].x1 < this->x1min) this->x1min = (this->points)[i].x1;
+         if((this->points)[i].x1 > this->x1max) this->x1max = (this->points)[i].x1;
+         if((this->points)[i].x2 < this->x2min) this->x2min = (this->points)[i].x2;
+         if((this->points)[i].x2 > this->x2max) this->x2max = (this->points)[i].x2;
+         if((this->points)[i].x3 < this->x3min) this->x3min = (this->points)[i].x3;
+         if((this->points)[i].x3 > this->x3max) this->x3max = (this->points)[i].x3;
+      }
+   }
+   this->consistent = true;
+}
+
+
+
diff --git a/VirtualFluidsBasics/geometry3d/GbSystem3D.h b/VirtualFluidsBasics/geometry3d/GbSystem3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..57955d6b9f582b4315de114be7866f733bb47134
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbSystem3D.h
@@ -0,0 +1,422 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbSystem3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBSYSTEM3D_H
+#define GBSYSTEM3D_H
+
+#include <iostream>
+#include <cmath>
+#include <vector>
+
+#include <GbPoint3D.h>
+#include <GbObject3D.h>
+#include <basics/utilities/UbMath.h>
+#include <basics/writer/WbWriter.h>
+
+class GbPolygon3D;
+class GbCuboid3D;
+class GbLine3D;
+
+namespace GbSystem3D
+{
+   extern double       getDistance(const GbPoint3D& p11, const GbPoint3D& p12);
+   extern GbPoint3D*   calculateIntersectionPoint3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22);
+   extern GbPolygon3D* clipPolygon3D(std::vector<GbPoint3D> points, double x11, double x12, double x13, double x21, double x22, double x23);
+   extern GbLine3D*    createClipLine3D(GbPoint3D& p1, GbPoint3D& p2, double x11, double x12, double x13, double x21, double x22, double x23);
+   extern bool         hasIntersectionPoint3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22);
+   extern bool         isParallelIn3D(GbPoint3D& p11, GbPoint3D& p12, GbPoint3D& p21, GbPoint3D& p22);
+   extern GbCuboid3D*  clipRectangle3D(GbPoint3D& p1, GbPoint3D& p2, double x11, double x12, double x13, double x21, double x22, double x23);
+
+   /*========================================================================================*/
+   inline static std::string writeGeoObject(GbObject3D* gbobject, const std::string& filename, WbWriter* writer)
+   {
+      std::vector<UbTupleFloat3> nodes;
+      std::vector<UbTupleInt3>   triangles;
+      gbobject->addSurfaceTriangleSet(nodes, triangles);
+
+      std::string outFilename = writer->writeTriangles(filename,nodes,triangles);
+      return outFilename;
+   }
+   //the same as before
+   /*========================================================================================*/
+   inline static std::string writeGeoObject(SPtr<GbObject3D> gbobject, const std::string& filename, WbWriter* writer)
+   {
+      std::vector<UbTupleFloat3> nodes;
+      std::vector<UbTupleInt3>   triangles;
+      gbobject->addSurfaceTriangleSet(nodes, triangles);
+
+      std::string outFilename = writer->writeTriangles(filename,nodes,triangles);
+      return outFilename;
+   }
+   /*========================================================================================*/
+   inline static std::vector< std::string > writeGeoObject(GbObject3D*  gbobject, const std::string& filename, std::vector< WbWriter* > writer )
+   {
+      std::vector<UbTupleFloat3> nodes;
+      std::vector<UbTupleInt3>   triangles;
+      gbobject->addSurfaceTriangleSet(nodes, triangles);
+
+      std::vector< std::string > outFilenames;
+      for(std::size_t i=0; i<writer.size(); ++i)
+         outFilenames.push_back( writer[i]->writeTriangles(filename,nodes,triangles) );
+      return outFilenames;
+   }
+   /*========================================================================================*/
+   inline static std::string writeGeoObjects(std::vector< GbObject3D* > gbobjects, const std::string& filename, WbWriter* writer)
+   {
+      std::vector<UbTupleFloat3> nodes;
+      std::vector<UbTupleInt3>   triangles;
+
+      for(std::size_t i=0; i<gbobjects.size(); ++i)
+      {
+         //std::cout<<i<<", "<<gbobjects[i]<<std::endl;
+         gbobjects[i]->addSurfaceTriangleSet(nodes, triangles);
+      }
+
+      std::string outFilename = writer->writeTriangles(filename,nodes,triangles);
+      return outFilename;
+   }
+   /*========================================================================================*/
+
+   //////////////////////////////////////////////////////////////////////////
+   class PointSet3
+   {
+   public:
+      PointSet3(int n);
+      PointSet3(const std::vector<GbPoint3D>& points);
+      ~PointSet3(){}
+      void   add(const GbPoint3D& point);
+      void   addUnequal(const GbPoint3D& point);
+      void   add(const std::vector<GbPoint3D>& p);
+      int    contains(GbPoint3D* point);
+      void   insert(const GbPoint3D& point, int index);
+      void   clear();
+      void   clearAndTrim();
+      int    containsEqual(const GbPoint3D& point);
+      bool   containsLine(GbPoint3D* point1, GbPoint3D* point2);
+      bool   containsEqualLine(const GbPoint3D& point1, const GbPoint3D& point2);
+      double getX1Minimum();
+      double getX1Maximum();
+      double getX2Minimum();
+      double getX2Maximum();
+      double getX3Minimum();
+      double getX3Maximum();
+      void   calculateValues();
+      int    size();
+      GbPoint3D* getPoint(int index);
+      GbPoint3D* getFirstPoint();
+      GbPoint3D* getLastPoint() ;
+      std::vector<GbPoint3D> getPoints();
+
+   private:
+      double    x1min;
+      double    x1max;
+      double    x2min;
+      double    x2max;
+      double    x3min;
+      double    x3max;
+      bool      consistent;
+      std::vector<GbPoint3D> points;
+
+      void init()
+      {
+         consistent = false;
+         x1min = x2min = x3min = 0.0;
+         x1max = x2max = x3max = 0.0;
+      }
+   };
+   /*=================================================================*/
+   class OldPointSet3
+   {
+   private:
+      int       sizet;
+      double    x1min;
+      double    x1max;
+      double    x2min;
+      double    x2max;
+      double    x3min;
+      double    x3max;
+      bool      consistent;
+      std::vector<GbPoint3D> points;
+
+      void init()
+      {
+         sizet      = 0;
+         x1min      = 0.0;
+         x1max      = 0.0;
+         x2min      = 0.0;
+         x2max      = 0.0;
+         x3min		  = 0.0;
+         x3max      = 0.0;
+         consistent = false;
+         //points   = NULL;
+      };
+
+   public:
+      OldPointSet3(int n)
+      {
+         this->init();
+         this->points.resize(n);
+      }
+      OldPointSet3(std::vector<GbPoint3D> &points)
+      {
+         this->init();
+         this->points.resize(0);//, NULL);
+         this->add(points);
+      };
+      ~OldPointSet3()
+      {
+         //			delete points;
+      };
+      void add(GbPoint3D point)
+         {
+            if(this->sizet>0 && point.equals(&(this->points)[this->sizet-1])) return;
+            if(this->sizet == (int)this->points.size())
+            {
+               std::vector<GbPoint3D> a;
+               a.resize(1+(this->sizet<<1));
+               for(int u=0; u<this->sizet; u++)  { (a)[u] = (points)[u];	}
+               this->points = a;
+            }
+            (this->points)[this->sizet] = point;
+            this->consistent				= false;
+            this->sizet++;
+         }
+         void addUnequal(GbPoint3D *point)
+         {
+            if(this->containsEqual(point) > 0) return;
+            if(this->sizet == (int)this->points.size())
+            {
+               std::vector<GbPoint3D> a;
+               a.resize(1+(this->sizet<<1));
+               for(int u=0; u<this->sizet; u++)  { (a)[u] = (points)[u];	}
+               this->points = a;
+            }
+            (this->points)[this->sizet] = point;
+            this->consistent        = false;
+            this->sizet++;
+         }
+         void add(std::vector<GbPoint3D> &p)
+         {
+            if(this->sizet+p.size() >= this->points.size())
+            {
+               std::vector<GbPoint3D> a;
+               a.resize(this->sizet+p.size());
+               for(int u=0; u<(int)this->points.size(); u++)  { (a)[u] = (this->points)[u];	}
+               this->points = a;
+            }
+            int u = this->sizet;// (int)this->points->size();
+            for(int b=0; b<(int)p.size(); b++)			(this->points)[u++] = (p)[b];
+            //u = this->sizet;
+            //for(int b=0; b<(int)p->size(); b++)
+            //	cout<<(this->points)[u++].toString()<<endl;
+            this->consistent  = false;
+            this->sizet      += (int)p.size();
+         };
+         //		void insert(GbPoint3D *point, int index)
+         //      {
+         //	 if(this.size == this.points.length)
+         //	 {
+         //	    GbPoint3D a[] = new GbPoint3D[1+(this.size<<1)];
+         //	    System.arraycopy(this.points, 0, a, 0, this.size);
+         //	    this.points = a;
+         //	 }
+         //	 System.arraycopy(this.points, index, this.points, index+1, this.size-index);
+         //	 this.points[index] = point;
+         //	 this.consistent    = false;
+         //	 this.size++;
+         //      }
+         //      void delete(GbPoint3D point)
+         //      {
+         //	 for(int i=this.size-1; i>=0; i--) if(this.points[i] == point) this.delete(i);
+         //      }
+         //      void delete(int index)
+         //      {
+         //	 int j = this.size - index - 1;
+         //	 if(j > 0) System.arraycopy(this.points, index + 1, this.points, index, j);
+         //	 this.consistent = false;
+         //	 this.size--;
+         //      }
+         void clear()
+         {
+            this->sizet    = 0;
+            this->consistent = false;
+         }
+         void clearAndTrim()
+         {
+            this->sizet       = 0;
+            this->points.resize(0);
+            this->consistent = false;
+         }
+
+         double getX1Minimum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x1min);
+         }
+         double getX1Maximum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x1max);
+         }
+         double getX2Minimum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x2min);
+         }
+         double getX2Maximum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x2max);
+         }
+         double getX3Minimum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x3min);
+         }
+         double getX3Maximum()
+         {
+            if(!this->consistent) this->calculateValues();
+            return(this->x3max);
+         }
+         void calculateValues()
+         {
+            this->x1min      = 0.0;
+            this->x1max      = 0.0;
+            this->x2min      = 0.0;
+            this->x2max      = 0.0;
+            this->x3min      = 0.0;
+            this->x3max      = 0.0;
+            this->consistent = true;
+
+            if(this->sizet == 0) return;
+
+            this->x1min = (this->points)[0].x1;
+            this->x1max = (this->points)[0].x1;
+            this->x2min = (this->points)[0].x2;
+            this->x2max = (this->points)[0].x2;
+            this->x3min = (this->points)[0].x3;
+            this->x3max = (this->points)[0].x3;
+
+            for(int i=this->sizet-1; i>0; i--)
+            {
+               if((this->points)[i].x1 < this->x1min) this->x1min = (this->points)[i].x1;
+               if((this->points)[i].x1 > this->x1max) this->x1max = (this->points)[i].x1;
+               if((this->points)[i].x2 < this->x2min) this->x2min = (this->points)[i].x2;
+               if((this->points)[i].x2 > this->x2max) this->x2max = (this->points)[i].x2;
+               if((this->points)[i].x3 < this->x3min) this->x3min = (this->points)[i].x3;
+               if((this->points)[i].x3 > this->x3max) this->x3max = (this->points)[i].x3;
+            }
+         };
+
+         int contains(GbPoint3D *point)
+         {
+            int n = 0;
+            for(int i=this->sizet-1; i>=0; i--) if(&(this->points)[i] == point) n++;
+            return(n);
+         };
+         int containsEqual(GbPoint3D *point)
+         {
+            int n = 0;
+            for(int i=this->sizet-1; i>=0; i--) if((this->points)[i].equals(point)) n++;
+            return(n);
+         }
+         bool containsLine(GbPoint3D *point1, GbPoint3D *point2)
+         {
+            for(int i=this->sizet-1; i>=0; i--) if(&(this->points)[i] == point1)
+            {
+               if(i == 0)
+               {
+                  if(&(this->points)[i+1]           == point2) return(true);
+                  if(&(this->points)[this->sizet-1] == point2) return(true);
+               }
+               else if(i == this->sizet-1)
+               {
+                  if(&(this->points)[0]   == point2) return(true);
+                  if(&(this->points)[i-1] == point2) return(true);
+               }
+               else
+               {
+                  if(&(this->points)[i+1] == point2) return(true);
+                  if(&(this->points)[i-1] == point2) return(true);
+               }
+            }
+            return(false);
+         };
+         //      boolean containsEqualLine(GbPoint2D point1, GbPoint2D point2)
+         //      {
+         //	 for(int i=this.size-1; i>=0; i--) if(this.points[i].equals(point1))
+         //	 {
+         //	    if(i == 0)
+         //	    {
+         //	       if(this.points[i+1].equals(point2))         return(true);
+         //	       if(this.points[this.size-1].equals(point2)) return(true);
+         //	    }
+         //	    else if(i == this.size-1)
+         //	    {
+         //	       if(this.points[0].equals(point2))   return(true);
+         //	       if(this.points[i-1].equals(point2)) return(true);
+         //	    }
+         //	    else
+         //	    {
+         //	       if(this.points[i+1].equals(point2)) return(true);
+         //	       if(this.points[i-1].equals(point2)) return(true);
+         //	    }
+         //	 }
+         //	 return(false);
+         //      }
+         GbPoint3D *getPoint(int index)
+         {
+            return(&(this->points)[index]);
+         }
+         GbPoint3D *getFirstPoint()
+         {
+            return(&(this->points)[0]);
+         }
+         GbPoint3D *getLastPoint() { return(&(this->points)[this->sizet-1]); }
+         int size()                { return(this->sizet);      }
+         std::vector<GbPoint3D> getPoints()
+         {
+            points.resize(sizet);
+            return points;
+            //int l = this->sizet;
+            //if(l > 1 && (this->points)[0].equals(&(this->points)[l-1])) l--;
+
+            //vector<GbPoint3D*> *a = new vector<GbPoint3D*>;
+            //a->resize(l, NULL);
+            //for(int u=0; u<l; u++)  { (*a)[u] = &((points)[u]);	}
+            //return(a);
+         }
+      };
+      /*=================================================================*/
+}
+
+#endif //GBSYSTEM3D_H
diff --git a/VirtualFluidsBasics/geometry3d/GbTriangle3D.cpp b/VirtualFluidsBasics/geometry3d/GbTriangle3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9024aaf40f67f226392e15a9cfc6470d55ca39a
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbTriangle3D.cpp
@@ -0,0 +1,1130 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbTriangle3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbTriangle3D.h>
+#include <GbSystem3D.h>
+#include <GbLine3D.h>
+#include <GbCuboid3D.h>
+
+#include <basics/utilities/UbMath.h>
+
+using namespace std;                                                               
+
+GbTriangle3D::GbTriangle3D()
+{
+   this->init();
+   this->consistent = false;
+}
+/*======================================================================*/
+/*
+* Creates an empty 2D triangle with the specified points.
+* @param point1 the 1st point
+* @param point2 the 2nd point
+* @param point3 the 3nd point
+*/
+GbTriangle3D::GbTriangle3D(GbPoint3D* point1, GbPoint3D* point2, GbPoint3D* point3)
+{
+   this->init();
+   this->points[0] = point1;
+   this->points[1] = point2;
+   this->points[2] = point3;
+
+   this->calculateNormal();
+   this->consistent = false;
+
+   this->points[0]->addObserver(this);
+   this->points[1]->addObserver(this);
+   this->points[2]->addObserver(this);
+   
+   //this.po        = new PointObserver(this);
+   //this.points[0].addObserver(this.po);
+   //this.points[1].addObserver(this.po);
+   //this.points[2].addObserver(this.po);
+}
+/*======================================================================*/
+/*
+* Creates a 3D triangle as clone of the specified 2D triangle.
+* @param triangle the 3D triangle to be cloned
+*/
+GbTriangle3D::GbTriangle3D(GbTriangle3D* triangle)
+{
+   this->init();
+   this->points[0] = triangle->points[0]->clone();
+   this->points[1] = triangle->points[1]->clone();
+   this->points[2] = triangle->points[2]->clone();
+
+   this->consistent = false;
+   this->calculateNormal();
+   this->calculateValues();
+}
+/*======================================================================*/
+GbTriangle3D::~GbTriangle3D()
+{
+   if(this->points[0]) this->points[0]->removeObserver(this);
+   if(this->points[1]) this->points[1]->removeObserver(this);
+   if(this->points[2]) this->points[2]->removeObserver(this);
+}
+/*======================================================================*/
+void GbTriangle3D::deletePoints()
+{ 
+   if(points[0]) { delete points[0]; points[0]=NULL;}
+   if(points[1]) { delete points[1]; points[1]=NULL;}
+   if(points[2]) { delete points[2]; points[2]=NULL;}
+}
+
+/*======================================================================*/
+/*  Methoden                                                            */
+/*                                                                      */
+/*
+* Creates a 3D triangle as clone of this 3D triangle.
+*/
+GbTriangle3D* GbTriangle3D::clone()
+{
+   return(new GbTriangle3D(this));
+}
+/*======================================================================*/
+/*
+* Returns the number of times this 2D triangle contains the specified point.
+* @param point the point
+* @return the number of times this 2D triangle contains the specified point
+*/
+int GbTriangle3D::contains(GbPoint3D* point)
+{
+   int n = 0;
+   for(int i=0; i<3; i++) if(this->points[i]->equals(point)) n++;
+   return(n);
+}
+/*======================================================================*/
+/*
+* Returns the number of times this 2D triangle contains a point equal to the specified point.
+* @param point the point
+* @return the number of times this 2D triangle contains a point equal to the specified point
+*/
+int GbTriangle3D::containsEqual(GbPoint3D* point)
+{
+   int n = 0;
+   for(int i=0; i<3; i++) if(this->points[i]->equals(point)) n++;
+   return(n);
+}
+/*======================================================================*/
+/*
+* Returns the specified point.
+* @param index the index (must be 0, 1, or 2)
+* @return the specified point
+* @exception ArrayIndexOutOfBoundsException if the specified index is not valid
+*/
+GbPoint3D* GbTriangle3D::getPoint(const int& index) 
+{
+   if(index < 0 || index > 2) throw UbException(UB_EXARGS,"invalid index specified: ");
+   return((this->points[index]));
+}
+/*======================================================================*/
+vector<GbPoint3D> GbTriangle3D::getPoints() 
+{
+   vector<GbPoint3D> p(3);
+   p[0] = *(points[0]);
+   p[1] = *(points[1]);
+   p[2] = *(points[2]);
+   return p;
+   //
+   //vector<GbPoint3D> p(3);// = new vector<GbPoint3D*>;
+   //p.resize(3);//, NULL);
+   //p[0] = this->points[0];
+   //p[1] = this->points[1];
+   //p[2] = this->points[2];
+   //return(p);
+}
+/*======================================================================*/
+/*
+* Returns the area of this triangle.
+* The area is positive for positive ordered points, otherwise negative.
+* @return the area of this triangle
+*/
+double GbTriangle3D::getArea()
+{
+   if(!this->consistent) this->calculateValues();
+   // throw UbException(UB_EXARGS,"not correct calculated ...");
+   return(this->area);
+}
+/*
+* Returns the centroid x1 coordinate of this triangle.
+* @return the centroid x1 coordinate of this triangle
+*/
+double GbTriangle3D::getX1Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1s);
+}
+/*
+* Returns the minimum x1 coordinate of this triangle.
+* @return the minimum x1 coordinate of this triangle
+*/
+double GbTriangle3D::getX1Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1min);
+}
+/*
+* Returns the maximum x1 coordinate of this triangle.
+* @return the maximum x1 coordinate of this triangle
+*/
+double GbTriangle3D::getX1Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x1max);
+}
+/*
+* Returns the centroid x2 coordinate of this triangle.
+* @return the centroid x2 coordinate of this triangle
+*/
+double GbTriangle3D::getX2Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2s);
+}
+/*                                                         
+* Returns the minimum x2 coordinate of this triangle.
+* @return the minimum x2 coordinate of this triangle
+*/
+double GbTriangle3D::getX2Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2min);
+}
+/*
+* Returns the maximum x2 coordinate of this triangle.
+* @return the maximum x2 coordinate of this triangle
+*/
+double GbTriangle3D::getX2Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x2max);
+}
+double GbTriangle3D::getX3Centroid()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3s);
+}
+double GbTriangle3D::getX3Minimum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3min);
+}
+double GbTriangle3D::getX3Maximum()
+{
+   if(!this->consistent) this->calculateValues();
+   return(this->x3max);
+}
+
+/*
+* Sets the specified point.
+* @param point the point
+* @param index the index (must be 0, 1, or 2)
+* @exception ArrayIndexOutOfBoundsException if the specified index is not valid
+*/
+void GbTriangle3D::setPoint(GbPoint3D* point, int index) 
+{
+   if(index < 0 || index > 2) throw UbException(UB_EXARGS,"invalid index specified: ");
+   this->points[index] = point;
+   this->consistent    = false;
+   this->calculateNormal();
+}
+
+/*
+* Returns the surface triangle set with new nodes !!!
+* @returns the surface triangle set with new nodes !!!
+*/
+vector<GbTriangle3D*> GbTriangle3D::getSurfaceTriangleSet()
+{
+   vector<GbTriangle3D*> triangles;
+   
+   triangles.push_back(new GbTriangle3D(new GbPoint3D(getPoint1()),new GbPoint3D(getPoint2()),new GbPoint3D(getPoint3())));
+
+   return triangles;
+}
+
+
+/*
+* Returns the string representation of the triangle
+* @returns the string representation of the triangle
+*/
+
+string GbTriangle3D::toString()
+{
+   stringstream ss;
+   ss<<"GbTriangle3D[area=";
+   ss<<this->getArea();
+
+   ss<<", x1s="<<this->x1s;
+   ss<<", x2s="<<this->x2s;
+   ss<<", x3s="<<this->x3s;
+   ss<<", x1min="<<this->x1min;
+   ss<<", x1max="<<this->x1max;
+   ss<<", x2min="<<this->x2min;
+   ss<<", x2max="<<this->x2max;
+   ss<<", x3min="<<this->x3min;
+   ss<<", x3max="<<this->x3max;
+   ss<<", points1="<<this->points[0]->toString();
+   ss<<", points2="<<this->points[1]->toString();
+   ss<<", points3="<<this->points[2]->toString();
+   ss<<"]";
+   return((ss.str()).c_str());
+}
+/*======================================================================*/
+double GbTriangle3D::getIntersectionRaytraceFactor(const double& x1, const double& x2, const double& x3, const double& rx1, const double& rx2, const double& rx3)
+{
+   //e1 = v1 - v0
+   double e1x1 = this->points[1]->x1-this->points[0]->x1;
+   double e1x2 = this->points[1]->x2-this->points[0]->x2;
+   double e1x3 = this->points[1]->x3-this->points[0]->x3;  
+
+   //e2 = v2 - v0
+   double e2x1 = this->points[2]->x1-this->points[0]->x1;
+   double e2x2 = this->points[2]->x2-this->points[0]->x2;
+   double e2x3 = this->points[2]->x3-this->points[0]->x3;  
+
+   //p = d x e2
+   double px1 = rx2*e2x3 - rx3*e2x2;
+   double px2 = rx3*e2x1 - rx1*e2x3;
+   double px3 = rx1*e2x2 - rx2*e2x1;
+
+   //a = e1 dot p
+   double a = e1x1*px1 + e1x2*px2 + e1x3*px3;
+   if(fabs(a)<1.E-10) return -1.0;
+   double f = 1.0/a;
+
+   //s = o - v0
+   double sx1 = x1 - this->points[0]->x1;
+   double sx2 = x2 - this->points[0]->x2;
+   double sx3 = x3 - this->points[0]->x3;
+
+   //u = f * ( s dot p)
+   double u = f * ( sx1*px1 + sx2*px2 + sx3*px3 );
+   if(u<-1.E-10 || u>1.0+1.E-10) return -1.0;
+
+   //q = s x e1
+   double qx1 = sx2*e1x3 - sx3*e1x2;
+   double qx2 = sx3*e1x1 - sx1*e1x3;
+   double qx3 = sx1*e1x2 - sx2*e1x1;
+
+   //v = f*(e2 dot q)
+   double v = f * (rx1*qx1 + rx2*qx2 + rx3*qx3);
+   if(v<-1.E-10 || (u+v)>1.0+1.E-10) return -1.0;
+
+   //t = f * (e2 dot q)
+   return f * (e2x1*qx1 + e2x2*qx2 + e2x3*qx3);
+}
+
+/*===========================================================*/
+
+GbLine3D* GbTriangle3D::createClippedLine3D(GbPoint3D& point1, GbPoint3D& point2)
+{
+   GbPoint3D *result = this->calculateIntersectionPoints3D(&point1, &point2);
+   if(!result) return NULL;
+
+   return new GbLine3D(result, new GbPoint3D(point2));
+
+   //return GbSystem::createClipLine3D(point1, point2,
+      //p1->getX1Coordinate(),p1->getX2Coordinate(),p1->getX3Coordinate(),
+      //p2->getX1Coordinate(),p2->getX2Coordinate(),p2->getX3Coordinate() );
+}
+
+//von Navodit ...
+/*===========================================================*/
+GbPoint3D* GbTriangle3D::calculateIntersectionPoints3D(GbLine3D* line)
+{
+   return this->calculateIntersectionPoints3D(line->getPoint1(), line->getPoint2());
+}
+/*===========================================================*/
+GbPoint3D* GbTriangle3D::calculateIntersectionPoints3D(GbPoint3D* linePoint1, GbPoint3D* linePoint2)
+{
+   GbVector3D Point1(linePoint1->x1, linePoint1->x2, linePoint1->x3);
+   GbVector3D Point2(linePoint2->x1, linePoint2->x2, linePoint2->x3);
+   GbVector3D direction = Point2-Point1;
+   GbVector3D GbPoint3D1(this->getPoint1()->x1,this->getPoint1()->x2,this->getPoint1()->x3);
+   GbVector3D GbPoint3D2(this->getPoint2()->x1,this->getPoint2()->x2,this->getPoint2()->x3);
+   GbVector3D GbPoint3D3(this->getPoint3()->x1,this->getPoint3()->x2,this->getPoint3()->x3);
+   GbVector3D V2V1 = GbPoint3D2-GbPoint3D1;
+   GbVector3D V3V1 = GbPoint3D3-GbPoint3D1;
+   GbVector3D V2V1V3V1 = V2V1.Cross(V3V1);
+   V2V1V3V1.Normalize();
+   GbVector3D Normal = V2V1V3V1;
+
+   double d = -Normal.Dot(GbPoint3D1);            
+   double denom = Normal.Dot(direction);       
+
+   if (UbMath::zero(denom)) return NULL;   //line does not intersect the plane of the triangle !
+   else
+   {
+      double mu = -1.*(d + Point1.Dot(Normal))/denom;            //mu = -(d+ Normal.Point1)/denom
+
+      //   GbVector3D p1 = Point2-Point1;
+      //   GbVector3D p2 = p1*mu;
+      //   GbVector3D p3 = Point1+p2;
+      GbVector3D point = Point1 + mu*(Point2 -Point1);
+
+      if (mu<0.0 || mu>1.0)    return NULL;     // Point of intersection of line and plane does not lie on the triangle   
+      else
+      {
+         //Test whether Point lies inside the triangle or not
+         bool test=true;
+         GbVector3D a = GbPoint3D1-point;
+         GbVector3D b = GbPoint3D2-point;
+         GbVector3D c = GbPoint3D3-point;
+         GbVector3D ab = a.Cross(b);
+         GbVector3D bc = b.Cross(c);
+         GbVector3D ca = c.Cross(a);
+         GbVector3D Q1 = ab*0.5;
+         GbVector3D Q2 = bc*0.5;
+         GbVector3D Q3 = ca*0.5;
+         GbVector3D Q1Q2 = Q1+Q2;
+         GbVector3D Q = Q1Q2+Q3;
+
+         if (UbMath::less(Q.Dot(Q1), 0.0)) test = false; 
+         if (UbMath::less(Q.Dot(Q2), 0.0)) test = false; 
+         if (UbMath::less(Q.Dot(Q3), 0.0)) test = false; 
+
+         if (test == true) return (new GbPoint3D(point.X1(), point.X2(), point.X3()));
+         else          return NULL;
+      }
+   }
+}
+
+/**
+* Returns the distance between the 3D triangle and the specified 3D Point                                                                      
+* @param point the 3D point from whom the distance is to be calculated
+* @return the distance of the specified point from the triangle
+*/
+double GbTriangle3D::calculateDistanceToPoint3D(GbPoint3D *point) 
+{
+   return this->calculateDistanceToPoint3D(point->x1, point->x2, point->x3);
+}
+/*=======================================================================*/
+double GbTriangle3D::calculateDistanceToPoint3D(const double& x1, const double& x2, const double& x3) 
+{
+   //
+   //throw UbException(UB_EXARGS,"Ich glaub GbTriangle3D::calculateDistanceToPoint3D(...) kann man so nicht nehmen,jedenfalls nicht fuer die q's");
+   cout<<"??? ch glaub GbTriangle3D::calculateDistanceToPoint3D(...) kann man so nicht nehmen,jedenfalls nicht fuer die q's"<<endl;
+   GbVector3D P0(x1, x2, x3);
+   GbVector3D P1(this->points[0]->x1, this->points[0]->x2, this->points[0]->x3);
+   GbVector3D P2(this->points[1]->x1, this->points[1]->x2, this->points[1]->x3);
+   GbVector3D P3(this->points[2]->x1, this->points[2]->x2, this->points[2]->x3);
+
+   //Determine normal to triangle
+   GbVector3D Normal = (P1-P2).Cross(P1-P3);
+   double alpha = UbMath::ACos((P1-P0).Dot(Normal)/((P1-P0).Length()*Normal.Length()));
+
+   double P0P0dash = (P0-P1).Length()*cos(alpha);
+   Normal.Normalize();
+   GbVector3D Projection = Normal*(-P0P0dash);
+
+   GbVector3D P0dash = P0+Projection;
+
+   //Check if point P0dash lies within the triangle P1P2P3.
+   bool test = false;
+   if ( ((P1-P0).Cross(P2-P0)).Dot(Normal) > 0 ) test = true;
+   if ( ((P2-P0).Cross(P3-P0)).Dot(Normal) > 0 ) test = true;
+   if ( ((P3-P0).Cross(P1-P0)).Dot(Normal) > 0 ) test = true;
+
+   if (test == true) return (P0-P0dash).Length();
+   else
+   // Determine the distance of point P0 from all edges and vertices and return the minimum distance
+   {
+      double dP0P1 = (P0-P1).Length(); //Distance of Point P0 from Point P1
+      double dP0P2 = (P0-P2).Length(); //Distance of Point P0 from Point P2
+      double dP0P3 = (P0-P3).Length(); //Distance of Point P0 from Point P3
+
+      GbVector3D MP1P2 = P2-P1;        //Direction vector for line P1P2
+      GbVector3D MP2P3 = P3-P2;        //Direction vector for line P2P3
+      GbVector3D MP3P1 = P1-P3;        //Direction vector for line P3P1
+
+      double tP1P2 = MP1P2.Dot(P0-P1) / MP1P2.Dot(MP1P2);
+      double tP2P3 = MP2P3.Dot(P0-P2) / MP2P3.Dot(MP2P3);
+      double tP3P1 = MP3P1.Dot(P0-P3) / MP3P1.Dot(MP3P1);
+
+      double dP1P2 = (P0-(P1+(MP1P2*tP1P2))).Length(); //Distance of Point P0 from line P1P2
+      double dP2P3 = (P0-(P2+(MP2P3*tP2P3))).Length(); //Distance of Point P0 from line P2P3
+      double dP3P1 = (P0-(P3+(MP3P1*tP3P1))).Length(); //Distance of Point P0 from line P3P1
+
+      double distanceP0[6]; //Array to store all the distances from Point P0
+      distanceP0[0] = dP0P1; 
+      distanceP0[1] = dP0P2; 
+      distanceP0[2] = dP0P3; 
+      distanceP0[3] = dP1P2; 
+      distanceP0[4] = dP2P3; 
+      distanceP0[5] = dP3P1; 
+
+      double d = 0.0;
+      //Find the minimum distance from Point P0
+      for (int i=0; i<6; i++)
+      {
+         if(distanceP0[i]<d) d = distanceP0[i];
+      }
+      return d;
+   }
+}
+/**
+* Returns the normalized distance between the 3D triangle and the specified 3D Point
+* copied from Benjamin A.
+* @param point the 3D point from whom the distance is to be calculated
+* @return the distance of the specified point from the triangle
+*/
+double GbTriangle3D::calculateNormalizedDistanceToPoint3D(const double& x1, const double& y1, const double& z1, 
+                                                          const double& x2, const double& y2, const double& z2)
+{
+    //face* pf
+    double xa, xb, xc, ya, yb, yc, za, zb, zc;
+    //double xp, yp, zp;
+    double tt=0, xi=0, eta=0;
+    double zaehler, nenner;
+    double wurzel3 = sqrt(3.);
+
+    //Weltkoordinaten der Dreiecke
+    xa = this->points[0]->x1;
+    xb = this->points[1]->x1;
+    xc = this->points[2]->x1;
+         
+    ya = this->points[0]->x2;
+    yb = this->points[1]->x2;
+    yc = this->points[2]->x2;
+
+    za = this->points[0]->x3;
+    zb = this->points[1]->x3;
+    zc = this->points[2]->x3;
+
+    //Shape-Funktionen zum Berechnen der Schnittpunkte
+    zaehler =
+       static_cast<double>(((-1.0*zc+zb)*ya+(yc-1.0*yb)*za+zc*yb-1.0*zb*yc)*x1
+       +((-1.0*zb+zc)*xa+(xb-1.0*xc)*za-1.0*xb*zc+xc*zb)*y1+((-1.0*yc+yb)*xa
+       +(-1.0*xb+xc)*ya-1.0*xc*yb+xb*yc)*z1+((-1.0*zc+zb)*ya+(yc-1.0*yb)*za
+       +zc*yb-1.0*zb*yc)*x2+((-1.0*zb+zc)*xa+(xb-1.0*xc)*za-1.0*xb*zc+xc*zb)*y2
+       +((-1.0*yc+yb)*xa+(-1.0*xb+xc)*ya-1.0*xc*yb+xb*yc)*z2+(2.0*zb*yc-2.0*zc*yb)*xa
+       +(2.0*xb*zc-2.0*xc*zb)*ya+(-2.0*xb*yc+2.0*xc*yb)*za);
+    nenner  =
+       static_cast<double>((((-1.0*zc+zb)*ya+(yc-1.0*yb)*za+zc*yb-1.0*zb*yc)*x1
+       +((-1.0*zb+zc)*xa+(xb-1.0*xc)*za-1.0*xb*zc+xc*zb)*y1+((-1.0*yc+yb)*xa
+       +(-1.0*xb+xc)*ya-1.0*xc*yb+xb*yc)*z1+((-1.0*zb+zc)*ya+(-1.0*yc+yb)*za-1.0*zc*yb+zb*yc)
+       *x2+((-1.0*zc+zb)*xa+(-1.0*xb+xc)*za+xb*zc-1.0*xc*zb)*y2+((yc-1.0*yb)*xa+(xb
+       -1.0*xc)*ya+xc*yb-1.0*xb*yc)*z2));
+    if( UbMath::greater(nenner, 0.0) ) tt = zaehler/nenner;
+    else tt=-999.;
+
+    zaehler =
+       static_cast<double>(((-2.0*zc+za+zb)*y2+(-1.0*yb-1.0*ya+2.0*yc)*z2+zc*ya
+       -1.0*zb*yc+zc*yb-1.0*za*yc)*x1+((-1.0*za+2.0*zc-1.0*zb)*x2+(xa-2.0*xc+xb)*z2
+       -1.0*xa*zc-1.0*xb*zc+xc*za+xc*zb)*y1+((-2.0*yc+ya+yb)*x2+(-1.0*xa-1.0*xb+2.0*xc)
+       *y2-1.0*xc*yb+xa*yc+xb*yc-1.0*xc*ya)*z1+(zb*yc-1.0*zc*ya-1.0*zc*yb+za*yc)
+       *x2+(-1.0*xc*za+xb*zc+xa*zc-1.0*xc*zb)*y2+(xc*yb-1.0*xa*yc-1.0*xb*yc+xc*ya)*z2);
+    nenner  =
+       static_cast<double>((((zc-1.0*zb)*ya+(yb-1.0*yc)*za+zb*yc-1.0*zc*yb)*x1
+       +((zb-1.0*zc)*xa+(xc-1.0*xb)*za-1.0*xc*zb+xb*zc)*y1+((-1.0*yb+yc)*xa+(xb-1.0*xc)
+       *ya-1.0*xb*yc+xc*yb)*z1+((zb-1.0*zc)*ya+(-1.0*yb+yc)*za+zc*yb-1.0*zb*yc)*x2
+       +((zc-1.0*zb)*xa+(xb-1.0*xc)*za-1.0*xb*zc+xc*zb)*y2+((yb-1.0*yc)*xa
+       +(xc-1.0*xb)*ya+xb*yc-1.0*xc*yb)*z2));
+    if( UbMath::greater(nenner, 0.0) ) xi = zaehler/nenner;
+    else xi=-999.;
+
+    zaehler =
+       static_cast<double>(((za-1.0*zb)*y2+(-1.0*ya+yb)*z2-1.0*za*yb+zb*ya)*x1+
+       ((-1.0*za+zb)*x2+(xa-1.0*xb)*z2-1.0*xa*zb+xb*za)*y1+((ya-1.0*yb)*x2+(xb-1.0*xa)
+       *y2+xa*yb-1.0*xb*ya)*z1+(-1.0*zb*ya+za*yb)*x2+(-1.0*xb*za+xa*zb)*y2
+       +(-1.0*xa*yb+xb*ya)*z2);
+    nenner  =
+       static_cast<double>((((zc-1.0*zb)*ya+(yb-1.0*yc)*za+zb*yc-1.0*zc*yb)*x1
+       +((zb-1.0*zc)*xa+(xc-1.0*xb)*za-1.0*xc*zb+xb*zc)*y1+((-1.0*yb+yc)*xa+(xb-1.0*xc)
+       *ya-1.0*xb*yc+xc*yb)*z1+((zb-1.0*zc)*ya+(-1.0*yb+yc)*za+zc*yb-1.0*zb*yc)*x2
+       +((zc-1.0*zb)*xa+(xb-1.0*xc)*za-1.0*xb*zc+xc*zb)*y2+((yb-1.0*yc)*xa+(xc-1.0*xb)
+       *ya+xb*yc-1.0*xc*yb)*z2));
+    if ( UbMath::greater(nenner, 0.0) ) eta = static_cast<double>((zaehler/nenner)*wurzel3*-1.);
+    else eta=-999.;
+
+    if (tt >= -1.0-UbMath::Epsilon<double>::val() && tt <= 1.0){
+       if(xi >= -1.0+eta/wurzel3-UbMath::Epsilon<double>::val() && xi <=
+          1.0-eta/wurzel3+UbMath::Epsilon<double>::val()){
+             if (eta >= 0-UbMath::Epsilon<double>::val() && eta <= wurzel3+UbMath::Epsilon<double>::val()){
+                /*xp = x1*(0.5-tt/2)+x2*(0.5+tt/2);
+                yp = y1*(0.5-tt/2)+y2*(0.5+tt/2);
+                zp = z1*(0.5-tt/2)+z2*(0.5+tt/2);*/
+                return
+                   static_cast<double>((sqrt(pow((x1*(0.5-tt/2)+x2*(0.5+tt/2))-x1,2)
+                   +pow((y1*(0.5-tt/2)+y2*(0.5+tt/2))-y1,2)+pow((z1*(0.5-tt/2)+z2*(0.5+tt/2))-z1,2))));
+             }
+          }
+    }
+    return (-999.);
+}
+/*
+* Returns true if the specified 2D point lies within (or on the border of) this 2D triangle.
+* @param point the 2D point to check
+* @return true if the specified 2D point lies within (or on the border of) this 2D triangle
+*/
+ bool GbTriangle3D::enclosesPoint2D(double x1, double x2)
+ {
+	 int i=0;
+	 //Punkt(x1,x2) liegt auf einem der Eckpunkte
+    if(x1==this->getPoint(0)->getX1Coordinate() && x2 == this->getPoint(0)->getX2Coordinate())	return true;
+	 if(x1==this->getPoint(1)->getX1Coordinate() && x2 == this->getPoint(1)->getX2Coordinate())	return true;
+	 if(x1==this->getPoint(2)->getX1Coordinate() && x2 == this->getPoint(2)->getX2Coordinate())  return true;
+
+	 //Erste Grade aus dem zu pruefenden Punkt(x,y) und einem zweiten Punkt(x+0.333,y+2.333)
+	 GbPoint3D p1;		p1.setX1(x1);			p1.setX2(x2);			p1.setX3(0.0);
+	 GbPoint3D p2;		p2.setX1(x1+0.333);	p2.setX2(x2+3.333);	p2.setX3(0.0);
+	 //Punkte des Dreiecks auf 2D reduziert
+	 GbPoint3D dp1;	dp1.setX1(this->getPoint(0)->getX1Coordinate());	dp1.setX2(this->getPoint(0)->getX2Coordinate());	dp1.setX3(0.0);
+	 GbPoint3D dp2;	dp2.setX1(this->getPoint(1)->getX1Coordinate());	dp2.setX2(this->getPoint(1)->getX2Coordinate());	dp2.setX3(0.0);
+	 GbPoint3D dp3;	dp3.setX1(this->getPoint(2)->getX1Coordinate());	dp3.setX2(this->getPoint(2)->getX2Coordinate());	dp3.setX3(0.0);
+	 //ueberpruefen, ob der Punkt(x,y) innerhalt der Boundingbox des Dreiecks liegt
+	 if(	 x1<this->getX1Maximum() && x1>getX1Minimum()
+		 && x2<this->getX2Maximum() && x2>getX2Minimum())
+	 {
+		 GbPoint3D* dummy = NULL;
+		 //ueberpruefen, ob der Punkt innerhalb des Dreiecks liegt
+		 dummy = GbSystem3D::calculateIntersectionPoint3D(p1,p2,dp1,dp2);
+		 if(dummy!=NULL)
+       {
+          if(dummy->getX1Coordinate()==p1.getX1Coordinate() && dummy->getX2Coordinate()==p1.getX2Coordinate())	
+          {
+             delete dummy;
+             return true;
+          }
+			 else if(dummy->getX1Coordinate()>p1.getX1Coordinate())
+          {
+             i++;
+          }
+			 else
+          {
+             i--;
+          }
+       }
+       if(dummy)  delete dummy;
+
+       dummy = GbSystem3D::calculateIntersectionPoint3D(p1,p2,dp2,dp3);
+		 if(dummy!=NULL)
+       {
+          if(dummy->getX1Coordinate()==p1.getX1Coordinate() && dummy->getX2Coordinate()==p1.getX2Coordinate())
+          {
+             if(dummy)  delete dummy;
+             return true;
+          }
+			 else if(dummy->getX1Coordinate()>p1.getX1Coordinate())
+          {
+             i++;
+          }
+			 else
+          {
+             i--;
+          }
+       }
+       if(dummy)  delete dummy;
+
+		 dummy = GbSystem3D::calculateIntersectionPoint3D(p1,p2,dp3,dp1);
+		 if(dummy!=NULL)
+       {
+          if(dummy->getX1Coordinate()==p1.getX1Coordinate() && dummy->getX2Coordinate()==p1.getX2Coordinate())
+          {
+             if(dummy)  delete dummy;
+             return true;
+          }
+			 else if(dummy->getX1Coordinate()>p1.getX1Coordinate())
+          {
+             i++;
+          }
+          else
+          {
+             i--;
+          }
+       }
+       if(dummy)  delete dummy;
+	 }
+	 if(i==-1) return true;
+	 if(i==1 ) return true;
+	
+    return false;
+ }
+
+///*
+//* Returns a new 2D polygon clipped by the specified 2D rectangle (result may be null!).
+//* @param rectangle the 2D rectangle
+//* @return a new 2D polygon clipped by the specified 2D rectangle
+//*/
+GbPolygon3D* GbTriangle3D::createClippedPolygon3D(GbCuboid3D* cube)
+{
+   return(GbSystem3D::clipPolygon3D(this->getPoints(), cube->getPoint1()->getX1Coordinate(), cube->getPoint1()->getX2Coordinate(), cube->getPoint1()->getX3Coordinate(), cube->getPoint2()->getX1Coordinate(), cube->getPoint2()->getX2Coordinate(), cube->getPoint2()->getX3Coordinate()));
+}
+///*
+//* Returns a new 2D polygon clipped by the specified 2D rectangle (result may be null!).
+//* @param p1 the 1st point of the rectangle
+//* @param p2 the 2nd point of the rectangle
+//* @return a new 2D polygon clipped by the specified 2D rectangle
+//*/
+//public GbPolygon2D createClippedPolygon2D(GbPoint2D p1, GbPoint2D p2)
+//{
+//   return(GbSystem.clipPolygon2D(this.points, p1.x1, p1.x2, p2.x1, p2.x2));
+//}
+/*
+* Returns a new 2D polygon clipped by the specified 2D rectangle (result may be null!).
+* @param p1x1 the 1st x1 coordinate of the rectangle
+* @param p1x2 the 1st x2 coordinate of the rectangle
+* @param p2x1 the 2nd x1 coordinate of the rectangle
+* @param p2x2 the 2nd x2 coordinate of the rectangle
+* @return a new 2D polygon clipped by the specified 2D rectangle
+*/
+GbPolygon3D* GbTriangle3D::createClippedPolygon3D(const double& p1x1, const double& p1x2, const double& p1x3, const double& p2x1, const double& p2x2, const double& p2x3)
+{
+   return(GbSystem3D::clipPolygon3D(this->getPoints(), p1x1, p1x2, p1x3, p2x1, p2x2, p2x3));
+}
+
+/*
+* Returns true if the specified 2D rectangle lies completely within this 2D triangle.
+* @param rectangle the 2D rectangle to check
+* @return true if the specified 2D rectangle lies completely within this 2D triangle
+*/
+//bool enclosesRectangle2D(GbRectangle2D *rectangle)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, rectangle.p1.x1, rectangle.p1.x2, rectangle.p2.x1, rectangle.p2.x2);
+//   return(p!=null && GbSystem.equal(Math.abs(p.getArea()), rectangle.getArea()));
+//}
+/*
+* Returns true if the specified 2D rectangle lies completely within this 2D triangle.
+* @param p1 the 1st point of the rectangle to check
+* @param p2 the 2nd point of the rectangle to check                         triangle
+* @return true if the specified 2D rectangle lies completely within this 2D
+*/
+//public boolean enclosesRectangle2D(GbPoint2D p1, GbPoint2D p2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1.x1, p1.x2, p2.x1, p2.x2);
+//   return(p!=null && GbSystem.equal(Math.abs(p.getArea()), Math.abs((p1.x1-p2.x1)*(p1.x2-p2.x2))));
+//}
+/*
+* Returns true if the specified 2D rectangle lies completely within this 2D triangle.
+* @param p1x1 the 1st x1 coordinate of the rectangle to check
+* @param p1x2 the 1st x2 coordinate of the rectangle to check
+* @param p2x1 the 2nd x1 coordinate of the rectangle to check
+* @param p2x2 the 2nd x2 coordinate of the rectangle to check
+* @return true if the specified 2D rectangle lies completely within this 2D triangle
+*/
+//public boolean enclosesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1x1, p1x2, p2x1, p2x2);
+//   return(p!=null && GbSystem.equal(Math.abs(p.getArea()), Math.abs((p1x1-p2x1)*(p1x2-p2x2))));
+//}
+
+/*
+* Returns true if the specified 2D rectangle is crossed by this 2D triangle.
+* @param rectangle the 2D rectangle to check
+* @return true if the specified 2D rectangle is crossed by this 2D triangle
+*/
+//public boolean crossesRectangle2D(GbRectangle2D rectangle)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, rectangle.p1.x1, rectangle.p1.x2, rectangle.p2.x1, rectangle.p2.x2);
+//   return(p!=null && GbSystem.inOpenInterval(Math.abs(p.getArea()), 0.0, rectangle.getArea()));
+//}
+/*
+* Returns true if the specified 2D rectangle is crossed by this 2D triangle.
+* @param p1 the 1st point of the rectangle to check
+* @param p2 the 2nd point of the rectangle to check
+* @return true if the specified 2D rectangle is crossed by this 2D triangle
+*/
+//public boolean crossesRectangle2D(GbPoint2D p1, GbPoint2D p2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1.x1, p1.x2, p2.x1, p2.x2);
+//   return(p!=null && GbSystem.inOpenInterval(Math.abs(p.getArea()), 0.0, Math.abs((p1.x1-p2.x1)*(p1.x2-p2.x2))));
+//}
+/*
+* Returns true if the specified 2D rectangle is crossed by this 2D triangle.
+* @param p1x1 the 1st x1 coordinate of the rectangle to check
+* @param p1x2 the 1st x2 coordinate of the rectangle to check
+* @param p2x1 the 2nd x1 coordinate of the rectangle to check
+* @param p2x2 the 2nd x2 coordinate of the rectangle to check
+* @return true if the specified 2D rectangle is crossed by this 2D triangle
+*/
+//public boolean crossesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1x1, p1x2, p2x1, p2x2);
+//   return(p!=null && GbSystem.inOpenInterval(Math.abs(p.getArea()), 0.0, Math.abs((p1x1-p2x1)*(p1x2-p2x2))));
+//}
+
+/*
+* Returns true if the specified 2D rectangle lies (at least partly) within this 2D triangle.
+* @param rectangle the 2D rectangle to check
+* @return true if the specified 2D rectangle lies (at least partly) within this 2D triangle
+*/
+//public boolean enclosesOrCrossesRectangle2D(GbRectangle2D rectangle)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, rectangle.p1.x1, rectangle.p1.x2, rectangle.p2.x1, rectangle.p2.x2);
+//   return(p!=null && GbSystem.greater(Math.abs(p.getArea()), 0.0));
+//}
+/*
+* Returns true if the specified 2D rectangle lies (at least partly) within this 2D triangle.
+* @param p1 the 1st point of the rectangle to check
+* @param p2 the 2nd point of the rectangle to check
+* @return true if the specified 2D rectangle lies (at least partly) within this 2D triangle
+*/
+//public boolean enclosesOrCrossesRectangle2D(GbPoint2D p1, GbPoint2D p2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1.x1, p1.x2, p2.x1, p2.x2);
+//   return(p!=null && GbSystem.greater(Math.abs(p.getArea()), 0.0));
+//}
+/*
+* Returns true if the specified 2D rectangle lies (at least partly) within this 2D triangle.
+* @param p1x1 the 1st x1 coordinate of the rectangle to check
+* @param p1x2 the 1st x2 coordinate of the rectangle to check
+* @param p2x1 the 2nd x1 coordinate of the rectangle to check
+* @param p2x2 the 2nd x2 coordinate of the rectangle to check
+* @return true if the specified 2D rectangle lies (at least partly) within this 2D triangle
+*/
+//public boolean enclosesOrCrossesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2)
+//{
+//   GbPolygon2D p = GbSystem.clipPolygon2D(this.points, p1x1, p1x2, p2x1, p2x2);
+//   return(p!=null && GbSystem.greater(Math.abs(p.getArea()), 0.0));
+//}
+/*======================================================================*/
+
+
+/*======================================================================*/
+/*  Private Methoden                                                    */
+/*                                                                      */
+void GbTriangle3D::calculateValues()
+{
+   this->x1min = this->points[0]->x1;
+   this->x1max = this->points[0]->x1;
+   this->x2min = this->points[0]->x2;
+   this->x2max = this->points[0]->x2;
+   this->x3min = this->points[0]->x3;
+   this->x3max = this->points[0]->x3;
+
+   if(this->points[1]->x1 < this->x1min) this->x1min = this->points[1]->x1;
+   if(this->points[1]->x1 > this->x1max) this->x1max = this->points[1]->x1;
+   if(this->points[1]->x2 < this->x2min) this->x2min = this->points[1]->x2;
+   if(this->points[1]->x2 > this->x2max) this->x2max = this->points[1]->x2;
+   if(this->points[1]->x3 < this->x3min) this->x3min = this->points[1]->x3;
+   if(this->points[1]->x3 > this->x3max) this->x3max = this->points[1]->x3;
+
+   if(this->points[2]->x1 < this->x1min) this->x1min = this->points[2]->x1;
+   if(this->points[2]->x1 > this->x1max) this->x1max = this->points[2]->x1;
+   if(this->points[2]->x2 < this->x2min) this->x2min = this->points[2]->x2;
+   if(this->points[2]->x2 > this->x2max) this->x2max = this->points[2]->x2;
+   if(this->points[2]->x3 < this->x3min) this->x3min = this->points[2]->x3;
+   if(this->points[2]->x3 > this->x3max) this->x3max = this->points[2]->x3;
+
+   this->x1s   = (this->points[0]->x1+this->points[1]->x1+this->points[2]->x1)/3.0;
+   this->x2s   = (this->points[0]->x2+this->points[1]->x2+this->points[2]->x2)/3.0;
+   this->x3s   = (this->points[0]->x3+this->points[1]->x3+this->points[2]->x3)/3.0;
+
+   GbVector3D A(points[0]->x1,points[0]->x2,points[0]->x3);
+   GbVector3D B(points[1]->x1,points[1]->x2,points[1]->x3);
+   GbVector3D C(points[2]->x1,points[2]->x2,points[2]->x3);
+   GbVector3D AB = B-A;
+   GbVector3D AC = C-A;
+   GbVector3D N = AB.Cross(AC);
+   this->area = 0.5*N.Length();
+   this->consistent = true;
+}
+/*======================================================================*/
+
+
+/*======================================================================*/
+GbVector3D GbTriangle3D::getNormal()
+{
+   this->calculateNormal();
+   return normal; 
+}
+/*======================================================================*/
+void GbTriangle3D::init()
+{
+   x1s        = 0.0;
+   x2s        = 0.0;
+   x3s        = 0.0;
+   x1min      = 0.0;
+   x1max      = 0.0;
+   x2min      = 0.0;
+   x2max      = 0.0;
+   area       = 0.0;
+   consistent = false;
+   points.resize(3,NULL);
+}
+/*=======================================================*/
+void GbTriangle3D::calculateNormal()
+{
+   GbPoint3D*& a = points[0]; 
+   GbPoint3D*& b = points[1];
+   GbPoint3D*& c = points[2];
+   normal[0] = ( c->getX3Coordinate() - a->getX3Coordinate()) * ( b->getX2Coordinate() - a->getX2Coordinate() ) -
+               ( b->getX3Coordinate() - a->getX3Coordinate()) * ( c->getX2Coordinate() - a->getX2Coordinate() );
+   normal[1] = ( b->getX3Coordinate() - a->getX3Coordinate()) * ( c->getX1Coordinate() - a->getX1Coordinate() ) -
+               ( b->getX1Coordinate() - a->getX1Coordinate()) * ( c->getX3Coordinate() - a->getX3Coordinate() );
+   normal[2] = ( b->getX1Coordinate() - a->getX1Coordinate()) * ( c->getX2Coordinate() - a->getX2Coordinate() ) -
+               ( b->getX2Coordinate() - a->getX2Coordinate()) * ( c->getX1Coordinate() - a->getX1Coordinate() );
+   normal.Normalize();
+}
+/*=======================================================*/
+//toDo: 
+double GbTriangle3D::getDistanceFromPoint(GbVector3D punct)
+{
+	GbVector3D Point1(this->getPoint1()->getX1Coordinate(), this->getPoint1()->getX2Coordinate(), this->getPoint1()->getX3Coordinate());
+	GbVector3D Point2(this->getPoint2()->getX1Coordinate(), this->getPoint2()->getX2Coordinate(), this->getPoint2()->getX3Coordinate());
+	GbVector3D Point3(this->getPoint3()->getX1Coordinate(), this->getPoint3()->getX2Coordinate(), this->getPoint3()->getX3Coordinate());
+
+	GbVector3D kDiff = Point1 - punct;
+	GbVector3D kEdge0 = Point2 - Point1;
+	GbVector3D kEdge1 = Point3 - Point1;
+	double fA00 = kEdge0.SquaredLength();
+	double fA01 = kEdge0.Dot(kEdge1);
+	double fA11 = kEdge1.SquaredLength();
+	double fB0 = kDiff.Dot(kEdge0);
+	double fB1 = kDiff.Dot(kEdge1);
+	double fC = kDiff.SquaredLength();
+	double fDet = fabs(fA00*fA11-fA01*fA01);
+	double fS = fA01*fB1-fA11*fB0;
+	double fT = fA01*fB0-fA00*fB1;
+	double fSqrDistance;
+
+	if (fS + fT <= fDet)
+	{
+		if (fS < (double)0.0)
+		{
+			if (fT < (double)0.0)  // region 4
+			{
+				if (fB0 < (double)0.0)
+				{
+					fT = (double)0.0;
+					if (-fB0 >= fA00)
+					{
+						fS = (double)1.0;
+						fSqrDistance = fA00+((double)2.0)*fB0+fC;
+					}
+					else
+					{
+						fS = -fB0/fA00;
+						fSqrDistance = fB0*fS+fC;
+					}
+				}
+				else
+				{
+					fS = (double)0.0;
+					if (fB1 >= (double)0.0)
+					{
+						fT = (double)0.0;
+						fSqrDistance = fC;
+					}
+					else if (-fB1 >= fA11)
+					{
+						fT = (double)1.0;
+						fSqrDistance = fA11+((double)2.0)*fB1+fC;
+					}
+					else
+					{
+						fT = -fB1/fA11;
+						fSqrDistance = fB1*fT+fC;
+					}
+				}
+			}
+			else  // region 3
+			{
+				fS = (double)0.0;
+				if (fB1 >= (double)0.0)
+				{
+					fT = (double)0.0;
+					fSqrDistance = fC;
+				}
+				else if (-fB1 >= fA11)
+				{
+					fT = (double)1.0;
+					fSqrDistance = fA11+((double)2.0)*fB1+fC;
+				}
+				else
+				{
+					fT = -fB1/fA11;
+					fSqrDistance = fB1*fT+fC;
+				}
+			}
+		}
+		else if (fT < (double)0.0)  // region 5
+		{
+			fT = (double)0.0;
+			if (fB0 >= (double)0.0)
+			{
+				fS = (double)0.0;
+				fSqrDistance = fC;
+			}
+			else if (-fB0 >= fA00)
+			{
+				fS = (double)1.0;
+				fSqrDistance = fA00+((double)2.0)*fB0+fC;
+			}
+			else
+			{
+				fS = -fB0/fA00;
+				fSqrDistance = fB0*fS+fC;
+			}
+		}
+		else  // region 0
+		{
+			// minimum at interior point
+			double fInvDet = ((double)1.0)/fDet;
+			fS *= fInvDet;
+			fT *= fInvDet;
+			fSqrDistance = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
+				fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
+		}
+	}
+	else
+	{
+		double fTmp0, fTmp1, fNumer, fDenom;
+
+		if (fS < (double)0.0)  // region 2
+		{
+			fTmp0 = fA01 + fB0;
+			fTmp1 = fA11 + fB1;
+			if (fTmp1 > fTmp0)
+			{
+				fNumer = fTmp1 - fTmp0;
+				fDenom = fA00-2.0f*fA01+fA11;
+				if (fNumer >= fDenom)
+				{
+					fS = (double)1.0;
+					fT = (double)0.0;
+					fSqrDistance = fA00+((double)2.0)*fB0+fC;
+				}
+				else
+				{
+					fS = fNumer/fDenom;
+					fT = (double)1.0 - fS;
+					fSqrDistance = fS*(fA00*fS+fA01*fT+2.0f*fB0) +
+						fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
+				}
+			}
+			else
+			{
+				fS = (double)0.0;
+				if (fTmp1 <= (double)0.0)
+				{
+					fT = (double)1.0;
+					fSqrDistance = fA11+((double)2.0)*fB1+fC;
+				}
+				else if (fB1 >= (double)0.0)
+				{
+					fT = (double)0.0;
+					fSqrDistance = fC;
+				}
+				else
+				{
+					fT = -fB1/fA11;
+					fSqrDistance = fB1*fT+fC;
+				}
+			}
+		}
+		else if (fT < (double)0.0)  // region 6
+		{
+			fTmp0 = fA01 + fB1;
+			fTmp1 = fA00 + fB0;
+			if (fTmp1 > fTmp0)
+			{
+				fNumer = fTmp1 - fTmp0;
+				fDenom = fA00-((double)2.0)*fA01+fA11;
+				if (fNumer >= fDenom)
+				{
+					fT = (double)1.0;
+					fS = (double)0.0;
+					fSqrDistance = fA11+((double)2.0)*fB1+fC;
+				}
+				else
+				{
+					fT = fNumer/fDenom;
+					fS = (double)1.0 - fT;
+					fSqrDistance = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
+						fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
+				}
+			}
+			else
+			{
+				fT = (double)0.0;
+				if (fTmp1 <= (double)0.0)
+				{
+					fS = (double)1.0;
+					fSqrDistance = fA00+((double)2.0)*fB0+fC;
+				}
+				else if (fB0 >= (double)0.0)
+				{
+					fS = (double)0.0;
+					fSqrDistance = fC;
+				}
+				else
+				{
+					fS = -fB0/fA00;
+					fSqrDistance = fB0*fS+fC;
+				}
+			}
+		}
+		else  // region 1
+		{
+			fNumer = fA11 + fB1 - fA01 - fB0;
+			if (fNumer <= (double)0.0)
+			{
+				fS = (double)0.0;
+				fT = (double)1.0;
+				fSqrDistance = fA11+((double)2.0)*fB1+fC;
+			}
+			else
+			{
+				fDenom = fA00-2.0f*fA01+fA11;
+				if (fNumer >= fDenom)
+				{
+					fS = (double)1.0;
+					fT = (double)0.0;
+					fSqrDistance = fA00+((double)2.0)*fB0+fC;
+				}
+				else
+				{
+					fS = fNumer/fDenom;
+					fT = (double)1.0 - fS;
+					fSqrDistance = fS*(fA00*fS+fA01*fT+((double)2.0)*fB0) +
+						fT*(fA01*fS+fA11*fT+((double)2.0)*fB1)+fC;
+				}
+			}
+		}
+	}
+
+	// account for numerical round-off error
+	if (fSqrDistance < (double)0.0)
+	{
+		fSqrDistance = (double)0.0;
+	}
+/*
+	m_kClosestPoint0 = punct;
+	m_kClosestPoint1 = m_rkTriangle.V[0] + fS*kEdge0 + fT*kEdge1;
+	m_afTriangleBary[1] = fS;
+	m_afTriangleBary[2] = fT;
+	m_afTriangleBary[0] = (double)1.0 - fS - fT;
+*/
+	return sqrt(fSqrDistance);
+}
diff --git a/VirtualFluidsBasics/geometry3d/GbTriangle3D.h b/VirtualFluidsBasics/geometry3d/GbTriangle3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..61a8f5ff5b83df090cc5c1c0f1b98fa0ad04aac0
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbTriangle3D.h
@@ -0,0 +1,216 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbTriangle3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBTRIANGLE3D_H
+#define GBTRIANGLE3D_H
+
+#include <sstream>
+
+#include <GbObject3D.h>
+#include <GbVector3D.h>
+#include <GbPoint3D.h>
+
+#include <PointerDefinitions.h>
+
+class GbCuboid3D;
+class GbPolygon3D;
+class GbObject3DCreator;
+
+//////////////////////////////////////////////////////////////////////////
+//! 
+//! \class GbTriangle3D
+//! 
+//! \brief This Class provides basic 3D triangle objects.
+//! \details The describing points are observed by 2D triangle objects.
+//! 
+//////////////////////////////////////////////////////////////////////////  
+
+class GbTriangle3D : public GbObject3D , public UbObserver
+{
+public:
+   /*======================================================================*/
+   /*  Konstruktoren                                                       */
+   /*                                                                      */
+   GbTriangle3D();
+   GbTriangle3D(GbPoint3D* point1, GbPoint3D* point2, GbPoint3D* point3);
+   GbTriangle3D(GbTriangle3D* triangle);
+   ~GbTriangle3D();
+   /*======================================================================*/
+   /*  Methoden                                                            */
+   /*                                                                      */
+   GbTriangle3D* clone();
+   void finalize()
+   {
+      this->deletePoints();
+   }
+
+   GbPoint3D* getPoint1()   { return this->points[0]; }
+   GbPoint3D* getPoint2()   { return this->points[1]; }
+   GbPoint3D* getPoint3()   { return this->points[2]; }
+
+   GbVector3D getNormal();
+   void       calculateNormal();
+
+   void deletePoints();
+
+   int contains(GbPoint3D* point);
+   int containsEqual(GbPoint3D* point);
+   GbPoint3D* getPoint(const int& index);
+   std::vector<GbPoint3D> getPoints();
+   double getArea();
+   double getX1Centroid();
+   double getX1Minimum();
+   double getX1Maximum();           
+   double getX2Centroid();
+   double getX2Minimum();
+   double getX2Maximum();
+   double getX3Centroid();
+   double getX3Minimum();
+   double getX3Maximum();
+
+   void setInconsistent() { this->consistent = false;}
+
+   void setPoint(GbPoint3D *point, int index);
+
+   //bool equals(GbObject3D *object)
+   std::vector<GbTriangle3D*> getSurfaceTriangleSet();
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3)   
+   {
+      //der einfachheit halber ... 
+      return false;
+      //throw UbException(__FILE__, __LINE__, "GbTriangle3D::isPointInObject3D- not implemented");
+   }
+   bool isPointInGbObject3D(const double& x1, const double& x2, const double& x3, bool& pointIsOnBoundary)   
+   {
+      //der einfachheit halber ... 
+      pointIsOnBoundary = false;
+      return false;
+      //throw UbException(__FILE__, __LINE__, "GbTriangle3D::isPointInObject3D- not implemented");
+   }
+   bool isCellInsideGbObject3D(const double& x11,const double& x21,const double& x31,const double& x12,const double& x22,const double& x23) { return false; }
+
+
+   // get distance from a point to the triangle
+   //todo CHANGE...
+   double getDistanceFromPoint(GbVector3D punct);
+
+   std::string toString();
+
+   /*======================================================================*/
+   /*  Calculation                                                         */
+   /*                                                                      */
+//   std::vector<GbPoint3D> calculateIntersectionPoints3D(GbLine3D *line);
+   bool hasRaytracing() { return true; }
+   /*|r| must be 1! einheitsvector!!*/
+   double getIntersectionRaytraceFactor(const double& x1, const double& x2, const double& x3, const double& rx1, const double& rx2, const double& rx3);
+//   bool isPointOnEdge(GbVector3D& q);
+   
+   GbPoint3D* calculateIntersectionPoints3D(GbLine3D* line);
+   GbPoint3D* calculateIntersectionPoints3D(GbPoint3D* linePoint1, GbPoint3D* linePoint2);
+   double calculateDistanceToPoint3D(GbPoint3D *point);
+   double calculateDistanceToPoint3D(const double& x1, const double& x2, const double& x3);      
+   double calculateNormalizedDistanceToPoint3D(const double& x1, const double& y1, const double& z1, const double& x2, const double& y2, const double& z2);
+
+   bool enclosesPoint2D(double x1, double x2);
+   GbPolygon3D* createClippedPolygon3D(GbCuboid3D* cube);   
+   GbLine3D* createClippedLine3D (GbPoint3D& point1, GbPoint3D& point2);
+   //public GbPolygon2D createClippedPolygon2D(GbPoint2D p1, GbPoint2D p2);
+   GbPolygon3D* createClippedPolygon3D(const double& p1x1, const double& p1x2, const double& p1x3, const double& p2x1, const double& p2x2, const double& p2x3);
+   //bool enclosesRectangle2D(GbRectangle2D *rectangle);
+   //public boolean enclosesRectangle2D(GbPoint2D p1, GbPoint2D p2);
+   //public boolean enclosesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2);
+   //public boolean crossesRectangle2D(GbRectangle2D rectangle);
+   //public boolean crossesRectangle2D(GbPoint2D p1, GbPoint2D p2);
+   //public boolean crossesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2);
+   //public boolean enclosesOrCrossesRectangle2D(GbRectangle2D rectangle);
+   //public boolean enclosesOrCrossesRectangle2D(GbPoint2D p1, GbPoint2D p2);
+   //public boolean enclosesOrCrossesRectangle2D(double p1x1, double p1x2, double p2x1, double p2x2);
+   /*======================================================================*/
+   /*======================================================================*/
+   /*  Private Methoden                                                    */
+   /*                                                                      */
+   virtual void calculateValues();
+
+
+   //virtuelle Methoden von UbObserver
+   //!! quick and dirty von sirann !!
+   void objectChanged(UbObservable* changedObject)
+   {
+      GbPoint3D* point = dynamic_cast<GbPoint3D*>(changedObject);
+      if(!point || (  this->points[0]!=point && this->points[1]!=point && this->points[2]!=point) ) 
+         return;
+      
+      this->consistent = false;
+   }
+   void objectWillBeDeleted(UbObservable* objectForDeletion)
+   {
+      if(this->points[0])
+      {
+         UbObservable* observedObj = dynamic_cast<UbObservable*>(this->points[0]);
+         if(objectForDeletion == observedObj) { this->points[0] = NULL; }
+      }
+      if(this->points[1])
+      {
+         UbObservable* observedObj = dynamic_cast<UbObservable*>(this->points[1]);
+         if(objectForDeletion == observedObj) { this->points[1] = NULL; }
+      }
+      if(this->points[2])
+      {
+         UbObservable* observedObj = dynamic_cast<UbObservable*>(this->points[2]);
+         if(objectForDeletion == observedObj) { this->points[2] = NULL; }
+      }
+      //ACHTUNG: eigentlich muessten in allen methoden von GbLine if abfragen fuer NULL pointer hin... toDo
+   }
+   using GbObject3D::isPointInGbObject3D; //Grund: dadurch muss man hier  isPointInGbObject3D(GbPoint3D*) nicht ausprogrammieren, welche sonst hier "ueberdeckt" waere
+
+protected:
+   bool   consistent;
+   double x1s;
+   double x2s;
+   double x3s;
+   double x1min;
+   double x1max;
+   double x2min;
+   double x2max;
+   double x3min;
+   double x3max;
+   double area;
+   
+   GbVector3D normal;
+   std::vector<GbPoint3D*> points;
+   
+private:
+   void init();
+};
+/*=========================================================================*/
+
+#endif
diff --git a/VirtualFluidsBasics/geometry3d/GbVector3D.cpp b/VirtualFluidsBasics/geometry3d/GbVector3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6246a7d15316bb432894937c43523f5a99ba5431
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbVector3D.cpp
@@ -0,0 +1,675 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbVector3D.cpp
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#include <GbVector3D.h>
+#include <GbPoint3D.h>
+
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbInfinity.h>
+
+using namespace std;
+
+
+const GbVector3D GbVector3D::ZERO(0.0,0.0,0.0);
+const GbVector3D GbVector3D::UNIT_X1(1.0,0.0,0.0);
+const GbVector3D GbVector3D::UNIT_X2(0.0,1.0,0.0);
+const GbVector3D GbVector3D::UNIT_X3(0.0,0.0,1.0);
+
+//----------------------------------------------------------------------------
+GbVector3D::GbVector3D () 
+{                                      
+   m_afTuple[0] = 0.0;
+   m_afTuple[1] = 0.0;
+   m_afTuple[2] = 0.0;
+}
+//----------------------------------------------------------------------------
+GbVector3D::GbVector3D (const double& fX, const double& fY, const double& fZ) 
+{
+   m_afTuple[0] = fX;
+   m_afTuple[1] = fY;
+   m_afTuple[2] = fZ;
+}
+//----------------------------------------------------------------------------
+GbVector3D::GbVector3D (const GbVector3D& rkV) 
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+}
+//----------------------------------------------------------------------------
+
+GbVector3D::GbVector3D (const GbPoint3D& point) 
+{
+   m_afTuple[0] = point.x1;
+   m_afTuple[1] = point.x2;
+   m_afTuple[2] = point.x3;
+}
+
+//----------------------------------------------------------------------------
+string GbVector3D::toString()
+{
+   std::stringstream ss;
+   ss<< "GbVector3D["<<m_afTuple[0]<<","<<m_afTuple[1]<<","<<m_afTuple[2]<<"]";
+   ss<<endl;
+   return((ss.str()).c_str());
+}
+//----------------------------------------------------------------------------
+GbVector3D::operator const double* () const
+{
+   return m_afTuple;
+}
+//----------------------------------------------------------------------------
+GbVector3D::operator double* ()
+{
+   return m_afTuple;
+}
+//----------------------------------------------------------------------------
+double GbVector3D::operator[] (int i) const
+{
+   assert( 0 <= i && i <= 2 );
+   if ( i < 0 )
+      i = 0;
+   else if ( i > 2 )
+      i = 2;
+
+   return m_afTuple[i];
+}
+//----------------------------------------------------------------------------
+double& GbVector3D::operator[] (int i)
+{
+   assert( 0 <= i && i <= 2 );
+   if ( i < 0 )
+      i = 0;
+   else if ( i > 2 )
+      i = 2;
+
+   return m_afTuple[i];
+}
+//----------------------------------------------------------------------------
+double GbVector3D::X1 () const
+{
+   return m_afTuple[0];
+}
+//----------------------------------------------------------------------------
+double& GbVector3D::X1 ()
+{
+   return m_afTuple[0];
+}
+//----------------------------------------------------------------------------
+double GbVector3D::X2 () const
+{
+   return m_afTuple[1];
+}
+//----------------------------------------------------------------------------
+double& GbVector3D::X2 ()
+{
+   return m_afTuple[1];
+}
+//----------------------------------------------------------------------------
+double GbVector3D::X3 () const
+{
+   return m_afTuple[2];
+}
+//----------------------------------------------------------------------------
+double& GbVector3D::X3 ()
+{
+   return m_afTuple[2];
+}
+//----------------------------------------------------------------------------
+GbVector3D& GbVector3D::operator= (const GbVector3D& rkV)
+{
+   m_afTuple[0] = rkV.m_afTuple[0];
+   m_afTuple[1] = rkV.m_afTuple[1];
+   m_afTuple[2] = rkV.m_afTuple[2];
+   return *this;
+}
+//----------------------------------------------------------------------------
+int GbVector3D::CompareArrays (const GbVector3D& rkV) const
+{
+   return memcmp(m_afTuple,rkV.m_afTuple,3*sizeof(double));
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator== (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) == 0;
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator!= (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) != 0;
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator< (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) < 0;
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator<= (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) <= 0;
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator> (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) > 0;
+}
+//----------------------------------------------------------------------------
+bool GbVector3D::operator>= (const GbVector3D& rkV) const
+{
+   return CompareArrays(rkV) >= 0;
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::operator+ (const GbVector3D& rkV) const
+{
+   return GbVector3D(
+      m_afTuple[0]+rkV.m_afTuple[0],
+      m_afTuple[1]+rkV.m_afTuple[1],
+      m_afTuple[2]+rkV.m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::Add(GbVector3D& vector)
+{
+   return GbVector3D(
+      m_afTuple[0]+vector.m_afTuple[0],
+      m_afTuple[1]+vector.m_afTuple[1],
+      m_afTuple[2]+vector.m_afTuple[2]);
+}
+
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::operator- (const GbVector3D& rkV) const
+{
+   return GbVector3D(
+      m_afTuple[0]-rkV.m_afTuple[0],
+      m_afTuple[1]-rkV.m_afTuple[1],
+      m_afTuple[2]-rkV.m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::Subtract(GbVector3D& vector)
+{
+   return GbVector3D(
+      m_afTuple[0]-vector.m_afTuple[0],
+      m_afTuple[1]-vector.m_afTuple[1],
+      m_afTuple[2]-vector.m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::operator* (const double& fScalar) const
+{
+   return GbVector3D( fScalar*m_afTuple[0],
+                      fScalar*m_afTuple[1],
+                      fScalar*m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::operator/ (const double& fScalar) const
+{
+   GbVector3D kQuot;
+
+   if ( fScalar != 0.0 )
+   {
+      double fInvScalar = 1.0/fScalar;
+      kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
+      kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
+      kQuot.m_afTuple[2] = fInvScalar*m_afTuple[2];
+   }
+   else
+   {
+      kQuot.m_afTuple[0] = Ub::inf;
+      kQuot.m_afTuple[1] = Ub::inf;
+      kQuot.m_afTuple[2] = Ub::inf;
+   }
+
+   return kQuot;
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::operator- () const
+{
+   return GbVector3D(
+      -m_afTuple[0],
+      -m_afTuple[1],
+      -m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D operator* (const double& fScalar, const GbVector3D& rkV)
+{
+   return GbVector3D(
+      fScalar*rkV[0],
+      fScalar*rkV[1],
+      fScalar*rkV[2]);
+}
+//----------------------------------------------------------------------------
+GbVector3D& GbVector3D::operator+= (const GbVector3D& rkV)
+{
+   m_afTuple[0] += rkV.m_afTuple[0];
+   m_afTuple[1] += rkV.m_afTuple[1];
+   m_afTuple[2] += rkV.m_afTuple[2];
+   return *this;
+}
+//----------------------------------------------------------------------------
+GbVector3D& GbVector3D::operator-= (const GbVector3D& rkV)
+{
+   m_afTuple[0] -= rkV.m_afTuple[0];
+   m_afTuple[1] -= rkV.m_afTuple[1];
+   m_afTuple[2] -= rkV.m_afTuple[2];
+   return *this;
+}
+//----------------------------------------------------------------------------
+GbVector3D& GbVector3D::operator*= (const double& fScalar)
+{
+   m_afTuple[0] *= fScalar;
+   m_afTuple[1] *= fScalar;
+   m_afTuple[2] *= fScalar;
+   return *this;
+}
+//----------------------------------------------------------------------------
+GbVector3D& GbVector3D::operator/= (const double& fScalar)
+{
+   if ( fScalar != (double)0.0 )
+   {
+      double fInvScalar = ((double)1.0)/fScalar;
+      m_afTuple[0] *= fInvScalar;
+      m_afTuple[1] *= fInvScalar;
+      m_afTuple[2] *= fInvScalar;
+   }
+   else
+   {
+      m_afTuple[0] = Ub::inf;
+      m_afTuple[1] = Ub::inf;
+      m_afTuple[2] = Ub::inf;
+   }
+
+   return *this;
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::Scale(const double& x)
+{
+   GbVector3D PointA(0.0,0.0,0.0);
+   PointA.m_afTuple[0] = x * m_afTuple[0];
+   PointA.m_afTuple[1] = x * m_afTuple[1];
+   PointA.m_afTuple[2] = x * m_afTuple[2];
+   return PointA;	
+}
+
+//----------------------------------------------------------------------------
+double GbVector3D::Length () const
+{
+   return std::sqrt(
+      m_afTuple[0]*m_afTuple[0] +
+      m_afTuple[1]*m_afTuple[1] +
+      m_afTuple[2]*m_afTuple[2]);
+}
+//----------------------------------------------------------------------------
+double GbVector3D::SquaredLength () const
+{
+   return
+      m_afTuple[0]*m_afTuple[0] +
+      m_afTuple[1]*m_afTuple[1] +
+      m_afTuple[2]*m_afTuple[2];
+}
+//----------------------------------------------------------------------------
+double GbVector3D::Dot (const GbVector3D& rkV) const
+{
+   return
+      m_afTuple[0]*rkV.m_afTuple[0] +
+      m_afTuple[1]*rkV.m_afTuple[1] +
+      m_afTuple[2]*rkV.m_afTuple[2];
+}
+//----------------------------------------------------------------------------
+double GbVector3D::Normalize ()
+{
+   double fLength = Length();
+
+   if ( fLength > UbMath::Epsilon<double>::val() )
+   {
+      double fInvLength = ((double)1.0)/fLength;
+      m_afTuple[0] *= fInvLength;
+      m_afTuple[1] *= fInvLength;
+      m_afTuple[2] *= fInvLength;
+   }
+   else
+   {
+      fLength = 0.0;
+      m_afTuple[0] = 0.0;
+      m_afTuple[1] = 0.0;
+      m_afTuple[2] = 0.0;
+   }
+
+   return fLength;
+}
+//----------------------------------------------------------------------------
+GbVector3D GbVector3D::Cross (const GbVector3D& rkV) const
+{
+   return GbVector3D(
+      m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+      m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+      m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
+}
+
+//----------------------------------------------------------------------------
+
+GbVector3D GbVector3D::UnitCross (const GbVector3D& rkV) const
+{
+   GbVector3D kCross(
+      m_afTuple[1]*rkV.m_afTuple[2] - m_afTuple[2]*rkV.m_afTuple[1],
+      m_afTuple[2]*rkV.m_afTuple[0] - m_afTuple[0]*rkV.m_afTuple[2],
+      m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0]);
+   kCross.Normalize();
+   return kCross;
+}
+//----------------------------------------------------------------------------
+void GbVector3D::GetBarycentrics (const GbVector3D& rkV0,
+                                  const GbVector3D& rkV1, const GbVector3D& rkV2,
+                                  const GbVector3D& rkV3, double afBary[4]) const
+{
+   // compute the vectors relative to V3 of the tetrahedron
+   GbVector3D akDiff[4] =
+   {
+      rkV0 - rkV3,
+         rkV1 - rkV3,
+         rkV2 - rkV3,
+         *this - rkV3
+   };
+
+   // If the vertices have large magnitude, the linear system of
+   // equations for computing barycentric coordinates can be
+   // ill-conditioned.  To avoid this, uniformly scale the tetrahedron
+   // edges to be of order 1.  The scaling of all differences does not
+   // change the barycentric coordinates.
+   double fMax = (double)0.0;
+   int i;
+   for (i = 0; i < 3; i++)
+   {
+      for (int j = 0; j < 3; j++)
+      {
+         double fValue = std::fabs(akDiff[i][j]);
+         if ( fValue > fMax )
+            fMax = fValue;
+      }
+   }
+
+   // scale down only large data
+   if ( fMax > (double)1.0 )
+   {
+      double fInvMax = ((double)1.0)/fMax;
+      for (i = 0; i < 4; i++)
+         akDiff[i] *= fInvMax;
+   }
+
+   double fDet = akDiff[0].Dot(akDiff[1].Cross(akDiff[2]));
+   GbVector3D kE1cE2 = akDiff[1].Cross(akDiff[2]);
+   GbVector3D kE2cE0 = akDiff[2].Cross(akDiff[0]);
+   GbVector3D kE0cE1 = akDiff[0].Cross(akDiff[1]);
+   if ( std::fabs(fDet) > UbMath::Epsilon<double>::val() )
+   {
+      double fInvDet = ((double)1.0)/fDet;
+      afBary[0] = akDiff[3].Dot(kE1cE2)*fInvDet;
+      afBary[1] = akDiff[3].Dot(kE2cE0)*fInvDet;
+      afBary[2] = akDiff[3].Dot(kE0cE1)*fInvDet;
+      afBary[3] = (double)1.0 - afBary[0] - afBary[1] - afBary[2];
+   }
+   else
+   {
+      // The tetrahedron is potentially flat.  Determine the face of
+      // maximum area and compute barycentric coordinates with respect
+      // to that face.
+      GbVector3D kE02 = rkV0 - rkV2;
+      GbVector3D kE12 = rkV1 - rkV2;
+      GbVector3D kE02cE12 = kE02.Cross(kE12);
+      double fMaxSqrArea = kE02cE12.SquaredLength();
+      int iMaxIndex = 3;
+      double fSqrArea = kE0cE1.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 0;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE1cE2.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 1;
+         fMaxSqrArea = fSqrArea;
+      }
+      fSqrArea = kE2cE0.SquaredLength();
+      if ( fSqrArea > fMaxSqrArea )
+      {
+         iMaxIndex = 2;
+         fMaxSqrArea = fSqrArea;
+      }
+
+      if ( fMaxSqrArea > UbMath::Epsilon<double>::val() )
+      {
+         double fInvSqrArea = ((double)1.0)/fMaxSqrArea;
+         GbVector3D kTmp;
+         if ( iMaxIndex == 0 )
+         {
+            kTmp = akDiff[3].Cross(akDiff[1]);
+            afBary[0] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            kTmp = akDiff[0].Cross(akDiff[3]);
+            afBary[1] = kE0cE1.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = (double)0.0;
+            afBary[3] = (double)1.0 - afBary[0] - afBary[1];
+         }
+         else if ( iMaxIndex == 1 )
+         {
+            afBary[0] = (double)0.0;
+            kTmp = akDiff[3].Cross(akDiff[2]);
+            afBary[1] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            kTmp = akDiff[1].Cross(akDiff[3]);
+            afBary[2] = kE1cE2.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = (double)1.0 - afBary[1] - afBary[2];
+         }
+         else if ( iMaxIndex == 2 )
+         {
+            kTmp = akDiff[2].Cross(akDiff[3]);
+            afBary[0] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[1] = (double)0.0;
+            kTmp = akDiff[3].Cross(akDiff[0]);
+            afBary[2] = kE2cE0.Dot(kTmp)*fInvSqrArea;
+            afBary[3] = (double)1.0 - afBary[0] - afBary[2];
+         }
+         else
+         {
+            akDiff[3] = *this - rkV2;
+            kTmp = akDiff[3].Cross(kE12);
+            afBary[0] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            kTmp = kE02.Cross(akDiff[3]);
+            afBary[1] = kE02cE12.Dot(kTmp)*fInvSqrArea;
+            afBary[2] = (double)1.0 - afBary[0] - afBary[1];
+            afBary[3] = (double)0.0;
+         }
+      }
+      else
+      {
+         // The tetrahedron is potentially a sliver.  Determine the edge of
+         // maximum length and compute barycentric coordinates with respect
+         // to that edge.
+         double fMaxSqrLength = akDiff[0].SquaredLength();
+         iMaxIndex = 0;  // <V0,V3>
+         double fSqrLength = akDiff[1].SquaredLength();
+         if ( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex = 1;  // <V1,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = akDiff[2].SquaredLength();
+         if ( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex = 2;  // <V2,V3>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE02.SquaredLength();
+         if ( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex = 3;  // <V0,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         fSqrLength = kE12.SquaredLength();
+         if ( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex = 4;  // <V1,V2>
+            fMaxSqrLength = fSqrLength;
+         }
+         GbVector3D kE01 = rkV0 - rkV1;
+         fSqrLength = kE01.SquaredLength();
+         if ( fSqrLength > fMaxSqrLength )
+         {
+            iMaxIndex = 5;  // <V0,V1>
+            fMaxSqrLength = fSqrLength;
+         }
+
+         if ( fMaxSqrLength > UbMath::Epsilon<double>::val() )
+         {
+            double fInvSqrLength = ((double)1.0)/fMaxSqrLength;
+            if ( iMaxIndex == 0 )
+            {
+               // P-V3 = t*(V0-V3)
+               afBary[0] = akDiff[3].Dot(akDiff[0])*fInvSqrLength;
+               afBary[1] = (double)0.0;
+               afBary[2] = (double)0.0;
+               afBary[3] = (double)1.0 - afBary[0];
+            }
+            else if ( iMaxIndex == 1 )
+            {
+               // P-V3 = t*(V1-V3)
+               afBary[0] = (double)0.0;
+               afBary[1] = akDiff[3].Dot(akDiff[1])*fInvSqrLength;
+               afBary[2] = (double)0.0;
+               afBary[3] = (double)1.0 - afBary[1];
+            }
+            else if ( iMaxIndex == 2 )
+            {
+               // P-V3 = t*(V2-V3)
+               afBary[0] = (double)0.0;
+               afBary[1] = (double)0.0;
+               afBary[2] = akDiff[3].Dot(akDiff[2])*fInvSqrLength;
+               afBary[3] = (double)1.0 - afBary[2];
+            }
+            else if ( iMaxIndex == 3 )
+            {
+               // P-V2 = t*(V0-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = akDiff[3].Dot(kE02)*fInvSqrLength;
+               afBary[1] = (double)0.0;
+               afBary[2] = (double)1.0 - afBary[0];
+               afBary[3] = (double)0.0;
+            }
+            else if ( iMaxIndex == 4 )
+            {
+               // P-V2 = t*(V1-V2)
+               akDiff[3] = *this - rkV2;
+               afBary[0] = (double)0.0;
+               afBary[1] = akDiff[3].Dot(kE12)*fInvSqrLength;
+               afBary[2] = (double)1.0 - afBary[1];
+               afBary[3] = (double)0.0;
+            }
+            else
+            {
+               // P-V1 = t*(V0-V1)
+               akDiff[3] = *this - rkV1;
+               afBary[0] = akDiff[3].Dot(kE01)*fInvSqrLength;
+               afBary[1] = (double)1.0 - afBary[0];
+               afBary[2] = (double)0.0;
+               afBary[3] = (double)0.0;
+            }
+         }
+         else
+         {
+            // tetrahedron is a nearly a point, just return equal weights
+            afBary[0] = (double)0.25;
+            afBary[1] = afBary[0];
+            afBary[2] = afBary[0];
+            afBary[3] = afBary[0];
+         }
+      }
+   }
+}
+//----------------------------------------------------------------------------
+void GbVector3D::Orthonormalize (GbVector3D& rkU, GbVector3D& rkV, GbVector3D& rkW)
+{
+   // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
+   // orthonormalization produces vectors u0, u1, and u2 as follows,
+   //
+   //   u0 = v0/|v0|
+   //   u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
+   //   u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
+   //
+   // where |A| indicates length of vector A and A*B indicates dot
+   // product of vectors A and B.
+
+   // compute u0
+   rkU.Normalize();
+
+   // compute u1
+   double fDot0 = rkU.Dot(rkV); 
+   rkV -= fDot0*rkU;
+   rkV.Normalize();
+
+   // compute u2
+   double fDot1 = rkV.Dot(rkW);
+   fDot0 = rkU.Dot(rkW);
+   rkW -= fDot0*rkU + fDot1*rkV;
+   rkW.Normalize();
+}
+//----------------------------------------------------------------------------
+void GbVector3D::Orthonormalize (GbVector3D* akV)
+{
+   Orthonormalize(akV[0],akV[1],akV[2]);
+}
+//----------------------------------------------------------------------------
+void GbVector3D::GenerateOrthonormalBasis (GbVector3D& rkU, GbVector3D& rkV,
+                                           GbVector3D& rkW, bool bUnitLengthW)
+{
+   if ( !bUnitLengthW )
+      rkW.Normalize();
+
+   double fInvLength;
+
+   if ( std::fabs(rkW.m_afTuple[0]) >=
+      std::fabs(rkW.m_afTuple[1]) )
+   {
+      // W.x or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[1] = (double)0.0;
+      rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength;
+   }
+   else
+   {
+      // W.y or W.z is the largest magnitude component, swap them
+      fInvLength = UbMath::invSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] + rkW.m_afTuple[2]*rkW.m_afTuple[2]);
+      rkU.m_afTuple[0] = (double)0.0;
+      rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength;
+      rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength;
+   }
+
+   rkV = rkW.Cross(rkU);
+}
+//----------------------------------------------------------------------------
+
diff --git a/VirtualFluidsBasics/geometry3d/GbVector3D.h b/VirtualFluidsBasics/geometry3d/GbVector3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..61184e8e0ff1e7ba621b095bb7de4f1f3c2b098e
--- /dev/null
+++ b/VirtualFluidsBasics/geometry3d/GbVector3D.h
@@ -0,0 +1,144 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GbVector3D.h
+//! \ingroup geometry3d
+//! \author Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+#ifndef GBVECTOR3D_H
+#define GBVECTOR3D_H
+                                                                   
+#include <cfloat>                               
+#include <cassert> 
+#include <string>
+
+#include <PointerDefinitions.h>
+
+class GbPoint3D;
+
+//! \brief This Class provides basic 3D vector objects.
+class GbVector3D 
+{
+public:
+   // construction
+    GbVector3D (); 
+    GbVector3D (const double& fX1, const double& fX2, const double& fX3);
+    GbVector3D (const GbVector3D& rkV);
+    GbVector3D (const GbPoint3D& rkV);
+
+    std::string toString();
+
+    // coordinate access
+    operator const double* () const;
+    operator double* ();
+    double operator[] (int i) const;
+    double& operator[] (int i);
+    double X1 () const;
+    double& X1 ();
+    double X2 () const;
+    double& X2 ();                                    
+    double X3 () const;
+    double& X3 ();
+
+    // assignment
+    GbVector3D& operator= (const GbVector3D& rkV);
+
+    // comparison
+    bool operator== (const GbVector3D& rkV) const;
+    bool operator!= (const GbVector3D& rkV) const;
+    bool operator<  (const GbVector3D& rkV) const;
+    bool operator<= (const GbVector3D& rkV) const;
+    bool operator>  (const GbVector3D& rkV) const;
+    bool operator>= (const GbVector3D& rkV) const;
+
+    // arithmetic operations
+    GbVector3D operator+ (const GbVector3D& rkV) const;
+    GbVector3D operator- (const GbVector3D& rkV) const;
+    GbVector3D operator* (const double& fScalar) const;
+    GbVector3D operator/ (const double& fScalar) const;
+    GbVector3D operator- () const;
+
+    // arithmetic updates
+    GbVector3D& operator+= (const GbVector3D& rkV);
+    GbVector3D& operator-= (const GbVector3D& rkV);
+    GbVector3D& operator*= (const double& fScalar);
+    GbVector3D& operator/= (const double& fScalar);
+
+    GbVector3D Add(GbVector3D& vector);
+    GbVector3D Subtract(GbVector3D& vector);
+    GbVector3D Scale(const double& x);
+
+    // vector operations
+    double Length () const;
+    double SquaredLength () const;
+    double Dot (const GbVector3D& rkV) const;
+    double Normalize ();
+
+    // The cross products are computed using the right-handed rule.  Be aware
+    // that some graphics APIs use a left-handed rule.  If you have to compute
+    // a cross product with these functions and send the result to the API
+    // that expects left-handed, you will need to change sign on the vector
+    // (replace each component value c by -c).
+    GbVector3D Cross (const GbVector3D& rkV) const;
+    GbVector3D UnitCross (const GbVector3D& rkV) const;
+
+    // Compute the barycentric coordinates of the point with respect to the
+    // tetrahedron <V0,V1,V2,V3>, P = b0*V0 + b1*V1 + b2*V2 + b3*V3, where
+    // b0 + b1 + b2 + b3 = 1.
+    void GetBarycentrics (const GbVector3D& rkV0,
+                          const GbVector3D& rkV1, const GbVector3D& rkV2,
+                          const GbVector3D& rkV3, double afBary[4]) const;
+
+    // Gram-Schmidt orthonormalization.  Take linearly independent vectors
+    // U, V, and W and compute an orthonormal set (unit length, mutually
+    // perpendicular).
+    static void Orthonormalize (GbVector3D& rkU, GbVector3D& rkV, GbVector3D& rkW);
+    static void Orthonormalize (GbVector3D* akV);
+
+    // Input W must be initialized to a nonzero vector, output is {U,V,W},
+    // an orthonormal basis.  A hint is provided about whether or not W
+    // is already unit length.
+    static void GenerateOrthonormalBasis (GbVector3D& rkU, GbVector3D& rkV,
+                                          GbVector3D& rkW, bool bUnitLengthW);
+
+    // special vectors
+    static const GbVector3D ZERO;
+    static const GbVector3D UNIT_X1;
+    static const GbVector3D UNIT_X2;
+    static const GbVector3D UNIT_X3;
+
+private:
+    // support for comparisons
+    int CompareArrays (const GbVector3D& rkV) const;
+
+    double m_afTuple[3];
+};
+
+GbVector3D operator* (const double& fScalar, const GbVector3D& rkV);
+
+#endif //GBVECTOR3D_H
diff --git a/VirtualFluidsCore/BoundaryConditions/BCAdapter.h b/VirtualFluidsCore/BoundaryConditions/BCAdapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..26437dafc6c6075d5ba8d8f64aecabd6c207e089
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCAdapter.h
@@ -0,0 +1,92 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCAdapter.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+#ifndef BCAdapter_H
+#define BCAdapter_H
+
+#include <PointerDefinitions.h>
+
+#include "BoundaryConditions.h"
+#include "BCAlgorithm.h"
+
+class D3Q27Interactor;
+
+//! \brief Abstract class of baundary conditions adapter
+//! \details  BCAdapter supports the definition of boundary conditions in grid generation
+class BCAdapter
+{
+public:
+   BCAdapter() 
+      :  secondaryBcOption(0)
+       , type(0)
+       , algorithmType(-1)
+   {
+   }
+   //! \param secondaryBcOption additional option of boundary conditions
+   BCAdapter(const short& secondaryBcOption) 
+      :  secondaryBcOption(secondaryBcOption) 
+       , type(0)
+       , algorithmType(-1)
+   {
+   }
+   virtual ~BCAdapter() {}
+
+   //methods
+   bool isTimeDependent() { return((this->type & TIMEDEPENDENT) ==  TIMEDEPENDENT); }
+
+   virtual short getSecondaryBcOption() { return this->secondaryBcOption; }
+   virtual void  setSecondaryBcOption(const short& val) { this->secondaryBcOption=val; }
+
+   virtual void init(const D3Q27Interactor* const& interactor, const double& time=0) = 0;
+   virtual void update(const D3Q27Interactor* const& interactor, const double& time=0) = 0;
+
+   virtual void adaptBC( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& time=0 ) = 0;
+   virtual void adaptBCForDirection( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& q, const int& fdirection, const double& time=0 ) = 0;
+
+   void setBcAlgorithm(SPtr<BCAlgorithm> alg) {algorithmType = alg->getType(); algorithm = alg;}
+   SPtr<BCAlgorithm> getAlgorithm() {return algorithm;} 
+   char getBcAlgorithmType() {return algorithmType;}
+
+protected:
+   short secondaryBcOption;
+
+   char  type;
+
+   SPtr<BCAlgorithm> algorithm;
+   char algorithmType;
+
+   static const char   TIMEDEPENDENT = 1<<0;//'1';
+   static const char   TIMEPERIODIC  = 1<<1;//'2';
+};
+
+
+#endif 
diff --git a/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp b/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..630b3ec7e4922309da0630eb09f0aa60c0e2cfa2
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.cpp
@@ -0,0 +1,103 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCAlgorithm.cpp
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "BCAlgorithm.h"
+
+#include "BoundaryConditions.h"
+#include "EsoTwist3D.h"
+#include "BCArray3D.h"
+
+
+BCAlgorithm::BCAlgorithm() : compressible(false)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setNodeIndex(int x1, int x2, int x3)
+{
+    this->x1 = x1;
+    this->x2 = x2;
+    this->x3 = x3;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setBcPointer(SPtr<BoundaryConditions> bcPtr)
+{
+    this->bcPtr = bcPtr;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setCompressible(bool c)
+{
+   compressible = c;
+
+   if (this->compressible)
+   {
+      calcFeqsForDirFct = &D3Q27System::getCompFeqForDirection;
+      calcMacrosFct = &D3Q27System::calcCompMacroscopicValues;
+      calcFeqFct = &D3Q27System::calcCompFeq;
+      compressibleFactor = 1.0;
+   }
+   else
+   {
+      calcFeqsForDirFct = &D3Q27System::getIncompFeqForDirection;
+      calcMacrosFct = &D3Q27System::calcIncompMacroscopicValues;
+      calcFeqFct = &D3Q27System::calcIncompFeq;
+      compressibleFactor = 0.0;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setCollFactor(LBMReal cf)
+{
+   collFactor = cf;
+}
+
+//////////////////////////////////////////////////////////////////////////
+char BCAlgorithm::getType()
+{
+   return type;
+}
+//////////////////////////////////////////////////////////////////////////
+bool BCAlgorithm::isPreCollision()
+{
+   return preCollision;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCArray3D> BCAlgorithm::getBcArray()
+{
+   return bcArray;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCAlgorithm::setBcArray(SPtr<BCArray3D> bcarray)
+{
+   bcArray = bcarray;
+}
+
diff --git a/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h b/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a3944c7e2c9ead7687818553446ef4cf1d2d5d8
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCAlgorithm.h
@@ -0,0 +1,100 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCAlgorithm.h
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BOUNDARYCONDITIONS_H
+#define BOUNDARYCONDITIONS_H
+
+#include <PointerDefinitions.h>
+
+#include "D3Q27System.h"
+
+class DistributionArray3D;
+class BCArray3D;
+class BoundaryConditions;
+
+//! \brief Abstract class of baundary conditions algorithm
+//! \details  BCAlgorithm provides interface for implementation of diferent boundary conditions
+class BCAlgorithm
+{
+public:
+   static const char VelocityBCAlgorithm = 0;
+   static const char EqDensityBCAlgorithm = 1;
+   static const char NonEqDensityBCAlgorithm = 2;
+   static const char NoSlipBCAlgorithm = 3;
+   static const char SlipBCAlgorithm = 4;
+   static const char HighViscosityNoSlipBCAlgorithm = 5;
+   static const char ThinWallNoSlipBCAlgorithm = 6;
+   static const char VelocityWithDensityBCAlgorithm = 7;
+   static const char NonReflectingOutflowBCAlgorithm = 8;
+
+public:
+   BCAlgorithm();
+   virtual ~BCAlgorithm() {}
+   
+   virtual void addDistributions(SPtr<DistributionArray3D> distributions) = 0;
+   void setNodeIndex(int x1, int x2, int x3);
+   void setBcPointer(SPtr<BoundaryConditions> bcPtr);
+   void setCompressible(bool c);
+   void setCollFactor(LBMReal cf);
+   char getType();
+   bool isPreCollision();
+   virtual SPtr<BCAlgorithm> clone() = 0;
+   SPtr<BCArray3D> getBcArray();
+   void setBcArray(SPtr<BCArray3D> bcarray);
+   virtual void applyBC() = 0;
+
+protected:
+   bool compressible;
+   char type;
+   bool preCollision;
+
+   SPtr<BoundaryConditions> bcPtr;
+   SPtr<DistributionArray3D> distributions;
+   SPtr<BCArray3D> bcArray;
+
+   LBMReal collFactor;
+   int x1, x2, x3;
+
+   LBMReal compressibleFactor;
+
+   typedef void(*CalcMacrosFct)(const LBMReal* const& /*f[27]*/, LBMReal& /*rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
+   typedef LBMReal(*CalcFeqForDirFct)(const int& /*direction*/, const LBMReal& /*(d)rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
+   typedef  void(*CalcFeqFct)(LBMReal* const& /*feq/*[27]*/, const LBMReal& /*rho*/, const LBMReal& /*vx1*/, const LBMReal& /*vx2*/, const LBMReal& /*vx3*/);
+   
+   CalcFeqForDirFct calcFeqsForDirFct ;
+   CalcMacrosFct    calcMacrosFct;
+   CalcFeqFct       calcFeqFct; 
+};
+
+
+#endif 
diff --git a/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp b/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..10fe50523d7e96da3cce3461703c466d0c513ddf
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCArray3D.cpp
@@ -0,0 +1,235 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCArray3D.cpp
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#include "BCArray3D.h"
+
+const int BCArray3D::SOLID = -1;
+const int BCArray3D::FLUID = -2;
+const int BCArray3D::INTERFACECF = -3;
+const int BCArray3D::INTERFACEFC = -4;
+const int BCArray3D::UNDEFINED = -5;
+
+//////////////////////////////////////////////////////////////////////////
+BCArray3D::BCArray3D() {}
+//////////////////////////////////////////////////////////////////////////
+BCArray3D::BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3)
+{
+   bcindexmatrix.resize(nx1, nx2, nx3, UNDEFINED);
+}
+//////////////////////////////////////////////////////////////////////////
+BCArray3D::BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val)
+{
+   bcindexmatrix.resize(nx1, nx2, nx3, val);
+}
+//////////////////////////////////////////////////////////////////////////
+BCArray3D::~BCArray3D() {}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::resize(std::size_t nx1, std::size_t nx2, std::size_t nx3)
+{
+   bcindexmatrix.resize(nx1, nx2, nx3);
+}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::resize(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val)
+{
+   bcindexmatrix.resize(nx1, nx2, nx3, val);
+}
+//////////////////////////////////////////////////////////////////////////
+bool BCArray3D::validIndices(std::size_t x1, std::size_t x2, std::size_t x3)  const
+{
+   if (x1 < 0 || x1 >= this->bcindexmatrix.getNX1()) return false;
+   if (x2 < 0 || x2 >= this->bcindexmatrix.getNX2()) return false;
+   if (x3 < 0 || x3 >= this->bcindexmatrix.getNX3()) return false;
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::setBC(std::size_t x1, std::size_t x2, std::size_t x3, SPtr<BoundaryConditions> const& bc)
+{
+   if (this->hasBC(x1, x2, x3))
+   {
+      if (this->getBC(x1, x2, x3) == bc) return;
+      else                            this->deleteBC(x1, x2, x3);
+   }
+
+   //if no vacant BCs available
+   if (indexContainer.empty())
+   {
+      bcvector.push_back(bc);
+      bcindexmatrix(x1, x2, x3) = (int)bcvector.size() - 1;
+   }
+   else
+   {
+      int index = indexContainer.back();
+      bcindexmatrix(x1, x2, x3) = index;
+      bcvector[index] = bc;
+      indexContainer.pop_back();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::setSolid(std::size_t x1, std::size_t x2, std::size_t x3)
+{
+   if (this->hasBC(x1, x2, x3)) this->deleteBC(x1, x2, x3);
+   bcindexmatrix(x1, x2, x3) = SOLID;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::setFluid(std::size_t x1, std::size_t x2, std::size_t x3)
+{
+   if (this->hasBC(x1, x2, x3)) this->deleteBC(x1, x2, x3);
+   bcindexmatrix(x1, x2, x3) = FLUID;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::setUndefined(std::size_t x1, std::size_t x2, std::size_t x3)
+{
+   if (this->hasBC(x1, x2, x3)) this->deleteBC(x1, x2, x3);
+   bcindexmatrix(x1, x2, x3) = UNDEFINED;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getNumberOfSolidEntries() const
+{
+   const std::vector<int>& data = bcindexmatrix.getDataVector();
+   std::size_t counter = 0;
+   for (std::size_t i = 0; i < data.size(); i++)
+      if (data[i] == SOLID) counter++;
+   return counter;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getNumberOfFluidEntries() const
+{
+   const std::vector<int>& data = bcindexmatrix.getDataVector();
+   std::size_t counter = 0;
+   for (std::size_t i = 0; i < data.size(); i++)
+   {
+      int tmp = data[i];
+      if (tmp == FLUID || tmp >= 0) counter++;
+   }
+   return counter;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getNumberOfFluidWithoutBCEntries() const
+{
+   const std::vector<int>& data = bcindexmatrix.getDataVector();
+   std::size_t counter = 0;
+   for (std::size_t i = 0; i < data.size(); i++)
+      if (data[i] == FLUID) counter++;
+   return counter;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getNumberOfBCEntries() const
+{
+   const std::vector<int>& data = bcindexmatrix.getDataVector();
+   std::size_t counter = 0;
+   for (std::size_t i = 0; i < data.size(); i++)
+      if (data[i] >= 0) counter++;
+   return counter;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getNumberOfUndefinedEntries() const
+{
+   const std::vector<int>& data = bcindexmatrix.getDataVector();
+   std::size_t counter = 0;
+   for (std::size_t i = 0; i < data.size(); i++)
+      if (data[i] == UNDEFINED) counter++;
+   return counter;
+}
+//////////////////////////////////////////////////////////////////////////
+std::size_t BCArray3D::getBCVectorSize() const
+{
+   return this->bcvector.size();
+}
+//////////////////////////////////////////////////////////////////////////
+std::string BCArray3D::toString() const
+{
+   std::size_t solidCounter = 0;
+   std::size_t fluidCounter = 0;
+   std::size_t bcCounter = 0;
+   std::size_t undefCounter = 0;
+
+   for (int x1 = 0; x1 < bcindexmatrix.getNX1(); x1++)
+   {
+      for (int x2 = 0; x2 < bcindexmatrix.getNX2(); x2++)
+      {
+         for (int x3 = 0; x3 < bcindexmatrix.getNX3(); x3++)
+         {
+            if (bcindexmatrix(x1, x2, x3) >= 0) bcCounter++;
+            else if (bcindexmatrix(x1, x2, x3) == FLUID) fluidCounter++;
+            else if (bcindexmatrix(x1, x2, x3) == SOLID) solidCounter++;
+            else if (bcindexmatrix(x1, x2, x3) == UNDEFINED) undefCounter++;
+            else throw UbException(UB_EXARGS, "invalid matrixEntry");
+         }
+      }
+   }
+
+   std::size_t unrefEntriesInBcVector = 0;
+   for (std::size_t i = 0; i < bcvector.size(); i++) if (!bcvector[i]) unrefEntriesInBcVector++;
+
+   std::stringstream text;
+   text << "BCArray<" << typeid(SPtr<BoundaryConditions>).name() << "," << typeid(int).name() << ">";
+   text << "[ entries: " << bcindexmatrix.getNX1() << "x" << bcindexmatrix.getNX2();
+   text << "x" << bcindexmatrix.getNX3() << "=";
+   text << bcindexmatrix.getNX1()*bcindexmatrix.getNX2()*bcindexmatrix.getNX3() << " ]:\n";
+   text << " - #fluid entries : " << fluidCounter << std::endl;
+   text << " - #bc    entries : " << bcCounter << std::endl;
+   text << " - #solid entries : " << solidCounter << std::endl;
+   text << " - #undef entries : " << undefCounter << std::endl;
+   text << " - bcvector-entries      : " << bcvector.size() << " (empty ones: " << unrefEntriesInBcVector << ")\n";
+   text << " - indexContainer-entries: " << indexContainer.size() << std::endl;
+
+   return text.str();
+}
+//////////////////////////////////////////////////////////////////////////
+std::vector< int >& BCArray3D::getBcindexmatrixDataVector()
+{
+   return bcindexmatrix.getDataVector();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::deleteBCAndSetType(std::size_t x1, std::size_t x2, std::size_t x3, int type)
+   {
+      this->deleteBC(x1, x2, x3);
+
+      //Assign matrix to new type
+      bcindexmatrix(x1, x2, x3) = type;
+   }
+//////////////////////////////////////////////////////////////////////////
+void BCArray3D::deleteBC(std::size_t x1, std::size_t x2, std::size_t x3)
+   {
+      //check if BC exists at all
+      int index = bcindexmatrix(x1, x2, x3);
+      if (index < 0) return;
+
+      //slide the released index into the index container
+      indexContainer.push_back(index);
+
+      //"delete" element
+      bcvector[index] = SPtr<BoundaryConditions>();
+   }
\ No newline at end of file
diff --git a/VirtualFluidsCore/BoundaryConditions/BCArray3D.h b/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..b87b03ed33e8a8c2e4e932b591f5cde6164ec101
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCArray3D.h
@@ -0,0 +1,224 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCArray3D.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#ifndef BCArray_H
+#define BCArray_H
+
+#include "BoundaryConditions.h"
+#include "basics/container/CbArray3D.h"
+
+#include <typeinfo>
+
+#include <PointerDefinitions.h>
+
+//! A class implements array to store boundary conditions flags 
+class BCArray3D
+{
+public:
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D();
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3);
+   //////////////////////////////////////////////////////////////////////////
+   BCArray3D(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
+   //////////////////////////////////////////////////////////////////////////
+   virtual ~BCArray3D();
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX1() const;
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX2() const;
+   //////////////////////////////////////////////////////////////////////////
+   inline std::size_t getNX3() const;
+   //////////////////////////////////////////////////////////////////////////
+   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3);
+   //////////////////////////////////////////////////////////////////////////
+   void resize(std::size_t nx1, std::size_t nx2, std::size_t nx3, int val);
+   //////////////////////////////////////////////////////////////////////////
+   bool validIndices(std::size_t x1, std::size_t x2, std::size_t x3)  const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const;
+   //////////////////////////////////////////////////////////////////////////
+   void setBC(std::size_t x1, std::size_t x2, std::size_t x3, SPtr<BoundaryConditions> const& bc);
+   //////////////////////////////////////////////////////////////////////////
+   inline int getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline const SPtr<BoundaryConditions> getBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline SPtr<BoundaryConditions> getBC(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   void setSolid(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setFluid(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   //true : FLUID or BC
+   //false: UNDEFINED or SOLID
+   inline bool isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setUndefined(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   inline bool isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfSolidEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfFluidEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfFluidWithoutBCEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfBCEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getNumberOfUndefinedEntries() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::size_t getBCVectorSize() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::string toString() const;
+   //////////////////////////////////////////////////////////////////////////
+   std::vector< int >& getBcindexmatrixDataVector();
+   //////////////////////////////////////////////////////////////////////////
+   bool isInsideOfDomain(const int &x1, const int &x2, const int &x3, const int& ghostLayerWidth) const;
+
+   static const int SOLID;     
+   static const int FLUID;     
+   static const int INTERFACECF; 
+   static const int INTERFACEFC; 
+   static const int UNDEFINED; 
+
+private:
+   //////////////////////////////////////////////////////////////////////////
+   void deleteBCAndSetType(std::size_t x1, std::size_t x2, std::size_t x3, int type);
+   //////////////////////////////////////////////////////////////////////////
+   void deleteBC(std::size_t x1, std::size_t x2, std::size_t x3);
+
+   friend class MPIIORestartCoProcessor;
+   friend class MPIIOMigrationCoProcessor;
+   friend class MPIIOMigrationBECoProcessor;
+
+protected:
+   //////////////////////////////////////////////////////////////////////////
+   //-1 solid // -2 fluid -...
+   CbArray3D<int, IndexerX3X2X1> bcindexmatrix;
+   std::vector<SPtr<BoundaryConditions>> bcvector;
+   std::vector<int> indexContainer;
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX1() const { return bcindexmatrix.getNX1(); }
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX2() const { return bcindexmatrix.getNX2(); }
+//////////////////////////////////////////////////////////////////////////
+inline std::size_t BCArray3D::getNX3() const { return bcindexmatrix.getNX3(); }
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::hasBC(std::size_t x1, std::size_t x2, std::size_t x3)  const
+{
+   return bcindexmatrix(x1, x2, x3) >= 0;
+}
+//////////////////////////////////////////////////////////////////////////
+inline int BCArray3D::getBCVectorIndex(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3);
+}
+//////////////////////////////////////////////////////////////////////////
+inline const SPtr<BoundaryConditions>  BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   int index = bcindexmatrix(x1, x2, x3);
+   if (index < 0) return SPtr<BoundaryConditions>(); //=> NULL Pointer
+
+   return bcvector[index];
+}
+//////////////////////////////////////////////////////////////////////////
+inline SPtr<BoundaryConditions> BCArray3D::getBC(std::size_t x1, std::size_t x2, std::size_t x3)
+{
+   int index = bcindexmatrix(x1, x2, x3);
+   if (index < 0) return SPtr<BoundaryConditions>(); //=> NULL Pointer
+
+   return bcvector[index];
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isSolid(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == SOLID;
+}
+//////////////////////////////////////////////////////////////////////////
+//true : FLUID or BC
+//false: UNDEFINED or SOLID
+inline bool BCArray3D::isFluid(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   int tmp = bcindexmatrix(x1, x2, x3);
+   return (tmp == FLUID || tmp >= 0);
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isFluidWithoutBC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == FLUID;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isUndefined(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == UNDEFINED;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInterfaceCF(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == INTERFACECF;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInterfaceFC(std::size_t x1, std::size_t x2, std::size_t x3) const
+{
+   return bcindexmatrix(x1, x2, x3) == INTERFACEFC;
+}
+//////////////////////////////////////////////////////////////////////////
+inline bool BCArray3D::isInsideOfDomain(const int& x1, const int& x2, const int& x3, const int& ghostLayerWidth) const
+{
+    const int minX1 = ghostLayerWidth;
+    const int maxX1 = (int)this->getNX1() - 1 - ghostLayerWidth;
+    const int minX2 = ghostLayerWidth;
+    const int maxX2 = (int)this->getNX2() - 1 - ghostLayerWidth;
+    const int minX3 = ghostLayerWidth;
+    const int maxX3 = (int)this->getNX3() - 1 - ghostLayerWidth;
+
+    return (!(x1 < minX1 || x1 > maxX1 || x2 < minX2 || x2 > maxX2 || x3 < minX3 || x3 > maxX3));
+}
+
+#endif 
diff --git a/VirtualFluidsCore/BoundaryConditions/BCFunction.cpp b/VirtualFluidsCore/BoundaryConditions/BCFunction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f661804b17bf64d5e5f8217f9947f816aeb7db9
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCFunction.cpp
@@ -0,0 +1,38 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCFunction.cpp
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#include "BCFunction.h"
+
+const double BCFunction::INFTIMEDEPENDENT = -1.0;
+const double BCFunction::INFCONST         = -10.0;
+
diff --git a/VirtualFluidsCore/BoundaryConditions/BCFunction.h b/VirtualFluidsCore/BoundaryConditions/BCFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f9ad2f342efaf5cd6eaa29b348b5e9f76a714a4
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCFunction.h
@@ -0,0 +1,113 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCFunction.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#ifndef D3Q27BCFUNCTION_H
+#define D3Q27BCFUNCTION_H
+
+#include <basics/utilities/UbInfinity.h>
+
+#include <MuParser/include/muParser.h>
+
+//! A class implements function parcer for boundary conditions  
+class BCFunction
+{
+public:
+   static const double INFTIMEDEPENDENT;
+   static const double INFCONST;
+
+public:
+   BCFunction() 
+      : starttime(-Ub::inf ), endtime(-Ub::inf ) 
+   {
+
+   }
+   BCFunction( const mu::Parser& function, const double& starttime, const double& endtime )
+      : function(function), starttime(starttime), endtime(endtime)
+   {
+
+   }
+   BCFunction( const std::string& functionstring, const double& starttime, const double& endtime )
+      : starttime(starttime), endtime(endtime)
+   {
+      this->setFunction(functionstring); 
+   }
+   BCFunction( const double& velocity, const double& starttime, const double& endtime )
+      : starttime(starttime), endtime(endtime)
+   {
+      this->setFunction(velocity); 
+   }
+
+   void setFunction(const mu::Parser& function) { this->function = function; }
+   void setFunction(const std::string& functionstring) { this->function.SetExpr(functionstring); }
+   void setFunction(const double& constVelocity) { std::stringstream dummy; dummy<<constVelocity; function.SetExpr(dummy.str());  }
+   void setStartTime(const double& starttime) {this->starttime = starttime; }
+   void setEndTime(const double& starttime) {this->endtime = endtime; }
+
+   mu::Parser&        getFunction()        { return function;  }
+   const mu::Parser&  getFunction()  const { return function;  }
+   const double&      getStartTime() const { return starttime; }
+   const double&      getEndTime()   const { return endtime;   }
+
+   std::string toString() const
+   {
+      std::stringstream info;
+      if     (starttime==INFTIMEDEPENDENT) info<<"start=inf. timedep., ";
+      else if(starttime==INFCONST        ) info<<"start=inf. const., ";
+      else                                 info<<"start="<<starttime<<", ";
+      if     (endtime==INFTIMEDEPENDENT) info<<"end=inf. timedep."<<std::endl;
+      else if(endtime==INFCONST        ) info<<"end=inf. const."<<std::endl;
+      else                               info<<"end="<<endtime<<std::endl;
+      info<<"expr="<<function.GetExpr()<<std::endl;
+      info<<"with constants: ";
+      mu::valmap_type cmap = function.GetConst();
+      for(mu::valmap_type::const_iterator item = cmap.begin(); item!=cmap.end(); ++item)
+         info<<item->first<<"="<<item->second<<", ";
+      return info.str();
+   }
+   /*==========================================================*/
+   friend inline std::ostream& operator << (std::ostream& os, const BCFunction& bc) 
+   {
+      os<<bc.toString();
+      return os;
+   }
+
+protected:
+   mu::Parser function;
+   double starttime;
+   double endtime;
+
+private:
+
+};
+
+#endif //D3Q27BCFUNCTION_H
diff --git a/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp b/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5eabfe8eedc25d9fd720ab34a1c16dff874774ee
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCProcessor.cpp
@@ -0,0 +1,102 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCProcessor.h
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "BCProcessor.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "DataSet3D.h"
+#include "ILBMKernel.h"
+#include "BCArray3D.h"
+#include "BCAlgorithm.h"
+
+BCProcessor::BCProcessor()
+{
+   
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessor::BCProcessor(SPtr<ILBMKernel> kernel)
+{
+   SPtr<DistributionArray3D> distributions = std::dynamic_pointer_cast<EsoTwist3D>(kernel->getDataSet()->getFdistributions());
+   bcArray = SPtr<BCArray3D>(new BCArray3D( distributions->getNX1(), distributions->getNX2(), distributions->getNX3(), BCArray3D::FLUID));
+}
+//////////////////////////////////////////////////////////////////////////
+BCProcessor::~BCProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCProcessor> BCProcessor::clone(SPtr<ILBMKernel> kernel)
+{
+   SPtr<BCProcessor> bcProcessor(new BCProcessor(kernel));
+   return bcProcessor;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCArray3D> BCProcessor::getBCArray()
+{ 
+   return bcArray; 
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::setBCArray(SPtr<BCArray3D> bcarray)
+{
+   bcArray = bcarray;
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::addBC(SPtr<BCAlgorithm> bc)
+{
+   if (bc->isPreCollision())
+   {
+      preBC.push_back(bc);
+   }
+   else
+   {
+      postBC.push_back(bc);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::applyPreCollisionBC()
+{
+   for(SPtr<BCAlgorithm> bc : preBC)
+      bc->applyBC();
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::applyPostCollisionBC()
+{
+    for (SPtr<BCAlgorithm> bc : postBC)
+        bc->applyBC();
+}
+//////////////////////////////////////////////////////////////////////////
+void BCProcessor::clearBC()
+{
+   preBC.clear();
+   postBC.clear();
+}
+
diff --git a/VirtualFluidsCore/BoundaryConditions/BCProcessor.h b/VirtualFluidsCore/BoundaryConditions/BCProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..9dc572b0d11df350846bc8f17b62bb57f356dc36
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BCProcessor.h
@@ -0,0 +1,68 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BCProcessor.h
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BC_PROCESSSOR_H
+#define BC_PROCESSSOR_H
+
+#include <PointerDefinitions.h>
+#include <vector>
+
+class BCArray3D;
+class BCAlgorithm;
+class ILBMKernel;
+
+//! A class provides an interface for boundary conditions in the calculation loop.  
+class BCProcessor
+{
+public:
+   BCProcessor();
+   BCProcessor(SPtr<ILBMKernel> kernel);
+   virtual ~BCProcessor();
+   virtual SPtr<BCArray3D> getBCArray();
+   virtual void setBCArray(SPtr<BCArray3D> bcarray);
+   virtual SPtr<BCProcessor> clone(SPtr<ILBMKernel> kernel);
+
+   void addBC(SPtr<BCAlgorithm> bc);
+   void applyPreCollisionBC();
+   void applyPostCollisionBC();
+   void clearBC();
+protected:
+   std::vector<SPtr<BCAlgorithm> > preBC;
+   std::vector<SPtr<BCAlgorithm> > postBC;
+   SPtr<BCArray3D> bcArray;
+
+private:
+
+};
+
+#endif
diff --git a/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.cpp b/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7dadd850f73b3ec678f30692bc2884c811f25144
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.cpp
@@ -0,0 +1,37 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BoundaryConditions.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#include "BoundaryConditions.h"
+
+const long long BoundaryConditions::maxOptionVal = ( 1<<optionDigits ) - 1; //2^3-1 -> 7 
+
diff --git a/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h b/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9131f4f15374705bf1efd408ca8c070c6884ea4
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/BoundaryConditions.h
@@ -0,0 +1,283 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BoundaryConditions.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+#ifndef BoundaryConditions_H
+#define BoundaryConditions_H
+
+#include <vector>
+#include <string>
+
+#include "Vector3D.h"
+#include "UbException.h"                  
+#include "UbSystem.h"
+#include "UbTuple.h"
+#include "D3Q27System.h"
+#include <PointerDefinitions.h>
+
+//! Difenition of baundary conditions in grid generation
+class BoundaryConditions 
+{
+public:
+   BoundaryConditions() 
+      : noslipBoundaryFlags(0)		
+      , slipBoundaryFlags(0)		
+      , velocityBoundaryFlags(0)		
+      , densityBoundaryFlags(0)		
+      , wallModelBoundaryFlags(0)
+      , bcVelocityX1(0.0f)
+      , bcVelocityX2(0.0f)
+      , bcVelocityX3(0.0f)
+      , bcDensity(0.0f)
+      , bcLodiDensity(0.0f)
+      , bcLodiVelocityX1(0.0f)
+      , bcLodiVelocityX2(0.0f)
+      , bcLodiVelocityX3(0.0f)
+      , bcLodiLentgh(0.0f)
+      , nx1(0.0f)
+      , nx2(0.0f)
+      , nx3(0.0f)
+      , algorithmType(-1)
+   {
+      UB_STATIC_ASSERT( sizeof(long long) >= 8);
+      UB_STATIC_ASSERT( (sizeof(long long)*8) >= (D3Q27System::FENDDIR+1)*BoundaryConditions::optionDigits );
+
+      for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++) 
+         q[fdir] = -999.; 
+   }
+   virtual ~BoundaryConditions() {}
+
+   virtual bool isEmpty() { return (noslipBoundaryFlags&slipBoundaryFlags&velocityBoundaryFlags&densityBoundaryFlags)==0;}
+   virtual bool hasBoundaryCondition()
+   {
+      return (  hasNoSlipBoundary() || hasSlipBoundary() 
+             || hasDensityBoundary() || hasVelocityBoundary() || hasWallModelBoundary() );
+   }
+
+   virtual bool hasBoundaryConditionFlag(const int& direction)
+   {
+      assert( direction >= D3Q27System::FSTARTDIR && direction <= D3Q27System::FENDDIR );
+
+      return (   hasNoSlipBoundaryFlag(direction) || hasSlipBoundaryFlag(direction) 
+              || hasDensityBoundaryFlag(direction) || hasVelocityBoundaryFlag(direction)  || hasWallModelBoundaryFlag(direction));
+   }
+protected:
+   void setFlagBits(long long& flag, const int& direction, const short& secOpt)
+   {
+      if( (secOpt+1)>maxOptionVal ) 
+         throw UbException(UB_EXARGS,"error: option > "+UbSystem::toString(maxOptionVal-1));
+      
+      //all digits at the respective positions to "0"
+      flag &= ~( maxOptionVal<<(direction*optionDigits) );
+      //set all digits according to the flag at the respective positions
+      flag |= ((long long)(secOpt+1)<<(direction*optionDigits));
+   }
+public:
+   /*===================== NoSlip Boundary ==================================================*/	
+   void       setNoSlipBoundaryFlag(const int& direction, const short& secOpt=0)    { this->setFlagBits(noslipBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetNoSlipBoundaryFlag(const int& direction)                         { this->noslipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetNoSlipBoundary()                                                 { this->noslipBoundaryFlags = 0;                                                               }
+   long long  getNoSlipBoundary()	                                                { return this->noslipBoundaryFlags;                                                            }
+   bool       hasNoSlipBoundary()					                                    { return (noslipBoundaryFlags!=0);                                                             }
+   bool       hasNoSlipBoundaryFlag(const int& direction)                           { return ( ( ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getNoSlipSecondaryOption(const int& direction)                        { return (short)( (  ( noslipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   /*===================== WallModel Boundary ==================================================*/	
+   void       setWallModelBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(wallModelBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetWallModelBoundaryFlag(const int& direction)                      { this->wallModelBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetWallModelBoundary()                                              { this->wallModelBoundaryFlags = 0;                                                               }
+   long long  getWallModelBoundary()	                                             { return this->wallModelBoundaryFlags;                                                            }
+   bool       hasWallModelBoundary()					                                 { return (wallModelBoundaryFlags!=0);                                                             }
+   bool       hasWallModelBoundaryFlag(const int& direction)                        { return ( ( ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getWallModelSecondaryOption(const int& direction)                     { return (short)( (  ( wallModelBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   /*===================== Slip-Solid Boundary ==================================================*/	
+   void       setSlipBoundaryFlag(const int& direction, const short& secOpt=0)      { this->setFlagBits(slipBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetSlipBoundaryFlag(const int& direction)                           { this->slipBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetSlipBoundary()                                                   { this->slipBoundaryFlags = 0;                                                               }
+   long long  getSlipBoundary()	                                                   { return this->slipBoundaryFlags;                                                            }
+   bool       hasSlipBoundary()					                                       { return (slipBoundaryFlags!=0);                                                             }
+   bool       hasSlipBoundaryFlag(const int& direction)	                           { return ( ( ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getSlipSecondaryOption(const int& direction)                          { return (short)( (  ( slipBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+   void       setNormalVector(const LBMReal& nx1,const LBMReal& nx2,const LBMReal& nx3)   { this->nx1 = nx1; this->nx2 = nx2;  this->nx3 = nx3;}
+   UbTupleDouble3 getNormalVector()                                                  { return makeUbTuple(nx1,nx2,nx3); }
+
+   /*============== Velocity Boundary ========================*/
+   void       setVelocityBoundaryFlag(const int& direction, const short& secOpt=0)  { this->setFlagBits(velocityBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetVelocityBoundaryFlag(const int& direction)                       { this->velocityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetVelocityBoundary()                 		                        { this->velocityBoundaryFlags = 0;                                                               }
+   long long  getVelocityBoundary()	               		                           { return this->velocityBoundaryFlags;                                                            }
+   bool       hasVelocityBoundary()   					 		                           { return this->velocityBoundaryFlags!=0;                                                         }
+   bool       hasVelocityBoundaryFlag(const int& direction)                         { return ( ( ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getVelocitySecondaryOption(const int& direction)                      { return (short)( (  ( velocityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+
+   void setBoundaryVelocity(const Vector3D& vx) 
+    {
+       setBoundaryVelocityX1((LBMReal)vx[0]); 
+       setBoundaryVelocityX2((LBMReal)vx[1]);
+       setBoundaryVelocityX3((LBMReal)vx[2]);
+   }
+   void  setBoundaryVelocityX1(const LBMReal& vx1) { this->bcVelocityX1 = vx1;  } 
+   void  setBoundaryVelocityX2(const LBMReal& vx2) { this->bcVelocityX2 = vx2;  } 
+   void  setBoundaryVelocityX3(const LBMReal& vx3) { this->bcVelocityX3 = vx3;  } 
+   LBMReal getBoundaryVelocityX1()                 { return this->bcVelocityX1; }
+   LBMReal getBoundaryVelocityX2()                 { return this->bcVelocityX2; }
+   LBMReal getBoundaryVelocityX3()                 { return this->bcVelocityX3; }
+   LBMReal getBoundaryVelocity(const int& direction) 
+   {                   
+      switch(direction)
+      {
+      case D3Q27System::E : return (LBMReal)( UbMath::c4o9*(+bcVelocityX1) );      //(2/cs^2)(=6)*rho_0(=1 for incompressible)*wi*u*ei with cs=1/sqrt(3)
+      case D3Q27System::W : return (LBMReal)( UbMath::c4o9*(-bcVelocityX1) );         
+      case D3Q27System::N : return (LBMReal)( UbMath::c4o9*(+bcVelocityX2) );   
+      case D3Q27System::S : return (LBMReal)( UbMath::c4o9*(-bcVelocityX2) );
+      case D3Q27System::T : return (LBMReal)( UbMath::c4o9*(+bcVelocityX3) );
+      case D3Q27System::B : return (LBMReal)( UbMath::c4o9*(-bcVelocityX3) );
+      case D3Q27System::NE: return (LBMReal)( UbMath::c1o9*(+bcVelocityX1+bcVelocityX2             ) );
+      case D3Q27System::SW: return (LBMReal)( UbMath::c1o9*(-bcVelocityX1-bcVelocityX2             ) );
+      case D3Q27System::SE: return (LBMReal)( UbMath::c1o9*(+bcVelocityX1-bcVelocityX2             ) );
+      case D3Q27System::NW: return (LBMReal)( UbMath::c1o9*(-bcVelocityX1+bcVelocityX2             ) );
+      case D3Q27System::TE: return (LBMReal)( UbMath::c1o9*(+bcVelocityX1             +bcVelocityX3) );
+      case D3Q27System::BW: return (LBMReal)( UbMath::c1o9*(-bcVelocityX1             -bcVelocityX3) );
+      case D3Q27System::BE: return (LBMReal)( UbMath::c1o9*(+bcVelocityX1             -bcVelocityX3) );
+      case D3Q27System::TW: return (LBMReal)( UbMath::c1o9*(-bcVelocityX1             +bcVelocityX3) );
+      case D3Q27System::TN: return (LBMReal)( UbMath::c1o9*(             +bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BS: return (LBMReal)( UbMath::c1o9*(             -bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BN: return (LBMReal)( UbMath::c1o9*(             +bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TS: return (LBMReal)( UbMath::c1o9*(             -bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::TNE: return (LBMReal)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BSW: return (LBMReal)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BNE: return (LBMReal)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TSW: return (LBMReal)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::TSE: return (LBMReal)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case D3Q27System::BNW: return (LBMReal)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::BSE: return (LBMReal)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case D3Q27System::TNW: return (LBMReal)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2+bcVelocityX3) ); 
+      default: throw UbException(UB_EXARGS,"unknown error");
+      }
+   }
+
+   /*============== Density Boundary ========================*/
+   void       setDensityBoundaryFlag(const int& direction, const short& secOpt=0) { this->setFlagBits(densityBoundaryFlags,direction,secOpt);                                     }  
+   void       unsetDensityBoundaryFlag(const int& direction)                      { this->densityBoundaryFlags &= ~( maxOptionVal<<(direction*optionDigits) );                    }
+   void       unsetDensityBoundary()                                              { this->densityBoundaryFlags = 0;                                                               }
+   long long  getDensityBoundary()	                                              { return this->densityBoundaryFlags;                                                            }
+   bool       hasDensityBoundary()					                                  { return (this->densityBoundaryFlags!=0);                                                       }
+   bool       hasDensityBoundaryFlag(const int& direction)	                      { return ( ( ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) != 0);         }
+   short      getDensitySecondaryOption(const int& direction)                     { return (short)( (  ( densityBoundaryFlags>>(optionDigits*direction) ) & maxOptionVal ) - 1 ); }
+
+   void  setBoundaryDensity(LBMReal density) { this->bcDensity = density; } 
+   LBMReal getBoundaryDensity()              { return this->bcDensity;    }
+
+   //Lodi extension
+   void  setDensityLodiDensity(const LBMReal& bcLodiDensity)       { this->bcLodiDensity    = bcLodiDensity;    } 
+   void  setDensityLodiVelocityX1(const LBMReal& bcLodiVelocityX1) { this->bcLodiVelocityX1 = bcLodiVelocityX1; } 
+   void  setDensityLodiVelocityX2(const LBMReal& bcLodiVelocityX2) { this->bcLodiVelocityX2 = bcLodiVelocityX2; } 
+   void  setDensityLodiVelocityX3(const LBMReal& bcLodiVelocityX3) { this->bcLodiVelocityX3 = bcLodiVelocityX3; } 
+   void  setDensityLodiLength(const LBMReal& bcLodiLentgh)         { this->bcLodiLentgh     = bcLodiLentgh;     } 
+   LBMReal getDensityLodiDensity() const                           { return this->bcLodiDensity;    } 
+   LBMReal getDensityLodiVelocityX1() const                        { return this->bcLodiVelocityX1; }
+   LBMReal getDensityLodiVelocityX2() const                        { return this->bcLodiVelocityX2; }
+   LBMReal getDensityLodiVelocityX3() const                        { return this->bcLodiVelocityX3; }
+   LBMReal getDensityLodiLength() const                            { return this->bcLodiLentgh;     }
+
+   LBMReal& densityLodiDensity()                                   { return this->bcLodiDensity;    } 
+   LBMReal& densityLodiVelocityX1()                                { return this->bcLodiVelocityX1; }
+   LBMReal& densityLodiVelocityX2()                                { return this->bcLodiVelocityX2; }
+   LBMReal& densityLodiVelocityX3()                                { return this->bcLodiVelocityX3; }
+   LBMReal& densityLodiLentgh()                                    { return this->bcLodiLentgh;     }
+
+   const LBMReal& densityLodiDensity()  const                      { return this->bcLodiDensity;    } 
+   const LBMReal& densityLodiVelocityX1() const                    { return this->bcLodiVelocityX1; }
+   const LBMReal& densityLodiVelocityX2() const                    { return this->bcLodiVelocityX2; }
+   const LBMReal& densityLodiVelocityX3() const                    { return this->bcLodiVelocityX3; }
+   const LBMReal& densityLodiLentgh()  const                       { return this->bcLodiLentgh;     }
+
+
+   /*======================= Qs =============================*/
+   void  setQ(const LBMReal& val, const int& direction) { q[direction] = val; }
+   LBMReal getQ(const int& direction)                   { return q[direction]; }
+   
+   virtual std::vector< std::string > getBCNames()
+   {
+      std::vector< std::string > tmp;
+      tmp.push_back( "NoSlipBC"   );
+      tmp.push_back( "SlipBC"     );
+      tmp.push_back( "VelocityBC" );
+      tmp.push_back( "DensityBC"  );
+      return tmp;
+   }
+   virtual std::vector< long long > getBCFlags()
+   {
+      std::vector< long long > tmp;
+      tmp.push_back( noslipBoundaryFlags   );
+      tmp.push_back( slipBoundaryFlags     );
+      tmp.push_back( velocityBoundaryFlags );
+      tmp.push_back( densityBoundaryFlags  );
+      return tmp;
+   }
+
+   static bool hasFlagForDirection(const long long& flag, const int& direction)
+   {
+      return ( ( ( flag>>(optionDigits*direction) ) & maxOptionVal ) != 0);
+   }
+
+   void setBcAlgorithmType(char alg) { algorithmType = alg; }
+   char getBcAlgorithmType() { return algorithmType; }
+
+public:
+   static const int       optionDigits = 2;  //--> 2 bits for secondary Option --> maxOptionVal = 7
+   static const long long maxOptionVal;// = ( 1<<optionDigits ) - 1; //2^3-1 -> 7
+
+protected:
+   LBMReal q[D3Q27System::FENDDIR+1];
+
+   long long noslipBoundaryFlags;		
+   long long slipBoundaryFlags;		
+   long long velocityBoundaryFlags;		
+   long long densityBoundaryFlags;		
+   long long wallModelBoundaryFlags;
+
+   LBMReal  bcVelocityX1;
+   LBMReal  bcVelocityX2;
+   LBMReal  bcVelocityX3;
+   LBMReal  bcDensity;
+
+   LBMReal  bcLodiDensity;
+   LBMReal  bcLodiVelocityX1;
+   LBMReal  bcLodiVelocityX2;
+   LBMReal  bcLodiVelocityX3;
+   LBMReal  bcLodiLentgh;
+
+   LBMReal  nx1,nx2,nx3;
+
+   char algorithmType;
+};
+
+#endif
diff --git a/VirtualFluidsCore/BoundaryConditions/CMakePackage.txt b/VirtualFluidsCore/BoundaryConditions/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e3e3f9a387b022a62ecc0d63c3ef0210313e906d
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
\ No newline at end of file
diff --git a/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.cpp b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58e479e39b3e71c291c95a435b7d2ed09c4b5aa3
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.cpp
@@ -0,0 +1,33 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NoSlipBCAdapter.cpp
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+#include "NoSlipBCAdapter.h"
diff --git a/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.h b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a09aefb44bed939467023825b7e4fbece3a9ab8
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAdapter.h
@@ -0,0 +1,68 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NoSlipBCAdapter.cpp
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#ifndef NoSlipBCAdapter_H
+#define NoSlipBCAdapter_H
+
+#include "BCAdapter.h"
+
+//! A class provides an interface for no-slip boundary condition in grid generator
+class NoSlipBCAdapter : public BCAdapter
+{
+public:
+   NoSlipBCAdapter()
+    : BCAdapter()
+   {
+   }
+   NoSlipBCAdapter(const short& secondaryBcOption)
+      : BCAdapter(secondaryBcOption)
+   {
+   }
+
+   void init(const D3Q27Interactor* const& interactor, const double& time=0) {}
+   void update(const D3Q27Interactor* const& interactor, const double& time=0) {}
+
+   void adaptBCForDirection( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& q, const int& fdirection, const double& time=0 )
+   {
+      bc->setNoSlipBoundaryFlag(D3Q27System::INVDIR[fdirection],secondaryBcOption);
+      bc->setQ((float)q,fdirection);
+   }
+   void adaptBC( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& time=0 ) 
+   {
+      bc->setBcAlgorithmType(algorithmType);
+   }
+
+private:
+
+};
+#endif //NoSlipBCAdapter_H
diff --git a/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5b68bf910f903d2c6c3ad839d02d64aff4ce83cc
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.cpp
@@ -0,0 +1,80 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NoSlipBCAlgorithm.cpp
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "NoSlipBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+NoSlipBCAlgorithm::NoSlipBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::NoSlipBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+NoSlipBCAlgorithm::~NoSlipBCAlgorithm()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCAlgorithm> NoSlipBCAlgorithm::clone()
+{
+   SPtr<BCAlgorithm> bc(new NoSlipBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void NoSlipBCAlgorithm::addDistributions(SPtr<DistributionArray3D> distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void NoSlipBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   distributions->getDistributionInv(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3;
+   calcMacrosFct(f, rho, vx1, vx2, vx3);
+   calcFeqFct(feq, rho, vx1, vx2, vx3);
+
+   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+   {
+      if (bcPtr->hasNoSlipBoundaryFlag(fdir))
+      {
+         //quadratic bounce back
+         const int invDir = D3Q27System::INVDIR[fdir];
+         LBMReal q = bcPtr->getQ(invDir);
+         LBMReal fReturn = ((1.0-q)/(1.0+q))*((f[invDir]-feq[invDir])/(1.0-collFactor)+feq[invDir])+((q/(1.0+q))*(f[invDir]+f[fdir]));
+         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
+      }
+   }
+}
diff --git a/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..1cf6d64203bcb5c77f39c3dc717a32e731f21516
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/NoSlipBCAlgorithm.h
@@ -0,0 +1,53 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NoSlipBCAlgorithm.h
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef NoSlipBCAlgorithm_h__
+#define NoSlipBCAlgorithm_h__
+
+#include "BCAlgorithm.h"
+#include <PointerDefinitions.h>
+
+class DistributionArray3D;
+
+//! A class implements no-slip boundary condition
+class NoSlipBCAlgorithm : public BCAlgorithm
+{
+public:
+   NoSlipBCAlgorithm();
+   virtual ~NoSlipBCAlgorithm();
+   SPtr<BCAlgorithm> clone();
+   void addDistributions(SPtr<DistributionArray3D> distributions);
+   void applyBC() override;
+private:
+};
+#endif 
diff --git a/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.cpp b/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7089da4e4b4a7d26df35fa91a01edbb487752a1c
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.cpp
@@ -0,0 +1,339 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file VelocityBCAdapter.cpp
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+
+#include "VelocityBCAdapter.h"
+#include "basics/utilities/UbLogger.h"
+#include "basics/utilities/UbMath.h"
+#include "basics/utilities/UbTuple.h"
+
+using namespace std;
+
+
+VelocityBCAdapter::VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const BCFunction& velVxBC)
+{
+   if(vx1) this->vx1BCs.push_back(velVxBC);
+   if(vx2) this->vx2BCs.push_back(velVxBC);
+   if(vx3) this->vx3BCs.push_back(velVxBC);
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const mu::Parser& function, const double& startTime, const double& endTime )
+{
+   if(vx1) this->vx1BCs.push_back(BCFunction(function,startTime,endTime));
+   if(vx2) this->vx2BCs.push_back(BCFunction(function,startTime,endTime));
+   if(vx3) this->vx3BCs.push_back(BCFunction(function,startTime,endTime));
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const mu::Parser& function1, const mu::Parser& function2, const mu::Parser& function3, const double& startTime, const double& endTime )
+{
+   if(vx1) this->vx1BCs.push_back(BCFunction(function1,startTime,endTime));
+   if(vx2) this->vx2BCs.push_back(BCFunction(function2,startTime,endTime));
+   if(vx3) this->vx3BCs.push_back(BCFunction(function3,startTime,endTime));
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const string& functionstring, const double& startTime, const double& endTime )
+{
+   if(vx1) this->vx1BCs.push_back(BCFunction(functionstring,startTime,endTime));
+   if(vx2) this->vx2BCs.push_back(BCFunction(functionstring,startTime,endTime));
+   if(vx3) this->vx3BCs.push_back(BCFunction(functionstring,startTime,endTime));
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const BCFunction& velBC, bool x1Dir, bool x2Dir, bool x3Dir)
+{
+   if(x1Dir) this->vx1BCs.push_back(velBC);
+   if(x2Dir) this->vx2BCs.push_back(velBC);
+   if(x3Dir) this->vx3BCs.push_back(velBC);
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const BCFunction& velVx1BC, const BCFunction& velVx2BC, const BCFunction& velVx3BC)
+{
+   if( velVx1BC.getEndTime()!=-Ub::inf ) this->vx1BCs.push_back(velVx1BC);
+   if( velVx2BC.getEndTime()!=-Ub::inf ) this->vx2BCs.push_back(velVx2BC);
+   if( velVx3BC.getEndTime()!=-Ub::inf ) this->vx3BCs.push_back(velVx3BC);
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const vector< BCFunction >& velVx1BCs, const vector< BCFunction >& velVx2BCs, const vector< BCFunction >& velVx3BCs)
+{
+   this->vx1BCs = velVx1BCs;
+   this->vx2BCs = velVx2BCs;
+   this->vx3BCs = velVx3BCs;
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const double& vx1, const double& vx1StartTime, const double& vx1EndTime,
+                                               const double& vx2, const double& vx2StartTime, const double& vx2EndTime,
+                                               const double& vx3, const double& vx3StartTime, const double& vx3EndTime )
+{
+   this->vx1BCs.push_back(BCFunction(vx1,vx1StartTime,vx1EndTime));
+   this->vx2BCs.push_back(BCFunction(vx2,vx2StartTime,vx2EndTime));
+   this->vx3BCs.push_back(BCFunction(vx3,vx3StartTime,vx3EndTime));
+   this->init();
+}
+/*==========================================================*/
+VelocityBCAdapter::VelocityBCAdapter(const string& vx1Function, const double& vx1StartTime, const double& vx1EndTime,
+                                               const string& vx2Function, const double& vx2StartTime, const double& vx2EndTime,
+                                               const string& vx3Function, const double& vx3StartTime, const double& vx3EndTime ) 
+{
+   if(vx1Function.size()) this->vx1BCs.push_back(BCFunction(vx1Function,vx1StartTime,vx1EndTime));
+   if(vx2Function.size()) this->vx2BCs.push_back(BCFunction(vx2Function,vx2StartTime,vx2EndTime));
+   if(vx3Function.size()) this->vx3BCs.push_back(BCFunction(vx3Function,vx3StartTime,vx3EndTime));
+   this->init();
+}
+/*==========================================================*/
+void VelocityBCAdapter::setNewVelocities(const double& vx1, const double& vx1StartTime, const double& vx1EndTime,
+                                              const double& vx2, const double& vx2StartTime, const double& vx2EndTime,
+                                              const double& vx3, const double& vx3StartTime, const double& vx3EndTime )
+{
+   this->clear();
+   this->vx1BCs.push_back(BCFunction(vx1,vx1StartTime,vx1EndTime));
+   this->vx2BCs.push_back(BCFunction(vx2,vx2StartTime,vx2EndTime));
+   this->vx3BCs.push_back(BCFunction(vx3,vx3StartTime,vx3EndTime));
+   this->init();
+}
+/*==========================================================*/
+void VelocityBCAdapter::init()
+{
+   this->unsetTimeDependent();
+   
+   this->timeStep = 0.0;
+
+   this->x1 = 0.0;
+   this->x2 = 0.0;
+   this->x3 = 0.0;
+
+   this->tmpVx1Function = NULL;
+   this->tmpVx2Function = NULL;
+   this->tmpVx3Function = NULL;
+
+   try //initilialization and validation of functions
+   {
+      this->init(vx1BCs);
+      this->init(vx2BCs);
+      this->init(vx3BCs);
+   }
+   catch(mu::Parser::exception_type& e){ stringstream error; error<<"mu::parser exception occurs, message("<<e.GetMsg()<<"), formula("<<e.GetExpr()+"), token("+e.GetToken()<<")"
+                                          <<", pos("<<e.GetPos()<<"), error code("<<e.GetCode(); throw UbException(error.str()); }
+   catch(...)                          { throw UbException(UB_EXARGS,"unknown exception" ); }
+}
+/*==========================================================*/
+void VelocityBCAdapter::init(std::vector<BCFunction>& vxBCs)
+{
+   for(size_t pos=0; pos<vxBCs.size(); ++pos)
+   {
+      if( !(    UbMath::equal( BCFunction::INFCONST, vxBCs[pos].getEndTime() )
+             && UbMath::greaterEqual( this->timeStep,  vxBCs[pos].getStartTime()  ) ) )
+      {
+         this->setTimeDependent();
+      }
+
+      vxBCs[pos].getFunction().DefineVar("t" , &this->timeStep);
+      vxBCs[pos].getFunction().DefineVar("x1", &this->x1      );
+      vxBCs[pos].getFunction().DefineVar("x2", &this->x2      );
+      vxBCs[pos].getFunction().DefineVar("x3", &this->x3      );
+
+      vxBCs[pos].getFunction().Eval(); //<-- validation
+   }
+}
+/*==========================================================*/
+void VelocityBCAdapter::init(const D3Q27Interactor* const& interactor, const double& time)
+{
+   this->timeStep       = time;
+   this->tmpVx1Function = this->tmpVx2Function = this->tmpVx3Function = NULL;
+
+   //aktuelle velocityfunction bestimmen
+   double maxEndtime = -Ub::inf;
+   
+   for(size_t pos=0; pos<vx1BCs.size(); ++pos)
+   {
+      if( UbMath::equal(vx1BCs[pos].getEndTime(),BCFunction::INFTIMEDEPENDENT) ) maxEndtime=Ub::inf;
+      maxEndtime = UbMath::max(maxEndtime,vx1BCs[pos].getStartTime(),vx1BCs[pos].getEndTime()); //startTime abfragen, da  INFCONST=-10
+      
+      if( UbMath::greaterEqual(this->timeStep,vx1BCs[pos].getStartTime()) ) 
+      {
+          if(   UbMath::lessEqual( this->timeStep     , vx1BCs[pos].getEndTime()     )
+             || UbMath::equal(     vx1BCs[pos].getEndTime(), (double)BCFunction::INFCONST        )
+             || UbMath::equal(     vx1BCs[pos].getEndTime(), (double)BCFunction::INFTIMEDEPENDENT)  )
+         {
+            tmpVx1Function = &vx1BCs[pos].getFunction();
+            break;
+         }
+      }
+   }
+   for(size_t pos=0; pos<vx2BCs.size(); ++pos)
+   {
+      if( UbMath::equal(vx2BCs[pos].getEndTime(),BCFunction::INFTIMEDEPENDENT)) maxEndtime=Ub::inf;
+      maxEndtime = UbMath::max(maxEndtime,vx2BCs[pos].getStartTime(),vx2BCs[pos].getEndTime()); //startTime abfragen, da  INFCONST=-10
+
+      if( UbMath::greaterEqual(this->timeStep,vx2BCs[pos].getStartTime()) ) 
+      {
+         if(   UbMath::lessEqual( this->timeStep     , vx2BCs[pos].getEndTime()      )
+            || UbMath::equal(     vx2BCs[pos].getEndTime(), (double)BCFunction::INFCONST         )
+            || UbMath::equal(     vx2BCs[pos].getEndTime(), (double)BCFunction::INFTIMEDEPENDENT )  )
+         {
+            tmpVx2Function = &vx2BCs[pos].getFunction();
+            break;
+         }
+      }
+   }
+   for(size_t pos=0; pos<vx3BCs.size(); ++pos)
+   {
+      if( UbMath::equal(vx3BCs[pos].getEndTime(),BCFunction::INFTIMEDEPENDENT)) maxEndtime=Ub::inf;
+      maxEndtime = UbMath::max(maxEndtime,vx3BCs[pos].getStartTime(),vx3BCs[pos].getEndTime()); //startTime abfragen, da  INFCONST=-10
+
+      if( UbMath::greaterEqual(this->timeStep,vx3BCs[pos].getStartTime()) ) 
+      {
+         if(   UbMath::lessEqual( this->timeStep     , vx3BCs[pos].getEndTime()      )
+            || UbMath::equal(     vx3BCs[pos].getEndTime(), (double)BCFunction::INFCONST         )
+            || UbMath::equal(     vx3BCs[pos].getEndTime(), (double)BCFunction::INFTIMEDEPENDENT )  )
+         {
+            tmpVx3Function = &vx3BCs[pos].getFunction();
+            break;
+         }
+      }
+   }
+
+   if( UbMath::greaterEqual(time,maxEndtime) ) 
+   {
+      if( !this->isTimePeriodic() ) this->unsetTimeDependent();
+      else //bei peridoic die interavalle neu setzen:
+      {
+         if( UbMath::equal(maxEndtime,BCFunction::INFCONST) )
+            for(size_t pos=0; pos<vx1BCs.size(); ++pos)
+            {
+               vx1BCs[pos].setStartTime( vx1BCs[pos].getStartTime() + timeStep );
+               vx1BCs[pos].setEndTime( vx1BCs[pos].getEndTime() + timeStep );
+            }
+            if( UbMath::equal(maxEndtime,BCFunction::INFCONST) )
+            for(size_t pos=0; pos<vx2BCs.size(); ++pos)
+            {
+               vx2BCs[pos].setStartTime( vx2BCs[pos].getStartTime() + timeStep );
+               vx2BCs[pos].setEndTime( vx2BCs[pos].getEndTime() + timeStep );
+            }
+         if( UbMath::equal(maxEndtime,BCFunction::INFCONST) )
+            for(size_t pos=0; pos<vx3BCs.size(); ++pos)
+            {
+               vx3BCs[pos].setStartTime( vx3BCs[pos].getStartTime() + timeStep );
+               vx3BCs[pos].setEndTime( vx3BCs[pos].getEndTime() + timeStep );
+            }
+        this->init(interactor,time);
+      }
+   }
+
+   UBLOG(logDEBUG4,"D3Q27VelocityBCAdapter::init(time="<<time<<") "
+                   <<", vx1= \""<<(tmpVx1Function ? tmpVx1Function->GetExpr() : "-")<<"\""
+                   <<", vx2= \""<<(tmpVx2Function ? tmpVx2Function->GetExpr() : "-")<<"\""
+                   <<", vx3= \""<<(tmpVx3Function ? tmpVx3Function->GetExpr() : "-")<<"\""
+                   <<", timedependent="<<boolalpha<<this->isTimeDependent()   );
+}
+/*==========================================================*/
+void VelocityBCAdapter::update( const D3Q27Interactor* const& interactor, const double& time ) 
+{
+   this->init(interactor,time);
+}
+/*==========================================================*/
+void VelocityBCAdapter::adaptBCForDirection( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& q, const int& fdirection, const double& time )
+{
+   bc->setVelocityBoundaryFlag(D3Q27System::INVDIR[fdirection],secondaryBcOption);
+   bc->setQ((float)q,fdirection);
+}
+/*==========================================================*/
+void VelocityBCAdapter::adaptBC( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& time ) 
+{
+   this->setNodeVelocity(interactor,bc,worldX1,worldX2,worldX3,time);
+   bc->setBcAlgorithmType(algorithmType);
+}
+/*==========================================================*/
+void VelocityBCAdapter::setNodeVelocity( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& timestep) 
+{
+   //Geschwindigkeiten setzen
+   try
+   {
+      //PunktKoordinaten bestimmen
+      this->x1 = worldX1;
+      this->x2 = worldX2;
+      this->x3 = worldX3;
+      this->timeStep = timestep;
+
+      if(tmpVx1Function) bc->setBoundaryVelocityX1((LBMReal)tmpVx1Function->Eval());  
+      if(tmpVx2Function) bc->setBoundaryVelocityX2((LBMReal)tmpVx2Function->Eval());
+      if(tmpVx3Function) bc->setBoundaryVelocityX3((LBMReal)tmpVx3Function->Eval());
+   }
+   catch(mu::Parser::exception_type& e){ stringstream error; error<<"mu::parser exception occurs, message("<<e.GetMsg()<<"), formula("<<e.GetExpr()+"), token("+e.GetToken()<<")"
+                                         <<", pos("<<e.GetPos()<<"), error code("<<e.GetCode(); throw UbException(error.str()); }
+   catch(...)                          { throw UbException(UB_EXARGS,"unknown exception" ); }
+}
+/*==========================================================*/
+UbTupleDouble3 VelocityBCAdapter::getVelocity(const double& x1, const double& x2, const double& x3, const double& timeStep) const
+{
+	double vx1 = 0.0;
+	double vx2 = 0.0;
+	double vx3 = 0.0;
+   this->x1 = x1;
+   this->x2 = x2;
+   this->x3 = x3;
+   this->timeStep = timeStep;
+	
+	if(tmpVx1Function) vx1 = tmpVx1Function->Eval();  
+   if(tmpVx2Function) vx2 = tmpVx2Function->Eval();
+   if(tmpVx3Function) vx3 = tmpVx3Function->Eval();
+    
+   return UbTupleDouble3(vx1,vx2,vx3);
+}
+/*==========================================================*/
+string VelocityBCAdapter::toString()
+{
+   stringstream info;
+   info<<"D3Q27VelocityBCAdapter:\n";
+   info<<" #vx1-functions = "<<(int)vx1BCs.size()<<endl;
+   info<<" #vx2-functions = "<<(int)vx2BCs.size()<<endl;
+   info<<" #vx3-functions = "<<(int)vx3BCs.size()<<endl;
+   info<<" protected variables: x1, x2, x3, t"<<endl;
+   
+   const vector<BCFunction>* bcvecs[3] = { &vx1BCs, &vx2BCs, &vx3BCs };
+   for(int i=0; i<3; i++)
+   {
+      for(size_t pos=0; pos<bcvecs[i]->size(); ++pos)
+      {
+         info<<"\n   vx"<<(i+1)<<"-function nr."<<pos<<":"<<endl;
+         info<<(*bcvecs[i])[pos]<<endl;
+      }
+   }
+   return info.str();
+}
+
+
diff --git a/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.h b/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ed2bdde1ed401c5e9ae2ee6a31832f89a047414
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/VelocityBCAdapter.h
@@ -0,0 +1,162 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file VelocityBCAdapter.h
+//! \ingroup BoundarConditions
+//! \author Sören Freudiger
+//=======================================================================================
+#ifndef VelocityBCAdapter_H
+#define VelocityBCAdapter_H
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <basics/utilities/UbInfinity.h>
+
+#include <BCAdapter.h>
+#include <BCFunction.h>
+
+//! \brief A class provides an interface for velocity boundary condition in grid generator.
+
+//! \details 
+//! Example:
+//! \code{.cpp}  vector<BCFunction> vx1BCs,vx2BCs,vx3BCs;
+//!        vx1BCs.push_back(BCFunction(0.01 , 0  , 100) );   //t=[0  ..100[ -> vx1 = 0.01
+//!        vx1BCs.push_back(BCFunction(0.004, 100, 200) );   //t=[100..200[ -> vx1 = 0.004
+//!        vx1BCs.push_back(BCFunction(0.03 , 200, 400) );   //t=[200..400] -> vx1 = 0.03
+//! 
+//!        vx2BCs.push_back(BCFunction(0.02 , 0  , 200) );   //t=[0  ..200[ -> vx2 = 0.02
+//!        vx2BCs.push_back(BCFunction(0.002, 200, 300) );   //t=[200..300[ -> vx2 = 0.002
+//!        vx2BCs.push_back(BCFunction(0.043, 300, 600) );   //t=[300..600] -> vx2 = 0.043
+//!        
+//!        VelocityBCAdapter bcAdapter(vx1BCs,vx2BCs,vx3BCs);
+//!        bcAdapter.setTimePeriodic(); //->  t=[0  ..100[ -> vx1 = 0.01
+//!                                     //    t=[100..200[ -> vx1 = 0.004
+//!                                     //    t=[200..400[ -> vx1 = 0.03
+//!                                     //    t=[400..500[ -> vx1 = 0.01
+//!                                     //    t=[500..600[ -> vx1 = 0.004
+//!                                     //    t=[600..800[ -> vx1 = 0.03  ...
+//!                                     //    t=[0  ..200[ -> vx2 = 0.02
+//!                                     //    t=[200..300[ -> vx2 = 0.002
+//!                                     //    t=[300..600] -> vx2 = 0.043
+//!                                     //    t=[600..800[ -> vx2 = 0.02
+//!                                     //    t=[800..900[ -> vx2 = 0.002
+//!                                     //    t=[900..1200]-> vx2 = 0.043  ...
+//! \endcode
+//! Example of parabolic inflow:
+//! \code{.cpp}
+//!    mu::Parser fct;
+//!    fct.SetExpr("max(vmax*(1.0-4.0*((x2-x2_vmax)^2+(x3-x3_vmax)^2)/H^2),0.0)"); //paraboloid (with vmax for (0/x2_vmax/x3_vmax) 
+//!    fct.DefineConst("x2Vmax", 0.0            ); //x2-Pos für vmax
+//!    fct.DefineConst("x3Vmax", 0.0            ); //x3-Pos für vmax
+//!    fct.DefineConst("H"     , diameterOfPipe);
+//!    fct.DefineConst("vmax"  , vmax           );
+//!    VelocityBCAdapter velBC(true, false ,false ,fct, 0, BCFunction::INFCONST);
+//! \endcode
+
+class VelocityBCAdapter : public BCAdapter
+{
+public:
+   //constructors
+   VelocityBCAdapter() { this->init(); }
+   
+   VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const BCFunction& velVxBC );
+
+   VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const mu::Parser& function, const double& startTime, const double& endTime  );
+
+   VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const mu::Parser& function1, const mu::Parser& function2, const mu::Parser& function3, const double& startTime, const double& endTime );
+   
+   VelocityBCAdapter(const bool& vx1, const bool& vx2, const bool& vx3, const std::string& functionstring, const double& startTime, const double& endTime );
+
+   VelocityBCAdapter(const BCFunction& velBC, bool x1Dir, bool x2Dir, bool x3Dir);
+
+   VelocityBCAdapter(const BCFunction& velVx1BC, const BCFunction& velVx2BC, const BCFunction& velVx3BC);
+
+   VelocityBCAdapter(const std::vector< BCFunction >& velVx1BCs, const std::vector< BCFunction >& velVx2BCs, const std::vector< BCFunction >& velVx3BCs);
+
+   VelocityBCAdapter(const double& vx1, const double& vx1StartTime, const double& vx1EndTime,
+                          const double& vx2, const double& vx2StartTime, const double& vx2EndTime,
+                          const double& vx3, const double& vx3StartTime, const double& vx3EndTime);
+
+   VelocityBCAdapter(const std::string& vx1Function, const double& vx1StartTime, const double& vx1EndTime,
+                          const std::string& vx2Function, const double& vx2StartTime, const double& vx2EndTime,
+                          const std::string& vx3Function, const double& vx3StartTime, const double& vx3EndTime ); 
+
+   //methods
+   void setTimePeriodic()    { (this->type |=   TIMEPERIODIC); }
+   void unsetTimePeriodic()  { (this->type &=  ~TIMEPERIODIC); }
+   bool isTimePeriodic()     { return ((this->type & TIMEPERIODIC) ==  TIMEPERIODIC); }
+
+   //The following is meant for moving objects... 
+   void setNewVelocities(const double& vx1, const double& vx1StartTime, const double& vx1EndTime,
+                         const double& vx2, const double& vx2StartTime, const double& vx2EndTime,
+                         const double& vx3, const double& vx3StartTime, const double& vx3EndTime);
+
+      
+   //------------- implements BCAdapter ----- start
+   std::string toString();
+   
+   void init(const D3Q27Interactor* const& interactor, const double& time=0);
+   void update(const D3Q27Interactor* const& interactor, const double& time=0);
+
+   void adaptBCForDirection( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& q, const int& fdirection, const double& time=0 );
+   void adaptBC( const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& time=0 );
+
+   //------------- implements BCAdapter ----- end
+
+   UbTupleDouble3 getVelocity(const double& x1, const double& x2, const double& x3, const double& timeStep) const;
+
+
+protected:
+   void init();
+   void init(std::vector<BCFunction>& vxBCs);
+
+   //time dependency is determined automatically via BCFunction intervals!
+   void setTimeDependent()   { (this->type |=   TIMEDEPENDENT); }
+   void unsetTimeDependent() { (this->type &=  ~TIMEDEPENDENT); }
+
+   void clear() { vx1BCs.clear(); vx2BCs.clear();  vx3BCs.clear(); this->init(); }
+   void setNodeVelocity(const D3Q27Interactor& interactor, SPtr<BoundaryConditions> bc, const double& worldX1, const double& worldX2, const double& worldX3, const double& timestep);
+
+private:
+   mutable mu::value_type x1, x2, x3;
+   mutable mu::value_type timeStep;
+
+   mu::Parser* tmpVx1Function;
+   mu::Parser* tmpVx2Function;
+   mu::Parser* tmpVx3Function;
+
+   std::vector<BCFunction> vx1BCs;
+   std::vector<BCFunction> vx2BCs;
+   std::vector<BCFunction> vx3BCs;
+
+};
+
+#endif
diff --git a/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp b/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d61840a7ecb8307b62b37013e2aded7998a5234a
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.cpp
@@ -0,0 +1,83 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file VelocityBCAlgorithm.cpp
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "VelocityBCAlgorithm.h"
+#include "DistributionArray3D.h"
+#include "BoundaryConditions.h"
+
+VelocityBCAlgorithm::VelocityBCAlgorithm()
+{
+   BCAlgorithm::type = BCAlgorithm::VelocityBCAlgorithm;
+   BCAlgorithm::preCollision = false;
+}
+//////////////////////////////////////////////////////////////////////////
+VelocityBCAlgorithm::~VelocityBCAlgorithm()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCAlgorithm> VelocityBCAlgorithm::clone()
+{
+   SPtr<BCAlgorithm> bc(new VelocityBCAlgorithm());
+   return bc;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityBCAlgorithm::addDistributions(SPtr<DistributionArray3D> distributions)
+{
+   this->distributions = distributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void VelocityBCAlgorithm::applyBC()
+{
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal feq[D3Q27System::ENDF+1];
+   distributions->getDistributionInv(f, x1, x2, x3);
+   LBMReal rho, vx1, vx2, vx3, drho;
+   calcMacrosFct(f, drho, vx1, vx2, vx3);
+   calcFeqFct(feq, drho, vx1, vx2, vx3);
+
+   rho = 1.0+drho*compressibleFactor;
+
+   for (int fdir = D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+   {
+      if (bcPtr->hasVelocityBoundaryFlag(fdir))
+      {
+         const int invDir = D3Q27System::INVDIR[fdir];
+         LBMReal q = bcPtr->getQ(invDir);
+         LBMReal velocity = bcPtr->getBoundaryVelocity(invDir);
+         LBMReal fReturn = f[invDir] - velocity;
+         distributions->setDistributionForDirection(fReturn, x1+D3Q27System::DX1[invDir], x2+D3Q27System::DX2[invDir], x3+D3Q27System::DX3[invDir], fdir);
+      }
+   }
+
+}
+
diff --git a/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h b/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..03b33779e50489a45b6b5f597716ca0dbc0b2bfb
--- /dev/null
+++ b/VirtualFluidsCore/BoundaryConditions/VelocityBCAlgorithm.h
@@ -0,0 +1,54 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file VelocityBCAlgorithm.h
+//! \ingroup BoundarConditions
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef VelocityBCAlgorithm_H
+#define VelocityBCAlgorithm_H
+
+#include "BCAlgorithm.h"
+#include <PointerDefinitions.h>
+
+class DistributionArray3D;
+
+//! \brief A class implements velocyty boundary condition
+class VelocityBCAlgorithm : public BCAlgorithm
+{
+public:
+   VelocityBCAlgorithm();
+   ~VelocityBCAlgorithm();
+   SPtr<BCAlgorithm> clone();
+   void addDistributions(SPtr<DistributionArray3D> distributions);
+   void applyBC() override;
+};
+
+#endif 
+
diff --git a/VirtualFluidsCore/CMakeLists.txt b/VirtualFluidsCore/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..041ad5363017623609cdbb1c4aa0fe7bd2d9d886
--- /dev/null
+++ b/VirtualFluidsCore/CMakeLists.txt
@@ -0,0 +1,46 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+########################################################
+## C++ PROJECT                                       ###
+########################################################
+PROJECT(VirtualFluids)
+  
+#################################################################
+###   PACKAGES						                          ###
+#################################################################
+SET(WITH_SUBFOLDERS_FOR_SG TRUE)
+
+INCLUDE(${SOURCE_ROOT}/ThirdParty/MuParser/CMakePackage.txt)
+
+#new VirtualFluids
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/BoundaryConditions/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Connectors/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Data/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Interactors/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/LBM/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Parallel/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Grid/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Visitors/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/CoProcessors/CMakePackage.txt)
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/Utilities/CMakePackage.txt)
+
+#old VirtualFluids
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsBasics/VirtualFluidsBasics.cmake)
+
+INCLUDE(${SOURCE_ROOT}/VirtualFluidsCore/IncludsList.cmake)
+
+IF(${USE_GCC})
+   SET(CAB_ADDITIONAL_LINK_LIBRARIES ${CAB_ADDITIONAL_LINK_LIBRARIES} rt)
+   SET(CAB_ADDITIONAL_LINK_LIBRARIES ${CAB_ADDITIONAL_LINK_LIBRARIES} gomp)
+ENDIF()
+
+IF(${USE_INTEL})
+   SET(CAB_ADDITIONAL_LINK_LIBRARIES ${CAB_ADDITIONAL_LINK_LIBRARIES} irc)
+   SET(CAB_ADDITIONAL_LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS} parallel)
+ENDIF()
+
+message("CAB_ADDITIONAL_LINK_LIBRARIES: " ${CAB_ADDITIONAL_LINK_LIBRARIES})
+#################################################################
+###   CREATE PROJECT                                          ###
+#################################################################
+CREATE_CAB_PROJECT(VirtualFluids STATIC)
diff --git a/VirtualFluidsCore/CoProcessors/CMakePackage.txt b/VirtualFluidsCore/CoProcessors/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/CoProcessors/CoProcessor.cpp b/VirtualFluidsCore/CoProcessors/CoProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7ea981940d5a903aa7599a5bd104f891d26569d
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/CoProcessor.cpp
@@ -0,0 +1,52 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CoProcessor.cpp
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "CoProcessor.h"
+
+#include "Grid3D.h"
+#include "UbScheduler.h"
+
+CoProcessor::CoProcessor()
+{
+}
+
+CoProcessor::CoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s): grid(grid), scheduler(s)
+{
+
+}
+
+CoProcessor::~CoProcessor()
+{
+
+}
+
diff --git a/VirtualFluidsCore/CoProcessors/CoProcessor.h b/VirtualFluidsCore/CoProcessors/CoProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..31779a0f6b169a57b88e1d77140ddb181137e8a7
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/CoProcessor.h
@@ -0,0 +1,66 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CoProcessor.h
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef CoProcessor_H
+#define CoProcessor_H
+
+#include <PointerDefinitions.h>
+
+class Grid3D;
+class UbScheduler;
+
+//! \class CoProcessor
+//! \brief An abstract class implements observer design pettern
+class CoProcessor
+{
+public:
+   //! Class default constructor
+   CoProcessor();
+   //! \brief Construct CoProcessor object for grid object and scheduler object.
+   //! \pre The Grid3D and UbScheduler objects must exist.
+   //! \param grid is observable Grid3D object
+   //! \param s is UbScheduler object for scheduling of observer
+   //! \details
+   //! Class CoProcessor implements the observer design pettern. CoProcessor object is observer.  Grid3D object is observable.
+   CoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s);
+   //! Class destructor
+   virtual ~CoProcessor();
+   //! \brief Updates observer
+   //! \param step is the actual time step
+   virtual void process(double step) = 0;
+protected:
+   SPtr<Grid3D> grid;
+   SPtr<UbScheduler> scheduler;
+};
+#endif
+
diff --git a/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp b/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38b11dd0119fabec07fd883c5240be643b2481e7
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.cpp
@@ -0,0 +1,94 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NUPSCounterCoProcessor.cpp
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "NUPSCounterCoProcessor.h"
+
+#include "Communicator.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+
+NUPSCounterCoProcessor::NUPSCounterCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, int numOfThreads, SPtr<Communicator> comm)
+                                                   : CoProcessor(grid, s),
+                                                     numOfThreads(numOfThreads),
+                                                     comm(comm),
+                                                     nup(0),
+                                                     nup_t(0),
+                                                     nupsStep(0.0)
+{
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      timer.resetAndStart();
+
+      double nop = comm->getNumberOfProcesses();
+      int minInitLevel = grid->getCoarsestInitializedLevel();
+      int maxInitLevel = grid->getFinestInitializedLevel();
+      UbTupleInt3 blocknx = grid->getBlockNX();
+      double nod = (double)(val<1>(blocknx)) * (double)(val<2>(blocknx)) * (double)(val<3>(blocknx));
+      nup = 0;
+
+      for(int level = minInitLevel; level<=maxInitLevel; level++)
+      {
+         int nob = grid->getNumberOfBlocks(level);
+         nup_t += (double)(1<<level) * nob * nod;
+      }
+      nup = nup_t / nop;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+NUPSCounterCoProcessor::~NUPSCounterCoProcessor() 
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void NUPSCounterCoProcessor::process(double step)
+{
+   if(scheduler->isDue(step) )
+      collectData(step);
+}
+//////////////////////////////////////////////////////////////////////////
+void NUPSCounterCoProcessor::collectData(double step)
+{
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      double time = timer.stop();
+      double nups_t = nup_t*(step-nupsStep)/time;
+      double nups = nup*(step-nupsStep)/time;
+      double tnups = nups/(double)numOfThreads;
+      UBLOG(logINFO, "Calculation step = "<<step);
+      UBLOG(logINFO, "Total performance = "<<nups_t<<" NUPS");
+      UBLOG(logINFO, "Performance per process = "<<nups<<" NUPS");
+      UBLOG(logINFO, "Performance per thread = "<<tnups<<" NUPS");
+      UBLOG(logINFO, "Time for " << step-nupsStep <<" steps = "<< time <<" s");
+      nupsStep = step;
+      timer.resetAndStart();
+   }
+}
diff --git a/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h b/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..a398f10e9e8085a06757dbe243b2e6ad059491e1
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/NUPSCounterCoProcessor.h
@@ -0,0 +1,77 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NUPSCounterCoProcessor.h
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef NUPSCOUNTERCoProcessor_H_
+#define NUPSCOUNTERCoProcessor_H_
+
+#include <PointerDefinitions.h>
+
+#include "CoProcessor.h"
+#include "basics/utilities/UbTiming.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+
+//! \class NUPSCounterCoProcessor
+//! \brief A class calculates Nodal Updates Per Second (NUPS)
+class NUPSCounterCoProcessor: public CoProcessor
+{
+public:
+   //! \brief Construct NUPSCounterCoProcessor object for grid object and scheduler object.
+   //! \pre The Grid3D and UbScheduler objects must exist.
+   //! \param grid is observable Grid3D object
+   //! \param s is UbScheduler object for scheduling of observer
+   //! \param numOfThreads is number of threads
+   //! \param comm is Communicator object
+   NUPSCounterCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, int numOfThreads, SPtr<Communicator> comm);
+   virtual ~NUPSCounterCoProcessor();
+
+   void process(double step)override;
+
+protected:
+   //! Collect data for calculation of NUPS
+   //! \param step is a time step
+   void collectData(double step);
+   UbTimer timer;
+   int numOfThreads;
+   double numberOfNodes;
+   double numberOfBlocks;
+   double nup;
+   double nup_t;
+   double nupsStep;
+   SPtr<Communicator> comm;
+};
+
+
+#endif 
diff --git a/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp b/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8256d2fea2c44b9f06df232c529212a49db61e98
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.cpp
@@ -0,0 +1,186 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteBlocksCoProcessor.cpp
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "WriteBlocksCoProcessor.h"
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+
+#include "D3Q27System.h"
+#include "Block3D.h"
+#include "UbScheduler.h"
+#include "Communicator.h"
+#include "Grid3D.h"
+
+WriteBlocksCoProcessor::WriteBlocksCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, 
+                                         const std::string& path, WbWriter* const writer, 
+                                         SPtr<Communicator> comm) :
+                                         CoProcessor(grid, s),
+                                         path(path),
+                                         writer(writer),
+                                         comm(comm)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteBlocksCoProcessor::~WriteBlocksCoProcessor() 
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBlocksCoProcessor::process(double step)
+{
+   if(scheduler->isDue(step) )
+      collectData(step);
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBlocksCoProcessor::collectData(double step)
+{
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      int istep = int(step);
+      std::vector<std::string> filenames;
+      std::vector< UbTupleFloat3 > nodes;
+      std::vector< UbTupleInt8 > cells;
+      std::vector<std::string> celldatanames;
+
+      celldatanames.push_back("isActive");
+      celldatanames.push_back("rank");
+      celldatanames.push_back("interface");
+      celldatanames.push_back("ID");
+      celldatanames.push_back("part");
+      celldatanames.push_back("level");
+      //celldatanames.push_back("connectorCF");
+      //celldatanames.push_back("connectorFC");
+#if defined VF_FETOL
+      celldatanames.push_back("bundle");
+#endif
+
+      std::vector< std::vector< double > > celldata(celldatanames.size());
+
+      int nr=0;
+      int minInitLevel = this->grid->getCoarsestInitializedLevel();
+      int maxInitLevel = this->grid->getFinestInitializedLevel();
+
+      for(int level = minInitLevel; level<=maxInitLevel;level++)
+      {
+         std::vector<SPtr<Block3D>> blockVector;
+         grid->getBlocks(level, blockVector);
+         for(SPtr<Block3D> block : blockVector)
+         {
+            UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+            UbTupleDouble3 blockLength = grid->getBlockLengths(block);
+
+            nodes.push_back(makeUbTuple((float)(val<1>(org)), (float)(val<2>(org)), (float)(val<3>(org))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)+val<1>(blockLength)), (float)(val<2>(org)), (float)(val<3>(org))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)+val<1>(blockLength)), (float)(val<2>(org)+val<2>(blockLength)), (float)(val<3>(org))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)), (float)(val<2>(org)+val<2>(blockLength)), (float)(val<3>(org))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)), (float)(val<2>(org)), (float)(val<3>(org)+val<3>(blockLength))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)+val<1>(blockLength)), (float)(val<2>(org)), (float)(val<3>(org)+val<3>(blockLength))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)+val<1>(blockLength)), (float)(val<2>(org)+val<2>(blockLength)), (float)(val<3>(org)+val<3>(blockLength))));
+            nodes.push_back(makeUbTuple((float)(val<1>(org)), (float)(val<2>(org)+val<2>(blockLength)), (float)(val<3>(org)+val<3>(blockLength))));
+            cells.push_back(makeUbTuple(nr, nr+1, nr+2, nr+3, nr+4, nr+5, nr+6, nr+7));
+            nr += 8;
+
+            //data
+            celldata[0].push_back((double)block->isActive());
+            celldata[1].push_back((double)block->getRank());
+            celldata[2].push_back((double)block->hasInterpolationFlag());
+            celldata[3].push_back((double)block->getGlobalID());
+            celldata[4].push_back((double)block->getPart());
+            celldata[5].push_back((double)block->getLevel());
+
+            //bool flag = false;
+            //std::vector<SPtr<Block3DConnector>> connectors;
+
+            //block->pushBackLocalInterpolationConnectorsCF(connectors);
+            //for (std::size_t i = 0; i<connectors.size(); i++)
+            //   if (connectors[i])
+            //   {
+            //      if (connectors[i]->getSendDir() == D3Q27System::BS)
+            //      {
+
+            //         flag = true;
+            //      }
+            //   }
+
+            //if (flag)
+            //{
+            //   celldata[6].push_back(1);
+            //   UBLOG(logINFO, "CF: "+block->toString());
+            //}
+            //else
+            //{
+            //   celldata[6].push_back(0);
+            //}
+
+            //flag = false;
+            //connectors.resize(0);
+            //block->pushBackLocalInterpolationConnectorsFC(connectors);
+            //for (std::size_t i = 0; i<connectors.size(); i++)
+            //   if (connectors[i])
+            //   {
+            //      if (connectors[i]->getSendDir() == D3Q27System::BS)
+            //      {
+
+            //         flag = true;
+            //      }
+            //   }
+
+            //if (flag)
+            //{
+            //   celldata[7].push_back(1);
+            //   UBLOG(logINFO, "FC: "+block->toString());
+            //}
+            //else
+            //{
+            //   celldata[7].push_back(0);
+            //}
+
+#ifdef VF_FETOL            
+            celldata[6].push_back( (double)block->getBundle());
+#endif
+         }
+      }
+
+      filenames.push_back(writer->writeOctsWithCellData(path+"/blocks/blocks_" + UbSystem::toString(grid->getRank()) + "_" + UbSystem::toString(istep),nodes,cells,celldatanames,celldata));
+
+      if (istep == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(path+"/blocks/blocks_collection",filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(path + "/blocks/blocks_collection", filenames, istep, false);
+      }
+
+      UBLOG(logINFO,"WriteBlocksCoProcessor step: " << istep);
+   }
+}
diff --git a/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h b/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..d797dbcccfb9b0e56c123e228c1c464411d4cde1
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteBlocksCoProcessor.h
@@ -0,0 +1,75 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteBlocksCoProcessor.h
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef WriteBlocksCoProcessor_H_
+#define WriteBlocksCoProcessor_H_
+
+#include <PointerDefinitions.h>
+#include <string>
+
+#include "CoProcessor.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+
+//! \class WriteBlocksCoProcessor
+//! \brief A class writes a block grid to a VTK-file
+class WriteBlocksCoProcessor: public CoProcessor 
+{
+public:
+   //! \brief Construct WriteBlocksCoProcessor object.
+   //! \pre The Grid3D and UbScheduler objects must exist.
+   //! \param grid is observable Grid3D object
+   //! \param s is UbScheduler object for scheduling of observer
+   //! \param path is path of folder for output
+   //! \param writer is WbWriter object
+   //! \param comm is Communicator object
+   WriteBlocksCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, const std::string& path, WbWriter* const writer, SPtr<Communicator> comm);
+   virtual ~WriteBlocksCoProcessor();
+
+   void process(double step) override;
+
+protected:
+   //! Collect data for VTK-file
+   //! \param step is a time step
+   void collectData(double step);
+
+   std::string path;
+   WbWriter* writer;
+   SPtr<Communicator>  comm;
+};
+
+
+#endif 
diff --git a/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp b/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc6601c732c8c1a69677c7a574e7b53831bb6b47
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.cpp
@@ -0,0 +1,299 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteBoundaryConditionsCoProcessor.cpp
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "WriteBoundaryConditionsCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include <vector>
+#include <string>
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "LBMUnitConverter.h"
+#include "Communicator.h"
+#include "WbWriter.h"
+#include "UbScheduler.h"
+#include "CbArray3D.h"
+#include "BCArray3D.h"
+
+using namespace std;
+
+WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteBoundaryConditionsCoProcessor::WriteBoundaryConditionsCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s,
+   const std::string& path, WbWriter* const writer, SPtr<Communicator> comm)
+   : CoProcessor(grid, s),
+   path(path),
+   writer(writer),
+   comm(comm)
+{
+   gridRank = comm->getProcessID();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::process(double step)
+{
+   if (scheduler->isDue(step))
+      collectData(step);
+
+   UBLOG(logDEBUG3, "WriteBoundaryConditionsCoProcessor::update:"<<step);
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::collectData(double step)
+{
+   int istep = static_cast<int>(step);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      for(SPtr<Block3D> block : blockVector[level])
+      {
+         if (block)
+         {
+            addDataGeo(block);
+         }
+      }
+   }
+
+   string pfilePath, partPath, subfolder, cfilePath;
+
+   subfolder = "bc"+UbSystem::toString(istep);
+   pfilePath = path+"/bc/"+subfolder;
+   cfilePath = path+"/bc/bc_collection";
+   partPath = pfilePath+"/bc"+UbSystem::toString(gridRank)+"_"+UbSystem::toString(istep);
+
+
+   string partName = writer->writeOctsWithNodeData(partPath, nodes, cells, datanames, data);
+   size_t found = partName.find_last_of("/");
+   string piece = partName.substr(found+1);
+   piece = subfolder+"/"+piece;
+
+   vector<string> cellDataNames;
+   vector<std::string> pieces;
+   pieces.push_back(piece);
+   if (comm->getProcessID()==comm->getRoot())
+   {
+      string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath, pieces, datanames, cellDataNames);
+      found = pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      vector<string> filenames;
+      filenames.push_back(piece);
+      if (step==CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath, filenames, istep, false);
+      }
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath, filenames, istep, false);
+      }
+      UBLOG(logINFO, "WriteBoundaryConditionsCoProcessor step: "<<istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteBoundaryConditionsCoProcessor::addDataGeo(SPtr<Block3D> block)
+{
+   UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+   UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
+   double         dx = grid->getDeltaX(block);
+
+   double level = (double)block->getLevel();
+
+   //Diese Daten werden geschrieben:
+   datanames.resize(0);
+   datanames.push_back("Boundary Conditions");
+   datanames.push_back("Geometry");
+   datanames.push_back("Level");
+   datanames.push_back("Algorithm");
+   //datanames.push_back("Interface CF");
+   datanames.push_back("qs");
+
+   data.resize(datanames.size());
+
+   SPtr<ILBMKernel> kernel = block->getKernel();
+   SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();
+
+   //knotennummerierung faengt immer bei 0 an!
+   int SWB, SEB, NEB, NWB, SWT, SET, NET, NWT;
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = (int)bcArray->getNX1();
+   int maxX2 = (int)bcArray->getNX2();
+   int maxX3 = (int)bcArray->getNX3();
+
+   //nummern vergeben und node vector erstellen + daten sammeln
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3, -1);
+   //D3Q27BoundaryConditionPtr bcPtr;
+   int nr = (int)nodes.size();
+
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+
+   int s=0;
+
+   
+
+   for (size_t ix3 = minX3; ix3<=maxX3; ix3++)
+   {
+      for (size_t ix2 = minX2; ix2<=maxX2; ix2++)
+      {
+         for (size_t ix1 = minX1; ix1<=maxX1; ix1++)
+         {
+            if (!bcArray->isUndefined(ix1, ix2, ix3))
+            {
+               int index = 0;
+               nodeNumbers(ix1, ix2, ix3) = nr++;
+               nodes.push_back(makeUbTuple(float(val<1>(org)-val<1>(nodeOffset)+ix1*dx),
+                  float(val<2>(org)-val<2>(nodeOffset)+ix2*dx),
+                  float(val<3>(org)-val<3>(nodeOffset)+ix3*dx)));
+
+
+
+               if (!bcArray->hasBC(ix1, ix2, ix3))
+               {
+                  data[index++].push_back(0.0);
+               }
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasNoSlipBoundary())
+                  data[index++].push_back(1.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasVelocityBoundary())
+                  data[index++].push_back(2.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasDensityBoundary())
+                  data[index++].push_back(3.0);
+               else if (bcArray->getBC(ix1, ix2, ix3)->hasSlipBoundary())
+                  data[index++].push_back(4.0);
+               //else
+               //   data[0].push_back(5.0);
+
+
+               if (bcArray->isSolid(ix1, ix2, ix3))
+               {
+                  data[index++].push_back(1.0);
+               }
+               else
+               {
+                  data[index++].push_back(0.0);
+               }
+                  
+
+               data[index++].push_back(level);
+
+               if (bcArray->hasBC(ix1, ix2, ix3))
+                  data[index++].push_back(bcArray->getBC(ix1, ix2, ix3)->getBcAlgorithmType());
+               else
+                  data[index++].push_back(-1.0);
+
+               //if (bcArray->isInterfaceCF(ix1, ix2, ix3))
+               //{
+               //   data[3].push_back(1.0);
+               //} 
+               //else
+               //{
+               //   data[3].push_back(0.0);
+               //}
+
+               if (bcArray->hasBC(ix1, ix2, ix3))
+               {
+                  unsigned int a = 1;
+                  unsigned int b = 0;
+                  for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++)
+                  {
+                     if (bcArray->getBC(ix1, ix2, ix3)->hasVelocityBoundaryFlag(fdir))
+                     {
+                        a = a << 1;
+                        if (bcArray->getBC(ix1, ix2, ix3)->hasVelocityBoundaryFlag(fdir))
+                        {
+                           b = b | a;
+                        }
+                     }
+                  }
+                  data[index++].push_back(b);
+               }
+               else
+                  data[index++].push_back(-1.0);
+            }
+         }
+      }
+   }
+
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+
+   //cell vector erstellen
+   for (int ix3 = minX3; ix3<=maxX3; ix3++)
+   {
+      for (int ix2 = minX2; ix2<=maxX2; ix2++)
+      {
+         for (int ix1 = minX1; ix1<=maxX1; ix1++)
+         {
+            if ((SWB = nodeNumbers(ix1, ix2, ix3))>=0
+               &&(SEB = nodeNumbers(ix1+1, ix2, ix3))>=0
+               &&(NEB = nodeNumbers(ix1+1, ix2+1, ix3))>=0
+               &&(NWB = nodeNumbers(ix1, ix2+1, ix3))>=0
+               &&(SWT = nodeNumbers(ix1, ix2, ix3+1))>=0
+               &&(SET = nodeNumbers(ix1+1, ix2, ix3+1))>=0
+               &&(NET = nodeNumbers(ix1+1, ix2+1, ix3+1))>=0
+               &&(NWT = nodeNumbers(ix1, ix2+1, ix3+1))>=0)
+            {
+               cells.push_back(makeUbTuple(SWB, SEB, NEB, NWB, SWT, SET, NET, NWT));
+            }
+         }
+      }
+   }
+}
diff --git a/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h b/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c2a2f612236913c50174ee390ae2c3b6da1f6d5
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteBoundaryConditionsCoProcessor.h
@@ -0,0 +1,89 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteBoundaryConditionsCoProcessor.h
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef WriteBoundaryConditionsCoProcessor_H
+#define WriteBoundaryConditionsCoProcessor_H
+
+#include <PointerDefinitions.h>
+#include <string>
+#include <vector>
+
+#include "CoProcessor.h"
+#include "UbTuple.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class WbWriter;
+class Block3D;
+class LBMUnitConverter;
+
+//! \brief A class writes boundary conditions information to a VTK-file
+class WriteBoundaryConditionsCoProcessor : public  CoProcessor
+{
+public:
+   WriteBoundaryConditionsCoProcessor();
+   //! \brief Construct WriteBoundaryConditionsCoProcessor object
+   //! \pre The Grid3D and UbScheduler objects must exist
+   //! \param grid is observable Grid3D object
+   //! \param s is UbScheduler object for scheduling of observer
+   //! \param path is path of folder for output
+   //! \param writer is WbWriter object
+   //! \param comm is Communicator object
+   WriteBoundaryConditionsCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, const std::string& path, WbWriter* const writer, SPtr<Communicator> comm);
+   ~WriteBoundaryConditionsCoProcessor() {}
+
+   void process(double step) override;
+
+protected:
+   //! Collect data for VTK-file
+   //! \param step is a time step
+   void collectData(double step);
+   void addDataGeo(SPtr<Block3D> block);
+   void clearData();
+
+private:
+   std::vector<UbTupleFloat3> nodes;
+   std::vector<UbTupleInt8> cells;
+   std::vector<std::string> datanames;
+   std::vector<std::vector<double> > data;
+   std::string path;
+   WbWriter* writer;
+   bool bcInformation;
+   std::vector<std::vector<SPtr<Block3D> > > blockVector;
+   int minInitLevel;
+   int maxInitLevel;
+   int gridRank;
+   SPtr<Communicator> comm;
+};
+#endif
diff --git a/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp b/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7a3788850684f533960a7eebfb57ad1a6208efa
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.cpp
@@ -0,0 +1,266 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteMacroscopicQuantitiesCoProcessor.cpp
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "WriteMacroscopicQuantitiesCoProcessor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include <vector>
+#include <string>
+
+#include "basics/writer/WbWriterVtkXmlASCII.h"
+#include "DataSet3D.h"
+#include "UbScheduler.h"
+#include "Grid3D.h"
+#include "Communicator.h"
+#include "LBMUnitConverter.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+WriteMacroscopicQuantitiesCoProcessor::WriteMacroscopicQuantitiesCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s,
+                                                                                 const std::string& path, WbWriter* const writer, 
+                                                                                 SPtr<LBMUnitConverter> conv, 
+                                                                                 SPtr<Communicator> comm)
+                                                                                 : CoProcessor(grid, s),
+                                                                                 path(path),
+                                                                                 writer(writer),
+                                                                                 conv(conv),
+                                                                                 comm(comm)
+{
+   gridRank = comm->getProcessID();
+   minInitLevel = this->grid->getCoarsestInitializedLevel();
+   maxInitLevel = this->grid->getFinestInitializedLevel();
+
+   blockVector.resize(maxInitLevel+1);
+
+   for (int level = minInitLevel; level<=maxInitLevel; level++)
+   {
+      grid->getBlocks(level, gridRank, true, blockVector[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::init()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::process(double step)
+{
+   if(scheduler->isDue(step) )
+      collectData(step);
+
+   UBLOG(logDEBUG3, "WriteMacroscopicQuantitiesCoProcessor::update:" << step);
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::collectData(double step)
+{
+   int istep = static_cast<int>(step);
+
+   for(int level = minInitLevel; level<=maxInitLevel;level++)
+   {
+      for(SPtr<Block3D> block : blockVector[level])
+      {
+         if (block)
+         {
+            addDataMQ(block);
+         }
+      }
+   }
+
+   std::string pfilePath, partPath, subfolder, cfilePath;
+
+      subfolder = "mq"+UbSystem::toString(istep);
+      pfilePath =  path+"/mq/"+subfolder;
+      cfilePath =  path+"/mq/mq_collection";
+      partPath = pfilePath+"/mq"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep);
+
+
+   std::string partName = writer->writeOctsWithNodeData(partPath,nodes,cells,datanames,data);
+   size_t found=partName.find_last_of("/");
+   std::string piece = partName.substr(found+1);
+   piece = subfolder + "/" + piece;
+
+   std::vector<std::string> cellDataNames;
+   std::vector<std::string> pieces;
+   pieces.push_back(piece);
+   if (comm->getProcessID() == comm->getRoot())
+   {
+      std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames);
+      found=pname.find_last_of("/");
+      piece = pname.substr(found+1);
+
+      std::vector<std::string> filenames;
+      filenames.push_back(piece);
+      if (step == CoProcessor::scheduler->getMinBegin())
+      {
+         WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false);
+      } 
+      else
+      {
+         WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false);
+      }
+      UBLOG(logINFO,"WriteMacroscopicQuantitiesCoProcessor step: " << istep);
+   }
+
+   clearData();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::clearData()
+{
+   nodes.clear();
+   cells.clear();
+   datanames.clear();
+   data.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void WriteMacroscopicQuantitiesCoProcessor::addDataMQ(SPtr<Block3D> block)
+{
+   double blockID = (double)block->getGlobalID();
+
+   //This data is written:
+   datanames.resize(0);
+   datanames.push_back("DRho");
+   datanames.push_back("Press");
+   datanames.push_back("Vx");
+   datanames.push_back("Vy");
+   datanames.push_back("Vz");
+   
+   data.resize(datanames.size());
+
+   SPtr<ILBMKernel> kernel = block->getKernel();
+   SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();          
+   SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();     
+   LBMReal f[D3Q27System::ENDF+1];
+   LBMReal vx1,vx2,vx3,drho,press;
+
+   //node numbering always starts at 0!
+   int SWB,SEB,NEB,NWB,SWT,SET,NET,NWT;
+
+   if(block->getKernel()->getCompressible())
+   {
+      calcMacros = &D3Q27System::calcCompMacroscopicValues;
+   }
+   else
+   {
+      calcMacros = &D3Q27System::calcIncompMacroscopicValues;
+   }
+
+   int minX1 = 0;
+   int minX2 = 0;
+   int minX3 = 0;
+
+   int maxX1 = (int)(distributions->getNX1());
+   int maxX2 = (int)(distributions->getNX2());
+   int maxX3 = (int)(distributions->getNX3());
+
+   //assign numbers and create node vector + collect data
+   CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1);
+   maxX1 -= 2;
+   maxX2 -= 2;
+   maxX3 -= 2;
+
+   int nr = (int)nodes.size();
+ 
+   for(int ix3=minX3; ix3<=maxX3; ix3++)
+   {
+      for(int ix2=minX2; ix2<=maxX2; ix2++)
+      {
+         for(int ix1=minX1; ix1<=maxX1; ix1++)
+         {
+            if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3))
+            {
+               int index = 0;
+               nodeNumbers(ix1,ix2,ix3) = nr++;
+               Vector3D worldCoordinates = grid->getNodeCoordinates(block, ix1, ix2, ix3);
+               nodes.push_back( UbTupleFloat3(float(worldCoordinates[0]),
+                                              float(worldCoordinates[1]),
+                                              float(worldCoordinates[2]) ));
+
+               distributions->getDistribution(f, ix1, ix2, ix3);
+               calcMacros(f,drho,vx1,vx2,vx3);
+               press = D3Q27System::calcPress(f,drho,vx1,vx2,vx3);
+
+               if (UbMath::isNaN(drho) || UbMath::isInfinity(drho)) 
+                  UB_THROW( UbException(UB_EXARGS,"drho is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+               if (UbMath::isNaN(press) || UbMath::isInfinity(press)) 
+                  UB_THROW( UbException(UB_EXARGS,"press is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                   ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+               if (UbMath::isNaN(vx1) || UbMath::isInfinity(vx1)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx1 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+               if (UbMath::isNaN(vx2) || UbMath::isInfinity(vx2)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx2 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+               if (UbMath::isNaN(vx3) || UbMath::isInfinity(vx3)) 
+                  UB_THROW( UbException(UB_EXARGS,"vx3 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+
+                  ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3)));
+               
+               data[index++].push_back(drho * conv->getFactorDensityLbToW());
+               data[index++].push_back(press * conv->getFactorPressureLbToW());
+               data[index++].push_back(vx1 * conv->getFactorVelocityLbToW());
+               data[index++].push_back(vx2 * conv->getFactorVelocityLbToW());
+               data[index++].push_back(vx3 * conv->getFactorVelocityLbToW());
+            }
+         }
+      }
+   }
+   maxX1 -= 1;
+   maxX2 -= 1;
+   maxX3 -= 1;
+   //cell vector erstellen
+   for(int ix3=minX3; ix3<=maxX3; ix3++)
+   {
+      for(int ix2=minX2; ix2<=maxX2; ix2++)
+      {
+         for(int ix1=minX1; ix1<=maxX1; ix1++)
+         {
+            if(   (SWB=nodeNumbers( ix1  , ix2,   ix3   )) >= 0
+               && (SEB=nodeNumbers( ix1+1, ix2,   ix3   )) >= 0
+               && (NEB=nodeNumbers( ix1+1, ix2+1, ix3   )) >= 0
+               && (NWB=nodeNumbers( ix1  , ix2+1, ix3   )) >= 0 
+               && (SWT=nodeNumbers( ix1  , ix2,   ix3+1 )) >= 0
+               && (SET=nodeNumbers( ix1+1, ix2,   ix3+1 )) >= 0
+               && (NET=nodeNumbers( ix1+1, ix2+1, ix3+1 )) >= 0
+               && (NWT=nodeNumbers( ix1  , ix2+1, ix3+1 )) >= 0                )
+            {
+               cells.push_back( makeUbTuple(SWB,SEB,NEB,NWB,SWT,SET,NET,NWT) );
+            }
+         }
+      }
+   }
+}
diff --git a/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h b/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h
new file mode 100644
index 0000000000000000000000000000000000000000..76ecc9437b38078e596febd9c8747189d92b973e
--- /dev/null
+++ b/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h
@@ -0,0 +1,102 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file WriteMacroscopicQuantitiesCoProcessor.h
+//! \ingroup CoProcessors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef WriteMacroscopicQuantitiesCoProcessor_H
+#define WriteMacroscopicQuantitiesCoProcessor_H
+
+#include <PointerDefinitions.h>
+#include <string>
+#include <vector>
+
+#include "CoProcessor.h"
+#include "UbTuple.h"
+#include "LBMSystem.h"
+
+class Communicator;
+class Grid3D;
+class UbScheduler;
+class LBMUnitConverter;
+class WbWriter;
+class Block3D;
+
+
+//! \brief A class writes macroscopic quantities information to a VTK-file
+class WriteMacroscopicQuantitiesCoProcessor : public CoProcessor 
+{
+public:
+   WriteMacroscopicQuantitiesCoProcessor();
+   //! \brief Construct WriteMacroscopicQuantitiesCoProcessor object
+   //! \pre The Grid3D and UbScheduler objects must exist
+   //! \param grid is observable Grid3D object
+   //! \param s is UbScheduler object for scheduling of observer
+   //! \param path is path of folder for output
+   //! \param writer is WbWriter object
+   //! \param conv is LBMUnitConverter object
+   //! \param comm is Communicator object
+   WriteMacroscopicQuantitiesCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s,
+                                           const std::string& path, WbWriter* const writer, 
+                                           SPtr<LBMUnitConverter> conv, SPtr<Communicator> comm);
+   ~WriteMacroscopicQuantitiesCoProcessor(){}
+
+   void process(double step) override;
+
+protected:
+   //! Collect data for VTK-file
+   //! \param step is a time step
+   void collectData(double step);
+   //! Collect data for VTK-file
+   //! \param block is a time step
+   void addDataMQ(SPtr<Block3D> block);
+   void clearData();
+
+private:
+   void init();
+   std::vector<UbTupleFloat3> nodes;
+   std::vector<UbTupleInt8> cells;
+   std::vector<std::string> datanames;
+   std::vector<std::vector<double> > data; 
+   std::string path;
+   WbWriter* writer;
+   SPtr<LBMUnitConverter> conv;
+   bool bcInformation;
+   std::vector<std::vector<SPtr<Block3D> > > blockVector;
+   int minInitLevel;
+   int maxInitLevel;
+   int gridRank;
+   SPtr<Communicator> comm;
+
+   typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/);
+   CalcMacrosFct calcMacros;
+};
+
+#endif
diff --git a/VirtualFluidsCore/Connectors/Block3DConnector.h b/VirtualFluidsCore/Connectors/Block3DConnector.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cf3cee9137d82598d9f7552bac0fbc1ea8dece7
--- /dev/null
+++ b/VirtualFluidsCore/Connectors/Block3DConnector.h
@@ -0,0 +1,82 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Block3DConnector.h
+//! \ingroup Connectors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BLOCK2DCONNECTOR_H
+#define BLOCK2DCONNECTOR_H
+
+#include <vector>
+#include <string>
+
+#include <basics/utilities/UbTuple.h>
+
+#include <PointerDefinitions.h>
+
+//! \brief   Abstract class of connectors  
+//! \details Connector send and receive full distributions between two blocks in shared memory.
+class Block3DConnector
+{
+public:
+   Block3DConnector() : sendDir(-1) {}
+   Block3DConnector(const int& sendDir) : sendDir(sendDir) {}
+   virtual ~Block3DConnector() {}
+   //!Iniitializes connector
+   virtual void init()=0;
+   //!Synchronizes the send-buffer length
+   virtual void sendTransmitterDataSize()=0;  
+   //!Synchronizes the receive-buffer length
+   virtual void receiveTransmitterDataSize()=0;
+
+   //Send (should be called in given order!!!)
+   virtual void prepareForSend()=0;
+   virtual void fillSendVectors()=0;
+   virtual void sendVectors()=0;
+   
+   //Receive (should be called in given order!!!)
+   virtual void prepareForReceive()=0;
+   virtual void receiveVectors()=0;
+   virtual void distributeReceiveVectors()=0;
+
+   //info section
+   virtual bool isLocalConnector()  = 0;
+   virtual bool isRemoteConnector() = 0;
+   virtual bool isInterpolationConnectorCF() = 0;
+   virtual bool isInterpolationConnectorFC() = 0;
+
+   //grid refinement
+   virtual int getSendDir() const { return sendDir; } 
+
+protected:
+   int  sendDir;
+};
+
+#endif //BLOCK3DCONNECTOR_H
diff --git a/VirtualFluidsCore/Connectors/CMakePackage.txt b/VirtualFluidsCore/Connectors/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e3e3f9a387b022a62ecc0d63c3ef0210313e906d
--- /dev/null
+++ b/VirtualFluidsCore/Connectors/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
\ No newline at end of file
diff --git a/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp b/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..26802ce3f9fc7b574c8023b83c2f79072185cc51
--- /dev/null
+++ b/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.cpp
@@ -0,0 +1,243 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27ETFullDirectConnector.cpp
+//! \ingroup Connectors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "D3Q27ETFullDirectConnector.h"
+#include "LBMKernel.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "DataSet3D.h"
+
+using namespace std;
+
+D3Q27ETFullDirectConnector::D3Q27ETFullDirectConnector(SPtr<Block3D> from, SPtr<Block3D> to, int sendDir)
+   : LocalBlock3DConnector(from, to, sendDir)
+
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27ETFullDirectConnector::init()
+{
+   maxX1 = (int)this->from.lock()->getKernel()->getDataSet()->getFdistributions()->getNX1() - 1;
+   maxX2 = (int)this->from.lock()->getKernel()->getDataSet()->getFdistributions()->getNX2() - 1;
+   maxX3 = (int)this->from.lock()->getKernel()->getDataSet()->getFdistributions()->getNX3() - 1;
+
+   fFrom = dynamic_pointer_cast<EsoTwist3D>(from.lock()->getKernel()->getDataSet()->getFdistributions());
+   fTo = dynamic_pointer_cast<EsoTwist3D>(to.lock()->getKernel()->getDataSet()->getFdistributions());
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27ETFullDirectConnector::sendVectors()
+{
+   localDistributionsFrom = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getLocalDistributions();
+   nonLocalDistributionsFrom = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getNonLocalDistributions();
+   zeroDistributionsFrom = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fFrom)->getZeroDistributions();
+
+   localDistributionsTo = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getLocalDistributions();
+   nonLocalDistributionsTo = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getNonLocalDistributions();
+   zeroDistributionsTo = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(this->fTo)->getZeroDistributions();
+
+   //EAST
+   if (sendDir == D3Q27System::E)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         for (int x2 = 1; x2 < maxX2; x2++)
+         {
+            exchangeData(maxX1 - 1, x2, x3, 0, x2, x3);
+         }
+      }
+   }
+   //WEST
+   else if (sendDir == D3Q27System::W)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         for (int x2 = 1; x2 < maxX2; x2++)
+         {
+            exchangeData(1, x2, x3, maxX1, x2, x3);
+         }
+      }
+   }
+   //NORTH
+   else if (sendDir == D3Q27System::N)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         for (int x1 = 1; x1 < maxX1; x1++)
+         {
+            exchangeData(x1, maxX2 - 1, x3, x1, 0, x3);
+         }
+      }
+   }
+   //SOUTH
+   else if (sendDir == D3Q27System::S)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         for (int x1 = 1; x1 < maxX1; x1++)
+         {
+            exchangeData(x1, 1, x3, x1, maxX2, x3);
+         }
+      }
+   }
+
+   //TOP
+   else if (sendDir == D3Q27System::T)
+   {
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         for (int x1 = 1; x1 < maxX1; x1++)
+         {
+            exchangeData(x1, x2, maxX3 - 1, x1, x2, 0);
+         }
+      }
+   }
+   //BOTTOM
+   else if (sendDir == D3Q27System::B)
+   {
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         for (int x1 = 1; x1 < maxX1; x1++)
+         {
+            exchangeData(x1, x2, 1, x1, x2, maxX3);
+         }
+      }
+   }
+   //NORTHEAST
+   else if (sendDir == D3Q27System::NE)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         exchangeData(maxX1 - 1, maxX2 - 1, x3, 0, 0, x3);
+      }
+   }
+   //NORTHWEST
+   else if (sendDir == D3Q27System::NW)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         exchangeData(1, maxX2 - 1, x3, maxX1, 0, x3);
+      }
+   }
+   //SOUTHWEST
+   else if (sendDir == D3Q27System::SW)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         exchangeData(1, 1, x3, maxX1, maxX2, x3);
+      }
+   }
+   //SOUTHEAST
+   else if (sendDir == D3Q27System::SE)
+   {
+      for (int x3 = 1; x3 < maxX3; x3++)
+      {
+         exchangeData(maxX1 - 1, 1, x3, 0, maxX2, x3);
+      }
+   }
+   else if (sendDir == D3Q27System::TE)
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         exchangeData(maxX1 - 1, x2, maxX3 - 1, 0, x2, 0);
+      }
+   else if (sendDir == D3Q27System::BW)
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         exchangeData(1, x2, 1, maxX1, x2, maxX3);
+      }
+   else if (sendDir == D3Q27System::BE)
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         exchangeData(maxX1 - 1, x2, 1, 0, x2, maxX3);
+      }
+   else if (sendDir == D3Q27System::TW)
+      for (int x2 = 1; x2 < maxX2; x2++)
+      {
+         exchangeData(1, x2, maxX3 - 1, maxX1, x2, 0);
+      }
+   else if (sendDir == D3Q27System::TN)
+      for (int x1 = 1; x1 < maxX1; x1++)
+      {
+         exchangeData(x1, maxX2 - 1, maxX3 - 1, x1, 0, 0);
+      }
+   else if (sendDir == D3Q27System::BS)
+      for (int x1 = 1; x1 < maxX1; x1++)
+      {
+         exchangeData(x1, 1, 1, x1, maxX2, maxX3);
+      }
+   else if (sendDir == D3Q27System::BN)
+      for (int x1 = 1; x1 < maxX1; x1++)
+      {
+         exchangeData(x1, maxX2 - 1, 1, x1, 0, maxX3);
+      }
+
+   else if (sendDir == D3Q27System::TS)
+      for (int x1 = 1; x1 < maxX1; x1++)
+      {
+         exchangeData(x1, 1, maxX3 - 1, x1, maxX2, 0);
+      }
+
+   else if (sendDir == D3Q27System::TSW)
+   {
+      exchangeData(1, 1, maxX3 - 1, maxX1, maxX2, 0);
+   }
+   else if (sendDir == D3Q27System::TSE)
+   {
+      exchangeData(maxX1 - 1, 1, maxX3 - 1, 0, maxX2, 0);
+   }
+   else if (sendDir == D3Q27System::TNW)
+   {
+      exchangeData(1, maxX2 - 1, maxX3 - 1, maxX1, 0, 0);
+   }
+   else if (sendDir == D3Q27System::TNE)
+   {
+      exchangeData(maxX1 - 1, maxX2 - 1, maxX3 - 1, 0, 0, 0);
+   }
+   else if (sendDir == D3Q27System::BSW)
+   {
+      exchangeData(1, 1, 1, maxX1, maxX2, maxX3);
+   }
+   else if (sendDir == D3Q27System::BSE)
+   {
+      exchangeData(maxX1 - 1, 1, 1, 0, maxX2, maxX3);
+   }
+   else if (sendDir == D3Q27System::BNW)
+   {
+      exchangeData(1, maxX2 - 1, 1, maxX1, 0, maxX3);
+   }
+   else if (sendDir == D3Q27System::BNE)
+   {
+      exchangeData(maxX1 - 1, maxX2 - 1, 1, 0, 0, maxX3);
+   }
+   else UB_THROW(UbException(UB_EXARGS, "unknown dir"));
+}
+
diff --git a/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h b/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h
new file mode 100644
index 0000000000000000000000000000000000000000..052ade1996c103f53b3d03e38525d90235f06c5f
--- /dev/null
+++ b/VirtualFluidsCore/Connectors/D3Q27ETFullDirectConnector.h
@@ -0,0 +1,107 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27ETFullDirectConnector.h
+//! \ingroup Connectors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef D3Q27ETFULLDIRECTCONNECTOR_H
+#define D3Q27ETFULLDIRECTCONNECTOR_H
+
+#include "LocalBlock3DConnector.h"
+#include "Block3D.h"
+#include "D3Q27System.h"
+#include "basics/container/CbArray3D.h"
+#include "basics/container/CbArray4D.h"
+#include "EsoTwist3D.h"
+
+//! \brief   Exchange data between blocks. 
+//! \details Connector send and receive full distributions between two blocks in shared memory.
+class D3Q27ETFullDirectConnector : public LocalBlock3DConnector
+{
+public:
+   D3Q27ETFullDirectConnector(SPtr<Block3D> from, SPtr<Block3D> to, int sendDir);
+   void init();
+   void sendVectors();
+
+protected:
+   inline void exchangeData(int x1From, int x2From, int x3From, int x1To, int x2To, int x3To);
+private:
+   int maxX1;
+   int maxX2;
+   int maxX3;
+
+   CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsFrom;
+   CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsFrom;
+   CbArray3D <LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributionsFrom;
+
+   CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsTo;
+   CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsTo;
+   CbArray3D <LBMReal, IndexerX3X2X1>::CbArray3DPtr   zeroDistributionsTo;
+
+   SPtr<EsoTwist3D>  fFrom;
+   SPtr<EsoTwist3D>  fTo;
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+inline void D3Q27ETFullDirectConnector::exchangeData(int x1From, int x2From, int x3From, int x1To, int x2To, int x3To)
+{
+   (*this->localDistributionsTo)(D3Q27System::ET_E, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_E, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_N, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_N, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_T, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_T, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_NE, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_NE, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_NW, x1To + 1, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_NW, x1From + 1, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TE, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TE, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TW, x1To + 1, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TW, x1From + 1, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TN, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TN, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TS, x1To, x2To + 1, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TS, x1From, x2From + 1, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TNE, x1To, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TNE, x1From, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TNW, x1To + 1, x2To, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TNW, x1From + 1, x2From, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TSE, x1To, x2To + 1, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TSE, x1From, x2From + 1, x3From);
+   (*this->localDistributionsTo)(D3Q27System::ET_TSW, x1To + 1, x2To + 1, x3To) = (*this->localDistributionsFrom)(D3Q27System::ET_TSW, x1From + 1, x2From + 1, x3From);
+
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_W, x1To + 1, x2To, x3To) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_W, x1From + 1, x2From, x3From);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_S, x1To, x2To + 1, x3To) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_S, x1From, x2From + 1, x3From);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_B, x1To, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_B, x1From, x2From, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_SW, x1To + 1, x2To + 1, x3To) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_SW, x1From + 1, x2From + 1, x3From);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_SE, x1To, x2To + 1, x3To) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_SE, x1From, x2From + 1, x3From);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BW, x1To + 1, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BW, x1From + 1, x2From, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BE, x1To, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BE, x1From, x2From, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BS, x1To, x2To + 1, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BS, x1From, x2From + 1, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BN, x1To, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BN, x1From, x2From, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BSW, x1To + 1, x2To + 1, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BSW, x1From + 1, x2From + 1, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BSE, x1To, x2To + 1, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BSE, x1From, x2From + 1, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BNW, x1To + 1, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BNW, x1From + 1, x2From, x3From + 1);
+   (*this->nonLocalDistributionsTo)(D3Q27System::ET_BNE, x1To, x2To, x3To + 1) = (*this->nonLocalDistributionsFrom)(D3Q27System::ET_BNE, x1From, x2From, x3From + 1);
+
+   (*this->zeroDistributionsTo)(x1To, x2To, x3To) = (*this->zeroDistributionsFrom)(x1From, x2From, x3From);
+}
+#endif 
+
diff --git a/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h b/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h
new file mode 100644
index 0000000000000000000000000000000000000000..c57e1f6e069d35a01f07e00b9186cadfee3d537d
--- /dev/null
+++ b/VirtualFluidsCore/Connectors/LocalBlock3DConnector.h
@@ -0,0 +1,74 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LocalBlock3DConnector.h
+//! \ingroup Connectors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef LocalBlock3DConnector_H
+#define LocalBlock3DConnector_H
+
+#include "Block3DConnector.h"
+#include "Block3D.h"
+#include "PointerDefinitions.h"
+
+//! A class provides an interface for connectors in shared memory
+class LocalBlock3DConnector : public Block3DConnector
+{
+public:
+   LocalBlock3DConnector(SPtr<Block3D> from, SPtr<Block3D> to, int sendDir)
+      : Block3DConnector(sendDir)
+      , from(from)
+      , to(to)
+   {
+
+   }
+   virtual ~LocalBlock3DConnector() {}
+   void sendTransmitterDataSize() {}
+   void receiveTransmitterDataSize() {}
+   virtual void init() = 0;
+   void prepareForReceive() {}
+   void prepareForSend() {}
+   void fillSendVectors() {}
+   virtual void sendVectors()=0;
+   void receiveVectors() {}
+
+   void distributeReceiveVectors() {}
+
+   bool isLocalConnector() { return true; }
+   bool isRemoteConnector() { return false; }
+   bool isInterpolationConnectorCF() { return false; }
+   bool isInterpolationConnectorFC() { return false; }
+
+protected:
+   WPtr<Block3D> from;
+   WPtr<Block3D> to;
+};
+
+#endif //LocalBlock3DConnector_H
diff --git a/VirtualFluidsCore/Data/CMakePackage.txt b/VirtualFluidsCore/Data/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Data/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp b/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ed36627d4f2c9d7c1fa4532e0e8befe958bed36
--- /dev/null
+++ b/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp
@@ -0,0 +1,686 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27EsoTwist3DSplittedVector.cpp
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "EsoTwistD3Q27System.h"
+
+D3Q27EsoTwist3DSplittedVector::D3Q27EsoTwist3DSplittedVector()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27EsoTwist3DSplittedVector::D3Q27EsoTwist3DSplittedVector( size_t nx1, size_t nx2, size_t nx3, LBMReal value )
+{
+   this->NX1 = nx1;
+   this->NX2 = nx2;
+   this->NX3 = nx3;
+
+   this->localDistributions    = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(13, nx1+1, nx2+1, nx3+1, value));
+   this->nonLocalDistributions = CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal,IndexerX4X3X2X1>(13, nx1+1, nx2+1, nx3+1, value));
+
+   this->restDistributions     = CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal,IndexerX3X2X1>(nx1, nx2, nx3, value));
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27EsoTwist3DSplittedVector::~D3Q27EsoTwist3DSplittedVector()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::swap()
+{
+   std::swap( this->localDistributions, this->nonLocalDistributions );
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::getDistribution(LBMReal* const f, size_t x1, size_t x2, size_t x3)
+{
+   f[D3Q27System::E] = (*this->localDistributions)(D3Q27System::ET_E, x1,x2,x3);
+   f[D3Q27System::N] = (*this->localDistributions)(D3Q27System::ET_N,x1,x2,x3);  
+   f[D3Q27System::T] = (*this->localDistributions)(D3Q27System::ET_T,x1,x2,x3);
+   f[D3Q27System::NE] = (*this->localDistributions)(D3Q27System::ET_NE,x1,x2,x3);
+   f[D3Q27System::NW] = (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,x3);
+   f[D3Q27System::TE] = (*this->localDistributions)(D3Q27System::ET_TE,x1,x2,x3);
+   f[D3Q27System::TW] = (*this->localDistributions)(D3Q27System::ET_TW, x1+1,x2,x3);
+   f[D3Q27System::TN] = (*this->localDistributions)(D3Q27System::ET_TN,x1,x2,x3);
+   f[D3Q27System::TS] = (*this->localDistributions)(D3Q27System::ET_TS,x1,x2+1,x3);
+   f[D3Q27System::TNE] = (*this->localDistributions)(D3Q27System::ET_TNE,x1,x2,x3);
+   f[D3Q27System::TNW] = (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,x3);
+   f[D3Q27System::TSE] = (*this->localDistributions)(D3Q27System::ET_TSE,x1,x2+1,x3);
+   f[D3Q27System::TSW] = (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3);
+
+   f[D3Q27System::W ] = (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,x3  );
+   f[D3Q27System::S ] = (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,x2+1,x3  );
+   f[D3Q27System::B ] = (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,x2,x3+1  );
+   f[D3Q27System::SW] = (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3 );
+   f[D3Q27System::SE] = (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,x2+1,x3 );
+   f[D3Q27System::BW] = (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,x3+1 );
+   f[D3Q27System::BE] = (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,x2,x3+1 );
+   f[D3Q27System::BS] = (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,x2+1,x3+1 );
+   f[D3Q27System::BN] = (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,x2,x3+1 );
+   f[D3Q27System::BSW] = (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1);
+   f[D3Q27System::BSE] = (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,x2+1,x3+1);
+   f[D3Q27System::BNW] = (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,x3+1);
+   f[D3Q27System::BNE] = (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,x2,x3+1);
+
+   f[D3Q27System::REST] = (*this->restDistributions)(x1,x2,x3);
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3)
+{
+   (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3)   = f[D3Q27System::INV_E];
+   (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3)   = f[D3Q27System::INV_N];
+   (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3)   = f[D3Q27System::INV_T];
+   (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3)  = f[D3Q27System::INV_NE];
+   (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3)  = f[D3Q27System::INV_NW];
+   (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3)  = f[D3Q27System::INV_TE];
+   (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3)  = f[D3Q27System::INV_TW];
+   (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3)  = f[D3Q27System::INV_TN];
+   (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3)  = f[D3Q27System::INV_TS];
+   (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f[D3Q27System::INV_TNE];
+   (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f[D3Q27System::INV_TNW];
+   (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f[D3Q27System::INV_TSE];
+   (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f[D3Q27System::INV_TSW];
+
+   (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f[D3Q27System::INV_W ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f[D3Q27System::INV_S ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f[D3Q27System::INV_B ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f[D3Q27System::INV_SW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f[D3Q27System::INV_SE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f[D3Q27System::INV_BW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f[D3Q27System::INV_BE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f[D3Q27System::INV_BS];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f[D3Q27System::INV_BN];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f[D3Q27System::INV_BSW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f[D3Q27System::INV_BSE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f[D3Q27System::INV_BNW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1) = f[D3Q27System::INV_BNE];
+
+   (*this->restDistributions)(x1,x2,x3) = f[D3Q27System::REST];
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::getDistributionInv(LBMReal* const f, size_t x1, size_t x2, size_t x3)
+{
+   f[D3Q27System::INV_E] = (*this->localDistributions)(D3Q27System::ET_E, x1,x2,x3);
+   f[D3Q27System::INV_N] = (*this->localDistributions)(D3Q27System::ET_N,x1,x2,x3);  
+   f[D3Q27System::INV_T] = (*this->localDistributions)(D3Q27System::ET_T,x1,x2,x3);
+   f[D3Q27System::INV_NE] = (*this->localDistributions)(D3Q27System::ET_NE,x1,x2,x3);
+   f[D3Q27System::INV_NW] = (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,x3);
+   f[D3Q27System::INV_TE] = (*this->localDistributions)(D3Q27System::ET_TE,x1,x2,x3);
+   f[D3Q27System::INV_TW] = (*this->localDistributions)(D3Q27System::ET_TW, x1+1,x2,x3);
+   f[D3Q27System::INV_TN] = (*this->localDistributions)(D3Q27System::ET_TN,x1,x2,x3);
+   f[D3Q27System::INV_TS] = (*this->localDistributions)(D3Q27System::ET_TS,x1,x2+1,x3);
+   f[D3Q27System::INV_TNE] = (*this->localDistributions)(D3Q27System::ET_TNE,x1,x2,x3);
+   f[D3Q27System::INV_TNW] = (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,x3);
+   f[D3Q27System::INV_TSE] = (*this->localDistributions)(D3Q27System::ET_TSE,x1,x2+1,x3);
+   f[D3Q27System::INV_TSW] = (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3);
+
+   f[D3Q27System::INV_W ] = (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,x3  );
+   f[D3Q27System::INV_S ] = (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,x2+1,x3  );
+   f[D3Q27System::INV_B ] = (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,x2,x3+1  );
+   f[D3Q27System::INV_SW] = (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3 );
+   f[D3Q27System::INV_SE] = (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,x2+1,x3 );
+   f[D3Q27System::INV_BW] = (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,x3+1 );
+   f[D3Q27System::INV_BE] = (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,x2,x3+1 );
+   f[D3Q27System::INV_BS] = (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,x2+1,x3+1 );
+   f[D3Q27System::INV_BN] = (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,x2,x3+1 );
+   f[D3Q27System::INV_BSW] = (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1);
+   f[D3Q27System::INV_BSE] = (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,x2+1,x3+1);
+   f[D3Q27System::INV_BNW] = (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,x3+1);
+   f[D3Q27System::INV_BNE] = (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,x2,x3+1);
+
+   f[D3Q27System::REST] = (*this->restDistributions)(x1,x2,x3);
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3)
+{
+   (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3) = f[D3Q27System::E];
+   (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3) = f[D3Q27System::N];
+   (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3) = f[D3Q27System::T];
+   (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3) = f[D3Q27System::NE];
+   (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3) = f[D3Q27System::NW];
+   (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3) = f[D3Q27System::TE];
+   (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3) = f[D3Q27System::TW];
+   (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3) = f[D3Q27System::TN];
+   (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3) = f[D3Q27System::TS];
+   (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f[D3Q27System::TNE];
+   (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f[D3Q27System::TNW];
+   (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f[D3Q27System::TSE];
+   (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f[D3Q27System::TSW];
+
+   (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f[D3Q27System::W ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f[D3Q27System::S ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f[D3Q27System::B ];
+   (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f[D3Q27System::SW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f[D3Q27System::SE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f[D3Q27System::BW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f[D3Q27System::BE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f[D3Q27System::BS];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f[D3Q27System::BN];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f[D3Q27System::BSW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f[D3Q27System::BSE];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f[D3Q27System::BNW];
+   (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1) = f[D3Q27System::BNE];
+
+   (*this->restDistributions)(x1,x2,x3) = f[D3Q27System::REST];
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction)
+{
+   bool directionFlag = false;
+   if ((direction & EsoTwistD3Q27System::etE) == EsoTwistD3Q27System::etE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f[D3Q27System::E]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etW) == EsoTwistD3Q27System::etW)
+      (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3) = f[D3Q27System::W]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etS) == EsoTwistD3Q27System::etS)
+      (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3) = f[D3Q27System::S]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etN) == EsoTwistD3Q27System::etN)
+      (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f[D3Q27System::N]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etB) == EsoTwistD3Q27System::etB)
+      (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3) = f[D3Q27System::B]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etT) == EsoTwistD3Q27System::etT)
+      (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f[D3Q27System::T]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etSW) == EsoTwistD3Q27System::etSW)
+      (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3) = f[D3Q27System::SW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etNE) == EsoTwistD3Q27System::etNE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f[D3Q27System::NE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etNW) == EsoTwistD3Q27System::etNW)
+      (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f[D3Q27System::NW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etSE) == EsoTwistD3Q27System::etSE)
+      (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3) = f[D3Q27System::SE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBW) == EsoTwistD3Q27System::etBW)
+      (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3) = f[D3Q27System::BW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTE) == EsoTwistD3Q27System::etTE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f[D3Q27System::TE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTW) == EsoTwistD3Q27System::etTW)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f[D3Q27System::TW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBE) == EsoTwistD3Q27System::etBE)
+      (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3) = f[D3Q27System::BE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBS) == EsoTwistD3Q27System::etBS)
+      (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3) = f[D3Q27System::BS]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTN) == EsoTwistD3Q27System::etTN)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f[D3Q27System::TN]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTS) == EsoTwistD3Q27System::etTS)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f[D3Q27System::TS]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBN) == EsoTwistD3Q27System::etBN)
+      (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3) = f[D3Q27System::BN]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBSW) == EsoTwistD3Q27System::etBSW)
+      (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f[D3Q27System::BSW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTNE) == EsoTwistD3Q27System::etTNE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f[D3Q27System::TNE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBSE) == EsoTwistD3Q27System::etBSE)
+      (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f[D3Q27System::BSE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTNW) == EsoTwistD3Q27System::etTNW)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f[D3Q27System::TNW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBNW) == EsoTwistD3Q27System::etBNW)
+      (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f[D3Q27System::BNW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTSE) == EsoTwistD3Q27System::etTSE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f[D3Q27System::TSE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBNE) == EsoTwistD3Q27System::etBNE)
+      (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f[D3Q27System::BNE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTSW) == EsoTwistD3Q27System::etTSW)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1) = f[D3Q27System::TSW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::REST) == EsoTwistD3Q27System::REST)
+      (*this->restDistributions)(x1,x2,x3) = f[D3Q27System::REST]; directionFlag=true;
+#ifdef _DEBUG
+   if(!directionFlag)UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );
+#endif //DEBUG
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction)
+{
+   switch (direction)
+   {
+   case D3Q27System::E :
+      (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f;
+      break;
+   case D3Q27System::W :
+      (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::S :
+      (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::N :
+      (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f;
+      break;
+   case D3Q27System::B :
+      (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::T :
+      (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f;
+      break;
+   case D3Q27System::SW :
+      (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::NE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f;
+      break;
+   case D3Q27System::NW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f;
+      break;
+   case D3Q27System::SE :
+      (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::BW :
+      (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::TE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::TW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::BE :
+      (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::BS :
+      (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::TN :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f;
+      break;
+   case D3Q27System::TS :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::BN :
+      (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3) = f;
+      break;
+   case D3Q27System::BSW :
+      (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::TNE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f;
+      break;
+   case D3Q27System::BSE :
+      (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::TNW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f;
+      break;
+   case D3Q27System::BNW :
+      (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f;
+      break;
+   case D3Q27System::TSE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f;
+      break;
+   case D3Q27System::BNE :
+      (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f;
+      break;
+   case D3Q27System::TSW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1) = f;
+      break;
+   case D3Q27System::REST :
+      (*this->restDistributions)(x1,x2,x3) = f;
+      break;
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );     
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction)
+{
+   bool directionFlag = false;
+   if ((direction & EsoTwistD3Q27System::etE) == EsoTwistD3Q27System::etE)
+       (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3) = f[D3Q27System::E]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etW) == EsoTwistD3Q27System::etW)
+      (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f[D3Q27System::W]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etS) == EsoTwistD3Q27System::etS)
+       (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f[D3Q27System::S]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etN) == EsoTwistD3Q27System::etN)
+      (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3) = f[D3Q27System::N]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etB) == EsoTwistD3Q27System::etB)
+       (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f[D3Q27System::B]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etT) == EsoTwistD3Q27System::etT)
+      (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3) = f[D3Q27System::T]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etSW) == EsoTwistD3Q27System::etSW)
+       (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f[D3Q27System::SW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etNE) == EsoTwistD3Q27System::etNE)
+      (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3) = f[D3Q27System::NE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etNW) == EsoTwistD3Q27System::etNW)
+       (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3) = f[D3Q27System::NW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etSE) == EsoTwistD3Q27System::etSE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f[D3Q27System::SE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBW) == EsoTwistD3Q27System::etBW)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f[D3Q27System::BW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTE) == EsoTwistD3Q27System::etTE)
+      (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3) = f[D3Q27System::TE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTW) == EsoTwistD3Q27System::etTW)
+       (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3) = f[D3Q27System::TW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBE) == EsoTwistD3Q27System::etBE)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f[D3Q27System::BE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBS) == EsoTwistD3Q27System::etBS)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f[D3Q27System::BS]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTN) == EsoTwistD3Q27System::etTN)
+      (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3) = f[D3Q27System::TN]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTS) == EsoTwistD3Q27System::etTS)
+       (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3) = f[D3Q27System::TS]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBN) == EsoTwistD3Q27System::etBN)
+      (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f[D3Q27System::BN]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBSW) == EsoTwistD3Q27System::etBSW)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f[D3Q27System::BSW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTNE) == EsoTwistD3Q27System::etTNE)
+      (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f[D3Q27System::TNE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBSE) == EsoTwistD3Q27System::etBSE)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f[D3Q27System::BSE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTNW) == EsoTwistD3Q27System::etTNW)
+      (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f[D3Q27System::TNW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBNW) == EsoTwistD3Q27System::etBNW)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f[D3Q27System::BNW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTSE) == EsoTwistD3Q27System::etTSE)
+      (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f[D3Q27System::TSE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etBNE) == EsoTwistD3Q27System::etBNE)
+       (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1)= f[D3Q27System::BNE]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::etTSW) == EsoTwistD3Q27System::etTSW)
+      (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f[D3Q27System::TSW]; directionFlag=true;
+   if ((direction & EsoTwistD3Q27System::REST) == EsoTwistD3Q27System::REST)
+      (*this->restDistributions)(x1,x2,x3) = f[D3Q27System::REST]; directionFlag=true;
+#ifdef _DEBUG
+   if(!directionFlag)UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );
+#endif //DEBUG
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction)
+{
+   switch (direction)
+   {
+   case D3Q27System::E :
+      (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::W :
+      (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    ) = f;
+      break;
+   case D3Q27System::S :
+      (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    ) = f;
+      break;
+   case D3Q27System::N :
+      (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::B :
+      (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  ) = f;
+      break;
+   case D3Q27System::T :
+      (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::SW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   ) = f;
+      break;
+   case D3Q27System::NE :
+      (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::NW :
+      (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::SE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   ) = f;
+      break;
+   case D3Q27System::BW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::TE :
+      (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::TW :
+      (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::BE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::BS :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 ) = f;
+      break;
+   case D3Q27System::TN :
+      (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::TS :
+      (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3) = f;
+      break;
+   case D3Q27System::BN :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 ) = f;
+      break;
+   case D3Q27System::BSW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1) = f;
+      break;
+   case D3Q27System::TNE :
+      (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3) = f;
+      break;
+   case D3Q27System::BSE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1) = f;
+      break;
+   case D3Q27System::TNW :
+      (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3) = f;
+      break;
+   case D3Q27System::BNW :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1) = f;
+      break;
+   case D3Q27System::TSE :
+      (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3) = f;
+      break;
+   case D3Q27System::BNE :
+      (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1) = f;
+      break;
+   case D3Q27System::TSW :
+      (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3) = f;
+      break;
+   case D3Q27System::REST :
+      (*this->restDistributions)(x1,x2,x3) = f;
+      break;
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );     
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal D3Q27EsoTwist3DSplittedVector::getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction)
+{
+   switch (direction)
+   {
+   case D3Q27System::W :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    );
+   case D3Q27System::E :
+      return (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3);
+   case D3Q27System::N :
+      return (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3);
+   case D3Q27System::S :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    );
+   case D3Q27System::T :
+      return (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3);
+   case D3Q27System::B :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  );
+   case D3Q27System::NE :
+      return (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3);
+   case D3Q27System::SW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   );
+   case D3Q27System::SE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   );
+   case D3Q27System::NW :
+      return (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3);
+   case D3Q27System::TE :
+      return (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3);
+   case D3Q27System::BW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 );
+   case D3Q27System::BE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 );
+   case D3Q27System::TW :
+      return (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3);
+   case D3Q27System::TN :
+      return (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3);
+   case D3Q27System::BS :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 );
+   case D3Q27System::BN :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 );
+   case D3Q27System::TS :
+      return (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3);
+   case D3Q27System::TNE :
+      return (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3);
+   case D3Q27System::BSW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1);
+   case D3Q27System::TNW :
+      return (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3);
+   case D3Q27System::BSE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1);
+   case D3Q27System::TSE :
+      return (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3);
+   case D3Q27System::BNW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1);
+   case D3Q27System::TSW :
+      return (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3);
+   case D3Q27System::BNE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1);
+   case D3Q27System::REST :
+      return (*this->restDistributions)(x1,x2,x3);
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );     
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal D3Q27EsoTwist3DSplittedVector::getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction)
+{
+   switch (direction)
+   {
+   case D3Q27System::E :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_W,x1+1,x2,  x3    );
+   case D3Q27System::W :
+      return (*this->localDistributions)(D3Q27System::ET_E,x1,  x2,  x3);
+   case D3Q27System::S :
+      return (*this->localDistributions)(D3Q27System::ET_N,x1,  x2,  x3);
+   case D3Q27System::N :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_S,x1,  x2+1,x3    );
+   case D3Q27System::B :
+      return (*this->localDistributions)(D3Q27System::ET_T,x1,  x2,  x3);
+   case D3Q27System::T :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_B,x1,  x2,  x3+1  );
+   case D3Q27System::SW :
+      return (*this->localDistributions)(D3Q27System::ET_NE,x1,  x2,  x3);
+   case D3Q27System::NE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_SW,x1+1,x2+1,x3   );
+   case D3Q27System::NW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_SE,x1,  x2+1,x3   );
+   case D3Q27System::SE :
+      return (*this->localDistributions)(D3Q27System::ET_NW,x1+1,x2,  x3);
+   case D3Q27System::BW :
+      return (*this->localDistributions)(D3Q27System::ET_TE,x1,  x2,  x3);
+   case D3Q27System::TE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BW,x1+1,x2,  x3+1 );
+   case D3Q27System::TW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BE,x1,  x2,  x3+1 );
+   case D3Q27System::BE :
+      return (*this->localDistributions)(D3Q27System::ET_TW,x1+1,x2,  x3);
+   case D3Q27System::BS :
+      return (*this->localDistributions)(D3Q27System::ET_TN,x1,  x2,  x3);
+   case D3Q27System::TN :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BS,x1,  x2+1,x3+1 );
+   case D3Q27System::TS :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BN,x1,  x2,  x3+1 );
+   case D3Q27System::BN :
+      return (*this->localDistributions)(D3Q27System::ET_TS,x1,  x2+1,x3);
+   case D3Q27System::BSW :
+      return (*this->localDistributions)(D3Q27System::ET_TNE,x1,  x2,  x3);
+   case D3Q27System::TNE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BSW,x1+1,x2+1,x3+1);
+   case D3Q27System::BSE :
+      return (*this->localDistributions)(D3Q27System::ET_TNW,x1+1,x2,  x3);
+   case D3Q27System::TNW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BSE,x1,  x2+1,x3+1);
+   case D3Q27System::BNW :
+      return (*this->localDistributions)(D3Q27System::ET_TSE,x1,  x2+1,x3);
+   case D3Q27System::TSE :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BNW,x1+1,x2,  x3+1);
+   case D3Q27System::BNE :
+      return (*this->localDistributions)(D3Q27System::ET_TSW,x1+1,x2+1,x3);
+   case D3Q27System::TSW :
+      return (*this->nonLocalDistributions)(D3Q27System::ET_BNE,x1,  x2,  x3+1);
+   case D3Q27System::REST :
+      return (*this->restDistributions)(x1,x2,x3);
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Direction didn't find") );     
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+size_t D3Q27EsoTwist3DSplittedVector::getNX1() const
+{
+   return NX1;
+}
+//////////////////////////////////////////////////////////////////////////
+size_t D3Q27EsoTwist3DSplittedVector::getNX2() const
+{
+   return NX2;
+}
+//////////////////////////////////////////////////////////////////////////
+size_t D3Q27EsoTwist3DSplittedVector::getNX3() const
+{
+   return NX3;
+}
+//////////////////////////////////////////////////////////////////////////
+CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr D3Q27EsoTwist3DSplittedVector::getLocalDistributions()
+{
+   return this->localDistributions;
+}
+//////////////////////////////////////////////////////////////////////////
+CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr D3Q27EsoTwist3DSplittedVector::getNonLocalDistributions()
+{
+   return this->nonLocalDistributions;
+}
+//////////////////////////////////////////////////////////////////////////
+CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr D3Q27EsoTwist3DSplittedVector::getZeroDistributions()
+{
+   return this->restDistributions;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setNX1(size_t newNX1)
+{
+   NX1 = newNX1;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setNX2(size_t newNX2)
+{
+   NX2 = newNX2;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setNX3(size_t newNX3)
+{
+   NX3 = newNX3;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array)
+{
+   localDistributions = array;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array)
+{
+   nonLocalDistributions = array;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27EsoTwist3DSplittedVector::setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr array)
+{
+   restDistributions = array;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
diff --git a/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h b/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
new file mode 100644
index 0000000000000000000000000000000000000000..725b845d0ac9776979c017f2a1caab9e903077d9
--- /dev/null
+++ b/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.h
@@ -0,0 +1,108 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27EsoTwist3DSplittedVector.h
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef D3Q27EsoTwist3DSplittedVector_h
+#define D3Q27EsoTwist3DSplittedVector_h
+
+#include "EsoTwist3D.h"
+#include "D3Q27System.h"
+#include "basics/container/CbArray4D.h"
+#include "basics/container/CbArray3D.h"
+
+//! \brief Class implements EsoTwist3D
+//! \details D3Q27EsoTwist3DSplittedVector uses three vectors to implement Esoteric Twist method
+class D3Q27EsoTwist3DSplittedVector : public EsoTwist3D
+{
+public:
+   D3Q27EsoTwist3DSplittedVector();
+   //! \param nx1 number of nodes in x1 direction
+   //! \param nx2 number of nodes in x2 direction
+   //! \param nx3 number of nodes in x3 direction
+   //! \param value initialisation value
+   D3Q27EsoTwist3DSplittedVector(size_t nx1, size_t nx2, size_t nx3, LBMReal value);
+   //////////////////////////////////////////////////////////////////////////
+   ~D3Q27EsoTwist3DSplittedVector();
+   //////////////////////////////////////////////////////////////////////////
+   void swap();
+   //////////////////////////////////////////////////////////////////////////
+   virtual void getDistribution( LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   ////////////////////////////////////////////////////////////////////////
+   virtual void getDistributionInv( LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction);
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction);
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX1() const;
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX2() const;
+   //////////////////////////////////////////////////////////////////////////
+   size_t getNX3() const;
+   //////////////////////////////////////////////////////////////////////////
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getLocalDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr getNonLocalDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr getZeroDistributions();
+   //////////////////////////////////////////////////////////////////////////
+   void setNX1(size_t newNX1);
+   void setNX2(size_t newNX2);
+   void setNX3(size_t newNX3);
+   void setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
+   void setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr array);
+   void setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr array);
+   
+protected:
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
+   CbArray4D<LBMReal,IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
+   CbArray3D<LBMReal,IndexerX3X2X1>::CbArray3DPtr   restDistributions;
+   size_t NX1, NX2, NX3;
+
+   friend class MPIIORestartCoProcessor;
+   friend class MPIIOMigrationCoProcessor;
+
+};
+
+#endif
diff --git a/VirtualFluidsCore/Data/DataSet3D.h b/VirtualFluidsCore/Data/DataSet3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..296a15065bfc74c3fa9d7862207dacebb9509361
--- /dev/null
+++ b/VirtualFluidsCore/Data/DataSet3D.h
@@ -0,0 +1,169 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file DataSet3D.h
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef DataSet3D_h
+#define DataSet3D_h
+
+#include <PointerDefinitions.h>
+
+#include "basics/container/CbArray4D.h"
+#include "basics/container/CbArray3D.h"
+#include "DistributionArray3D.h"
+
+typedef CbArray4D<LBMReal,IndexerX4X3X2X1> AverageValuesArray3D;
+typedef CbArray4D<LBMReal,IndexerX4X3X2X1> ShearStressValuesArray3D;
+typedef CbArray3D<LBMReal, IndexerX3X2X1> RelaxationFactorArray3D;
+
+//! A class provides an interface for data structures in the kernel.
+class DataSet3D
+{
+public:
+   SPtr<DistributionArray3D> getFdistributions() const;
+   void setFdistributions(SPtr<DistributionArray3D> distributions);
+
+   SPtr<AverageValuesArray3D> getAverageDensity() const;
+   void setAverageDensity(SPtr<AverageValuesArray3D> values);
+
+   SPtr<AverageValuesArray3D> getAverageVelocity() const;
+   void setAverageVelocity(SPtr<AverageValuesArray3D> values);
+
+   SPtr<AverageValuesArray3D> getAverageFluctuations() const;
+   void setAverageFluctuations(SPtr<AverageValuesArray3D> values);
+
+   SPtr<AverageValuesArray3D> getAverageTriplecorrelations() const;
+   void setAverageTriplecorrelations(SPtr<AverageValuesArray3D> values);
+   
+   SPtr<AverageValuesArray3D> getAverageValues() const;
+   void setAverageValues(SPtr<AverageValuesArray3D> values);
+   
+   SPtr<ShearStressValuesArray3D> getShearStressValues() const;
+   void setShearStressValues(SPtr<ShearStressValuesArray3D> values);
+
+   SPtr<RelaxationFactorArray3D> getRelaxationFactor() const;
+   void setRelaxationFactor(SPtr<RelaxationFactorArray3D> values);
+protected:
+private:
+   SPtr<DistributionArray3D> fdistributions;
+   SPtr<AverageValuesArray3D> averageValues;
+
+   SPtr<AverageValuesArray3D> averageDensity;
+   SPtr<AverageValuesArray3D> averageVelocity;
+   SPtr<AverageValuesArray3D> averageFluktuations;
+   SPtr<AverageValuesArray3D> averageTriplecorrelations;
+
+   SPtr<ShearStressValuesArray3D> shearStressValues;
+
+   SPtr<RelaxationFactorArray3D> relaxationFactor;
+
+};
+
+inline SPtr<DistributionArray3D> DataSet3D::getFdistributions() const
+{ 
+   return fdistributions; 
+}
+
+inline void DataSet3D::setFdistributions(SPtr<DistributionArray3D> distributions)
+{ 
+   fdistributions = distributions; 
+}
+
+inline SPtr<AverageValuesArray3D> DataSet3D::getAverageValues() const
+{ 
+   return averageValues; 
+}
+
+inline void DataSet3D::setAverageValues(SPtr<AverageValuesArray3D> values)
+{ 
+   averageValues = values; 
+}
+
+inline SPtr<AverageValuesArray3D> DataSet3D::getAverageDensity() const
+{
+   return averageDensity;
+}
+
+inline void DataSet3D::setAverageDensity(SPtr<AverageValuesArray3D> values)
+{
+   averageDensity = values;
+}
+
+inline SPtr<AverageValuesArray3D> DataSet3D::getAverageVelocity() const
+{
+   return averageVelocity;
+}
+
+inline void DataSet3D::setAverageVelocity(SPtr<AverageValuesArray3D> values)
+{
+   averageVelocity = values;
+}
+
+inline SPtr<AverageValuesArray3D> DataSet3D::getAverageFluctuations() const
+{
+   return averageFluktuations;
+}
+
+inline void DataSet3D::setAverageFluctuations(SPtr<AverageValuesArray3D> values)
+{
+   averageFluktuations = values;
+}
+
+inline SPtr<AverageValuesArray3D> DataSet3D::getAverageTriplecorrelations() const
+{
+   return averageTriplecorrelations;
+}
+
+inline void DataSet3D::setAverageTriplecorrelations(SPtr<AverageValuesArray3D> values)
+{
+   averageTriplecorrelations = values;
+}
+
+inline SPtr<ShearStressValuesArray3D> DataSet3D::getShearStressValues() const
+{ 
+   return shearStressValues; 
+}
+
+inline void DataSet3D::setShearStressValues(SPtr<ShearStressValuesArray3D> values)
+{ 
+   shearStressValues = values; 
+}
+
+inline SPtr<RelaxationFactorArray3D> DataSet3D::getRelaxationFactor() const
+{
+   return relaxationFactor;
+}
+
+inline void DataSet3D::setRelaxationFactor(SPtr<RelaxationFactorArray3D> values)
+{
+   relaxationFactor = values;
+}
+#endif
diff --git a/VirtualFluidsCore/Data/DistributionArray3D.h b/VirtualFluidsCore/Data/DistributionArray3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e333b5046d73b2aee355e7657725acfbe8cb336
--- /dev/null
+++ b/VirtualFluidsCore/Data/DistributionArray3D.h
@@ -0,0 +1,92 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file DistributionArray3D.h
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef DistributionArray3D_H
+#define DistributionArray3D_H
+
+#include <LBMSystem.h>
+
+//! \brief Abstract class of data structure for LBM
+class DistributionArray3D
+{
+public:
+   DistributionArray3D() {};
+   virtual ~DistributionArray3D(){};
+   //! get number of nodes for x1 direction
+   virtual size_t getNX1() const = 0;
+   //! get number of nodes for x2 direction
+   virtual size_t getNX2() const = 0;
+   //! get number of nodes for x3 direction
+   virtual size_t getNX3() const = 0;
+   //! get distribution
+   //! \param f distribution 
+   //! \param x1 coordinate x1
+   //! \param x2 coordinate x2
+   //! \param x3 coordinate x3
+   virtual void getDistribution(LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //! set distribution
+   //! \param f distribution 
+   //! \param x1 coordinate x1
+   //! \param x2 coordinate x2
+   //! \param x3 coordinate x3
+   virtual void setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //! get distribution in inverse order
+   //! \param f distribution 
+   //! \param x1 coordinate x1
+   //! \param x2 coordinate x2
+   //! \param x3 coordinate x3   
+   virtual void getDistributionInv( LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //! set distribution in inverse order
+   //! \param f distribution 
+   //! \param x1 coordinate x1
+   //! \param x1 coordinate x2
+   //! \param x1 coordinate x3   
+   virtual void setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //! set distribution in inverse order
+   //! \param f distribution 
+   //! \param x1 coordinate x1
+   //! \param x1 coordinate x2
+   //! \param x1 coordinate x3   
+   virtual void setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   virtual void setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction) = 0;
+   virtual LBMReal getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction) = 0;
+   virtual void setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   virtual void setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   virtual LBMReal getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction) = 0;
+   virtual void swap() = 0;
+protected:
+private:
+
+};
+
+#endif
diff --git a/VirtualFluidsCore/Data/EsoTwist3D.h b/VirtualFluidsCore/Data/EsoTwist3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b1178aaa33977751518a63011b2efe3e4202e1e
--- /dev/null
+++ b/VirtualFluidsCore/Data/EsoTwist3D.h
@@ -0,0 +1,84 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file EsoTwist3D.h
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef ESOTWIST3D_H
+#define ESOTWIST3D_H
+
+#include "DistributionArray3D.h"
+#include <LBMSystem.h>
+
+//! \brief Abstract class for implementation of Esoteric Twist method
+//! \details EsoTwist3D provide an interface for different implementations of Esoteric Twist method 
+//! <a href="https://doi.org/10.3390/computation5020019"><b>[ Geier et al., (2017), 10.3390/computation5020019]</b></a> 
+// Geier, M., & Schönherr, M. (2017). Esoteric twist: an efficient in-place streaming algorithmus for the lattice Boltzmann method on massively parallel hardware. Computation, 5(2), 19.
+
+class EsoTwist3D : public DistributionArray3D
+{
+public:
+   EsoTwist3D(){};
+   virtual ~EsoTwist3D(){};
+   //////////////////////////////////////////////////////////////////////////
+   virtual void swap() = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void getDistribution(LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistribution(const LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   ////////////////////////////////////////////////////////////////////////
+   virtual void getDistributionInv( LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInv(const LBMReal* const f, size_t x1, size_t x2, size_t x3) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   //virtual void getDistributionInvForDirection(LBMReal* const& f, const size_t& x1, const size_t& x2, const size_t& x3, const unsigned long int& direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionInvForDirection(size_t x1, size_t x2, size_t x3, int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(const LBMReal* const f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual void setDistributionInvForDirection(LBMReal f, size_t x1, size_t x2, size_t x3, unsigned long int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual LBMReal getDistributionForDirection(size_t x1, size_t x2, size_t x3, int direction) = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual size_t getNX1() const = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual size_t getNX2() const = 0;
+   //////////////////////////////////////////////////////////////////////////
+   virtual size_t getNX3() const = 0;
+   //////////////////////////////////////////////////////////////////////////
+  
+};
+
+#endif
diff --git a/VirtualFluidsCore/Data/EsoTwistD3Q27System.cpp b/VirtualFluidsCore/Data/EsoTwistD3Q27System.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5924dc2f93445ea7c6e748169d17fc3671404640
--- /dev/null
+++ b/VirtualFluidsCore/Data/EsoTwistD3Q27System.cpp
@@ -0,0 +1,125 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file EsoTwistD3Q27System.cpp
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "EsoTwistD3Q27System.h"
+
+//index                                                              0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  
+//f:                                                                 E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW REST
+const int EsoTwistD3Q27System::ETX1[EsoTwistD3Q27System::ENDF+1] = { 0,  1,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0 };
+const int EsoTwistD3Q27System::ETX2[EsoTwistD3Q27System::ENDF+1] = { 0,  0,  0,  1,  0,  0,  0,  1,  0, -1,  0,  0,  0,  0,  0,  1, -1,  0,  0, -1,  0,  1,  0, -1,  0,  1,  0 };
+const int EsoTwistD3Q27System::ETX3[EsoTwistD3Q27System::ENDF+1] = { 0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  1,  0, -1,  0,  1,  1,  0,  0, -1,  0, -1,  0,  1,  0,  1,  0 };
+
+const int EsoTwistD3Q27System::etINVDIR[EsoTwistD3Q27System::ENDF+1] = { D3Q27System::INV_E,   
+                                                                           D3Q27System::INV_W,  
+                                                                           D3Q27System::INV_N,  
+                                                                           D3Q27System::INV_S,  
+                                                                           D3Q27System::INV_T,  
+                                                                           D3Q27System::INV_B,  
+                                                                           D3Q27System::INV_NE, 
+                                                                           D3Q27System::INV_SW, 
+                                                                           D3Q27System::INV_SE, 
+                                                                           D3Q27System::INV_NW,
+                                                                           D3Q27System::INV_TE, 
+                                                                           D3Q27System::INV_BW, 
+                                                                           D3Q27System::INV_BE, 
+                                                                           D3Q27System::INV_TW, 
+                                                                           D3Q27System::INV_TN, 
+                                                                           D3Q27System::INV_BS, 
+                                                                           D3Q27System::INV_BN, 
+                                                                           D3Q27System::INV_TS, 
+                                                                           D3Q27System::INV_TNE,
+                                                                           D3Q27System::INV_TNW,
+                                                                           D3Q27System::INV_TSE,
+                                                                           D3Q27System::INV_TSW,
+                                                                           D3Q27System::INV_BNE,
+                                                                           D3Q27System::INV_BNW,
+                                                                           D3Q27System::INV_BSE,
+                                                                           D3Q27System::INV_BSW,
+                                                                           D3Q27System::REST};
+
+const unsigned long int EsoTwistD3Q27System::etDIR[EsoTwistD3Q27System::ENDF+1] = { etE,   
+                                                                                    etW,  
+                                                                                    etN,  
+                                                                                    etS,  
+                                                                                    etT,  
+                                                                                    etB,  
+                                                                                    etNE, 
+                                                                                    etSW, 
+                                                                                    etSE, 
+                                                                                    etNW,
+                                                                                    etTE, 
+                                                                                    etBW, 
+                                                                                    etBE, 
+                                                                                    etTW, 
+                                                                                    etTN, 
+                                                                                    etBS, 
+                                                                                    etBN, 
+                                                                                    etTS,
+                                                                                    etTNE,
+                                                                                    etTNW,
+                                                                                    etTSE,
+                                                                                    etTSW,
+                                                                                    etBNE,
+                                                                                    etBNW,
+                                                                                    etBSE,
+                                                                                    etBSW,
+                                                                                    etZERO};
+
+ const unsigned long int EsoTwistD3Q27System::etZERO = 1;/*f0 */
+ const unsigned long int EsoTwistD3Q27System::etE =  2;    /*f1 */
+ const unsigned long int EsoTwistD3Q27System::etW =  4;    /*f2 */
+ const unsigned long int EsoTwistD3Q27System::etN =  8;    /*f3 */
+ const unsigned long int EsoTwistD3Q27System::etS =  16;   /*f4 */
+ const unsigned long int EsoTwistD3Q27System::etT =  32;    /*f5 */
+ const unsigned long int EsoTwistD3Q27System::etB =  64;   /*f6 */
+ const unsigned long int EsoTwistD3Q27System::etNE = 128;  /*f7 */
+ const unsigned long int EsoTwistD3Q27System::etSW = 256;  /*f8 */
+ const unsigned long int EsoTwistD3Q27System::etSE = 512;  /*f9 */
+ const unsigned long int EsoTwistD3Q27System::etNW = 1024;  /*f10*/
+ const unsigned long int EsoTwistD3Q27System::etTE = 2048;  /*f11*/
+ const unsigned long int EsoTwistD3Q27System::etBW = 4096;  /*f12*/
+ const unsigned long int EsoTwistD3Q27System::etBE = 8192;  /*f13*/
+ const unsigned long int EsoTwistD3Q27System::etTW = 16384;  /*f14*/
+ const unsigned long int EsoTwistD3Q27System::etTN = 32768;  /*f15*/
+ const unsigned long int EsoTwistD3Q27System::etBS = 65536;  /*f16*/
+ const unsigned long int EsoTwistD3Q27System::etBN = 131072;  /*f17*/
+ const unsigned long int EsoTwistD3Q27System::etTS = 262144;  /*f18*/
+ const unsigned long int EsoTwistD3Q27System::etTNE = 524288;
+ const unsigned long int EsoTwistD3Q27System::etTNW = 1048576;
+ const unsigned long int EsoTwistD3Q27System::etTSE = 2097152;
+ const unsigned long int EsoTwistD3Q27System::etTSW = 4194304;
+ const unsigned long int EsoTwistD3Q27System::etBNE = 8388608;
+ const unsigned long int EsoTwistD3Q27System::etBNW = 16777216;
+ const unsigned long int EsoTwistD3Q27System::etBSE = 33554432;
+const unsigned long int EsoTwistD3Q27System::etBSW = 67108864;
+
diff --git a/VirtualFluidsCore/Data/EsoTwistD3Q27System.h b/VirtualFluidsCore/Data/EsoTwistD3Q27System.h
new file mode 100644
index 0000000000000000000000000000000000000000..290abf4d06e843cc79b4597dc2d1e745bdd91f6d
--- /dev/null
+++ b/VirtualFluidsCore/Data/EsoTwistD3Q27System.h
@@ -0,0 +1,142 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file EsoTwistD3Q27System.h
+//! \ingroup Data
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef ESOTWISTD3Q27SYSTEM_H
+#define ESOTWISTD3Q27SYSTEM_H
+
+#include "D3Q27System.h"
+
+//! 
+struct EsoTwistD3Q27System
+{
+   const static int FSTARTDIR = D3Q27System::FSTARTDIR;
+   const static int FENDDIR   = D3Q27System::FENDDIR;   //gellerstyle: meint alle frichtungen OHNE f0
+
+   const static int STARTF    = D3Q27System::STARTF;
+   const static int ENDF  		= D3Q27System::ENDF;
+
+   const static int STARTDIR  = D3Q27System::STARTDIR;
+   const static int ENDDIR		= D3Q27System::ENDDIR;
+
+   static const int REST = D3Q27System::REST;/*f0 */
+   static const int E =  D3Q27System::E;    /*f1 */ 
+   static const int W =  D3Q27System::W;    /*f2 */ 
+   static const int N =  D3Q27System::N;    /*f3 */ 
+   static const int S =  D3Q27System::S;   /*f4 */ 
+   static const int T =  D3Q27System::T;    /*f5 */ 
+   static const int B =  D3Q27System::B;   /*f6 */ 
+   static const int NE = D3Q27System::NE;  /*f7 */ 
+   static const int SW = D3Q27System::SW;  /*f8 */ 
+   static const int SE = D3Q27System::SE;  /*f9 */ 
+   static const int NW = D3Q27System::NW;  /*f10*/ 
+   static const int TE = D3Q27System::TE;  /*f11*/ 
+   static const int BW = D3Q27System::BW;  /*f12*/ 
+   static const int BE = D3Q27System::BE;  /*f13*/ 
+   static const int TW = D3Q27System::TW;  /*f14*/ 
+   static const int TN = D3Q27System::TN;  /*f15*/ 
+   static const int BS = D3Q27System::BS;  /*f16*/ 
+   static const int BN = D3Q27System::BN;  /*f17*/ 
+   static const int TS = D3Q27System::TS;  /*f18*/ 
+   static const int TNE = D3Q27System::TNE;
+   static const int TNW = D3Q27System::TNW;
+   static const int TSE = D3Q27System::TSE;
+   static const int TSW = D3Q27System::TSW;
+   static const int BNE = D3Q27System::BNE;
+   static const int BNW = D3Q27System::BNW;
+   static const int BSE = D3Q27System::BSE;
+   static const int BSW = D3Q27System::BSW;
+ 
+
+   static const int INV_E   = D3Q27System::W;  
+   static const int INV_W   = D3Q27System::E;  
+   static const int INV_N   = D3Q27System::S;  
+   static const int INV_S   = D3Q27System::N;  
+   static const int INV_T   = D3Q27System::B;  
+   static const int INV_B   = D3Q27System::T;  
+   static const int INV_NE  = D3Q27System::SW; 
+   static const int INV_SW  = D3Q27System::NE; 
+   static const int INV_SE  = D3Q27System::NW; 
+   static const int INV_NW  = D3Q27System::SE; 
+   static const int INV_TE  = D3Q27System::BW; 
+   static const int INV_BW  = D3Q27System::TE; 
+   static const int INV_BE  = D3Q27System::TW; 
+   static const int INV_TW  = D3Q27System::BE; 
+   static const int INV_TN  = D3Q27System::BS; 
+   static const int INV_BS  = D3Q27System::TN; 
+   static const int INV_BN  = D3Q27System::TS; 
+   static const int INV_TS  = D3Q27System::BN; 
+   static const int INV_TNE = D3Q27System::BSW;
+   static const int INV_TNW = D3Q27System::BSE;
+   static const int INV_TSE = D3Q27System::BNW;
+   static const int INV_TSW = D3Q27System::BNE;
+   static const int INV_BNE = D3Q27System::TSW;
+   static const int INV_BNW = D3Q27System::TSE;
+   static const int INV_BSE = D3Q27System::TNW;
+   static const int INV_BSW = D3Q27System::TNE;
+
+   static const unsigned long int etZERO;// 1;/*f0 */
+   static const unsigned long int etE;//  2;    /*f1 */
+   static const unsigned long int etW;//  4;    /*f2 */
+   static const unsigned long int etN;//  8;    /*f3 */
+   static const unsigned long int etS;//  16;   /*f4 */
+   static const unsigned long int etT;//  32;    /*f5 */
+   static const unsigned long int etB;//  64;   /*f6 */
+   static const unsigned long int etNE;// 128;  /*f7 */
+   static const unsigned long int etSW;// 256;  /*f8 */
+   static const unsigned long int etSE;// 512;  /*f9 */
+   static const unsigned long int etNW;// 1024;  /*f10*/
+   static const unsigned long int etTE;// 2048;  /*f11*/
+   static const unsigned long int etBW;// 4096;  /*f12*/
+   static const unsigned long int etBE;// 8192;  /*f13*/
+   static const unsigned long int etTW;// 16384;  /*f14*/
+   static const unsigned long int etTN;// 32768;  /*f15*/
+   static const unsigned long int etBS;// 65536;  /*f16*/
+   static const unsigned long int etBN;// 131072;  /*f17*/
+   static const unsigned long int etTS;// 262144;  /*f18*/
+   static const unsigned long int etTNE;// 524288;
+   static const unsigned long int etTNW;// 1048576;
+   static const unsigned long int etTSE;// 2097152;
+   static const unsigned long int etTSW;// 4194304;
+   static const unsigned long int etBNE;// 8388608;
+   static const unsigned long int etBNW;// 16777216;
+   static const unsigned long int etBSE;// 33554432;
+   static const unsigned long int etBSW;// = 67108864;
+
+   const static int ETX1[ENDF+1];
+   const static int ETX2[ENDF+1];
+   const static int ETX3[ENDF+1];
+   const static int etINVDIR[ENDF+1]; 
+   const static unsigned long int etDIR[ENDF+1]; 
+};
+
+#endif
diff --git a/VirtualFluidsCore/Grid/BasicCalculator.cpp b/VirtualFluidsCore/Grid/BasicCalculator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a2ee9647cf9700cca5bb0e7139eb821d4eef19a
--- /dev/null
+++ b/VirtualFluidsCore/Grid/BasicCalculator.cpp
@@ -0,0 +1,400 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BasicCalculator.cpp
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "BasicCalculator.h"
+
+#include "Block3D.h"
+#include "BCProcessor.h"
+#include "LBMKernel.h"
+#include "Block3DConnector.h"
+#include "UbScheduler.h"
+#include "UbLogger.h"
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+#define OMP_SCHEDULE guided
+
+//#define TIMING
+//#include "UbTiming.h"
+
+BasicCalculator::BasicCalculator(SPtr<Grid3D> grid, SPtr<UbScheduler> additionalGhostLayerUpdateScheduler, int numberOfTimeSteps) : 
+   Calculator(grid, additionalGhostLayerUpdateScheduler, numberOfTimeSteps)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BasicCalculator::~BasicCalculator()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::calculate()
+{
+   UBLOG(logDEBUG1, "BasicCalculator::calculate() - started");
+   int calcStep = 0;
+   try
+   {
+      int minInitLevel = minLevel;
+      int maxInitLevel = maxLevel-minLevel;
+      int straightStartLevel = minInitLevel;
+      int internalIterations = 1<<(maxInitLevel-minInitLevel);
+      int forwardStartLevel;
+      int threshold;
+
+#ifdef TIMING
+      UbTimer timer;
+      double time[6];
+#endif
+
+      for (calcStep = startTimeStep; calcStep<=numberOfTimeSteps; calcStep++)
+      {
+         //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+         UBLOG(logINFO, "calcStep = "<<calcStep);
+#endif
+         //////////////////////////////////////////////////////////////////////////
+
+         for (int staggeredStep = 1; staggeredStep<=internalIterations; staggeredStep++)
+         {
+            forwardStartLevel = straightStartLevel;
+            if (staggeredStep==internalIterations) straightStartLevel = minInitLevel;
+            else
+            {
+               for (straightStartLevel = maxInitLevel, threshold = 1;
+                  (staggeredStep&threshold)!=threshold; straightStartLevel--, threshold <<= 1);
+            }
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            timer.resetAndStart();
+#endif
+            //////////////////////////////////////////////////////////////////////////
+            applyPreCollisionBC(straightStartLevel, maxInitLevel);
+
+            //do collision for all blocks
+            calculateBlocks(straightStartLevel, maxInitLevel, calcStep);
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[0] = timer.stop();
+            UBLOG(logINFO, "calculateBlocks time = "<<time[0]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+                        //////////////////////////////////////////////////////////////////////////
+                        //exchange data between blocks
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[1] = timer.stop();
+            UBLOG(logINFO, "exchangeBlockData time = "<<time[1]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+            applyPostCollisionBC(straightStartLevel, maxInitLevel);
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[2] = timer.stop();
+            UBLOG(logINFO, "applyBCs time = "<<time[2]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+            //swap distributions in kernel
+            swapDistributions(straightStartLevel, maxInitLevel);
+            //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+            time[3] = timer.stop();
+            UBLOG(logINFO, "swapDistributions time = "<<time[3]);
+#endif
+            //////////////////////////////////////////////////////////////////////////
+            if (refinement)
+            {
+               if (straightStartLevel<maxInitLevel)
+                  exchangeBlockData(straightStartLevel, maxInitLevel);
+               //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[4] = timer.stop();
+               UBLOG(logINFO, "refinement exchangeBlockData time = "<<time[4]);
+#endif
+               //////////////////////////////////////////////////////////////////////////
+               //now ghost nodes have actual values
+               //interpolation of interface nodes between grid levels
+               interpolation(straightStartLevel, maxInitLevel);
+               //////////////////////////////////////////////////////////////////////////
+#ifdef TIMING
+               time[5] = timer.stop();
+               UBLOG(logINFO, "refinement interpolation time = "<<time[5]);
+#endif
+               //////////////////////////////////////////////////////////////////////////
+            }
+         }
+         //exchange data between blocks for visualization
+         if (additionalGhostLayerUpdateScheduler->isDue(calcStep))
+         {
+            exchangeBlockData(straightStartLevel, maxInitLevel);
+         }
+         coProcess((double)(calcStep));
+         //now ghost nodes have actual values
+      }
+      UBLOG(logDEBUG1, "BasicCalculator::calculate() - stoped");
+   }
+   catch (std::exception& e)
+   {
+      UBLOG(logERROR, e.what());
+      UBLOG(logERROR, " step = "<<calcStep);
+      //throw;
+      exit(EXIT_FAILURE);
+   }
+   catch (std::string& s)
+   {
+      UBLOG(logERROR, s);
+      exit(EXIT_FAILURE);
+   }
+   catch (...)
+   {
+      UBLOG(logERROR, "unknown exception");
+      exit(EXIT_FAILURE);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::calculateBlocks(int startLevel, int maxInitLevel, int calcStep)
+{
+#ifdef _OPENMP
+#pragma omp parallel
+#endif
+   {
+      SPtr<Block3D> blockTemp;
+      try
+      {
+         //startLevel bis maxInitLevel
+         for (int level = startLevel; level<=maxInitLevel; level++)
+         {
+            //timer.resetAndStart();
+            //call LBM kernel
+            int size = (int)blocks[level].size();
+#ifdef _OPENMP
+#pragma omp for schedule(OMP_SCHEDULE)
+#endif
+            for (int i =0; i<size; i++)
+            {
+               blockTemp = blocks[level][i];
+               blockTemp->getKernel()->calculate(calcStep);
+            }
+            //timer.stop();
+            //UBLOG(logINFO, "level = " << level << " blocks = " << blocks[level].size() << " collision time = " << timer.getTotalTime());
+         }
+      }
+      catch (std::exception& e)
+      {
+         UBLOG(logERROR, e.what());
+         //UBLOG(logERROR, blockTemp->toString()<<" step = "<<calcStep);
+         //throw;
+         exit(EXIT_FAILURE);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::exchangeBlockData(int startLevel, int maxInitLevel)
+{
+   //startLevel bis maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      //connectorsPrepareLocal(localConns[level]);
+      connectorsSendLocal(localConns[level]);
+      //connectorsReceiveLocal(localConns[level]);
+
+      connectorsPrepareRemote(remoteConns[level]);
+      connectorsSendRemote(remoteConns[level]);
+      connectorsReceiveRemote(remoteConns[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::swapDistributions(int startLevel, int maxInitLevel)
+{
+#ifdef _OPENMP
+#pragma omp parallel
+#endif
+   {
+      //from startLevel to maxInitLevel
+      for (int level = startLevel; level<=maxInitLevel; level++)
+      {
+         int size = (int)blocks[level].size();
+#ifdef _OPENMP
+#pragma omp for schedule(OMP_SCHEDULE)
+#endif
+         for (int i =0; i<size; i++)
+         {
+            blocks[level][i]->getKernel()->swapDistributions();
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::connectorsPrepareLocal(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+#ifdef _OPENMP
+#pragma omp parallel for schedule(OMP_SCHEDULE)
+#endif
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->prepareForReceive();
+      connectors[i]->prepareForSend();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::connectorsSendLocal(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+#ifdef _OPENMP
+#pragma omp parallel for schedule(OMP_SCHEDULE)
+#endif
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->fillSendVectors();
+      connectors[i]->sendVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::connectorsReceiveLocal(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+#ifdef _OPENMP
+#pragma omp parallel for schedule(OMP_SCHEDULE)
+#endif
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->receiveVectors();
+      connectors[i]->distributeReceiveVectors();
+   }
+}
+void BasicCalculator::connectorsPrepareRemote(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->prepareForReceive();
+      connectors[i]->prepareForSend();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::connectorsSendRemote(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->fillSendVectors();
+      connectors[i]->sendVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::connectorsReceiveRemote(std::vector< SPtr<Block3DConnector> >& connectors)
+{
+   int size = (int)connectors.size();
+   for (int i =0; i<size; i++)
+   {
+      connectors[i]->receiveVectors();
+      connectors[i]->distributeReceiveVectors();
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::interpolation(int startLevel, int maxInitLevel)
+{
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsPrepareLocal(localInterConns[level]);
+      connectorsPrepareRemote(remoteInterConns[level]);
+   }
+
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsSendLocal(localInterConns[level]);
+      connectorsSendRemote(remoteInterConns[level]);
+   }
+
+   for (int level = startLevel; level<maxInitLevel; level++)
+   {
+      connectorsReceiveLocal(localInterConns[level]);
+      connectorsReceiveRemote(remoteInterConns[level]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::applyPreCollisionBC(int startLevel, int maxInitLevel)
+{
+   //from startLevel to maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      int size = (int)blocks[level].size();
+#ifdef _OPENMP
+#pragma omp parallel for schedule(OMP_SCHEDULE)
+#endif
+      for (int i =0; i<size; i++)
+      {
+         blocks[level][i]->getKernel()->getBCProcessor()->applyPreCollisionBC();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BasicCalculator::applyPostCollisionBC(int startLevel, int maxInitLevel)
+{
+   try{
+   //from startLevel to maxInitLevel
+   for (int level = startLevel; level<=maxInitLevel; level++)
+   {
+      int size = (int)blocks[level].size();
+#ifdef _OPENMP
+#pragma omp parallel for schedule(OMP_SCHEDULE)
+#endif
+      for (int i =0; i<size; i++)
+      {
+         blocks[level][i]->getKernel()->getBCProcessor()->applyPostCollisionBC();
+      }
+   }
+}
+   catch (std::exception& e)
+   {
+      UBLOG(logERROR, e.what());
+      //UBLOG(logERROR, " step = "<<calcStep);
+      //throw;
+      exit(EXIT_FAILURE);
+   }
+   catch (std::string& s)
+   {
+      UBLOG(logERROR, s);
+      //throw;
+      exit(EXIT_FAILURE);
+   }
+   catch (...)
+   {
+      UBLOG(logERROR, "unknown exception");
+      //throw;
+      exit(EXIT_FAILURE);
+   }
+}
+
diff --git a/VirtualFluidsCore/Grid/BasicCalculator.h b/VirtualFluidsCore/Grid/BasicCalculator.h
new file mode 100644
index 0000000000000000000000000000000000000000..8137a21c37d6972d40919bb7ae1cc45199edfc56
--- /dev/null
+++ b/VirtualFluidsCore/Grid/BasicCalculator.h
@@ -0,0 +1,70 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BasicCalculator.h
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BasicCalculator_h__
+#define BasicCalculator_h__
+
+#include "Calculator.h"
+
+class Block3DConnector;
+
+//! \class BasicCalculator 
+//! \brief Class implements basic functionality with OpenMP parallelization for main calculation LBM loop  
+
+class BasicCalculator : public Calculator
+{
+public:
+   BasicCalculator(SPtr<Grid3D> grid, SPtr<UbScheduler> additionalGhostLayerUpdateScheduler, int numberOfTimeSteps);
+   virtual ~BasicCalculator();
+   virtual void calculate();
+
+protected:
+   void calculateBlocks(int startLevel, int maxInitLevel, int calcStep);
+   void swapDistributions(int startLevel, int maxInitLevel);
+   void exchangeBlockData(int startLevel, int maxInitLevel);
+   void connectorsPrepareLocal(std::vector< SPtr<Block3DConnector> >& connectors);
+   void connectorsSendLocal(std::vector< SPtr<Block3DConnector> >& connectors);
+   void connectorsReceiveLocal(std::vector< SPtr<Block3DConnector> >& connectors);
+   void connectorsPrepareRemote(std::vector< SPtr<Block3DConnector> >& connectors);
+   void connectorsSendRemote(std::vector< SPtr<Block3DConnector> >& connectors);
+   void connectorsReceiveRemote(std::vector< SPtr<Block3DConnector> >& connectors);
+   void interpolation(int startLevel, int maxInitLevel);
+   void applyPreCollisionBC(int startLevel, int maxInitLevel);
+   void applyPostCollisionBC(int startLevel, int maxInitLevel);
+private:
+};
+
+#endif // BasicCalculator_h__
+
+
+
diff --git a/VirtualFluidsCore/Grid/Block3D.cpp b/VirtualFluidsCore/Grid/Block3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0aa676dc38a2438ff5ba500bf2c3d4bc4e901d0
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Block3D.cpp
@@ -0,0 +1,532 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Block3D.cpp
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "Block3D.h"
+
+#include "Grid3DSystem.h"
+#include "Block3DConnector.h"
+#include "LBMKernel.h"
+
+
+int Block3D::counter = 0;
+//////////////////////////////////////////////////////////////////////////
+Block3D::Block3D() : x1(0),x2(0),x3(0)
+                     ,active(true)
+                     ,globalID(-1)
+                     ,rank(-1),part(-1)
+                     ,interpolationFlagCF(0)
+                     ,interpolationFlagFC(0)
+                     ,level(-1)
+                     ,bundle(-1)
+                     ,lrank(-1)
+                     ,localID(-1)
+{
+}
+//////////////////////////////////////////////////////////////////////////
+Block3D::Block3D(int x1, int x2, int x3, int level)
+               : x1(x1), x2(x2), x3(x3)
+               ,active(true)
+               ,globalID(-1)
+               ,rank(0),part(0)
+               ,interpolationFlagCF(0)
+               ,interpolationFlagFC(0)
+               ,level(level)
+               ,bundle(0)
+               ,lrank(-1)
+               ,localID(-1)
+{
+   globalID = counter++;
+}
+//////////////////////////////////////////////////////////////////////////
+Block3D::~Block3D()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::operator==(const Block3D& src) const
+{
+   return (x1==src.x1 && x2==src.x2 && x3==src.x3); 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::operator!=(const Block3D& src) const
+{
+   return !(*this==src);
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getX1() const 
+{ 
+   return this->x1; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getX2() const 
+{ 
+   return this->x2; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getX3() const 
+{ 
+   return this->x3; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setActive(bool active) 
+{ 
+   this->active = active; 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::isActive()    const           
+{ 
+   return this->active;   
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::isNotActive() const           
+{ 
+   return(!this->active); 
+}
+//////////////////////////////////////////////////////////////////////////
+void  Block3D::setKernel(SPtr<LBMKernel> kernel) 
+{  
+   this->kernel = kernel; 
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<ILBMKernel> Block3D::getKernel() const              
+{  
+   return this->kernel; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::deleteKernel()             
+{  
+   this->kernel = SPtr<LBMKernel>(); 
+}
+//////////////////////////////////////////////////////////////////////////
+int  Block3D::getBundle() const          
+{ 
+   return bundle;       
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setBundle(int bundle) 
+{ 
+   this->bundle = bundle; 
+} 
+//////////////////////////////////////////////////////////////////////////
+void  Block3D::setRank(int rank) 
+{  
+   this->rank = rank; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getRank() const            
+{  
+   return this->rank; 
+}
+//////////////////////////////////////////////////////////////////////////
+void  Block3D::setLocalRank(int rank) 
+{  
+   this->lrank = rank; 
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getLocalRank() const            
+{  
+   return this->lrank; 
+}
+//////////////////////////////////////////////////////////////////////////
+int  Block3D::getGlobalID() const        
+{ 
+   return this->globalID; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setGlobalID(int id) 
+{ 
+   this->globalID = id; 
+}
+//////////////////////////////////////////////////////////////////////////
+int  Block3D::getLocalID() const        
+{ 
+   return this->localID; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setLocalID(int id) 
+{ 
+   this->localID = id; 
+}
+//////////////////////////////////////////////////////////////////////////
+int  Block3D::getPart() const        
+{ 
+   return this->part; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setPart(int part) 
+{ 
+   this->part = part; 
+}
+//////////////////////////////////////////////////////////////////////////
+int  Block3D::getLevel() const        
+{ 
+   return this->level; 
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setLevel(int level) 
+{ 
+   this->level = level; 
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3DConnector> Block3D::getConnector(int dir) const
+{ 
+   for(SPtr<Block3DConnector> c : connectors)
+   {
+      if( c ) 
+      {
+            if(c->getSendDir() == dir) return c;
+      }
+   }
+  return SPtr<Block3DConnector>();     
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setConnector(SPtr<Block3DConnector> connector)
+{
+   connectors.push_back(connector);
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::deleteConnectors()
+{
+   connectors.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasConnectors()
+{
+   for(SPtr<Block3DConnector> c : connectors)
+      if( c ) return true;
+   
+   return false;
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackSameLevelConnectors(  std::vector<SPtr<Block3DConnector>>& localSameLevelConnectors
+                                            , std::vector<SPtr<Block3DConnector>>& remoteSameLevelConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isLocalConnector() && !connector->isInterpolationConnectorCF() && !connector->isInterpolationConnectorFC() ) 
+            localSameLevelConnectors.push_back(this->connectors[i]);
+         else                                
+            remoteSameLevelConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackLocalSameLevelConnectors( std::vector<SPtr<Block3DConnector>>& localSameLevelConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isLocalConnector() && !connector->isInterpolationConnectorCF() && !connector->isInterpolationConnectorFC() ) 
+            localSameLevelConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackLocalSameLevelConnectors( std::vector<SPtr<Block3DConnector>>& localSameLevelConnectors, const int& dir)
+{
+   SPtr<Block3DConnector> connector = this->connectors[dir];
+   if( this->connectors[dir] )
+   {
+      if( connector->isLocalConnector() && !connector->isInterpolationConnectorCF() && !connector->isInterpolationConnectorFC() ) 
+         localSameLevelConnectors.push_back(this->connectors[dir]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackRemoteSameLevelConnectors( std::vector<SPtr<Block3DConnector>>& remoteSameLevelConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isRemoteConnector() && !connector->isInterpolationConnectorCF() && !connector->isInterpolationConnectorFC() ) 
+            remoteSameLevelConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackRemoteSameLevelConnectors( std::vector<SPtr<Block3DConnector>>& remoteSameLevelConnectors, const int& dir )
+{
+   SPtr<Block3DConnector> connector = this->connectors[dir];
+   if( this->connectors[dir] )
+   {
+      if( connector->isRemoteConnector() && !connector->isInterpolationConnectorCF() && !connector->isInterpolationConnectorFC() ) 
+         remoteSameLevelConnectors.push_back(this->connectors[dir]);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackLocalInterpolationConnectorsCF( std::vector<SPtr<Block3DConnector>>& localInterpolationConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isLocalConnector() && connector->isInterpolationConnectorCF() )
+            localInterpolationConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackRemoteInterpolationConnectorsCF( std::vector<SPtr<Block3DConnector>>& remoteInterpolationConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isRemoteConnector() && connector->isInterpolationConnectorCF() )
+            remoteInterpolationConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackLocalInterpolationConnectorsFC( std::vector<SPtr<Block3DConnector>>& localInterpolationConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isLocalConnector() && connector->isInterpolationConnectorFC() )
+            localInterpolationConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::pushBackRemoteInterpolationConnectorsFC( std::vector<SPtr<Block3DConnector>>& remoteInterpolationConnectors )
+{
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isRemoteConnector() && connector->isInterpolationConnectorFC() )
+            remoteInterpolationConnectors.push_back(this->connectors[i]);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getNumberOfLocalConnectors()
+{
+   int count = 0;
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isLocalConnector() ) count++;
+      }
+   }
+   return count;
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getNumberOfRemoteConnectors()
+{
+   int count = 0;
+   for(int i=0; i<(int)connectors.size(); i++)
+   {
+      SPtr<Block3DConnector> connector = this->connectors[i];
+      if( this->connectors[i] )
+      {
+         if( connector->isRemoteConnector() ) count++;
+      }
+   }
+   return count;
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getNumberOfLocalConnectorsForSurfaces()
+{
+   int count = 0;
+   
+   if(connectors.size() < 6)
+      return count;
+
+   for(int dir=0; dir<=5; dir++) //Hard coding. It works if you have 0...5 for E, N ... B 
+   {
+      SPtr<Block3DConnector> connector = this->connectors[dir];
+      if( this->connectors[dir] )
+      {
+         if( connector->isLocalConnector() ) count++;
+      }
+   }
+   return count;
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getNumberOfRemoteConnectorsForSurfaces()
+{
+   int count = 0;
+   for(int dir=0; dir<=5; dir++) //Hard coding. It works if you have 0...5 for E, N ... B 
+   {
+      SPtr<Block3DConnector> connector = this->connectors[dir];
+      if( this->connectors[dir] )
+      {
+         if( connector->isRemoteConnector() ) count++;
+      }
+   }
+   return count;
+}
+void Block3D::setCollectionOfInterpolationFlagCF(int flags)
+{
+   interpolationFlagCF = flags;
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setInterpolationFlagCF(int dir)
+{
+   UbSystem::setBit(interpolationFlagCF, 1<<dir);
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getCollectionOfInterpolationFlagCF()
+{
+   return interpolationFlagCF;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlagCF(int dir)
+{
+   return UbSystem::bitCheck( interpolationFlagCF, 1<<dir );
+}
+void Block3D::setCollectionOfInterpolationFlagFC(int flags)
+{
+   interpolationFlagFC = flags;
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setInterpolationFlagFC(int dir)
+{
+   UbSystem::setBit(interpolationFlagFC, 1<<dir);
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getCollectionOfInterpolationFlagFC()
+{
+   return interpolationFlagFC;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlagFC(int dir)
+{
+   return UbSystem::bitCheck( interpolationFlagFC, 1<<dir );
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlag()
+{ 
+   return(interpolationFlagCF!=0 || interpolationFlagFC!=0); 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlag(int direction)     
+{ 
+   return(hasInterpolationFlagCF(direction) || hasInterpolationFlagFC(direction)); 
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlagCF()
+{
+   return(interpolationFlagCF!=0);
+}
+//////////////////////////////////////////////////////////////////////////
+bool Block3D::hasInterpolationFlagFC()
+{
+   return(interpolationFlagFC!=0);
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::deleteInterpolationFlag()
+{
+   interpolationFlagFC = 0;
+   interpolationFlagCF = 0;
+}
+//////////////////////////////////////////////////////////////////////////
+std::string Block3D::toString() 
+{
+   std::stringstream ss;
+   ss<<"Block3D[(x1,x2,x3,level),";
+   ss<<" ("<<this->x1<<", "<<this->x2<<", "<<this->x3<<", "<<this->level<<"), id=" << globalID; 
+   ss<< ", active="<<this->active<< ", bundle="<<this->bundle<< ", rank="<<this->rank<<"]";
+   ss<<" connectors:";
+   for(std::size_t i=0; i<connectors.size(); i++)
+      if( connectors[i] )
+      {
+         if(connectors[i]->isLocalConnector())
+            ss <<"l."<< Grid3DSystem::getDirectionString(connectors[i]->getSendDir()) << ", ";
+         if(connectors[i]->isRemoteConnector())
+            ss <<"r."<< Grid3DSystem::getDirectionString(connectors[i]->getSendDir()) << ", ";
+         if(connectors[i]->isInterpolationConnectorCF())
+            ss <<"cf."<< Grid3DSystem::getDirectionString(connectors[i]->getSendDir()) << ", ";
+         if(connectors[i]->isInterpolationConnectorFC())
+            ss <<"fc."<< Grid3DSystem::getDirectionString(connectors[i]->getSendDir()) << ", ";
+      }
+   return ss.str();
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::setWeight( int rank, int weight )
+{
+   std::map<int, int>::iterator it;
+   if((it = this->weight.find(rank)) != this->weight.end())
+       it->second = weight;
+   else
+      this->weight.insert(std::make_pair(rank, weight));
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getWeight( int rank )
+{
+   std::map<int, int>::iterator it;
+   if((it = this->weight.find(rank)) != this->weight.end())
+      return it->second;
+   else
+      return 0;
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::addWeight( int rank, int weight )
+{
+   int weight_old = getWeight(rank);
+   weight += weight_old;
+   setWeight(rank, weight);
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::addWeightForAll( int weight )
+{
+   typedef std::map<int, int> wMap;
+   for (wMap::value_type &w : this->weight)
+   {
+      w.second += weight;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Block3D::clearWeight()
+{
+   this->weight.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+int Block3D::getWeightSize()
+{
+   return static_cast<int>(this->weight.size());
+}
diff --git a/VirtualFluidsCore/Grid/Block3D.h b/VirtualFluidsCore/Grid/Block3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..a47c0c9df5e66d23292abee4bc4dc13b37c86d8b
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Block3D.h
@@ -0,0 +1,165 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Block3D.h
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BLOCK3D_H
+#define BLOCK3D_H
+
+#include <PointerDefinitions.h>
+#include <vector>
+#include <map>
+#include <string>
+
+class Block3DConnector;
+class LBMKernel;
+class ILBMKernel;
+
+//! A class implements a block structure
+class Block3D
+{
+public:
+   Block3D();
+   Block3D(int x1, int x2, int x3, int level);
+   virtual ~Block3D();
+   bool operator==(const Block3D& src) const;
+   bool operator!=(const Block3D& src) const;
+
+   int getX1() const;
+   int getX2() const;
+   int getX3() const;
+
+   void setActive(bool active);
+   bool isActive()    const;
+   bool isNotActive() const;
+
+   void setKernel(SPtr<LBMKernel> kernel);
+   SPtr<ILBMKernel> getKernel() const;
+   void deleteKernel();
+
+   void setBundle(int bundle);
+   int  getBundle() const;
+
+   void setRank(int rank);
+   int  getRank() const;
+
+   void setLocalRank(int rank);
+   int  getLocalRank() const;
+
+   int  getGlobalID() const;
+   void setGlobalID(int id);
+
+   int  getLocalID() const;
+   void setLocalID(int id);
+
+   int  getPart() const;
+   void setPart(int part);
+
+   int  getLevel() const;
+   void setLevel(int level);
+
+   //Connector-Section
+   void                 setConnector(SPtr<Block3DConnector> connector);
+   SPtr<Block3DConnector>  getConnector(int dir) const;
+   bool                 hasConnectors();
+   void                 deleteConnectors();
+   void pushBackSameLevelConnectors(  std::vector<SPtr<Block3DConnector> >& localSameLevelConnectors
+                                    , std::vector<SPtr<Block3DConnector> >& remoteSameLevelConnectors );
+   void pushBackLocalSameLevelConnectors( std::vector<SPtr<Block3DConnector> >& localSameLevelConnectors );
+   void pushBackRemoteSameLevelConnectors( std::vector<SPtr<Block3DConnector> >& remoteSameLevelConnectors );
+   void pushBackLocalInterpolationConnectorsCF( std::vector<SPtr<Block3DConnector> >& localInterpolationConnectors );
+   void pushBackRemoteInterpolationConnectorsCF( std::vector<SPtr<Block3DConnector> >& remoteInterpolationConnectors );
+   void pushBackLocalInterpolationConnectorsFC( std::vector<SPtr<Block3DConnector> >& localInterpolationConnectors );
+   void pushBackRemoteInterpolationConnectorsFC( std::vector<SPtr<Block3DConnector> >& remoteInterpolationConnectors );
+   void pushBackLocalSameLevelConnectors( std::vector<SPtr<Block3DConnector> >& localSameLevelConnectors, const int& dir);
+   void pushBackRemoteSameLevelConnectors( std::vector<SPtr<Block3DConnector> >& remoteSameLevelConnectors, const int& dir );
+   int getNumberOfLocalConnectors();
+   int getNumberOfRemoteConnectors();
+   int getNumberOfLocalConnectorsForSurfaces();
+   int getNumberOfRemoteConnectorsForSurfaces();
+
+   void setWeight(int rank, int weight);
+   int  getWeight(int rank);
+   void addWeightForAll(int weight);
+   void addWeight(int rank, int weight);
+   void clearWeight();
+   int  getWeightSize();
+
+   //interpolation
+   bool hasInterpolationFlag();
+   bool hasInterpolationFlag(int dir);
+   void deleteInterpolationFlag();
+
+   int  getCollectionOfInterpolationFlagCF();
+   void setCollectionOfInterpolationFlagCF(int flags);
+   
+   void setInterpolationFlagCF(int dir);
+   bool hasInterpolationFlagCF(int dir);
+   bool hasInterpolationFlagCF();
+
+   int  getCollectionOfInterpolationFlagFC();
+   void setCollectionOfInterpolationFlagFC(int flags);
+   
+   void setInterpolationFlagFC(int dir);
+   bool hasInterpolationFlagFC(int dir);
+   bool hasInterpolationFlagFC();
+
+   std::string toString() ;
+
+   static int getMaxGlobalID() { return counter; }
+   static void setMaxGlobalID(int c) { counter = 0; }
+
+private:
+  int   x1;
+  int   x2;
+  int   x3;
+
+  bool active;
+
+  int interpolationFlagCF;
+  int interpolationFlagFC;
+
+  SPtr<LBMKernel> kernel;
+  std::vector<SPtr<Block3DConnector> > connectors;
+  std::map<int, int> weight;
+
+  int bundle;
+  int rank;
+  int lrank;
+  int globalID;
+  int localID;
+  int part;
+  int level;
+  static int counter;
+
+};
+
+#endif  //BLOCK3D_H
diff --git a/VirtualFluidsCore/Grid/CMakePackage.txt b/VirtualFluidsCore/Grid/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Grid/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Grid/Calculator.cpp b/VirtualFluidsCore/Grid/Calculator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bdd85a797731ceb51532ef4e43fb23c4e46f0f94
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Calculator.cpp
@@ -0,0 +1,248 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Calculator.cpp
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "Calculator.h"
+
+#include "Grid3D.h"
+#include "Block3DConnector.h"
+#include "Block3D.h"
+#include "UbScheduler.h"
+#include "CoProcessor.h"
+
+#include <basics/utilities/UbException.h>
+
+Calculator::Calculator(SPtr<Grid3D> grid, SPtr<UbScheduler> additionalGhostLayerUpdateScheduler, int numberOfTimeSteps) :
+   grid(grid),
+   additionalGhostLayerUpdateScheduler(additionalGhostLayerUpdateScheduler),
+   numberOfTimeSteps(numberOfTimeSteps)
+{
+   this->grid = grid;
+   startTimeStep = int(grid->getTimeStep())+1;
+   minLevel = grid->getCoarsestInitializedLevel();
+   maxLevel = grid->getFinestInitializedLevel();
+   if (maxLevel > 0)
+      refinement = true;
+   else
+      refinement = false;
+   blocks.resize(maxLevel+1);
+   localConns.resize(maxLevel+1);
+   remoteConns.resize(maxLevel+1);
+   localInterConns.resize(maxLevel);
+   remoteInterConns.resize(maxLevel);
+
+   int gridRank = grid->getRank();
+
+   for (int level = minLevel; level <= maxLevel; level++)
+   {
+      std::vector<SPtr<Block3D>> blockVector;
+      grid->getBlocks(level, gridRank, true, blockVector);
+      for (SPtr<Block3D> const block : blockVector)
+         if (block)
+            blocks[block->getLevel()].push_back(block);
+   }
+
+   initLocalConnectors();
+   initRemoteConnectors();
+}
+//////////////////////////////////////////////////////////////////////////
+Calculator::~Calculator()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::addCoProcessor(SPtr<CoProcessor> coProcessor)
+{
+   coProcessors.push_back(coProcessor);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::coProcess(double step)
+{
+   for (SPtr<CoProcessor> cp : coProcessors)
+   {
+      cp->process(step);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initLocalConnectors()
+{
+   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - start");
+
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      for(SPtr<Block3D> block : blocks[l])
+      {     
+         block->pushBackLocalSameLevelConnectors(localConns[l]);
+
+         if (l != maxLevel)
+            block->pushBackLocalInterpolationConnectorsCF(localInterConns[l]);
+      }
+      if (l != maxLevel)
+      {
+         for(SPtr<Block3D> block : blocks[l+1])
+         {     
+            block->pushBackLocalInterpolationConnectorsFC(localInterConns[l]);
+         }
+      }
+      UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localConns["<<l<<"])");
+      initConnectors(localConns[l]);
+
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initConnectors()-initConnectors(localInterConns["<<l<<"])");
+         initConnectors(localInterConns[l]);
+      }
+   }
+   
+   UBLOG(logDEBUG1, "Calculator::initLocalConnectors() - end");
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initRemoteConnectors()
+{
+   std::vector< std::vector< SPtr<Block3DConnector> > > remoteInterConnsCF;
+   std::vector< std::vector< SPtr<Block3DConnector> > > remoteInterConnsFC;
+   remoteInterConnsCF.resize(maxLevel+1);
+   remoteInterConnsFC.resize(maxLevel+1);
+
+   for(int l = minLevel; l<=maxLevel;l++)
+   {
+      std::vector<SPtr<Block3D>> blockVector;
+      //grid->getBlocks(level, gridRank, true, blockVector);
+      grid->getBlocks(l, blockVector);
+      for(SPtr<Block3D> block : blockVector)
+      {
+         int l = block->getLevel();
+         block->pushBackRemoteSameLevelConnectors(remoteConns[l]);
+
+         block->pushBackRemoteInterpolationConnectorsCF(remoteInterConnsCF[l]);
+         block->pushBackRemoteInterpolationConnectorsFC(remoteInterConnsFC[l]);
+      }
+   }
+
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteConns["<<l<<"])");
+      initConnectors(remoteConns[l]);
+      if (l != maxLevel)
+      {
+		 for(int i = 0; i < remoteInterConnsCF[l].size(); i++)
+			remoteInterConns[l].push_back(remoteInterConnsCF[l][i]);
+		 for(int i = 0; i < remoteInterConnsFC[l+1].size(); i++)
+	      remoteInterConns[l].push_back(remoteInterConnsFC[l+1][i]);
+      }
+   }
+   //////////////////////////////////////////////////////////////////////////
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-initConnectors(remoteInterConns["<<l<<"])");
+         for(SPtr<Block3DConnector> c : remoteInterConns[l] ) c->init();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
+   //////////////////////////////////////////////////////////////////////////
+   //sendTransmitterDataSize
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-sendTransmitterDataSize(remoteInterConns["<<l<<"])");
+         for(SPtr<Block3DConnector> c : remoteInterConns[l] ) c->sendTransmitterDataSize();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+   //receiveTransmitterDataSize
+   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
+   for (int l = minLevel; l <= maxLevel; l++)
+   {
+      if (l != maxLevel)
+      {
+         UBLOG(logDEBUG5, "Calculator::initRemoteConnectors()-receiveTransmitterDataSize(remoteInterConns["<<l<<"])");
+         for(SPtr<Block3DConnector> c : remoteInterConns[l] ) c->receiveTransmitterDataSize();
+      }
+   }
+   //UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::initConnectors(std::vector<SPtr<Block3DConnector>>& connectors)
+{
+   UBLOG(logDEBUG1, "Calculator::initConnectors() - start");
+
+   //initialization
+   //////////////////////////////////////////////////////////////////////////
+   //initialize connectors
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - start");
+   for(SPtr<Block3DConnector> c : connectors ) c->init();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - connectoren initialisieren - end");
+   //////////////////////////////////////////////////////////////////////////
+   //sendTransmitterDataSize
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - start");
+   for(SPtr<Block3DConnector> c : connectors ) c->sendTransmitterDataSize();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - sendTransmitterDataSize - end");
+   //////////////////////////////////////////////////////////////////////////
+   //receiveTransmitterDataSize
+   //wenn er hier bei verteilten berechnungen stopped, dann ist vermutlich auf einer seite ein nicht aktiver block!!!
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - start");
+   for(SPtr<Block3DConnector> c : connectors ) c->receiveTransmitterDataSize();
+   UBLOG(logDEBUG5, "Calculator::initConnectors() - receiveTransmitterDataSize - end");
+
+   UBLOG(logDEBUG1, "Calculator::initConnectors() - end");
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteBlocks()
+{
+   for(std::vector< SPtr<Block3D> > &bs : blocks)
+      bs.resize(0);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteConnectors()
+{
+   deleteConnectors(localConns);
+   deleteConnectors(remoteConns);
+
+   deleteConnectors(localInterConns);
+   deleteConnectors(remoteInterConns);
+}
+//////////////////////////////////////////////////////////////////////////
+void Calculator::deleteConnectors(std::vector< std::vector< SPtr<Block3DConnector> > >& conns)
+{
+   for(std::vector< SPtr<Block3DConnector> > &c : conns)
+      c.resize(0);
+}
+//////////////////////////////////////////////////////////////////////////
+
diff --git a/VirtualFluidsCore/Grid/Calculator.h b/VirtualFluidsCore/Grid/Calculator.h
new file mode 100644
index 0000000000000000000000000000000000000000..7816bdc587303ba81309f6cecf07857747079314
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Calculator.h
@@ -0,0 +1,90 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Calculator.h
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef CALCULATOR_H
+#define CALCULATOR_H
+
+#include <PointerDefinitions.h>
+#include <vector>
+
+class Grid3D;
+class UbScheduler;
+class Block3D;
+class Block3DConnector;
+class CoProcessor;
+
+//! \class Calculator 
+//! \brief A base class for main calculation loop  
+
+class Calculator 
+{
+public:
+   Calculator(SPtr<Grid3D> grid, SPtr<UbScheduler> additionalGhostLayerUpdateScheduler, int numberOfTimeSteps);
+   virtual ~Calculator();
+   //! control of coProcessors
+   void addCoProcessor(SPtr<CoProcessor> coProcessor);
+   void coProcess(double step);
+
+   virtual void calculate()=0;
+protected:
+   virtual void initLocalConnectors();
+   virtual void initRemoteConnectors();
+   void initConnectors(std::vector<SPtr<Block3DConnector> >& connectors);
+   void deleteBlocks();
+   void deleteConnectors();
+   void deleteConnectors(std::vector< std::vector< SPtr<Block3DConnector> > >& conns);
+
+   int minLevel, maxLevel;
+   int startTimeStep;
+   int numberOfTimeSteps;
+   std::vector< std::vector< SPtr<Block3DConnector> > > localConns;
+   std::vector< std::vector< SPtr<Block3DConnector> > > remoteConns;
+
+   bool refinement;
+   SPtr<Grid3D> grid;
+   SPtr<UbScheduler> additionalGhostLayerUpdateScheduler;
+   std::vector< std::vector<SPtr<Block3D> > > blocks;
+
+   //localInterConns and remoteInterConns save interpolation connectors 
+   //every element save CF connectors for current level and FC connectors for next level
+   //e.g. 
+   //localInterConns[0] = CF(0), FC(1)
+   //localInterConns[1] = CF(1), FC(2)
+   //localInterConns[2] 
+   std::vector< std::vector< SPtr<Block3DConnector> > > localInterConns;
+   std::vector< std::vector< SPtr<Block3DConnector> > > remoteInterConns;
+
+   std::vector< SPtr<CoProcessor> > coProcessors;
+};
+
+#endif
diff --git a/VirtualFluidsCore/Grid/Grid3D.cpp b/VirtualFluidsCore/Grid/Grid3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e62153933173d3fec14fdd70e7b1378c587316ff
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Grid3D.cpp
@@ -0,0 +1,2039 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Grid.cpp
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "Grid3D.h"
+
+#include <set>
+
+#include <geometry3d/CoordinateTransformation3D.h>
+#include <basics/writer/WbWriterVtkXmlASCII.h>
+
+#include "Grid3DVisitor.h"
+#include "Block3DVisitor.h"
+#include "Interactor3D.h"
+#include "Grid3DSystem.h"
+#include "LBMSystem.h"
+#include <Block3D.h>
+#include <Communicator.h>
+
+
+using namespace std;
+
+Grid3D::Grid3D() :
+   rank(0),
+   bundle(0),
+   orgDeltaX(1.0),
+   periodicX1(false),
+   periodicX2(false),
+   periodicX3(false),
+   timeStep(0.0),
+   blockNx1(0),
+   blockNx2(0),
+   blockNx3(0),
+   nx1(0),
+   nx2(0),
+   nx3(0)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Grid3D(SPtr<Communicator> comm) :
+   rank(0),
+   bundle(0),
+   orgDeltaX(1.0),
+   periodicX1(false),
+   periodicX2(false),
+   periodicX3(false),
+   timeStep(0.0),
+   blockNx1(0),
+   blockNx2(0),
+   blockNx3(0),
+   nx1(0),
+   nx2(0),
+   nx3(0)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+   rank = comm->getProcessID();
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Grid3D(SPtr<Communicator> comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3) :
+   rank(0),
+   bundle(0),
+   orgDeltaX(1.0),
+   periodicX1(false),
+   periodicX2(false),
+   periodicX3(false),
+   timeStep(0.0),
+   blockNx1(blockNx1),
+   blockNx2(blockNx2),
+   blockNx3(blockNx2),
+   nx1(gridNx1),
+   nx2(gridNx2),
+   nx3(gridNx3)
+{
+   levelSet.resize(Grid3DSystem::MAXLEVEL+1);
+   rank = comm->getProcessID();
+   trafo = SPtr<CoordinateTransformation3D>(new CoordinateTransformation3D(0.0, 0.0, 0.0, (double)blockNx1, (double)blockNx2, (double)blockNx3));
+   UbTupleInt3 minInd(0, 0, 0);
+   UbTupleInt3 maxInd(gridNx1, gridNx2, gridNx3);
+   this->fillExtentWithBlocks(minInd, maxInd);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addInteractor(SPtr<Interactor3D> interactor)
+{
+   interactors.push_back(interactor);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addAndInitInteractor(SPtr<Interactor3D> interactor, double timestep)
+{
+   interactors.push_back(interactor);
+   interactor->initInteractor(timestep);
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::Interactor3DSet Grid3D::getInteractors()
+{
+   return interactors;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(Block3DVisitor& blockVisitor)
+{
+   int startLevel   = blockVisitor.getStartLevel();
+   int stopLevel    = blockVisitor.getStopLevel();
+
+   if (startLevel < 0 || stopLevel < 0 || startLevel > Grid3DSystem::MAXLEVEL || stopLevel > Grid3DSystem::MAXLEVEL)
+      throw UbException(UB_EXARGS, "not valid level!");
+
+   bool dir     = startLevel < stopLevel;
+   if (dir) stopLevel += 1;
+   else stopLevel    -= 1;
+
+//#pragma omp parallel
+//   {
+//      for (int l = startLevel; l!=stopLevel;)
+//      {
+//         std::vector<SPtr<Block3D>> blockVector;
+//         getBlocks(l, blockVector);
+//         int sizeb = (int)blockVector.size();
+//
+//#pragma omp for
+//         for (int i = 0; i < sizeb; i++)
+//         {
+//            blockVisitor.visit(shared_from_this(), blockVector[i]);
+//         }
+//         if (dir)  l++;
+//         else     l--;
+//      }
+//   }
+   for(int l=startLevel; l!=stopLevel;)
+   {
+      std::vector<SPtr<Block3D>> blockVector;
+      getBlocks(l, blockVector);
+      for(SPtr<Block3D> b : blockVector)
+      {
+         blockVisitor.visit( shared_from_this(), b );
+      }
+      if(dir)  l++;
+      else     l--;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(Grid3DVisitor& gridVisitor)
+{
+   gridVisitor.visit(shared_from_this());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::accept(SPtr<Grid3DVisitor> gridVisitor)
+{
+   gridVisitor->visit(shared_from_this());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::addBlock(SPtr<Block3D> block)
+{
+   if (block)
+   {
+      this->blockIdMap.insert(std::make_pair(block->getGlobalID(), block));
+      int level = block->getLevel();
+      this->levelSet[level].insert(std::make_pair(Block3DKey(block->getX1(), block->getX2(), block->getX3()), block)).second;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::deleteBlock(SPtr<Block3D> block)
+{
+   return this->deleteBlock(block->getX1(), block->getX2(), block->getX3(), block->getLevel());
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::deleteBlock(int ix1, int ix2, int ix3, int level)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2, ix3, level);
+   if (block)
+   {
+      this->blockIdMap.erase(block->getGlobalID());
+      return this->levelSet[level].erase(Block3DKey(ix1, ix2, ix3)) > 0;
+   }
+   else
+   {
+      return false;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::replaceBlock(SPtr<Block3D> block)
+{
+   if (block)
+   {
+      this->deleteBlock(block);
+      this->addBlock(block);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::getBlock(int ix1, int ix2, int ix3, int level) const
+{
+   if (!this->hasLevel(level)) return SPtr<Block3D>();
+
+   int N1 = (nx1<<level);
+   int N2 = (nx2<<level);
+   int N3 = (nx3<<level);
+
+   if (!this->isPeriodicX1() && (ix1>N1-1  || ix1<0)) return SPtr<Block3D>();
+   else if (this->isPeriodicX1() && (ix1>=N1-1 || ix1<0)) { ix1=((ix1%N1)+N1)%N1; }
+   if (!this->isPeriodicX2() && (ix2>N2-1  || ix2<0)) return SPtr<Block3D>();
+   else if (this->isPeriodicX2() && (ix2>=N2-1 || ix2<0)) { ix2=((ix2%N2)+N2)%N2; }
+   if (!this->isPeriodicX3() && (ix3>N3-1  || ix3<0)) return SPtr<Block3D>();
+   else if (this->isPeriodicX3() && (ix3>=N3-1 || ix3<0)) { ix3=((ix3%N3)+N3)%N3; }
+
+   Block3DMap::const_iterator it;
+   it = levelSet[level].find(Block3DKey(ix1, ix2, ix3));
+   if (it == levelSet[level].end())
+      return SPtr<Block3D>();
+   else
+      return it->second;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::getBlock(int id) const
+{
+   BlockIDMap::const_iterator it;
+   if ((it=blockIdMap.find(id)) == blockIdMap.end())
+   {
+      return SPtr<Block3D>();
+   }
+
+   return it->second;
+}
+//////////////////////////////////////////////////////////////////////////
+Grid3D::BlockIDMap& Grid3D::getBlockIDs()
+{
+   return blockIdMap;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::getSuperBlock(SPtr<Block3D> block)
+{
+   int ix1 = block->getX1();
+   int ix2 = block->getX2();
+   int ix3 = block->getX3();
+   int level = block->getLevel();
+   return getSuperBlock(ix1, ix2, ix3, level);
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::getSuperBlock(int ix1, int ix2, int ix3, int level)
+{
+   if (!this->hasLevel(level)) return SPtr<Block3D>();
+   if (level <  1) throw UbException(UB_EXARGS, "level <1");
+
+   //from Lower Level to higher:	 >> 	1 in x1,x2,x3 
+   SPtr<Block3D> block;
+   for (int l=level-1; l>=0; l--)
+   {
+      ix1 = ix1 >> 1;
+      ix2 = ix2 >> 1;
+      ix3 = ix3 >> 1;
+
+      block = this->getBlock(ix1, ix2, ix3, l);
+      if (block) return block;
+   }
+   return SPtr<Block3D>();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocks(SPtr<Block3D> block, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   int ix1 = block->getX1();
+   int ix2 = block->getX2();
+   int ix3 = block->getX3();
+   int level = block->getLevel();
+   getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   if (!this->getBlock(ix1, ix2, ix3, level)) return;
+   if (level > 0 && !this->getSuperBlock(ix1, ix2, ix3, level)) return;
+   if (level >=  Grid3DSystem::MAXLEVEL)    throw UbException(UB_EXARGS, "Level bigger then MAXLEVEL");
+
+   int x1[] ={ ix1<<1, (ix1<<1)+1 };
+   int x2[] ={ ix2<<1, (ix2<<1)+1 };
+   int x3[] ={ ix3<<1, (ix3<<1)+1 };
+   int l    = level + 1;
+
+   for (int i=0; i<2; i++)
+      for (int j=0; j<2; j++)
+         for (int k=0; k<2; k++)
+         {
+            SPtr<Block3D> block = this->getBlock(x1[i], x2[j], x3[k], l);
+            if (block) blocks.push_back(block);
+            else if (l < levelDepth) this->getSubBlocks(x1[i], x2[j], x3[k], l, levelDepth, blocks);
+         }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::expandBlock(int ix1, int ix2, int ix3, int level)
+{
+   this->checkLevel(level);
+
+   SPtr<Block3D> block = this->getBlock(ix1, ix2, ix3, level);
+   if (!block)             throw UbException(UB_EXARGS, "block(x1="+UbSystem::toString(ix1)+", x2="+UbSystem::toString(ix2)+", x3="+UbSystem::toString(ix3)+", l="+UbSystem::toString(level)+") is not exist");
+
+   //da bei periodic der eigentliche block andere indizes hat:
+   ix1 = block->getX1();
+   ix2 = block->getX2();
+   ix3 = block->getX3();
+
+   int l      = level+1;
+   if (l>Grid3DSystem::MAXLEVEL) throw UbException(UB_EXARGS, "level > Grid3D::MAXLEVEL");
+
+   int west   = ix1<<1;
+   int east   = west+1;
+   int south  = ix2<<1;
+   int north  = south+1;
+   int bottom = ix3<<1;
+   int top    = bottom+1;
+
+   SPtr<Block3D> blockBSW = SPtr<Block3D>(new Block3D(west, south, bottom, l));
+   SPtr<Block3D> blockBSE = SPtr<Block3D>(new Block3D(east, south, bottom, l));
+   SPtr<Block3D> blockBNW = SPtr<Block3D>(new Block3D(west, north, bottom, l));
+   SPtr<Block3D> blockBNE = SPtr<Block3D>(new Block3D(east, north, bottom, l));
+   SPtr<Block3D> blockTSW = SPtr<Block3D>(new Block3D(west, south, top, l));
+   SPtr<Block3D> blockTSE = SPtr<Block3D>(new Block3D(east, south, top, l));
+   SPtr<Block3D> blockTNW = SPtr<Block3D>(new Block3D(west, north, top, l));
+   SPtr<Block3D> blockTNE = SPtr<Block3D>(new Block3D(east, north, top, l));
+
+   if (!this->deleteBlock(ix1, ix2, ix3, level))
+      throw UbException(UB_EXARGS, "could not delete block");
+
+   this->addBlock(blockBSW);
+   this->addBlock(blockBSE);
+   this->addBlock(blockBNW);
+   this->addBlock(blockBNE);
+   this->addBlock(blockTSW);
+   this->addBlock(blockTSE);
+   this->addBlock(blockTNW);
+   this->addBlock(blockTNE);
+
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth)
+{
+   using UbSystem::toString;
+
+   SPtr<Block3D> fblock = this->getBlock(fix1, fix2, fix3, flevel);
+   if (flevel <  1) throw UbException(UB_EXARGS, "level of block ("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is < 1");
+   if (!fblock)
+   {
+      throw UbException(UB_EXARGS, "specific block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") doesn't exists");
+   }
+   if (!fblock->isActive()) throw UbException(UB_EXARGS, "block("+toString(fix1)+","+toString(fix2)+","+toString(fix3)+","+toString(flevel)+") is not active");
+
+   //da bei periodic der eigentliche block andere indizes hat:
+   fix1 = fblock->getX1();
+   fix2 = fblock->getX2();
+   fix3 = fblock->getX3();
+
+   int cix1 = fblock->getX1() >> 1;
+   int cix2 = fblock->getX2() >> 1;
+   int cix3 = fblock->getX3() >> 1;
+
+   int fx1[2] ={ cix1<<1,  (cix1<<1)+1 };
+   int fx2[2] ={ cix2<<1,  (cix2<<1)+1 };
+   int fx3[2] ={ cix3<<1,  (cix3<<1)+1 };
+   int clevel = flevel - 1;
+
+   vector<SPtr<Block3D>> blocks;
+   for (int i=0; i<2; i++)
+      for (int k=0; k<2; k++)
+         for (int l=0; l<2; l++)
+         {
+            this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
+            while (!blocks.empty())
+            {
+               //man muss nur eine von den moeglichen acht "collapsen", die anderen werden
+               //dann (rekursiv) collapsed, da die schleife oben alle vier abfragt
+               this->collapseBlock(blocks[0]->getX1(), blocks[0]->getX2(), blocks[0]->getX3(), blocks[0]->getLevel(), levelDepth);
+               this->getSubBlocks(fx1[k], fx2[i], fx3[l], flevel, levelDepth, blocks);
+            }
+         }
+
+   vector<SPtr<Block3D>> fineBlocks(8);
+   /*BSW*/fineBlocks[0] = this->getBlock(fx1[0], fx2[0], fx3[0], flevel);
+   /*BSE*/fineBlocks[1] = this->getBlock(fx1[1], fx2[0], fx3[0], flevel);
+   /*BNE*/fineBlocks[2] = this->getBlock(fx1[1], fx2[1], fx3[0], flevel);
+   /*BNW*/fineBlocks[3] = this->getBlock(fx1[0], fx2[1], fx3[0], flevel);
+   /*TSW*/fineBlocks[4] = this->getBlock(fx1[0], fx2[0], fx3[1], flevel);
+   /*TSE*/fineBlocks[5] = this->getBlock(fx1[1], fx2[0], fx3[1], flevel);
+   /*TNE*/fineBlocks[6] = this->getBlock(fx1[1], fx2[1], fx3[1], flevel);
+   /*TNW*/fineBlocks[7] = this->getBlock(fx1[0], fx2[1], fx3[1], flevel);
+
+   SPtr<Block3D> cblock = SPtr<Block3D>(new Block3D(cix1, cix2, cix3, clevel));
+
+   for (int i=0; i<2; i++)
+      for (int k=0; k<2; k++)
+         for (int l=0; l<2; l++)
+            if (!this->deleteBlock(fx1[k], fx2[i], fx3[l], flevel))
+               throw UbException(UB_EXARGS, "could not delete block");
+
+   this->addBlock(cblock);
+
+   return cblock;
+}
+//////////////////////////////////////////////////////////////////////////
+// TODO: make visitor for this
+void Grid3D::deleteConnectors()
+{
+   for (Block3DMap blockMap : levelSet)
+   {
+      for (Block3DMap::value_type b : blockMap)
+      {
+         SPtr<Block3D> block =  b.second;
+         block->deleteConnectors();
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setRank(int rank)
+{
+   this->rank = rank;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getRank() const
+{
+   return rank;
+}
+//////////////////////////////////////////////////////////////////////////
+int  Grid3D::getBundle() const
+{
+   return bundle;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setBundle(int bundle)
+{
+   this->bundle = bundle;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX1() const
+{
+   return this->periodicX1;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX2() const
+{
+   return this->periodicX2;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::isPeriodicX3() const
+{
+   return this->periodicX3;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX1(bool value)
+{
+   this->periodicX1 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX2(bool value)
+{
+   this->periodicX2 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setPeriodicX3(bool value)
+{
+   this->periodicX3 = value;
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const
+{
+   if (!trafo)
+   {
+      return makeUbTuple((int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord);
+   }
+
+   return makeUbTuple((int)trafo->transformForwardToX1Coordinate(blockX1Coord, blockX2Coord, blockX3Coord)
+      , (int)trafo->transformForwardToX2Coordinate(blockX1Coord, blockX2Coord, blockX3Coord)
+      , (int)trafo->transformForwardToX3Coordinate(blockX1Coord, blockX2Coord, blockX3Coord));
+
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const
+{
+   if (!trafo)
+   {
+      return makeUbTuple((int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord);
+   }
+
+   double dx = getDeltaX(level);
+   double blockLentghX1, blockLentghX2, blockLentghX3;
+   blockLentghX1 = blockNx1*dx;
+   blockLentghX2 = blockNx2*dx;
+   blockLentghX3 = blockNx3*dx;
+   UbTupleDouble3 org = getBlockWorldCoordinates(0, 0, 0, 0);
+
+   SPtr<CoordinateTransformation3D> trafo_temp(new CoordinateTransformation3D(val<1>(org), val<2>(org), val<3>(org), blockLentghX1, blockLentghX2, blockLentghX3));
+
+   if (!trafo_temp)
+   {
+      return makeUbTuple((int)blockX1Coord, (int)blockX2Coord, (int)blockX3Coord);
+   }
+
+   return makeUbTuple((int)trafo_temp->transformForwardToX1Coordinate(blockX1Coord, blockX2Coord, blockX3Coord)
+      , (int)trafo_temp->transformForwardToX2Coordinate(blockX1Coord, blockX2Coord, blockX3Coord)
+      , (int)trafo_temp->transformForwardToX3Coordinate(blockX1Coord, blockX2Coord, blockX3Coord));
+
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3  Grid3D::getBlockLengths(const SPtr<Block3D> block) const
+{
+   int    level = block->getLevel();
+   double delta = 1.0/(double)(1<<level);
+
+   if (!trafo) makeUbTuple<double, double, double>(delta, delta, delta);
+
+   return makeUbTuple(trafo->getX1CoordinateScaling()*delta,
+      trafo->getX2CoordinateScaling()*delta,
+      trafo->getX3CoordinateScaling()*delta);
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble6 Grid3D::getBlockOversize() const
+{
+   return makeUbTuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setCoordinateTransformator(SPtr<CoordinateTransformation3D> trafo)
+{
+   this->trafo = trafo;
+}
+//////////////////////////////////////////////////////////////////////////
+const SPtr<CoordinateTransformation3D> Grid3D::getCoordinateTransformator() const
+{
+   return this->trafo;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setDeltaX(double dx)
+{
+   this->orgDeltaX = dx;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setDeltaX(double worldUnit, double gridUnit)
+{
+   this->orgDeltaX = worldUnit/gridUnit;
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getDeltaX(int level) const
+{
+   double delta = this->orgDeltaX/(double)(1<<level);
+   return delta;
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getDeltaX(SPtr<Block3D> block) const
+{
+   return getDeltaX(block->getLevel());
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3  Grid3D::getNodeOffset(SPtr<Block3D> block) const
+{
+   double delta = this->getDeltaX(block);
+   return makeUbTuple(OFFSET * delta, OFFSET * delta, OFFSET * delta);
+}
+////////////////////////////////////////////////////////////////////////////
+Vector3D Grid3D::getNodeCoordinates(SPtr<Block3D> block, int ix1, int ix2, int ix3) const
+{
+   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
+   double deltaX = getDeltaX(block);
+
+   double x1 = val<1>(org) - val<1>(nodeOffset) + (double)ix1*deltaX;
+   double x2 = val<2>(org) - val<2>(nodeOffset) + (double)ix2*deltaX;
+   double x3 = val<3>(org) - val<3>(nodeOffset) + (double)ix3*deltaX;
+
+   return Vector3D(x1, x2, x3);
+}
+////////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getNodeIndexes(SPtr<Block3D> block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const
+{
+   UbTupleDouble3 org = this->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = this->getNodeOffset(block);
+   double deltaX = getDeltaX(block);
+
+   int ix1, ix2, ix3;
+   double ixx1=(abs(nodeX1Coord - val<1>(org) + val<1>(nodeOffset)) / deltaX);
+   double ixx2=(abs(nodeX2Coord - val<2>(org) + val<2>(nodeOffset)) / deltaX);
+   double ixx3=(abs(nodeX3Coord - val<3>(org) + val<3>(nodeOffset)) / deltaX);
+   if (ixx1-(int)ixx1>.9999999999) ix1=(int)ixx1+1; else ix1=(int)ixx1;
+   if (ixx2-(int)ixx2>.9999999999) ix2=(int)ixx2+1; else ix2=(int)ixx2;
+   if (ixx3-(int)ixx3>.9999999999) ix3=(int)ixx3+1; else ix3=(int)ixx3;
+
+   return makeUbTuple(ix1, ix2, ix3);
+}
+//////////////////////////////////////////////////////////////////////////
+//returns tuple with origin of block in world-coordinates
+UbTupleDouble3 Grid3D::getBlockWorldCoordinates(SPtr<Block3D> block) const
+{
+   if (!block)
+      throw UbException(UB_EXARGS, "block " + block->toString() + "is not exist");
+
+   int blockX1Index = block->getX1();
+   int blockX2Index = block->getX2();
+   int blockX3Index = block->getX3();
+   int level = block->getLevel();
+
+   return this->getBlockWorldCoordinates(blockX1Index, blockX2Index, blockX3Index, level);
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleDouble3 Grid3D::getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const
+{
+   double c1oShiftedLevel = 1.0/(double)(1<<level);
+   double x1 = (double)blockX1Index*c1oShiftedLevel;
+   double x2 = (double)blockX2Index*c1oShiftedLevel;
+   double x3 = (double)blockX3Index*c1oShiftedLevel;
+
+   if (!trafo) return UbTupleDouble3(x1, x2, x3);
+
+   return UbTupleDouble3(trafo->transformBackwardToX1Coordinate(x1, x2, x3)
+      , trafo->transformBackwardToX2Coordinate(x1, x2, x3)
+      , trafo->transformBackwardToX3Coordinate(x1, x2, x3));
+}
+//////////////////////////////////////////////////////////////////////////
+//double Grid3D::getDeltaT(SPtr<Block3D> block) const 
+//{ 
+//   int    level = block->getLevel();
+//   double delta = 1.0/(double)(1<<level);
+//   return delta; 
+//}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::checkLevel(int level)
+{
+   if (level < 0)
+   {
+      throw UbException(UB_EXARGS, "l("+UbSystem::toString(level)+(string)")<0");
+   }
+   if (level > Grid3DSystem::MAXLEVEL)
+   {
+      throw UbException(UB_EXARGS, "l("+UbSystem::toString(level)+(string)")>MAXLEVEL");
+   }
+   if (this->levelSet[level].size() == 0)
+   {
+      throw UbException(UB_EXARGS, "levelMap for level("+UbSystem::toString(level)+(string)")==NULL");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Grid3D::hasLevel(int level) const
+{
+   if (level < 0) return false;
+   if (level > Grid3DSystem::MAXLEVEL) return false;
+   if (this->levelSet[level].size() == 0) return false;
+
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setBlockNX(int nx1, int nx2, int nx3)
+{
+   blockNx1 = nx1;
+   blockNx2 = nx2;
+   blockNx3 = nx3;
+}
+//////////////////////////////////////////////////////////////////////////
+UbTupleInt3 Grid3D::getBlockNX() const
+{
+   return makeUbTuple(blockNx1, blockNx2, blockNx3);
+}
+//////////////////////////////////////////////////////////////////////////
+
+SPtr<Block3D> Grid3D::getNeighborBlock(int dir, int ix1, int ix2, int ix3, int level) const
+{
+   return this->getBlock(ix1+Grid3DSystem::EX1[dir], ix2+Grid3DSystem::EX2[dir], ix3+Grid3DSystem::EX3[dir], level);
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> Grid3D::getNeighborBlock(int dir, SPtr<Block3D> block) const
+{
+   int x1 = block->getX1();
+   int x2 = block->getX2();
+   int x3 = block->getX3();
+   int level = block->getLevel();
+   return this->getNeighborBlock(dir, x1, x2, x3, level);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   for (int dir=Grid3DSystem::STARTDIR; dir<=Grid3DSystem::ENDDIR; dir++)
+      //for (int dir = Grid3DSystem::STARTDIR; dir<=Grid3DSystem::TS; dir++)
+   {
+      this->getNeighborBlocksForDirection(dir, ix1, ix2, ix3, level, levelDepth, blocks);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getAllNeighbors(SPtr<Block3D> block, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   int x1 = block->getX1();
+   int x2 = block->getX2();
+   int x3 = block->getX3();
+   getAllNeighbors(x1, x2, x3, level, levelDepth, blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+  /**
+   * Returns all direct northern neighbor cells of the specified grid cell (may be NULL!).
+   * @param ix1 index in x1 direction
+   * @param ix2 index in x2 direction
+   * @param ix3 index in x3 direction
+   * @param level the level
+   */
+void Grid3D::getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2+1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouth(ix1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottom(ix1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+
+   }
+   this->getSubBlocksTop(ix1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2-1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3, level);
+      if (block) { blocks.push_back(block); }
+
+   }
+   this->getSubBlocksNorth(ix1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksWest(ix1+1, ix2, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksEast(ix1-1, ix2, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals                                            
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2+1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouthWest(ix1+1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2+1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksSouthEast(ix1-1, ix2+1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2-1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksNorthWest(ix1+1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2-1, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksNorthEast(ix1-1, ix2-1, ix3, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals  top                                     
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomWest(ix1+1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomEast(ix1-1, ix2, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2+1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouth(ix1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2-1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorth(ix1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//   diagonals  bottom                                
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopWest(ix1+1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopEast(ix1-1, ix2, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2+1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2+1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouth(ix1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2-1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2-1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorth(ix1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2+1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouthWest(ix1+1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2+1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomSouthEast(ix1-1, ix2+1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2-1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorthWest(ix1+1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2-1, ix3+1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3+1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksBottomNorthEast(ix1-1, ix2-1, ix3+1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2+1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2+1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouthWest(ix1+1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2+1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2+1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopSouthEast(ix1-1, ix2+1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1+1, ix2-1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1+1, ix2-1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorthWest(ix1+1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1-1, ix2-1, ix3-1, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1-1, ix2-1, ix3-1, level);
+      if (block) { blocks.push_back(block); }
+   }
+   this->getSubBlocksTopNorthEast(ix1-1, ix2-1, ix3-1, level, blocks, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   switch (dir)
+   {
+   case Grid3DSystem::E: this->getNeighborsEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::W: this->getNeighborsWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::N: this->getNeighborsNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::S: this->getNeighborsSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::T: this->getNeighborsTop(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::B: this->getNeighborsBottom(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::NE: this->getNeighborsNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::SW: this->getNeighborsSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::SE: this->getNeighborsSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::NW: this->getNeighborsNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TE: this->getNeighborsTopEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BW: this->getNeighborsBottomWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BE: this->getNeighborsBottomEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TW: this->getNeighborsTopWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TN: this->getNeighborsTopNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BS: this->getNeighborsBottomSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BN: this->getNeighborsBottomNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TS: this->getNeighborsTopSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   default:throw UbException(UB_EXARGS, "direction "+UbSystem::toString(dir)+" is not exist");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   SPtr<Block3D> block = this->getBlock(ix1, ix2, ix3, level);
+   if (block) { blocks.push_back(block); }
+
+   if (level > 0)
+   {
+      block = this->getSuperBlock(ix1, ix2, ix3, level);
+      if (block) { blocks.push_back(block); }
+   }
+   // this->getSubBlocksNull(ix1, ix2, ix3, level, blocks, levelDepth);
+   this->getSubBlocks(ix1, ix2, ix3, level, levelDepth, blocks);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksZero(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1E  = (ix1 << 1) + 1;
+   int x1W  = (ix1 << 1);
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1E, x2S, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1E, x2S, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3T, l);
+   if (block != NULL)      blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1E, x2N, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2N, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1W, x2S, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2N, x3T, l);
+   if (block != NULL)      blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1W, x2N, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks)
+{
+   switch (dir)
+   {
+   case Grid3DSystem::E: this->getNeighborsEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::W: this->getNeighborsWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::N: this->getNeighborsNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::S: this->getNeighborsSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::T: this->getNeighborsTop(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::B: this->getNeighborsBottom(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::NE: this->getNeighborsNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::SW: this->getNeighborsSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::SE: this->getNeighborsSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::NW: this->getNeighborsNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TE: this->getNeighborsTopEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BW: this->getNeighborsBottomWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BE: this->getNeighborsBottomEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TW: this->getNeighborsTopWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TN: this->getNeighborsTopNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BS: this->getNeighborsBottomSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BN: this->getNeighborsBottomNorth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TS: this->getNeighborsTopSouth(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNE: this->getNeighborsTopNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TNW: this->getNeighborsTopNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSE: this->getNeighborsTopSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::TSW: this->getNeighborsTopSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNE: this->getNeighborsBottomNorthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BNW: this->getNeighborsBottomNorthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSE: this->getNeighborsBottomSouthEast(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::BSW: this->getNeighborsBottomSouthWest(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   case Grid3DSystem::REST: this->getNeighborsZero(ix1, ix2, ix3, level, levelDepth, blocks); break;
+   default:throw UbException(UB_EXARGS, "direction "+UbSystem::toString(dir)+" is not exist");
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksEast(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1, x2S, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1, x2S, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2N, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1, x2N, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2S, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1, x2S, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2N, x3T, l);
+   if (block != NULL)      blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksEast(x1, x2N, x3T, l, blockVector, levelDepth);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksWest(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1, x2S, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksWest(x1, x2S, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2N, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksWest(x1, x2N, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2S, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksWest(x1, x2S, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1, x2N, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksWest(x1, x2N, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2  = (ix2 << 1) + 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1W, x2, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2, x3B, l);
+   if (block != NULL)      blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksNorth(x1W, x2, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksNorth(x1E, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2  = ix2 << 1;
+   int x3B = ix3 << 1;
+   int x3T = x3B + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1W, x2, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2, x3B, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3B, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksSouth(x1W, x2, x3T, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2, x3T, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksSouth(x1E, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTop(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1) + 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1W, x2N, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksTop(x1W, x2N, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksTop(x1E, x2N, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksTop(x1W, x2S, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksTop(x1E, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottom(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>> &blockVector, int levelDepth)
+{
+   int x1W = ix1 << 1;
+   int x1E = x1W + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> block = this->getBlock(x1W, x2N, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksBottom(x1W, x2N, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2N, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksBottom(x1E, x2N, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1W, x2S, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksBottom(x1W, x2S, x3, l, blockVector, levelDepth);
+
+   block = this->getBlock(x1E, x2S, x3, l);
+   if (block != NULL)       blockVector.push_back(block);
+   else if (l < levelDepth) this->getSubBlocksBottom(x1E, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2  = (ix2 << 1) + 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockB = this->getBlock(x1, x2, x3B, l);
+   if (blockB) blockVector.push_back(blockB);
+   else if (l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3B, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockT = this->getBlock(x1, x2, x3T, l);
+   if (blockT) blockVector.push_back(blockT);
+   else if (l < levelDepth) this->getSubBlocksNorthEast(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1);
+   int x2  = (ix2 << 1) + 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockB = this->getBlock(x1, x2, x3B, l);
+   if (blockB) blockVector.push_back(blockB);
+   else if (l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3B, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockT = this->getBlock(x1, x2, x3T, l);
+   if (blockT) blockVector.push_back(blockT);
+   else if (l < levelDepth) this->getSubBlocksNorthWest(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2  = ix2 << 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockB = this->getBlock(x1, x2, x3B, l);
+   if (blockB) blockVector.push_back(blockB);
+   else if (l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3B, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockT = this->getBlock(x1, x2, x3T, l);
+   if (blockT) blockVector.push_back(blockT);
+   else if (l < levelDepth) this->getSubBlocksSouthWest(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2  = ix2 << 1;
+   int x3B = (ix3 << 1);
+   int x3T = x3B+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockB = this->getBlock(x1, x2, x3B, l);
+   if (blockB) blockVector.push_back(blockB);
+   else if (l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3B, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockT = this->getBlock(x1, x2, x3T, l);
+   if (blockT) blockVector.push_back(blockT);
+   else if (l < levelDepth) this->getSubBlocksSouthEast(x1, x2, x3T, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = (ix2 << 1);
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockN = this->getBlock(x1, x2N, x3, l);
+   if (blockN) blockVector.push_back(blockN);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockS = this->getBlock(x1, x2S, x3, l);
+   if (blockS) blockVector.push_back(blockS);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = ix1 << 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockN = this->getBlock(x1, x2N, x3, l);
+   if (blockN) blockVector.push_back(blockN);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockS = this->getBlock(x1, x2S, x3, l);
+   if (blockS) blockVector.push_back(blockS);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1) + 1;
+   int x2S = ix2 << 1;
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockN = this->getBlock(x1, x2N, x3, l);
+   if (blockN) blockVector.push_back(blockN);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockS = this->getBlock(x1, x2S, x3, l);
+   if (blockS) blockVector.push_back(blockS);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1  = (ix1 << 1);
+   int x2S = (ix2 << 1);
+   int x2N = x2S + 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockN = this->getBlock(x1, x2N, x3, l);
+   if (blockN) blockVector.push_back(blockN);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2N, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockS = this->getBlock(x1, x2S, x3, l);
+   if (blockS) blockVector.push_back(blockS);
+   else if (l < levelDepth) this->getSubBlocksTopEast(x1, x2S, x3, l, blockVector, levelDepth);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//  edge-diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1)+1;
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockE = this->getBlock(x1E, x2, x3, l);
+   if (blockE) blockVector.push_back(blockE);
+   else if (l < levelDepth) this->getSubBlocksTopNorth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockW = this->getBlock(x1W, x2, x3, l);
+   if (blockW) blockVector.push_back(blockW);
+   else if (l < levelDepth) this->getSubBlocksTopNorth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1);
+   int x3  = (ix3 << 1)+1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockE = this->getBlock(x1E, x2, x3, l);
+   if (blockE) blockVector.push_back(blockE);
+   else if (l < levelDepth) this->getSubBlocksTopSouth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockW = this->getBlock(x1W, x2, x3, l);
+   if (blockW) blockVector.push_back(blockW);
+   else if (l < levelDepth) this->getSubBlocksTopSouth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1E = ix1 << 1;
+   int x1W = x1E + 1;
+   int x2  = (ix2 << 1)+1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockE = this->getBlock(x1E, x2, x3, l);
+   if (blockE) blockVector.push_back(blockE);
+   else if (l < levelDepth) this->getSubBlocksBottomNorth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockW = this->getBlock(x1W, x2, x3, l);
+   if (blockW) blockVector.push_back(blockW);
+   else if (l < levelDepth) this->getSubBlocksBottomNorth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1E = (ix1 << 1);
+   int x1W = x1E + 1;
+   int x2  = ix2 << 1;
+   int x3  = ix3 << 1;
+   int l   = level + 1;
+
+   SPtr<Block3D> blockE = this->getBlock(x1E, x2, x3, l);
+   if (blockE) blockVector.push_back(blockE);
+   else if (l < levelDepth) this->getSubBlocksBottomSouth(x1E, x2, x3, l, blockVector, levelDepth);
+
+   SPtr<Block3D> blockW = this->getBlock(x1W, x2, x3, l);
+   if (blockW) blockVector.push_back(blockW);
+   else if (l < levelDepth) this->getSubBlocksBottomSouth(x1W, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+//  space-diagonals
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockTNE = this->getBlock(x1, x2, x3, l);
+   if (blockTNE) blockVector.push_back(blockTNE);
+   else if (l < levelDepth) this->getSubBlocksTopNorthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = ix1 << 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockTNW = this->getBlock(x1, x2, x3, l);
+   if (blockTNW) blockVector.push_back(blockTNW);
+   else if (l < levelDepth) this->getSubBlocksTopNorthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 =  ix2 << 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockTNW = this->getBlock(x1, x2, x3, l);
+   if (blockTNW) blockVector.push_back(blockTNW);
+   else if (l < levelDepth) this->getSubBlocksTopSouthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 =  ix1 << 1;
+   int x2 =  ix2 << 1;
+   int x3 = (ix3 << 1) + 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockTSW = this->getBlock(x1, x2, x3, l);
+   if (blockTSW) blockVector.push_back(blockTSW);
+   else if (l < levelDepth) this->getSubBlocksTopSouthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockBNE = this->getBlock(x1, x2, x3, l);
+   if (blockBNE) blockVector.push_back(blockBNE);
+   else if (l < levelDepth) this->getSubBlocksBottomNorthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 =  ix1 << 1;
+   int x2 = (ix2 << 1) + 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockBNW = this->getBlock(x1, x2, x3, l);
+   if (blockBNW) blockVector.push_back(blockBNW);
+   else if (l < levelDepth) this->getSubBlocksBottomNorthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = (ix1 << 1) + 1;
+   int x2 =  ix2 << 1;
+   int x3 =  ix3 << 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockBSE = this->getBlock(x1, x2, x3, l);
+   if (blockBSE) blockVector.push_back(blockBSE);
+   else if (l < levelDepth) this->getSubBlocksBottomSouthEast(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth)
+{
+   int x1 = ix1 << 1;
+   int x2 = ix2 << 1;
+   int x3 = ix3 << 1;
+   int l  = level + 1;
+
+   SPtr<Block3D> blockBSW = this->getBlock(x1, x2, x3, l);
+   if (blockBSW) blockVector.push_back(blockBSW);
+   else if (l < levelDepth) this->getSubBlocksBottomSouthWest(x1, x2, x3, l, blockVector, levelDepth);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, std::vector<SPtr<Block3D>>& blockVector)
+{
+   for (Block3DMap::value_type b : levelSet[level])
+   {
+      blockVector.push_back(b.second);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, int rank, std::vector<SPtr<Block3D>>& blockVector)
+{
+   for (Block3DMap::value_type b : levelSet[level])
+   {
+      SPtr<Block3D> block = b.second;
+      int blockRank = block->getRank();
+      if (blockRank == rank)
+      {
+         blockVector.push_back(b.second);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocks(int level, int rank, bool active, std::vector<SPtr<Block3D>>& blockVector)
+{
+   for (Block3DMap::value_type b : levelSet[level])
+   {
+      SPtr<Block3D> block = b.second;
+      int blockRank = block->getRank();
+
+      if (blockRank == rank && active ? block->isActive() : block->isNotActive())
+      {
+         blockVector.push_back(b.second);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getFinestInitializedLevel()
+{
+   for (int i=Grid3DSystem::MAXLEVEL; i>=0; i--) if (this->levelSet[i].size() > 0) return(i);
+   return(-1);
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getCoarsestInitializedLevel()
+{
+   for (int i=0; i<=Grid3DSystem::MAXLEVEL; i++) if (this->levelSet[i].size() > 0) return(i);
+   return(-1);
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX1(int nx1)
+{
+   this->nx1 = nx1;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX2(int nx2)
+{
+   this->nx2 = nx2;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setNX3(int nx3)
+{
+   this->nx3 = nx3;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX1() const
+{
+   return this->nx1;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX2() const
+{
+   return this->nx2;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNX3() const
+{
+   return this->nx3;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::deleteBlocks(const std::vector<int>& ids)
+{
+   for (int i : ids)
+   {
+      SPtr<Block3D> block = getBlock(i);
+      if (block) this->deleteBlock(block);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNumberOfBlocks()
+{
+   int c = 0;
+   for (Block3DMap l : levelSet)
+   {
+      c += (int)l.size();
+   }
+   return c;
+}
+//////////////////////////////////////////////////////////////////////////
+int Grid3D::getNumberOfBlocks(int level)
+{
+   return (int)levelSet[level].size();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocksByCuboid(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<SPtr<Block3D>>& blocks)
+{
+   int coarsestLevel = this->getCoarsestInitializedLevel();
+   int finestLevel   = this->getFinestInitializedLevel();
+
+   //////////////////////////////////////////////////////////////////////////
+   //MINIMALE BLOCK-INDIZES BESTIMMEN
+   //  
+   //min:
+   double dMinX1 = trafo->transformForwardToX1Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+   double dMinX2 = trafo->transformForwardToX2Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+   double dMinX3 = trafo->transformForwardToX3Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+
+   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden,
+   //da beim Transformieren der "groessere" Index rauskommt
+   int iMinX1 = (int)dMinX1; if (UbMath::zero(dMinX1-iMinX1)) iMinX1-=1;
+   int iMinX2 = (int)dMinX2; if (UbMath::zero(dMinX2-iMinX2)) iMinX2-=1;
+   int iMinX3 = (int)dMinX3; if (UbMath::zero(dMinX3-iMinX3)) iMinX3-=1;
+
+   //max (hier kann die Zusatzabfrage vernachlaessigt werden):
+   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+
+   SPtr<Block3D> block;
+
+   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
+   std::set<SPtr<Block3D>> blockset;
+   for (int level=coarsestLevel; level<=finestLevel; level++)
+   {
+      //damit bei negativen werten auch der "kleinere" genommen wird -> floor!
+      int minx1 = (int)std::floor((double)iMinX1/(1<<(finestLevel-level)));
+      int minx2 = (int)std::floor((double)iMinX2/(1<<(finestLevel-level)));
+      int minx3 = (int)std::floor((double)iMinX3/(1<<(finestLevel-level)));
+
+      int maxx1 = iMaxX1/(1<<(finestLevel-level));
+      int maxx2 = iMaxX2/(1<<(finestLevel-level));
+      int maxx3 = iMaxX3/(1<<(finestLevel-level));
+
+      for (int ix1=minx1; ix1<=maxx1; ix1++)
+         for (int ix2=minx2; ix2<=maxx2; ix2++)
+            for (int ix3=minx3; ix3<=maxx3; ix3++)
+               if ((block=this->getBlock(ix1, ix2, ix3, level)))
+               {
+                  if (block->getRank() == rank)
+                  {
+                     blockset.insert(block);
+                  }
+               }
+   }
+
+   blocks.resize(blockset.size());
+   std::copy(blockset.begin(), blockset.end(), blocks.begin());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getBlocksByCuboid(int level, double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<SPtr<Block3D>>& blocks)
+{
+   //////////////////////////////////////////////////////////////////////////
+   //MINIMALE BLOCK-INDIZES BESTIMMEN
+   //
+   //min:
+   double dMinX1 = trafo->transformForwardToX1Coordinate(minX1, minX2, minX3)*(1<<level);
+   double dMinX2 = trafo->transformForwardToX2Coordinate(minX1, minX2, minX3)*(1<<level);
+   double dMinX3 = trafo->transformForwardToX3Coordinate(minX1, minX2, minX3)*(1<<level);
+
+   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden:
+   int iMinX1 = (int)dMinX1; if (UbMath::zero(dMinX1-iMinX1)) iMinX1-=1;
+   int iMinX2 = (int)dMinX2; if (UbMath::zero(dMinX2-iMinX2)) iMinX2-=1;
+   int iMinX3 = (int)dMinX3; if (UbMath::zero(dMinX3-iMinX3)) iMinX3-=1;
+
+   //max:
+   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate(maxX1, maxX2, maxX3)*(1<<level));
+   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate(maxX1, maxX2, maxX3)*(1<<level));
+   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate(maxX1, maxX2, maxX3)*(1<<level));
+
+
+   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
+   std::set<SPtr<Block3D>> blockset;
+   SPtr<Block3D> block;
+
+   for (int ix1=iMinX1; ix1<=iMaxX1; ix1++)
+      for (int ix2=iMinX2; ix2<=iMaxX2; ix2++)
+         for (int ix3=iMinX3; ix3<=iMaxX3; ix3++)
+            if ((block=this->getBlock(ix1, ix2, ix3, level)))
+            {
+               if (block->getRank() == rank)
+               {
+                  blockset.insert(block);
+               }
+            }
+
+   blocks.resize(blockset.size());
+   std::copy(blockset.begin(), blockset.end(), blocks.begin());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::getAllBlocksByCuboid(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<SPtr<Block3D>>& blocks)
+{
+   int coarsestLevel = this->getCoarsestInitializedLevel();
+   int finestLevel   = this->getFinestInitializedLevel();
+
+   //////////////////////////////////////////////////////////////////////////
+   //MINIMALE BLOCK-INDIZES BESTIMMEN
+   //  
+   //min:
+   double dMinX1 = trafo->transformForwardToX1Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+   double dMinX2 = trafo->transformForwardToX2Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+   double dMinX3 = trafo->transformForwardToX3Coordinate(minX1, minX2, minX3)*(1<<finestLevel);
+
+   //Achtung, wenn minX1 genau auf grenze zwischen zwei bloecken -> der "kleinere" muss genommen werden,
+   //da beim Transformieren der "groessere" Index rauskommt
+   int iMinX1 = (int)dMinX1; if (UbMath::zero(dMinX1-iMinX1)) iMinX1-=1;
+   int iMinX2 = (int)dMinX2; if (UbMath::zero(dMinX2-iMinX2)) iMinX2-=1;
+   int iMinX3 = (int)dMinX3; if (UbMath::zero(dMinX3-iMinX3)) iMinX3-=1;
+
+   //max (hier kann die Zusatzabfrage vernachlaessigt werden):
+   int iMaxX1 = (int)(trafo->transformForwardToX1Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+   int iMaxX2 = (int)(trafo->transformForwardToX2Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+   int iMaxX3 = (int)(trafo->transformForwardToX3Coordinate(maxX1, maxX2, maxX3)*(1<<finestLevel));
+
+   SPtr<Block3D> block;
+
+   //set, um doppelte bloecke zu vermeiden, die u.U. bei periodic auftreten koennen
+   std::set<SPtr<Block3D>> blockset;
+   for (int level=coarsestLevel; level<=finestLevel; level++)
+   {
+      //damit bei negativen werten auch der "kleinere" genommen wird -> floor!
+      int minx1 = (int)std::floor((double)iMinX1/(1<<(finestLevel-level)));
+      int minx2 = (int)std::floor((double)iMinX2/(1<<(finestLevel-level)));
+      int minx3 = (int)std::floor((double)iMinX3/(1<<(finestLevel-level)));
+
+      int maxx1 = iMaxX1/(1<<(finestLevel-level));
+      int maxx2 = iMaxX2/(1<<(finestLevel-level));
+      int maxx3 = iMaxX3/(1<<(finestLevel-level));
+
+      for (int ix1=minx1; ix1<=maxx1; ix1++)
+         for (int ix2=minx2; ix2<=maxx2; ix2++)
+            for (int ix3=minx3; ix3<=maxx3; ix3++)
+               if ((block=this->getBlock(ix1, ix2, ix3, level)))
+               {
+                  if (block)
+                  {
+                     blockset.insert(block);
+                  }
+               }
+   }
+
+   blocks.resize(blockset.size());
+   std::copy(blockset.begin(), blockset.end(), blocks.begin());
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::calcStartCoordinatesAndDelta(SPtr<Block3D> block, double& worldX1, double& worldX2, double& worldX3, double& deltaX)
+{
+   int blocklevel  = block->getLevel();
+   worldX1  = block->getX1()/(float)(1<<blocklevel);
+   worldX2  = block->getX2()/(float)(1<<blocklevel);
+   worldX3  = block->getX3()/(float)(1<<blocklevel);
+   deltaX   = (double)1.0/(double)(this->blockNx1*(double)(1<<blocklevel));
+
+   if (this->trafo)
+   {
+      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
+      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
+      deltaX  = this->trafo->getX1CoordinateScaling()/(double)(this->blockNx1*(double)(1<<blocklevel));
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::calcStartCoordinatesWithOutOverlap(SPtr<Block3D> block, double& worldX1, double& worldX2, double& worldX3)
+{
+   int blocklevel  = block->getLevel();
+   worldX1  = block->getX1()/(float)(1<<blocklevel);
+   worldX2  = block->getX2()/(float)(1<<blocklevel);
+   worldX3  = block->getX3()/(float)(1<<blocklevel);
+
+   if (this->trafo)
+   {
+      double x1tmp = worldX1, x2tmp = worldX2, x3tmp = worldX3;
+      worldX1 = this->trafo->transformBackwardToX1Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX2 = this->trafo->transformBackwardToX2Coordinate(x1tmp, x2tmp, x3tmp);
+      worldX3 = this->trafo->transformBackwardToX3Coordinate(x1tmp, x2tmp, x3tmp);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::setTimeStep(double step)
+{
+   timeStep = step;
+}
+//////////////////////////////////////////////////////////////////////////
+double Grid3D::getTimeStep() const
+{
+   return timeStep;
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::fillExtentWithBlocks(UbTupleInt3 minInd, UbTupleInt3 maxInd)
+{
+   for (int x3 = val<3>(minInd); x3 < val<3>(maxInd); x3++)
+   {
+      for (int x2 = val<2>(minInd); x2 < val<2>(maxInd); x2++)
+      {
+         for (int x1 = val<1>(minInd); x1 < val<1>(maxInd); x1++)
+         {
+            SPtr<Block3D> block(new Block3D(x1, x2, x3, 0));
+            this->addBlock(block);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+//void Grid3D::notifyObservers( double step )
+//{
+//   for(ObserverPtr o, observers)
+//   {
+//      o->update(step);
+//   }
+//
+//   //std::list<ObserverWeakPtr>::iterator iter = observers.begin();
+//
+//   //GridObserversSet::iterator iter = observers.begin();
+//   //while(iter != observers.end())
+//   //{
+//   //   if ((*iter).expired())
+//   //   {
+//   //      iter = observers.erase(iter);
+//   //   }
+//   //   else
+//   //   {
+//   //      ObserverPtr observer = (*iter).lock(); // create a shared_ptr from the weak_ptr
+//   //      observer->update(step);
+//   //      ++iter;
+//   //   }
+//   //}
+//
+//}
+//////////////////////////////////////////////////////////////////////////
+//void Grid3D::addObserver( ObserverPtr observer )
+//{
+//   observers.insert(observer);
+//   //observers.push_back(observer);
+//}
+////////////////////////////////////////////////////////////////////////////
+//void Grid3D::removeObserver( ObserverPtr observer )
+//{
+//   observers.erase(observer);
+//   //observers.remove(observer);
+//}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::deleteBlockIDs()
+{
+   this->blockIdMap.clear();
+}
+//////////////////////////////////////////////////////////////////////////
+void Grid3D::renumberBlockIDs()
+{
+   deleteBlockIDs();
+
+   int startLevel = getCoarsestInitializedLevel();
+   int stopLevel = getFinestInitializedLevel();
+   int counter = 0;
+
+   for (int l = startLevel; l <= stopLevel; l++)
+   {
+      std::vector<SPtr<Block3D>> blockVector;
+      getBlocks(l, blockVector);
+      for (SPtr<Block3D> block : blockVector)
+      {
+         block->setGlobalID(counter);
+         blockIdMap.insert(std::make_pair(counter, block));
+         //Block3D::setMaxGlobalID(counter);
+         counter++;
+      }
+   }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+
diff --git a/VirtualFluidsCore/Grid/Grid3D.h b/VirtualFluidsCore/Grid/Grid3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..e392b90a077c6168914befbf52327698811c9a75
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Grid3D.h
@@ -0,0 +1,274 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Grid.h
+//! \ingroup Grid
+//! \author Konstantin Kutscher, Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+
+#ifndef GRID3D_H
+#define GRID3D_H
+
+
+#include <vector>
+#include <map>
+#include <PointerDefinitions.h>
+
+#include <basics/utilities/Vector3D.h>
+#include <basics/utilities/UbTuple.h>
+#include <basics/utilities/UbKeys.h>
+
+class CoordinateTransformation3D;
+
+#include <Block3DVisitor.h>
+#include <Grid3DVisitor.h>
+
+class Communicator;
+class Block3D;
+class Interactor3D;
+
+#define OFFSET 0.5
+
+//! A class implements block grid 
+//////////////////////////////////////////////////////////////////////////
+class Grid3D : public enableSharedFromThis<Grid3D>
+{
+public:
+   typedef UbKeys::Key3<int>                  Block3DKey;
+   typedef std::map< Block3DKey, SPtr<Block3D> > Block3DMap;
+   typedef std::map< int, SPtr<Block3D> >    BlockIDMap;
+   typedef std::vector<Block3DMap>        LevelSet;
+   typedef std::vector<SPtr<Interactor3D> >   Interactor3DSet;
+
+public:
+   Grid3D();
+   Grid3D(SPtr<Communicator> comm);
+   Grid3D(SPtr<Communicator> comm, int blockNx1, int blockNx2, int blockNx3, int gridNx1, int gridNx2, int gridNx3);
+   virtual ~Grid3D(){}
+   //////////////////////////////////////////////////////////////////////////
+   //blocks control
+   void addBlock(SPtr<Block3D> block);
+   bool deleteBlock(SPtr<Block3D> block);
+   bool deleteBlock(int ix1, int ix2, int ix3, int level);
+   void deleteBlocks(const std::vector<int>& ids);
+   void replaceBlock(SPtr<Block3D> block);
+   SPtr<Block3D> getBlock(int ix1, int ix2, int ix3, int level) const;
+   SPtr<Block3D> getBlock(int id) const;
+   void getBlocksByCuboid(double minX1, double minX2, double minX3, 
+                          double maxX1, double maxX2, double maxX3, 
+                          std::vector<SPtr<Block3D>>& blocks);
+   void getBlocksByCuboid(int level, double minX1, double minX2, double minX3, 
+                          double maxX1, double maxX2, double maxX3, 
+                          std::vector<SPtr<Block3D>>& blocks);
+   void getAllBlocksByCuboid(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, std::vector<SPtr<Block3D>>& blocks);
+   //!get blocks for level
+   void getBlocks(int level, std::vector<SPtr<Block3D>>& blockVector);
+   //!get blocks for level with current rank
+   void getBlocks(int level, int rank, std::vector<SPtr<Block3D>>& blockVector);
+   //!get only active or not active blocks 
+   void getBlocks(int level, int rank, bool active, std::vector<SPtr<Block3D>>& blockVector);
+   int getNumberOfBlocks();
+   int getNumberOfBlocks(int level);
+   BlockIDMap& getBlockIDs();
+   void deleteBlockIDs();
+   void renumberBlockIDs();
+   SPtr<Block3D> getSuperBlock(SPtr<Block3D> block);
+   SPtr<Block3D> getSuperBlock(int ix1, int ix2, int ix3, int level);
+   void getSubBlocks(SPtr<Block3D> block, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getSubBlocks(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blockVector);
+   SPtr<Block3D> getNeighborBlock(int dir, int ix1, int ix2, int ix3, int level) const;
+   SPtr<Block3D> getNeighborBlock(int dir, SPtr<Block3D> block) const;
+   bool expandBlock(int ix1, int ix2, int ix3, int level);
+   SPtr<Block3D> collapseBlock(int fix1, int fix2, int fix3, int flevel, int levelDepth);
+   void getAllNeighbors(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getAllNeighbors(SPtr<Block3D> block, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborBlocksForDirection(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborBlocksForDirectionWithDirZero(int dir, int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+
+   void getNeighborsZero(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTop(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottom(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+
+   void getNeighborsNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+
+   void getNeighborsTopNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+
+   void getNeighborsBottomNorth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomSouth(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+
+   void getNeighborsTopNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsTopSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomNorthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomNorthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomSouthEast(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   void getNeighborsBottomSouthWest(int ix1, int ix2, int ix3, int level, int levelDepth, std::vector<SPtr<Block3D>>& blocks);
+   //////////////////////////////////////////////////////////////////////////
+   //level control
+   int getFinestInitializedLevel();
+   int getCoarsestInitializedLevel();
+   //////////////////////////////////////////////////////////////////////////
+   void deleteConnectors();
+   //////////////////////////////////////////////////////////////////////////
+   //interactors control
+   void addInteractor(SPtr<Interactor3D> interactor);
+   void addAndInitInteractor(SPtr<Interactor3D> interactor, double timestep=0);
+   Interactor3DSet getInteractors();
+   //////////////////////////////////////////////////////////////////////////
+   //visitors
+   void accept(Block3DVisitor& blockVisitor);
+   void accept(Grid3DVisitor& gridVisitor);
+   void accept(SPtr<Grid3DVisitor> gridVisitor);
+   //////////////////////////////////////////////////////////////////////////
+   //bundle and rank for distributed memory
+   void setBundle(int bundle);
+   int  getBundle() const;
+   int  getRank() const;
+   void setRank(int rank);
+   //////////////////////////////////////////////////////////////////////////
+   //periodic boundary
+   bool isPeriodicX1() const;
+   bool isPeriodicX2() const;
+   bool isPeriodicX3() const;
+   void setPeriodicX1(bool value);
+   void setPeriodicX2(bool value);
+   void setPeriodicX3(bool value);
+   //////////////////////////////////////////////////////////////////////////
+   //Topology
+   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord)  const;
+   UbTupleInt3 getBlockIndexes(double blockX1Coord, double blockX2Coord, double blockX3Coord, int level)  const;
+   UbTupleDouble3 getBlockLengths(SPtr<Block3D> block) const;
+   UbTupleDouble6 getBlockOversize() const ;
+   void setCoordinateTransformator(SPtr<CoordinateTransformation3D>  trafo);
+   const SPtr<CoordinateTransformation3D>  getCoordinateTransformator() const ;
+   void setDeltaX(double dx);
+   void setDeltaX(double worldUnit, double gridUnit);
+   double getDeltaX(int level) const;
+   double getDeltaX(SPtr<Block3D> block) const;
+   UbTupleDouble3 getNodeOffset(SPtr<Block3D> block) const ;
+   Vector3D getNodeCoordinates(SPtr<Block3D> block, int ix1, int ix2, int ix3) const;
+   UbTupleInt3 getNodeIndexes(SPtr<Block3D> block, double nodeX1Coord, double nodeX2Coord, double nodeX3Coord) const;
+   void setBlockNX(int nx1, int nx2, int nx3);
+   UbTupleInt3 getBlockNX() const;
+   UbTupleDouble3 getBlockWorldCoordinates(SPtr<Block3D> block) const;
+   UbTupleDouble3 getBlockWorldCoordinates(int blockX1Index, int blockX2Index, int blockX3Index, int level) const;
+   void setNX1(int nx1);
+   void setNX2(int nx2);
+   void setNX3(int nx3);
+   int  getNX1() const;
+   int  getNX2() const;
+   int  getNX3() const;
+   void calcStartCoordinatesAndDelta(SPtr<Block3D> block, double& worldX1, double& worldX2, double& worldX3, double& deltaX);
+   void calcStartCoordinatesWithOutOverlap(SPtr<Block3D> block, double& worldX1, double& worldX2, double& worldX3);
+   //////////////////////////////////////////////////////////////////////////
+   //LBM
+   //double getDeltaT(SPtr<Block3D>) const;
+   //////////////////////////////////////////////////////////////////////////
+   void setTimeStep(double step);
+   double getTimeStep() const;
+
+protected:
+   void checkLevel(int level);
+   bool hasLevel(int level) const;
+
+   void fillExtentWithBlocks( UbTupleInt3 minInd, UbTupleInt3 maxInd );
+
+   void getSubBlocksZero(int ix1, int ix2, int ix3, int level,std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksSouth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTop(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottom(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksSouthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksSouthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksNorthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksTopEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopNorth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksBottomEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouth(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+   void getSubBlocksTopNorthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopNorthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksTopSouthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomNorthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouthEast(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+   void getSubBlocksBottomSouthWest(int ix1, int ix2, int ix3, int level, std::vector<SPtr<Block3D>>& blockVector, int levelDepth);
+
+private:
+   LevelSet levelSet;
+   BlockIDMap blockIdMap;
+   Interactor3DSet interactors;
+
+   int rank;
+   int bundle;
+   
+   bool periodicX1;
+   bool periodicX2;
+   bool periodicX3;
+
+   int blockNx1;    
+   int blockNx2;    
+   int blockNx3; 
+
+   int nx1;    
+   int nx2;    
+   int nx3;    
+
+   SPtr<CoordinateTransformation3D> trafo;
+   double orgDeltaX;
+
+   double timeStep;
+   
+};
+
+#endif 
diff --git a/VirtualFluidsCore/Grid/Grid3DSystem.cpp b/VirtualFluidsCore/Grid/Grid3DSystem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7363f263a9ddbb21968d86960df856e9cb0f6e1f
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Grid3DSystem.cpp
@@ -0,0 +1,81 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Grid3DSystem.cpp
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include <Grid3DSystem.h>
+
+namespace Grid3DSystem
+{
+   const int INVDIR[] = { INV_E  ,   
+                          INV_W  ,  
+                          INV_N  ,  
+                          INV_S  ,  
+                          INV_T  ,  
+                          INV_B  ,  
+                          INV_NE , 
+                          INV_NW , 
+                          INV_SE , 
+                          INV_SW ,
+                          INV_TE , 
+                          INV_TW , 
+                          INV_BE , 
+                          INV_BW , 
+                          INV_TN , 
+                          INV_TS , 
+                          INV_BN , 
+                          INV_BS , 
+                          INV_TNE,
+                          INV_TNW,
+                          INV_TSE,
+                          INV_TSW,
+                          INV_BNE,
+                          INV_BNW,
+                          INV_BSE,
+                          INV_BSW    };
+
+   //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
+   //direction:        E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+   const int EX1[] = { 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1 };
+   const int EX2[] = { 0, 0, 1, -1, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1 };
+   const int EX3[] = { 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1 };
+}
+
+//////////////////////////////////////////////////////////////////////////
+const int& Grid3DSystem::getInvertDirection(const int& direction)
+{  
+#ifdef _DEBUG
+   if(direction<STARTDIR || direction>ENDDIR) 
+      throw UbException(UB_EXARGS,"unknown direction");
+#endif
+   return INVDIR[direction];
+}
+
diff --git a/VirtualFluidsCore/Grid/Grid3DSystem.h b/VirtualFluidsCore/Grid/Grid3DSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbcb213162e0a16fa514ea41d7cb055ddd27dd4d
--- /dev/null
+++ b/VirtualFluidsCore/Grid/Grid3DSystem.h
@@ -0,0 +1,185 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Grid3DSystem.h
+//! \ingroup Grid
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef Grid3DSystem_H
+#define Grid3DSystem_H
+
+#include <cmath>
+#include <iostream>
+#include <string>
+
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbException.h>
+
+
+namespace Grid3DSystem
+{
+   static const int STARTDIR = 0;
+
+   static const int E    /*f1 */ = 0;
+   static const int W    /*f2 */ = 1;
+   static const int N    /*f3 */ = 2;
+   static const int S    /*f4 */ = 3;
+   static const int T    /*f5 */ = 4;
+   static const int B    /*f6 */ = 5;
+   static const int NE   /*f7 */ = 6;
+   static const int SW   /*f8 */ = 7;
+   static const int SE   /*f9 */ = 8;
+   static const int NW   /*f10*/ = 9;
+   static const int TE   /*f11*/ = 10;
+   static const int BW   /*f12*/ = 11;
+   static const int BE   /*f13*/ = 12;
+   static const int TW   /*f14*/ = 13;
+   static const int TN   /*f15*/ = 14;
+   static const int BS   /*f16*/ = 15;
+   static const int BN   /*f17*/ = 16;
+   static const int TS   /*f18*/ = 17;
+   static const int TNE          = 18;
+   static const int TNW          = 19;
+   static const int TSE          = 20;
+   static const int TSW          = 21;
+   static const int BNE          = 22;
+   static const int BNW          = 23;
+   static const int BSE          = 24;
+   static const int BSW          = 25;
+   static const int REST /*f0 */ = 26;
+
+   static const int ENDDIR = 25; 
+
+   static const int INV_E   = W;  
+   static const int INV_W   = E;  
+   static const int INV_N   = S;  
+   static const int INV_S   = N;  
+   static const int INV_T   = B;  
+   static const int INV_B   = T;  
+   static const int INV_NE  = SW; 
+   static const int INV_NW  = SE; 
+   static const int INV_SE  = NW; 
+   static const int INV_SW  = NE; 
+   static const int INV_TE  = BW; 
+   static const int INV_TW  = BE; 
+   static const int INV_BE  = TW; 
+   static const int INV_BW  = TE; 
+   static const int INV_TN  = BS; 
+   static const int INV_TS  = BN; 
+   static const int INV_BN  = TS; 
+   static const int INV_BS  = TN; 
+   static const int INV_TNE = BSW;
+   static const int INV_TNW = BSE;
+   static const int INV_TSE = BNW;
+   static const int INV_TSW = BNE;
+   static const int INV_BNE = TSW;
+   static const int INV_BNW = TSE;
+   static const int INV_BSE = TNW;
+   static const int INV_BSW = TNE;
+
+   extern const int INVDIR[ENDDIR+1];
+
+   static const int MAXLEVEL  = 25;
+
+   extern const int EX1[ENDDIR+1];
+   extern const int EX2[ENDDIR+1];
+   extern const int EX3[ENDDIR+1];
+
+   inline std::string getDirectionString(int direction)
+   {
+      switch(direction)
+      {
+      case E   : return "E"; 
+      case W   : return "W"; 
+      case N   : return "N"; 
+      case S   : return "S"; 
+      case T   : return "T";
+      case B   : return "B"; 
+      case NE  : return "NE";
+      case NW  : return "NW";
+      case SE  : return "SE";
+      case SW  : return "SW";
+      case TE  : return "TE";
+      case TW  : return "TW";
+      case BE  : return "BE";
+      case BW  : return "BW";
+      case TN  : return "TN";
+      case TS  : return "TS";
+      case BN  : return "BN";
+      case BS  : return "BS";
+      case TNE : return "TNE";
+      case TNW : return "TNW";
+      case TSE : return "TSE";
+      case TSW : return "TSW";
+      case BNE : return "BNE";
+      case BNW : return "BNW";
+      case BSE : return "BSE";
+      case BSW : return "BSW";
+      default  : return "Cell3DSystem::getDrectionString(...) - unknown dir";
+      }
+   }
+   static const int&       getInvertDirection(const int& direction);
+
+//////////////////////////////////////////////////////////////////////////
+   static inline void setNeighborCoordinatesForDirection(int &x1, int &x2,int &x3, const int& direction)
+   {
+      switch(direction)
+      {
+      case Grid3DSystem::E  :  x1++;             break;
+      case Grid3DSystem::N  :  x2++;             break;
+      case Grid3DSystem::T  :  x3++;             break;
+      case Grid3DSystem::W  :  x1--;             break;
+      case Grid3DSystem::S  :  x2--;             break;
+      case Grid3DSystem::B  :  x3--;             break;
+      case Grid3DSystem::NE :  x1++; x2++;       break;
+      case Grid3DSystem::NW :  x1--; x2++;       break;
+      case Grid3DSystem::SW :  x1--; x2--;       break;
+      case Grid3DSystem::SE :  x1++; x2--;       break;
+      case Grid3DSystem::TE :  x1++; x3++;       break;
+      case Grid3DSystem::BW :  x1--; x3--;       break;
+      case Grid3DSystem::BE :  x1++; x3--;       break;
+      case Grid3DSystem::TW :  x1--; x3++;       break;
+      case Grid3DSystem::TN :  x2++; x3++;       break;
+      case Grid3DSystem::BS :  x2--; x3--;       break;
+      case Grid3DSystem::BN :  x2++; x3--;       break;
+      case Grid3DSystem::TS :  x2--; x3++;       break;
+      case Grid3DSystem::TNE:  x1++; x2++; x3++; break;
+      case Grid3DSystem::TNW:  x1--; x2++; x3++; break;
+      case Grid3DSystem::TSE:  x1++; x2--; x3++; break;
+      case Grid3DSystem::TSW:  x1--; x2--; x3++; break;
+      case Grid3DSystem::BNE:  x1++; x2++; x3--; break;
+      case Grid3DSystem::BNW:  x1--; x2++; x3--; break;
+      case Grid3DSystem::BSE:  x1++; x2--; x3--; break;
+      case Grid3DSystem::BSW:  x1--; x2--; x3--; break;
+      default: throw UbException(UB_EXARGS,"no direction ...");
+      }
+   }
+}
+
+#endif 
diff --git a/VirtualFluidsCore/IncludsList.cmake b/VirtualFluidsCore/IncludsList.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..5fed1de0af06af1a5942bac957f0b8909e0a7d76
--- /dev/null
+++ b/VirtualFluidsCore/IncludsList.cmake
@@ -0,0 +1,17 @@
+#directory pathes for header files
+
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/BoundaryConditions)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Connectors)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Data)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Interactors)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/LBM)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Parallel)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Grid)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Visitors)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/CoProcessors)
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/VirtualFluidsCore/Utilities)
+
+INCLUDE_DIRECTORIES(${SOURCE_ROOT}/ThirdParty)
+
+
diff --git a/VirtualFluidsCore/Interactors/CMakePackage.txt b/VirtualFluidsCore/Interactors/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp b/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..811a04691528b5820835a2aa1622ebad0782ddd8
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/D3Q27Interactor.cpp
@@ -0,0 +1,744 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27Interactor.cpp
+//! \ingroup Interactor
+//! \author Sören Freudiger
+//! \author Sebastian Geller
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "D3Q27Interactor.h"
+#include <basics/utilities/UbMath.h>
+#include <basics/utilities/UbLogger.h>
+
+#include <basics/writer/WbWriterVtkXmlBinary.h>
+
+#include <GbCuboid3D.h>
+#include <GbLine3D.h>
+#include "Block3D.h"
+#include "Grid3D.h"
+#include "BCArray3D.h"
+#include "BoundaryConditions.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "BCAdapter.h"
+
+
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor() : Interactor3D()
+{
+   this->reinitWithStoredQsFlag = false;
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type)
+: Interactor3D(geoObject3D, grid, type), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, SPtr<BCAdapter> bcAdapter,  int type)
+   :   Interactor3D(geoObject3D, grid, type), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->addBCAdapter(bcAdapter); 
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, SPtr<BCAdapter> bcAdapter,  int type, Interactor3D::Accuracy a)
+   :   Interactor3D(geoObject3D, grid, type, a), relevantForForces(false)
+{
+   this->reinitWithStoredQsFlag = false;
+   this->addBCAdapter(bcAdapter); 
+   this->initRayVectors();
+}
+//////////////////////////////////////////////////////////////////////////
+D3Q27Interactor::~D3Q27Interactor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::initRayVectors()
+{
+   int fdir; 
+   double c1oS2 = UbMath::one_over_sqrt2;
+   double c1oS3 = UbMath::one_over_sqrt3;
+   fdir = D3Q27System::E;  rayX1[fdir] =  1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::W;  rayX1[fdir] = -1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::N;  rayX1[fdir] =  0.0;   rayX2[fdir] =  1.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::S;  rayX1[fdir] =  0.0;   rayX2[fdir] = -1.0;   rayX3[fdir] =  0.0;
+   fdir = D3Q27System::T;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  1.0;
+   fdir = D3Q27System::B;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] = -1.0;
+   fdir = D3Q27System::NE; rayX1[fdir] =  c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::SW; rayX1[fdir] = -c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::SE; rayX1[fdir] =  c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::NW; rayX1[fdir] = -c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+   fdir = D3Q27System::TE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::BW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::BE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::TW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::TN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] =  c1oS2;
+   fdir = D3Q27System::BS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::BN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] = -c1oS2;
+   fdir = D3Q27System::TS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] =  c1oS2;
+
+   fdir = D3Q27System::TNW; rayX1[fdir] = -c1oS3; rayX2[fdir] = c1oS3; rayX3[fdir] =   c1oS3;
+   fdir = D3Q27System::TNE; rayX1[fdir] =  c1oS3; rayX2[fdir] = c1oS3; rayX3[fdir] =   c1oS3;
+   fdir = D3Q27System::TSW; rayX1[fdir] = -c1oS3; rayX2[fdir] =-c1oS3; rayX3[fdir] =   c1oS3;
+   fdir = D3Q27System::TSE; rayX1[fdir] =  c1oS3; rayX2[fdir] =-c1oS3; rayX3[fdir] =   c1oS3;
+   fdir = D3Q27System::BNW; rayX1[fdir] = -c1oS3; rayX2[fdir] = c1oS3; rayX3[fdir] =  -c1oS3;
+   fdir = D3Q27System::BNE; rayX1[fdir] =  c1oS3; rayX2[fdir] = c1oS3; rayX3[fdir] =  -c1oS3;
+   fdir = D3Q27System::BSW; rayX1[fdir] = -c1oS3; rayX2[fdir] =-c1oS3; rayX3[fdir] =  -c1oS3;
+   fdir = D3Q27System::BSE; rayX1[fdir] =  c1oS3; rayX2[fdir] =-c1oS3; rayX3[fdir] =  -c1oS3;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::initInteractor(const double& timeStep)
+{
+   UBLOG(logDEBUG5,"D3Q27Interactor::initInteractor - "<<" for timestep = "<<timeStep);
+   
+   //////////////////////////////////////////////////////////////////////////
+   //init bcs
+   int nofAdapter = (int)bcAdapters.size();
+   if(nofAdapter==0) UBLOG(logWARNING,"WARNING - D3Q27Interactor::initInteractor Warning - no nodeAdapter available");
+   bool needTimeDependence = false;
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      bcAdapters[pos]->init(this,timeStep);
+      if(bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+
+   Interactor3D::initInteractor(timeStep);
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::updateInteractor(const double& timestep)
+{
+   UBLOG(logDEBUG5,"D3Q27Interactor::updateInteractor - for timestep = "<<timestep);
+
+   //////////////////////////////////////////////////////////////////////////
+   //update bcs
+   int nofAdapter = (int)bcAdapters.size();
+   if(nofAdapter==0) UBLOG(logERROR,"WARNING - D3Q27Interactor::updateInteractor Warning - no nodeAdapter available for ");
+
+   bool needTimeDependence = false;
+
+   for(int pos=0; pos<nofAdapter; ++pos)
+   {
+      bcAdapters[pos]->update(this,timestep);
+      if(bcAdapters[pos]->isTimeDependent()) needTimeDependence = true;
+   }
+   if(needTimeDependence) this->setTimeDependent();
+   else                   this->unsetTimeDependent();
+   
+   for(BcNodeIndicesMap::value_type t : bcNodeIndicesMap)
+   {
+      SPtr<Block3D> block = t.first;
+      std::set< std::vector<int> >& transNodeIndicesSet = t.second;
+
+      if(block->isNotActive() || !block) continue;
+
+      SPtr<ILBMKernel> kernel = block->getKernel();
+      SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();
+
+      set< std::vector<int> >::iterator setPos;
+
+      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+      {
+         int    x1      = (*setPos)[0];
+         int    x2      = (*setPos)[1];
+         int    x3      = (*setPos)[2];
+         Vector3D coords = grid.lock()->getNodeCoordinates(block, x1, x2, x3);
+         double worldX1 = coords[0];
+         double worldX2 = coords[1];
+         double worldX3 = coords[2];
+
+         SPtr<BoundaryConditions> bc = bcArray->getBC(x1,x2,x3);
+         if(bc) //may be that the BC has been deleted by the solid setting of another interactor
+         {
+            for(size_t i=0; i<bcAdapters.size(); i++)
+               bcAdapters[i]->adaptBC(*this,bc,worldX1,worldX2,worldX3,timestep);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+// calculation takes place in the real coordinate system !!!
+// not normalized!
+// x1, x2, x3 are the coordinates at the bottom left of the "system"
+// extendedBoundingGeoOfGeoObject MUST already have been magnified by delta_x_level in each direction for SOLID
+bool D3Q27Interactor::setDifferencesToGbObject3D(const SPtr<Block3D> block)
+{
+   if(!block) return false;
+
+   if(block->isNotActive()) return false;//continue;
+
+   bcNodeIndicesMap[block] = set< std::vector<int> >();
+   set< std::vector<int> >& transNodeIndices = bcNodeIndicesMap[block];
+   solidNodeIndicesMap[block] = set< UbTupleInt3 >();
+   set< UbTupleInt3 >& solidNodeIndices = solidNodeIndicesMap[block];
+
+
+   double timestep = 0;
+   bool oneEntryGotBC = false; 
+   bool gotQs         = false; 
+   SPtr<BoundaryConditions> bc;
+
+   SPtr<ILBMKernel> kernel = block->getKernel();
+   SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();
+
+   double internX1,internX2,internX3;
+
+
+   //width of ghost layer 
+   int gl = kernel->getGhostLayerWidth();
+
+   int startIX1 = 0;
+   int startIX2 = 0;
+   int startIX3 = 0; 
+   int stopIX1  = (int)bcArray->getNX1();
+   int stopIX2  = (int)bcArray->getNX2();
+   int stopIX3  = (int)bcArray->getNX3(); 
+
+   double         dx       = grid.lock()->getDeltaX(block);
+   UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
+
+   //other boundingRect than in init, because here the boundrect has to be increased by one dx
+   GbCuboid3D extendedBoundingGeoOfGeoObject(  geoObject3D->getX1Minimum()-1.02*dx 
+                                             , geoObject3D->getX2Minimum()-1.02*dx 
+                                             , geoObject3D->getX3Minimum()-1.02*dx 
+                                             , geoObject3D->getX1Maximum()+1.02*dx 
+                                             , geoObject3D->getX2Maximum()+1.02*dx 
+                                             , geoObject3D->getX3Maximum()+1.02*dx );
+
+   double deltaX1=dx, deltaX2 =dx, deltaX3=dx;
+
+   if(   geoObject3D->hasRaytracing() 
+        || (this->isInverseSolid() && geoObject3D->raytracingSupportsPointsInside() ) )
+   {
+      //if deltaX1==deltaX2==deltaX3 (must for LB!!)
+      if(!UbMath::zero( deltaX1-deltaX2 + deltaX1-deltaX3 + deltaX2-deltaX3 ) )
+         throw UbException(UB_EXARGS,"fuer den bei LB nicht vorkommenden Fall deltaX1!=deltaX2!=deltaX3  nicht implementiert ");
+
+      vector<double> distNeigh(D3Q27System::FENDDIR+1, UbMath::sqrt2*deltaX1);
+      distNeigh[D3Q27System::E] = distNeigh[D3Q27System::W] = distNeigh[D3Q27System::N] = deltaX1;
+      distNeigh[D3Q27System::S] = distNeigh[D3Q27System::T] = distNeigh[D3Q27System::B] = deltaX1;
+      distNeigh[D3Q27System::NE]  = distNeigh[D3Q27System::NW]  = distNeigh[D3Q27System::SW]  = distNeigh[D3Q27System::SE]  = UbMath::sqrt2*deltaX1;
+      distNeigh[D3Q27System::TE]  = distNeigh[D3Q27System::TN]  = distNeigh[D3Q27System::TW]  = distNeigh[D3Q27System::TS]  = UbMath::sqrt2*deltaX1;
+      distNeigh[D3Q27System::BE]  = distNeigh[D3Q27System::BN]  = distNeigh[D3Q27System::BW]  = distNeigh[D3Q27System::BS]  = UbMath::sqrt2*deltaX1;
+      distNeigh[D3Q27System::TNE] = distNeigh[D3Q27System::TNW] = distNeigh[D3Q27System::TSE] = distNeigh[D3Q27System::TSW] = UbMath::sqrt3*deltaX1;
+      distNeigh[D3Q27System::BNE] = distNeigh[D3Q27System::BNW] = distNeigh[D3Q27System::BSE] = distNeigh[D3Q27System::BSW] = UbMath::sqrt3*deltaX1;
+      double q;
+      bool pointOnBoundary = false;
+
+//#ifdef _OPENMP
+//      #pragma omp parallel for private(internX1,internX2,internX3,gotQs,bc,q )
+//#endif
+      for(int ix3=startIX3; ix3<stopIX3; ix3++)
+      {
+         for(int ix2=startIX2; ix2<stopIX2; ix2++)
+         {
+            for(int ix1=startIX1; ix1<stopIX1; ix1++)
+            {
+               //TODO: further, investigate if this is not a mistake
+               if(bcArray->isUndefined(ix1, ix2, ix3)) continue;
+
+               Vector3D coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
+               internX1 = coords[0];
+               internX2 = coords[1];
+               internX3 = coords[2];
+
+               // Point in the object test is superfluous, since the start and stop indices already exist
+               // are determined -> only point-in-cube indexes are considered
+               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
+               {
+                  if(this->isSolid() )
+                  {
+                     if(this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3))
+                     {
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+                  else if( this->isInverseSolid()  )
+                  {
+                     //in inverse solid all nodes are OUTSIDE and on the boundary SOLID
+                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                        || pointOnBoundary == true )
+                     {
+
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+
+                  if(bcArray->isSolid(ix1,ix2,ix3)) 
+                     continue;
+
+                  gotQs = false;
+
+                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                  {
+                     q = geoObject3D->getIntersectionRaytraceFactor(internX1,internX2,internX3,rayX1[fdir],rayX2[fdir],rayX3[fdir]);
+                     q /= distNeigh[fdir];
+
+                     //assert(UbMath::lessEqual(q, 1.0));
+
+                     if( UbMath::inClosedInterval(q, 1.0, 1.0) ) q = 1.0;
+                     if( UbMath::greater(q, 0.0) && UbMath::lessEqual(q, 1.0) )
+                     {
+                        //#pragma omp critical (BC_CHANGE)
+                        {
+                           bc = bcArray->getBC(ix1,ix2,ix3);
+                           if(!bc)
+                           {
+                              bc = SPtr<BoundaryConditions>(new BoundaryConditions);
+                              bcArray->setBC(ix1,ix2,ix3,bc);
+                           }
+
+                           if(bc->hasNoSlipBoundary())
+                           {
+                              bc->setBoundaryVelocityX1(0.0);
+                              bc->setBoundaryVelocityX2(0.0);
+                              bc->setBoundaryVelocityX3(0.0);
+                           }
+                       
+                           for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                              bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir, timestep);
+                        }
+
+                        gotQs=true;
+                     }
+                  }
+
+                  if(gotQs)
+                  {
+                     {
+                        oneEntryGotBC = true;
+
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        transNodeIndices.insert(p);
+                     
+                        for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                           bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3, timestep);
+                     }
+                  }
+               }
+               else if( this->isInverseSolid()  )
+               {
+                  //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+                  if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                     || pointOnBoundary == true )
+                 {
+                     {
+                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                        bcArray->setSolid(ix1,ix2,ix3); 
+                     }
+                     continue;
+                  }
+               }
+            }
+         }
+      }
+   }
+   else  //clipping -> slower (currently also used for all inverse Solid objects whose raytracing does not work for nodes INSIDE the geo)
+   {
+      bool pointOnBoundary = false;
+      for(int ix1=startIX1; ix1<stopIX1; ix1++)
+      {
+         for(int ix2=startIX2; ix2<stopIX2; ix2++)
+         {
+            for(int ix3=startIX3; ix3<stopIX3; ix3++)
+            {
+               if(bcArray->isSolid(ix1,ix2,ix3) || bcArray->isUndefined(ix1, ix2, ix3)) continue;
+
+               Vector3D coords = grid.lock()->getNodeCoordinates(block, ix1, ix2, ix3);
+               internX1 = coords[0];
+               internX2 = coords[1];
+               internX3 = coords[2];
+
+               if(extendedBoundingGeoOfGeoObject.isPointInGbObject3D(internX1,internX2,internX3))
+               {
+                  if( this->isSolid() && this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3) )
+                  {
+                     {
+                        solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                        bcArray->setSolid(ix1,ix2,ix3); 
+                     }
+                     continue;
+                  }
+                  else if( this->isInverseSolid()  )
+                  {
+                     //bei inverse solid sind alle Knoten AUSSERHALB und auf der boundary SOLID
+                     if( !this->geoObject3D->isPointInGbObject3D(internX1, internX2, internX3, pointOnBoundary) 
+                         || pointOnBoundary == true )
+                     {
+                        {
+                           solidNodeIndices.insert(UbTupleInt3(ix1, ix2, ix3));
+                           bcArray->setSolid(ix1,ix2,ix3); 
+                        }
+                        continue;
+                     }
+                  }
+
+                  gotQs = false;
+
+                  GbPoint3D pointA(internX1,internX2,internX3);
+                  for(int fdir=D3Q27System::FSTARTDIR; fdir<=D3Q27System::FENDDIR; fdir++)
+                  {
+                     double x1B = internX1+D3Q27System::DX1[fdir]*deltaX1;
+                     double x2B = internX2+D3Q27System::DX2[fdir]*deltaX2;
+                     double x3B = internX3+D3Q27System::DX3[fdir]*deltaX3;
+
+                     GbPoint3D pointB(x1B,x2B,x3B);
+                     GbLine3D* clippedLine = this->geoObject3D->createClippedLine3D(pointA, pointB);
+
+                     if(clippedLine)
+                     {
+                        double q=0.0;
+                        if( !this->isInverseSolid() )  //A is outside
+                        {
+                           double distanceAB = pointA.getDistance(&pointB); //pointA to B
+                           double distanceAP = UbMath::min(pointA.getDistance(clippedLine->getPoint1()),
+                                                           pointA.getDistance(clippedLine->getPoint2()) );
+                           q = distanceAP/distanceAB;
+                        }
+                        else
+                        {
+                           bool pointIsOnBoundary = false;
+                           if(   !clippedLine->getPoint1()->equals(&pointB)
+                              && !clippedLine->getPoint2()->equals(&pointB) )
+                           {
+                              //A is inside, a clipped line must not contain B
+                              double distanceAB = pointA.getDistance(&pointB); //pointA to B
+                              double distanceAP = clippedLine->getLength();
+                              q = distanceAP/distanceAB;
+                           }
+                           else if(  this->geoObject3D->isPointInGbObject3D( pointB.getX1Coordinate()
+                                                                            ,pointB.getX2Coordinate()
+                                                                            ,pointB.getX3Coordinate()
+                                                                            ,pointIsOnBoundary )
+                                   && pointIsOnBoundary )
+                           {
+                              //A is definitely inside, B is exactly on ObjectBoundary => q = 1.0
+                              q=1.0;
+                           }
+                           else
+                           {
+                              q = 0.0;
+                           }
+                        }
+
+                        if(UbMath::inClosedInterval(q, 1.0, 1.0)) q = 1.0;
+                        if(UbMath::lessEqual(q, 1.0) && UbMath::greater(q, 0.0))
+                        {
+                           {
+                              bc = bcArray->getBC(ix1,ix2,ix3);
+                              if(!bc)
+                              {
+                                 bc = SPtr<BoundaryConditions>(new BoundaryConditions);
+                                 bcArray->setBC(ix1,ix2,ix3,bc);
+                              }
+                              for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                                 bcAdapters[index]->adaptBCForDirection(*this,bc,internX1,internX2,internX3,q,fdir,timestep);
+                           }
+                                          
+                           gotQs=true;
+                        }
+
+                        clippedLine->deletePoint1();
+                        clippedLine->deletePoint2();
+                        delete clippedLine;
+                     }
+                  }
+
+                  if(gotQs)
+                  {
+                     {
+                        oneEntryGotBC = true;
+
+                        std::vector<int> p(3);
+                        p[0]=ix1; p[1]=ix2; p[2]=ix3;
+                        transNodeIndices.insert(p);
+
+                        for(int index=(int)bcAdapters.size()-1; index>=0; --index)
+                           bcAdapters[index]->adaptBC(*this,bc,internX1,internX2,internX3,timestep);
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   return oneEntryGotBC;
+}
+//////////////////////////////////////////////////////////////////////////
+void D3Q27Interactor::addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines)
+{
+      for(SPtr<Block3D> block : bcBlocks)
+      {
+         if(!block) continue;
+
+         double         dx       = grid.lock()->getDeltaX(block);
+         UbTupleDouble3 orgDelta = grid.lock()->getNodeOffset(block);
+
+         SPtr<ILBMKernel> kernel = block->getKernel();
+         SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();
+
+         map<SPtr<Block3D>, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
+         if(pos==bcNodeIndicesMap.end()) 
+         {
+            UB_THROW( UbException(UB_EXARGS,"block nicht in indizes map!!!") );
+         }
+         set< std::vector<int> >& transNodeIndicesSet = pos->second;
+         set< std::vector<int> >::iterator setPos;
+
+         std::size_t node1Index, node2Index;
+
+         UbTupleDouble3 blockOrg = grid.lock()->getBlockWorldCoordinates(block);
+
+         for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+         {
+            int ix1 = (*setPos)[0];
+            int ix2 = (*setPos)[1];
+            int ix3 = (*setPos)[2];
+
+            if(bcArray->isFluid(ix1,ix2,ix3)) //it may be that the node is replaced by another interactor e.g. was marked as solid !!!
+            {
+               if( !bcArray->hasBC(ix1,ix2,ix3) ) continue;
+               SPtr<BoundaryConditions> bc = bcArray->getBC(ix1,ix2,ix3);
+
+               double x1a = val<1>(blockOrg) - val<1>(orgDelta) + ix1 * dx;
+               double x2a = val<2>(blockOrg) - val<2>(orgDelta) + ix2 * dx;
+               double x3a = val<3>(blockOrg) - val<3>(orgDelta) + ix3 * dx;
+               nodes.push_back( makeUbTuple( (float)x1a, (float)x2a, (float)x3a ) );
+               node1Index = nodes.size()-1;
+
+               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
+               {
+                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
+                  {
+                     double x1b, x2b, x3b, q = bc->getQ(dir);
+                     switch(dir)
+                     {
+                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     default: throw UbException(UB_EXARGS,"unknown direction");
+                     }
+
+                     nodes.push_back( makeUbTuple( (float)x1b, (float)x2b, (float)x3b ) );
+                     node2Index = nodes.size()-1;
+
+                     lines.push_back( makeUbTuple( (int)node1Index, (int)node2Index) );
+                  }
+               }
+            }
+         }
+      }
+}
+////////////////////////////////////////////////////////////////////////////
+vector< pair<GbPoint3D,GbPoint3D> >  D3Q27Interactor::getQsLineSet()
+{
+   vector< pair<GbPoint3D,GbPoint3D> >  QsLineSet;
+   pair<GbPoint3D,GbPoint3D> pointpair;
+
+   UbTupleInt3 blocknx = grid.lock()->getBlockNX();
+
+   int blocknx1 = val<1>(blocknx);
+   int blocknx2 = val<2>(blocknx);
+   int blocknx3 = val<3>(blocknx);
+
+   for(SPtr<Block3D> block : bcBlocks)
+   {
+      SPtr<ILBMKernel> kernel = block->getKernel();
+      SPtr<BCArray3D> bcMatrix = kernel->getBCProcessor()->getBCArray();
+      UbTupleDouble3 nodeOffset   = grid.lock()->getNodeOffset(block);
+
+      //Check whether top row is double in the system or not
+      bool include_N_Face  = false; //x1=[0..blocknx1[ && x3=[0..blocknx3[
+      bool include_E_Face  = false; //x2=[0..blocknx2[ && x3=[0..blocknx3[
+      bool include_T_Face  = false; //x1=[0..blocknx1[ && x2=[0..blocknx2[
+      bool include_NE_Edge = false; //(x1/x2/x3)=(blocknx1/blocknx2/[0..blocknx3[)
+      bool include_TN_Edge = false; //(x1/x2/x3)=([0..blocknx1[/blocknx2/blocknx1)
+      bool include_TE_Edge = false; //(x1/x2/x3)=(blocknx1/[0..blocknx2[/blocknx2)
+      if(block)
+      {
+         if( !block->getConnector(D3Q27System::N ) ) include_N_Face  = true;
+         if( !block->getConnector(D3Q27System::E ) ) include_E_Face  = true;
+         if( !block->getConnector(D3Q27System::T ) ) include_T_Face  = true;
+         if( !block->getConnector(D3Q27System::NE) && include_N_Face && include_E_Face ) include_NE_Edge = true;
+         if( !block->getConnector(D3Q27System::TN) && include_T_Face && include_N_Face ) include_TN_Edge = true;
+         if( !block->getConnector(D3Q27System::TE) && include_T_Face && include_E_Face ) include_TE_Edge = true;
+      }
+
+      map<SPtr<Block3D>, set< std::vector<int> > >::iterator pos = bcNodeIndicesMap.find(block);
+      if(pos==bcNodeIndicesMap.end()) throw UbException(UB_EXARGS,"block nicht in indizes map!!!"+block->toString());
+      set< std::vector<int> >& transNodeIndicesSet = pos->second;
+      set< std::vector<int> >::iterator setPos;
+
+      double x1,x2,x3,dx;
+      grid.lock()->calcStartCoordinatesAndDelta(block,x1,x2,x3,dx);
+
+      for(setPos=transNodeIndicesSet.begin(); setPos!=transNodeIndicesSet.end();  ++setPos)
+      {
+         int ix1 = (*setPos)[0];
+         int ix2 = (*setPos)[1];
+         int ix3 = (*setPos)[2];
+
+         if(   ( ix1<blocknx1 && ix2<blocknx2 && ix3<blocknx3 ) 
+            || ( include_E_Face  && ix1==blocknx1 && ix2<blocknx2  && ix3<blocknx3  )
+            || ( include_N_Face  && ix2==blocknx2 && ix1<blocknx1  && ix3<blocknx3  )
+            || ( include_T_Face  && ix3==blocknx3 && ix1<blocknx1  && ix2<blocknx2  )
+            || ( include_NE_Edge && ix1==blocknx1 && ix2==blocknx2 )
+            || ( include_TN_Edge && ix2==blocknx2 && ix3==blocknx3 )
+            || ( include_TE_Edge && ix1==blocknx1 && ix3==blocknx3 ) )
+         {
+            if(bcMatrix->isFluid(ix1,ix2,ix3)) //it may be that the node is replaced by another interactor e.g. was marked as solid !!!
+            {
+               if( !bcMatrix->hasBC(ix1,ix2,ix3) ) continue;
+               SPtr<BoundaryConditions> bc = bcMatrix->getBC(ix1,ix2,ix3);
+               double x1a = x1-val<1>(nodeOffset)+dx * ix1;
+               double x2a = x2-val<2>(nodeOffset)+dx * ix2;
+               double x3a = x3-val<3>(nodeOffset)+dx * ix3;
+               pointpair.first.setX1(x1a);
+               pointpair.first.setX2(x2a);
+               pointpair.first.setX3(x3a);
+               for(int dir = D3Q27System::FSTARTDIR; dir<=D3Q27System::FENDDIR; dir++)
+               {
+                  if (bc->hasBoundaryConditionFlag(D3Q27System::INVDIR[dir]))
+                  {
+                     double x1b, x2b, x3b, q = bc->getQ(dir);
+                     switch(dir)
+                     {
+                     case D3Q27System::E : x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::N : x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::W : x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a         ; break;
+                     case D3Q27System::S : x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NE: x1b = x1a+q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::NW: x1b = x1a-q*dx; x2b = x2a+q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SW: x1b = x1a-q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::SE: x1b = x1a+q*dx; x2b = x2a-q*dx; x3b = x3a         ; break;
+                     case D3Q27System::T : x1b = x1a         ; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a+q*dx; break;
+                     case D3Q27System::TS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::B : x1b = x1a         ; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BE: x1b = x1a+q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BN: x1b = x1a         ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BW: x1b = x1a-q*dx; x2b = x2a         ; x3b = x3a-q*dx; break;
+                     case D3Q27System::BS: x1b = x1a         ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BNE : x1b = x1a+q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TSW : x1b = x1a-q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::TSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a+q*dx; break;
+                     case D3Q27System::BNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::BSE : x1b = x1a+q*dx  ; x2b = x2a-q*dx; x3b = x3a-q*dx; break;
+                     case D3Q27System::TNW : x1b = x1a-q*dx  ; x2b = x2a+q*dx; x3b = x3a+q*dx; break;
+                     default: throw UbException(UB_EXARGS,"unknown direction");
+                     }
+                     pointpair.second.setX1(x1b);
+                     pointpair.second.setX2(x2b);
+                     pointpair.second.setX3(x3b);
+                     QsLineSet.push_back(pointpair);
+                  }
+               }
+
+            }
+         }
+      }
+   }
+   return QsLineSet;
+}
+
+void D3Q27Interactor::writeValidationAVSFile(string filename)
+{
+   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - start ");
+   ofstream out(filename.c_str(),ios::out);
+   if(!out) throw UbException(UB_EXARGS,"couldn't open file "+filename);
+
+   int numpoints, numlines;
+   vector< pair<GbPoint3D,GbPoint3D> > qsLineSet = this->getQsLineSet();
+   numlines  = (unsigned)qsLineSet.size();
+   numpoints = numlines*2;
+
+   out<<"# UCD-File created by D3Q27Interactor\n";
+   out<<numpoints<<" "<<numlines<<" 0 0 0 "<<endl;
+   int nr=1;
+   for (int i=0; i<numlines; i++)
+   {
+      out<<nr++<<" "<<qsLineSet[i].first.getX1Coordinate() <<" " <<qsLineSet[i].first.getX2Coordinate() <<" " <<qsLineSet[i].first.getX3Coordinate() <<" \n";
+      out<<nr++<<" "<<qsLineSet[i].second.getX1Coordinate()<<" " <<qsLineSet[i].second.getX2Coordinate()<<" " <<qsLineSet[i].second.getX3Coordinate() <<" \n";
+   }
+   nr = 1;
+   for (int i=0; i<numlines; i++)
+   {
+      int el = nr+1;
+      out<<i+1<<" "<<2<<" line "<<nr<<" "<<el<<" "<<endl;
+      nr=el+1;
+   }
+   UBLOG(logINFO,"D3Q27Interactor::writeValidationAVSFile("<<filename<<") - end");
+}
diff --git a/VirtualFluidsCore/Interactors/D3Q27Interactor.h b/VirtualFluidsCore/Interactors/D3Q27Interactor.h
new file mode 100644
index 0000000000000000000000000000000000000000..3410a5a910a34e499d948207698925749c5f6a16
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/D3Q27Interactor.h
@@ -0,0 +1,115 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27Interactor.h
+//! \ingroup Interactor
+//! \author Sören Freudiger
+//! \author Sebastian Geller
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef D3Q27INTERACTOR_H
+#define D3Q27INTERACTOR_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <PointerDefinitions.h>
+
+#include "UbException.h"
+#include "UbTuple.h"
+#include "GbPoint3D.h"
+#include "Interactor3D.h"
+#include "D3Q27System.h"
+
+class BCAdapter;
+class Block3D;
+class Grid3D;
+class GbObject3D;
+
+typedef std::map<SPtr<Block3D>, std::set< std::vector<int> > > BcNodeIndicesMap;
+typedef std::map<SPtr<Block3D>, std::set< UbTupleInt3 > > SolidNodeIndicesMap;
+
+//! \brief A specialized class for grid generation.
+//! \details Support standard geometric primitives.
+class D3Q27Interactor : public Interactor3D 
+{
+public:
+   D3Q27Interactor();
+   D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type);
+   D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, SPtr<BCAdapter> bcAdapter,  int type);
+   D3Q27Interactor(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, SPtr<BCAdapter> bcAdapter,  int type, Interactor3D::Accuracy a);
+
+   virtual ~D3Q27Interactor();
+
+   void setRelevantForForces(const bool& value) {  this->relevantForForces = value; }
+   bool isRelevantForForces() { return this->relevantForForces; }
+
+   virtual void addBCAdapter(const SPtr<BCAdapter> bcAdapter) { bcAdapters.push_back(bcAdapter); }
+   void deleteBCAdapter() { bcAdapters.clear(); }
+
+ 
+   virtual void initInteractor(const double& timeStep=0);
+   void updateInteractor(const double& timestep=0); 
+
+   void setReinitWithStoredQs(bool reinitWithStoredQsFlag) { this->reinitWithStoredQsFlag = reinitWithStoredQsFlag; }
+   
+   void removeSolidBlocks() { Interactor3D::removeSolidBlocks(); solidNodeIndicesMap.clear(); }
+   void removeBcBlocks() { Interactor3D::removeBcBlocks(); bcNodeIndicesMap.clear(); }
+
+   bool setDifferencesToGbObject3D(const SPtr<Block3D> block);
+
+   ObObject* clone() { throw UbException(UB_EXARGS,"not implemented");	}
+
+
+   void writeValidationAVSFile(std::string filename);  
+   virtual std::vector< std::pair<GbPoint3D,GbPoint3D> >  getQsLineSet();
+
+   void addQsLineSet(std::vector<UbTupleFloat3 >& nodes, std::vector<UbTupleInt2 >& lines);
+
+   const BcNodeIndicesMap& getBcNodeIndicesMap() const { return bcNodeIndicesMap; }
+
+protected:
+   bool relevantForForces;
+   bool reinitWithStoredQsFlag;
+
+   std::vector<SPtr<BCAdapter> > bcAdapters;
+
+   SolidNodeIndicesMap solidNodeIndicesMap;
+   BcNodeIndicesMap bcNodeIndicesMap;
+   
+   void   initRayVectors();
+   double rayX1[D3Q27System::FENDDIR+1];
+   double rayX2[D3Q27System::FENDDIR+1];
+   double rayX3[D3Q27System::FENDDIR+1];
+
+};
+
+
+#endif
diff --git a/VirtualFluidsCore/Interactors/Interactor3D.cpp b/VirtualFluidsCore/Interactors/Interactor3D.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7fdab60f4da5ec779b7200f26b95d61d9e42475
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/Interactor3D.cpp
@@ -0,0 +1,346 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Interactor3D.cpp
+//! \ingroup Interactor
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "Interactor3D.h"
+
+#include <fstream>
+#include <geometry3d/GbCuboid3D.h>
+#include <basics/utilities/UbMath.h>
+#include "UbException.h"
+
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "GbObject3D.h"
+
+
+using namespace std;
+
+const int Interactor3D::SOLID	           = (1<<0); //1
+const int Interactor3D::INVERSESOLID       = (1<<1); //2
+const int Interactor3D::TIMEDEPENDENT      = (1<<2); //4   //zeitlich
+const int Interactor3D::FLUID              = (1<<3); //8
+const int Interactor3D::MOVEABLE           = (1<<4); //16  // geometrisch
+const int Interactor3D::CHANGENOTNECESSARY = (1<<5); //32
+
+
+
+//////////////////////////////////////////////////////////////////////////
+Interactor3D::Interactor3D()
+  : type(SOLID)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+Interactor3D::Interactor3D(SPtr<Grid3D> grid, int type)
+   :   type(type)
+     , grid(grid)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+Interactor3D::Interactor3D(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type)
+   :   geoObject3D(geoObject3D)
+     , grid(grid)
+     , type(type)
+     , accuracy(SIMPLE)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+Interactor3D::Interactor3D(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type, Interactor3D::Accuracy a)
+   :   geoObject3D(geoObject3D)
+   , grid(grid)
+   , type(type)
+   , accuracy(a)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+Interactor3D::~Interactor3D()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::arePointsInsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   bool result = true;
+   for (double ix3=minX3; ix3<=maxX3; ix3+=delta)
+      for (double ix2=minX2; ix2<=maxX2; ix2+=delta)
+         for (double ix1=minX1; ix1<=maxX1; ix1+=delta)
+            result = result && this->geoObject3D->isPointInGbObject3D(ix1, ix2, ix3);
+
+   return result;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::arePointsOutsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   bool result = true;
+   for (double ix3=minX3; ix3<=maxX3; ix3+=delta)
+      for (double ix2=minX2; ix2<=maxX2; ix2+=delta)
+         for (double ix1=minX1; ix1<=maxX1; ix1+=delta)
+            result = result && (!this->geoObject3D->isPointInGbObject3D(ix1, ix2, ix3));
+
+   return result;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::arePointsCuttingGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   bool result = true;
+   for (double ix3=minX3; ix3<=maxX3; ix3+=delta)
+      for (double ix2=minX2; ix2<=maxX2; ix2+=delta)
+         for (double ix1=minX1; ix1<=maxX1; ix1+=delta)
+            result = result || this->geoObject3D->isPointInGbObject3D(ix1, ix2, ix3);
+
+   return result;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::isBlockOutsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   switch (accuracy)
+   {
+      //simple duff
+   case SIMPLE:
+      return !this->geoObject3D->isCellInsideOrCuttingGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3);
+      //test only edges
+   case EDGES:
+      return arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, minX2, minX3, delta) &&
+             arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(minX1, maxX2, maxX3, maxX1, maxX2, maxX3, delta) &&
+             
+             arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, minX3, delta) &&
+             arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(maxX1, minX2, maxX3, maxX1, maxX2, maxX3, delta) &&
+             
+             arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, minX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(maxX1, maxX2, minX3, maxX1, maxX2, maxX3, delta);   
+      //test only faces
+   case FACES:
+      return arePointsOutsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, minX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsOutsideGeoObject(minX1, minX2, maxX3, maxX1, maxX2, maxX3, delta);
+      //test all points
+   case POINTS:
+      return arePointsOutsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, delta);
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Accuracy isn't correct") );
+      break;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::isBlockInsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   switch (accuracy)
+   {
+      //simple duff
+   case SIMPLE:
+      return this->geoObject3D->isCellInsideGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3);
+      //test only edges
+   case EDGES:
+      return arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, minX2, minX3, delta) &&
+             arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) &&
+             arePointsInsideGeoObject(minX1, maxX2, maxX3, maxX1, maxX2, maxX3, delta) &&
+             
+             arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, minX3, delta) &&
+             arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) &&
+             arePointsInsideGeoObject(maxX1, minX2, maxX3, maxX1, maxX2, maxX3, delta) &&
+             
+             arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) &&
+             arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, minX2, maxX3, delta) &&
+             arePointsInsideGeoObject(maxX1, maxX2, minX3, maxX1, maxX2, maxX3, delta);   
+      //test only faces
+   case FACES:
+      return arePointsInsideGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) &&
+             arePointsInsideGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, minX2, maxX3, delta) &&
+             arePointsInsideGeoObject(minX1, maxX2, minX3, maxX1, maxX2, maxX3, delta) &&
+             arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, minX3, delta) &&
+             arePointsInsideGeoObject(minX1, minX2, maxX3, maxX1, maxX2, maxX3, delta);
+      //test all points
+   case POINTS:
+      return arePointsInsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, delta);
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Accuracy isn't correct") );
+      break;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::isBlockCuttingGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta)
+{
+   switch (accuracy)
+   {
+      //simple duff
+   case SIMPLE:
+      return this->geoObject3D->isCellCuttingGbObject3D(minX1,minX2,minX3,maxX1,maxX2,maxX3);
+      //test only edges
+   case EDGES:
+      return arePointsCuttingGeoObject(minX1, minX2, minX3, maxX1, minX2, minX3, delta) ||
+             arePointsCuttingGeoObject(minX1, maxX2, minX3, maxX1, maxX2, minX3, delta) ||
+             arePointsCuttingGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(minX1, maxX2, maxX3, maxX1, maxX2, maxX3, delta) ||
+                                                                             
+             arePointsCuttingGeoObject(minX1, minX2, minX3, minX1, maxX2, minX3, delta) ||
+             arePointsCuttingGeoObject(maxX1, minX2, minX3, maxX1, maxX2, minX3, delta) ||
+             arePointsCuttingGeoObject(minX1, minX2, maxX3, maxX1, minX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(maxX1, minX2, maxX3, maxX1, maxX2, maxX3, delta) ||
+                                                                             
+             arePointsCuttingGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(minX1, maxX2, minX3, maxX1, minX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(maxX1, maxX2, minX3, maxX1, maxX2, maxX3, delta);   
+      //test only faceCutting
+   case FACES:        
+      return arePointsCuttingGeoObject(minX1, minX2, minX3, minX1, maxX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(maxX1, minX2, minX3, maxX1, maxX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(minX1, minX2, minX3, maxX1, minX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(minX1, maxX2, minX3, maxX1, maxX2, maxX3, delta) ||
+             arePointsCuttingGeoObject(minX1, minX2, minX3, maxX1, maxX2, minX3, delta) ||
+             arePointsCuttingGeoObject(minX1, minX2, maxX3, maxX1, maxX2, maxX3, delta);
+      //test all pointCutting
+   case POINTS:       
+      return arePointsCuttingGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, delta);
+   default:
+      UB_THROW( UbException(UB_EXARGS, "Accuracy isn't correct") );
+      break;
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::setSolidBlock(SPtr<Block3D> block)
+{
+   double minX1,minX2,minX3,maxX1,maxX2,maxX3;
+
+   double deltaX = grid.lock()->getDeltaX(block);
+   UbTupleDouble3 blockLengths  = grid.lock()->getBlockLengths(block);
+   UbTupleDouble3 org = grid.lock()->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = grid.lock()->getNodeOffset(block);
+
+   //coordinates of block without ghost layer
+   minX1 = val<1>(org) + val<1>(nodeOffset);
+   minX2 = val<2>(org) + val<2>(nodeOffset);
+   minX3 = val<3>(org) + val<3>(nodeOffset);
+   maxX1 = val<1>(org) + val<1>(blockLengths) - val<1>(nodeOffset);
+   maxX2 = val<2>(org) + val<2>(blockLengths) - val<2>(nodeOffset);
+   maxX3 = val<3>(org) + val<3>(blockLengths) - val<3>(nodeOffset);
+
+   if(this->isInverseSolid())
+   {
+      if(isBlockOutsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
+      {
+         block->setActive(false);
+         this->solidBlocks.push_back(block);
+      }
+   }
+   else //solid 
+   {
+      if(isBlockInsideGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
+      {
+         block->setActive(false);
+         this->solidBlocks.push_back(block);
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::setBCBlock(SPtr<Block3D> block)
+{
+   double minX1,minX2,minX3,maxX1,maxX2,maxX3;
+
+   double deltaX = grid.lock()->getDeltaX(block);
+   UbTupleDouble3 blockLengths  = grid.lock()->getBlockLengths(block);
+   UbTupleDouble3 org = grid.lock()->getBlockWorldCoordinates(block);
+   UbTupleDouble3 nodeOffset = grid.lock()->getNodeOffset(block);
+
+   //coordinates of block with ghost layer
+   minX1 = val<1>(org) - val<1>(nodeOffset);
+   minX2 = val<2>(org) - val<2>(nodeOffset);
+   minX3 = val<3>(org) - val<3>(nodeOffset);
+   maxX1 = val<1>(org) + val<1>(blockLengths) + val<1>(nodeOffset);
+   maxX2 = val<2>(org) + val<2>(blockLengths) + val<2>(nodeOffset);
+   maxX3 = val<3>(org) + val<3>(blockLengths) + val<3>(nodeOffset);
+
+   if(isBlockCuttingGeoObject(minX1, minX2, minX3, maxX1, maxX2, maxX3, deltaX))
+      this->bcBlocks.push_back(block);
+}
+
+UbTupleDouble3 Interactor3D::getForces()
+{
+    UB_THROW( UbException("UbTupleDouble3 getForces() - gehoert in die abgeleitete klasse") );
+}
+void Interactor3D::setID(int id)
+{
+   this->id = id;
+}
+//////////////////////////////////////////////////////////////////////////
+int Interactor3D::getID()
+{
+   return id;
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::setActive()
+{
+   active = true;
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::setInactive()
+{
+   active = false;
+}
+//////////////////////////////////////////////////////////////////////////
+bool Interactor3D::isActive()
+{
+   return active;
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::initInteractor(const double& timeStep)
+{
+   //UBLOG(logINFO, "transBlocks.size = "<<transBlocks.size());
+
+   for(SPtr<Block3D> block : bcBlocks)
+   {
+      this->setDifferencesToGbObject3D(block);
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void Interactor3D::updateInteractor(const double& timeStep)
+{
+   UB_THROW( UbException("Interactor3D::updateInteractor - toDo") );
+}
+//////////////////////////////////////////////////////////////////////////
+
diff --git a/VirtualFluidsCore/Interactors/Interactor3D.h b/VirtualFluidsCore/Interactors/Interactor3D.h
new file mode 100644
index 0000000000000000000000000000000000000000..56390b18caa29810606a964700460afc3428422d
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/Interactor3D.h
@@ -0,0 +1,146 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Interactor3D.h
+//! \ingroup Interactor
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef INTERACTOR3D_H
+#define INTERACTOR3D_H
+
+#include <vector>
+#include <PointerDefinitions.h>
+
+#include "UbSystem.h"
+#include "UbTuple.h"
+
+class Block3D;
+class Grid3D;
+class GbObject3D;
+
+//! A base class for grid generation.
+class Interactor3D : public enableSharedFromThis<Interactor3D>
+{
+public:
+   enum Accuracy{SIMPLE, EDGES, FACES, POINTS};
+   Interactor3D();
+   Interactor3D(SPtr<Grid3D> grid, int type=Interactor3D::SOLID);
+   Interactor3D(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type);
+   //! constructor
+   //! \param a set accuracy for arePointsInObject() and arePointsNotInObject()
+   Interactor3D(SPtr<GbObject3D> geoObject3D, SPtr<Grid3D> grid, int type, Interactor3D::Accuracy a);
+   
+   virtual ~Interactor3D();
+   virtual void initInteractor(const double& timestep=0); 
+   virtual void updateInteractor(const double& timestep=0)=0;
+
+   void setSolidBlock(SPtr<Block3D> block);
+   void setBCBlock(SPtr<Block3D> block);
+
+    virtual UbTupleDouble3 getForces();
+
+   void setSolid()        { UbSystem::setBit(this->type, SOLID   ); }
+   void setMoveable()     { UbSystem::setBit(this->type, MOVEABLE); }
+   
+   bool isSolid()         { return UbSystem::bitCheck(this->type, SOLID        ); }
+   bool isInverseSolid()  { return UbSystem::bitCheck(this->type, INVERSESOLID ); }
+   bool isTimeDependent() { return UbSystem::bitCheck(this->type, TIMEDEPENDENT); }
+   bool isMoveable()      { return UbSystem::bitCheck(this->type, MOVEABLE     ); }
+   
+   SPtr<Grid3D> getGrid3D()  const { return grid.lock();   }
+   void setGrid3D(SPtr<Grid3D> grid) { this->grid = grid; }
+   virtual SPtr<GbObject3D>  getGbObject3D() const { return geoObject3D; }
+   virtual bool setDifferencesToGbObject3D(const SPtr<Block3D> block/*, const double& x1, const double& x2, const double& x3, const double& blockLengthX1, const double& blockLengthX2, const double& blockLengthX3, const double& timestep=0*/)
+   {
+      //UBLOG(logINFO, "Interactor3D::setDifferencesToGbObject3D()");
+      return false;  
+   }
+
+   virtual std::vector<SPtr<Block3D> >& getBcBlocks() { return this->bcBlocks; }
+   virtual void removeBcBlocks() { this->bcBlocks.clear(); }
+   virtual std::vector<SPtr<Block3D> >& getSolidBlockSet() { return this->solidBlocks; }
+   virtual void removeSolidBlocks() { this->solidBlocks.clear(); }
+
+   void setID(int id);
+   int getID();
+
+   void setActive();
+   void setInactive();
+   bool isActive();
+
+protected:
+   void setTimeDependent()   { UbSystem::setBit(this->type  , TIMEDEPENDENT); }
+   void unsetTimeDependent() { UbSystem::unsetBit(this->type, TIMEDEPENDENT); }
+   
+   //! detect that points are inside object
+   //! \param min/max coordinates of bounding box
+   //! \param delta is delta x
+   bool arePointsInsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+   
+   //! detect that points aren't inside object
+   //! \param min/max coordinates of bounding box
+   //! \param delta is delta x
+   bool arePointsOutsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+
+   //! detect that points are cutting object
+   //! \param min/max coordinates of bounding box
+   //! \param delta is delta x
+   bool arePointsCuttingGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+   
+   bool isBlockOutsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+   bool isBlockInsideGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+   bool isBlockCuttingGeoObject(double minX1, double minX2, double minX3, double maxX1, double maxX2, double maxX3, double delta);
+
+   int type;
+   
+   WPtr<Grid3D> grid;
+   SPtr<GbObject3D> geoObject3D;
+
+   std::vector<SPtr<Block3D> > bcBlocks;
+   std::vector<SPtr<Block3D> > solidBlocks;
+   int accuracy;
+   
+   bool active;
+   int id;
+
+public:
+   static const int SOLID	            ;//= (1<<0); //1
+   static const int INVERSESOLID       ;//= (1<<1); //2
+   static const int TIMEDEPENDENT      ;//= (1<<2); //4   //zeitlich
+   static const int FLUID              ;//= (1<<3); //8
+   static const int MOVEABLE           ;//= (1<<4); //16  // geometrisch
+   static const int CHANGENOTNECESSARY ;//= (1<<5); //32
+
+private:
+
+};
+
+
+
+#endif
diff --git a/VirtualFluidsCore/Interactors/InteractorsHelper.cpp b/VirtualFluidsCore/Interactors/InteractorsHelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff6fe730cae27dc2ce08690096a1c51bfb54a01d
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/InteractorsHelper.cpp
@@ -0,0 +1,78 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file InteractorsHelper.cpp
+//! \ingroup Interactor
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "InteractorsHelper.h"
+
+#include <Grid3DVisitor.h>
+#include <Grid3D.h>
+#include <Interactor3D.h>
+#include "Block3D.h"
+#include "SetSolidBlocksBlockVisitor.h"
+#include "SetBcBlocksBlockVisitor.h"
+
+
+InteractorsHelper::InteractorsHelper(SPtr<Grid3D> grid) :grid(grid)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+InteractorsHelper::~InteractorsHelper()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void InteractorsHelper::addInteractor( SPtr<Interactor3D> interactor )
+{
+   interactors.push_back(interactor);
+}
+//////////////////////////////////////////////////////////////////////////
+void InteractorsHelper::setBC()
+{
+    for(SPtr<Interactor3D> i : interactors)
+        i->initInteractor();
+}
+//////////////////////////////////////////////////////////////////////////
+void InteractorsHelper::selectBlocks()
+{
+   setBcBlocks();
+}
+//////////////////////////////////////////////////////////////////////////
+void InteractorsHelper::setBcBlocks()
+{
+    for(const SPtr<Interactor3D> interactor : interactors)
+    {
+       SetBcBlocksBlockVisitor v(interactor);
+       grid->accept(v);
+    }
+}
+
diff --git a/VirtualFluidsCore/Interactors/InteractorsHelper.h b/VirtualFluidsCore/Interactors/InteractorsHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..29ed01a16432fb1080d01735d67aafcea46ee38c
--- /dev/null
+++ b/VirtualFluidsCore/Interactors/InteractorsHelper.h
@@ -0,0 +1,66 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file InteractorsHelper.h
+//! \ingroup Interactor
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef InteractorsHelper_h 
+#define InteractorsHelper_h
+
+#include <vector>
+#include <PointerDefinitions.h>
+
+
+class Interactor3D;
+class Block3D;
+class Grid3D;
+class Grid3DVisitor;
+
+//! A helper class for grid generation.
+class InteractorsHelper
+{
+public:
+   InteractorsHelper(SPtr<Grid3D> grid);
+   ~InteractorsHelper();
+
+   void addInteractor(SPtr<Interactor3D> interactor);
+   void selectBlocks();
+   void setBC();
+protected:
+   void setBcBlocks();
+private:
+   std::vector<SPtr<Interactor3D> > interactors;
+   SPtr<Grid3D> grid;
+   std::vector<SPtr<Block3D> > solidBlocks;
+   SPtr<Grid3DVisitor> visitor;
+   bool deleteBlocks;
+};
+
+#endif
diff --git a/VirtualFluidsCore/LBM/CMakePackage.txt b/VirtualFluidsCore/LBM/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/LBM/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp b/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..79f0a586ad946cdf1624b8d915318006a0a7d24c
--- /dev/null
+++ b/VirtualFluidsCore/LBM/CumulantK17LBMKernel.cpp
@@ -0,0 +1,648 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CumulantK17LBMKernel.cpp
+//! \ingroup LBM
+//! \author Konstantin Kutscher, Martin Geier
+//=======================================================================================
+
+#include "CumulantK17LBMKernel.h"
+#include "D3Q27System.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include <math.h>
+#include "DataSet3D.h"
+#include "LBMKernel.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+#define PROOF_CORRECTNESS
+
+using namespace UbMath;
+
+//////////////////////////////////////////////////////////////////////////
+CumulantK17LBMKernel::CumulantK17LBMKernel()
+{
+   this->compressible = true;
+}
+//////////////////////////////////////////////////////////////////////////
+CumulantK17LBMKernel::~CumulantK17LBMKernel(void)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void CumulantK17LBMKernel::initDataSet()
+{
+   SPtr<DistributionArray3D> d(new D3Q27EsoTwist3DSplittedVector(nx[0] + 2, nx[1] + 2, nx[2] + 2, -999.9));
+   dataSet->setFdistributions(d);
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<LBMKernel> CumulantK17LBMKernel::clone()
+{
+   SPtr<LBMKernel> kernel(new CumulantK17LBMKernel());
+   kernel->setNX(nx);
+   std::dynamic_pointer_cast<CumulantK17LBMKernel>(kernel)->initDataSet();
+   kernel->setCollisionFactor(this->collFactor);
+   kernel->setBCProcessor(bcProcessor->clone(kernel));
+   kernel->setWithForcing(withForcing);
+   kernel->setForcingX1(muForcingX1);
+   kernel->setForcingX2(muForcingX2);
+   kernel->setForcingX3(muForcingX3);
+   kernel->setIndex(ix1, ix2, ix3);
+   kernel->setDeltaT(deltaT);
+   kernel->setBlock(block.lock());
+
+   return kernel;
+}
+//////////////////////////////////////////////////////////////////////////
+void CumulantK17LBMKernel::calculate(int step)
+{
+   //////////////////////////////////////////////////////////////////////////
+	//! Cumulant K17 Kernel is based on
+   //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+	//! and 
+	//! <a href="https://doi.org/10.1016/j.jcp.2017.07.004"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.07.004 ]</b></a>
+	//!
+	//! The cumulant kernel is executed in the following steps
+	//!
+	////////////////////////////////////////////////////////////////////////////////
+	//! - Get node index coordinates from thredIdx, blockIdx, blockDim and gridDim.
+	//!
+   using namespace D3Q27System;
+   using namespace std;
+
+   //initializing of forcing stuff 
+   if (withForcing)
+   {
+      muForcingX1.DefineVar("x1", &muX1); muForcingX1.DefineVar("x2", &muX2); muForcingX1.DefineVar("x3", &muX3);
+      muForcingX2.DefineVar("x1", &muX1); muForcingX2.DefineVar("x2", &muX2); muForcingX2.DefineVar("x3", &muX3);
+      muForcingX3.DefineVar("x1", &muX1); muForcingX3.DefineVar("x2", &muX2); muForcingX3.DefineVar("x3", &muX3);
+
+      muDeltaT = deltaT;
+
+      muForcingX1.DefineVar("dt", &muDeltaT);
+      muForcingX2.DefineVar("dt", &muDeltaT);
+      muForcingX3.DefineVar("dt", &muDeltaT);
+
+      muNu = (1.0 / 3.0) * (1.0 / collFactor - 1.0 / 2.0);
+
+      muForcingX1.DefineVar("nu", &muNu);
+      muForcingX2.DefineVar("nu", &muNu);
+      muForcingX3.DefineVar("nu", &muNu);
+
+      LBMReal forcingX1 = 0;
+      LBMReal forcingX2 = 0;
+      LBMReal forcingX3 = 0;
+   }
+   /////////////////////////////////////
+
+   localDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+   nonLocalDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+   restDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+   SPtr<BCArray3D> bcArray = this->getBCProcessor()->getBCArray();
+
+   const int bcArrayMaxX1 = (int)bcArray->getNX1();
+   const int bcArrayMaxX2 = (int)bcArray->getNX2();
+   const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+   int minX1 = ghostLayerWidth;
+   int minX2 = ghostLayerWidth;
+   int minX3 = ghostLayerWidth;
+   int maxX1 = bcArrayMaxX1 - ghostLayerWidth;
+   int maxX2 = bcArrayMaxX2 - ghostLayerWidth;
+   int maxX3 = bcArrayMaxX3 - ghostLayerWidth;
+
+   LBMReal omega = collFactor;
+
+   for (int x3 = minX3; x3 < maxX3; x3++)
+   {
+      for (int x2 = minX2; x2 < maxX2; x2++)
+      {
+         for (int x1 = minX1; x1 < maxX1; x1++)
+         {
+            if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
+            {
+               int x1p = x1 + 1;
+               int x2p = x2 + 1;
+               int x3p = x3 + 1;
+               //////////////////////////////////////////////////////////////////////////
+               //////////////////////////////////////////////////////////////////////////
+			      //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm
+			      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+			      //!
+               ////////////////////////////////////////////////////////////////////////////
+               //////////////////////////////////////////////////////////////////////////
+
+               //E   N  T
+               //c   c  c
+               //////////
+               //W   S  B
+               //a   a  a
+
+               //Rest is b
+
+               //mfxyz
+               //a - negative
+               //b - null
+               //c - positive
+
+               // a b c
+               //-1 0 1
+
+               LBMReal mfcbb = (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3);
+               LBMReal mfbcb = (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3);
+               LBMReal mfbbc = (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3);
+               LBMReal mfccb = (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3);
+               LBMReal mfacb = (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3);
+               LBMReal mfcbc = (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3);
+               LBMReal mfabc = (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3);
+               LBMReal mfbcc = (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3);
+               LBMReal mfbac = (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3);
+               LBMReal mfccc = (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3);
+               LBMReal mfacc = (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3);
+               LBMReal mfcac = (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3);
+               LBMReal mfaac = (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3);
+
+               LBMReal mfabb = (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3);
+               LBMReal mfbab = (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3);
+               LBMReal mfbba = (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p);
+               LBMReal mfaab = (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3);
+               LBMReal mfcab = (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3);
+               LBMReal mfaba = (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p);
+               LBMReal mfcba = (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p);
+               LBMReal mfbaa = (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p);
+               LBMReal mfbca = (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p);
+               LBMReal mfaaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+               LBMReal mfcaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p);
+               LBMReal mfaca = (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p);
+               LBMReal mfcca = (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p);
+
+               LBMReal mfbbb = (*this->restDistributions)(x1, x2, x3);
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               //! - Calculate density and velocity using pyramid summation for low round-off errors as in Eq. (J1)-(J3)
+			      //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			      //!
+               LBMReal drho = ((((mfccc + mfaaa) + (mfaca + mfcac)) + ((mfacc + mfcaa) + (mfaac + mfcca))) +
+                  (((mfbac + mfbca) + (mfbaa + mfbcc)) + ((mfabc + mfcba) + (mfaba + mfcbc)) + ((mfacb + mfcab) + (mfaab + mfccb))) +
+                  ((mfabb + mfcbb) + (mfbab + mfbcb)) + (mfbba + mfbbc)) + mfbbb;
+
+               LBMReal rho = c1 + drho;
+               LBMReal OOrho = c1 / rho;
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal vvx = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfcaa - mfacc) + (mfcca - mfaac))) +
+                  (((mfcba - mfabc) + (mfcbc - mfaba)) + ((mfcab - mfacb) + (mfccb - mfaab))) +
+                  (mfcbb - mfabb)) / rho;
+               LBMReal vvy = ((((mfccc - mfaaa) + (mfaca - mfcac)) + ((mfacc - mfcaa) + (mfcca - mfaac))) +
+                  (((mfbca - mfbac) + (mfbcc - mfbaa)) + ((mfacb - mfcab) + (mfccb - mfaab))) +
+                  (mfbcb - mfbab)) / rho;
+               LBMReal vvz = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfacc - mfcaa) + (mfaac - mfcca))) +
+                  (((mfbac - mfbca) + (mfbcc - mfbaa)) + ((mfabc - mfcba) + (mfcbc - mfaba))) +
+                  (mfbbc - mfbba)) / rho;
+               ////////////////////////////////////////////////////////////////////////////////////
+               //forcing 
+               ///////////////////////////////////////////////////////////////////////////////////////////
+               if (withForcing)
+               {
+                  muX1 = static_cast<double>(x1 - 1 + ix1 * maxX1);
+                  muX2 = static_cast<double>(x2 - 1 + ix2 * maxX2);
+                  muX3 = static_cast<double>(x3 - 1 + ix3 * maxX3);
+
+                  forcingX1 = muForcingX1.Eval();
+                  forcingX2 = muForcingX2.Eval();
+                  forcingX3 = muForcingX3.Eval();
+
+                  ////////////////////////////////////////////////////////////////////////////////////
+			         //! - Add half of the acceleration (body force) to the velocity as in Eq. (42)
+			         //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			         //!
+                  vvx += forcingX1 * deltaT * c1o2; // X
+                  vvy += forcingX2 * deltaT * c1o2; // Y
+                  vvz += forcingX3 * deltaT * c1o2; // Z
+               }
+               ///////////////////////////////////////////////////////////////////////////////////////////               
+               ////////////////////////////////////////////////////////////////////////////////////
+               LBMReal oMdrho = c1;
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      // calculate the square of velocities for this lattice node
+               LBMReal vx2 = vvx * vvx;
+               LBMReal vy2 = vvy * vvy;
+               LBMReal vz2 = vvz * vvz;
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Set relaxation limiters for third order cumulants to default value \f$ \lambda=0.001 \f$ according to section 6 in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               LBMReal wadjust;
+               LBMReal qudricLimitP = c1o100;
+               LBMReal qudricLimitM = c1o100;
+               LBMReal qudricLimitD = c1o100;
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Chimera transform from well conditioned distributions to central moments as defined in Appendix J in
+			      //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			      //! see also Eq. (6)-(14) in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Z - Dir
+               forwardInverseChimeraWithK(mfaaa, mfaab, mfaac, vvz, vz2, c36, c1o36);
+               forwardInverseChimeraWithK(mfaba, mfabb, mfabc, vvz, vz2, c9, c1o9);
+               forwardInverseChimeraWithK(mfaca, mfacb, mfacc, vvz, vz2, c36, c1o36);
+               forwardInverseChimeraWithK(mfbaa, mfbab, mfbac, vvz, vz2, c9, c1o9);
+               forwardInverseChimeraWithK(mfbba, mfbbb, mfbbc, vvz, vz2, c9o4, c4o9);
+               forwardInverseChimeraWithK(mfbca, mfbcb, mfbcc, vvz, vz2, c9, c1o9);
+               forwardInverseChimeraWithK(mfcaa, mfcab, mfcac, vvz, vz2, c36, c1o36);
+               forwardInverseChimeraWithK(mfcba, mfcbb, mfcbc, vvz, vz2, c9, c1o9);
+               forwardInverseChimeraWithK(mfcca, mfccb, mfccc, vvz, vz2, c36, c1o36);
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Y - Dir
+               forwardInverseChimeraWithK(mfaaa, mfaba, mfaca, vvy, vy2, c6, c1o6);
+               forwardChimera(mfaab, mfabb, mfacb, vvy, vy2);
+               forwardInverseChimeraWithK(mfaac, mfabc, mfacc, vvy, vy2, c18, c1o18);
+               forwardInverseChimeraWithK(mfbaa, mfbba, mfbca, vvy, vy2, c3o2, c2o3);
+               forwardChimera(mfbab, mfbbb, mfbcb, vvy, vy2);
+               forwardInverseChimeraWithK(mfbac, mfbbc, mfbcc, vvy, vy2, c9o2, c2o9);
+               forwardInverseChimeraWithK(mfcaa, mfcba, mfcca, vvy, vy2, c6, c1o6);
+               forwardChimera(mfcab, mfcbb, mfccb, vvy, vy2);
+               forwardInverseChimeraWithK(mfcac, mfcbc, mfccc, vvy, vy2, c18, c1o18);
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               // X - Dir
+               forwardInverseChimeraWithK(mfaaa, mfbaa, mfcaa, vvx, vx2, c1, c1);
+               forwardChimera(mfaba, mfbba, mfcba, vvx, vx2);
+               forwardInverseChimeraWithK(mfaca, mfbca, mfcca, vvx, vx2, c3, c1o3);
+               forwardChimera(mfaab, mfbab, mfcab, vvx, vx2);
+               forwardChimera(mfabb, mfbbb, mfcbb, vvx, vx2);
+               forwardChimera(mfacb, mfbcb, mfccb, vvx, vx2);
+               forwardInverseChimeraWithK(mfaac, mfbac, mfcac, vvx, vx2, c3, c1o3);
+               forwardChimera(mfabc, mfbbc, mfcbc, vvx, vx2);
+               forwardInverseChimeraWithK(mfacc, mfbcc, mfccc, vvx, vx2, c9, c1o9);
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Setting relaxation rates for non-hydrodynamic cumulants (default values). Variable names and equations according to
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!  => [NAME IN PAPER]=[NAME IN CODE]=[DEFAULT VALUE].
+			      //!  - Trace of second order cumulants \f$ C_{200}+C_{020}+C_{002} \f$ used to adjust bulk viscosity:\f$\omega_2=OxxPyyPzz=1.0 \f$.
+			      //!  - Third order cumulants \f$ C_{120}+C_{102} \f$, \f$ C_{210}+C_{012} \f$, \f$ C_{201}+C_{021} \f$: \f$\omega_3=OxyyPxzz\f$ set according to Eq. (111) with simplifications assuming \f$\omega_2=1.0\f$.
+			      //!  - Third order cumulants \f$ C_{120}-C_{102} \f$, \f$ C_{210}-C_{012} \f$, \f$ C_{201}-C_{021} \f$: \f$\omega_4 = OxyyMxzz\f$ set according to Eq. (112) with simplifications assuming \f$\omega_2 = 1.0\f$.
+			      //!  - Third order cumulants \f$ C_{111} \f$: \f$\omega_5 = Oxyz\f$ set according to Eq. (113) with simplifications assuming \f$\omega_2 = 1.0\f$  (modify for different bulk viscosity).
+			      //!  - Fourth order cumulants \f$ C_{220} \f$, \f$ C_{202} \f$, \f$ C_{022} \f$, \f$ C_{211} \f$, \f$ C_{121} \f$, \f$ C_{112} \f$: for simplification all set to the same default value \f$ \omega_6=\omega_7=\omega_8=O4=1.0 \f$.
+			      //!  - Fifth order cumulants \f$ C_{221}\f$, \f$C_{212}\f$, \f$C_{122}\f$: \f$\omega_9=O5=1.0\f$.
+			      //!  - Sixth order cumulant \f$ C_{222}\f$: \f$\omega_{10}=O6=1.0\f$.
+			      //!
+			      ////////////////////////////////////////////////////////////
+			      //2.
+			      LBMReal OxxPyyPzz = c1;
+			      ////////////////////////////////////////////////////////////
+			      //3.
+			      LBMReal OxyyPxzz = c8  * (-c2 + omega) * ( c1 + c2*omega) / (-c8 - c14*omega + c7*omega*omega);
+			      LBMReal OxyyMxzz = c8  * (-c2 + omega) * (-c7 + c4*omega) / (c56 - c50*omega + c9*omega*omega);
+			      LBMReal Oxyz     = c24 * (-c2 + omega) * (-c2 - c7*omega + c3*omega*omega) / (c48 + c152*omega - c130*omega*omega + c29*omega*omega*omega);
+			      ////////////////////////////////////////////////////////////
+			      //4.
+			      LBMReal O4 = c1;
+			      ////////////////////////////////////////////////////////////
+			      //5.
+			      LBMReal O5 = c1;
+			      ////////////////////////////////////////////////////////////
+			      //6.
+			      LBMReal O6 = c1;
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - A and B: parameters for fourth order convergence of the diffusion term according to Eq. (114) and (115)
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //! with simplifications assuming \f$\omega_2 = 1.0\f$ (modify for different bulk viscosity).
+			      //!
+			      LBMReal A = (c4 + c2*omega - c3*omega*omega) / (c2 - c7*omega + c5*omega*omega);
+			      LBMReal B = (c4 + c28*omega - c14*omega*omega) / (c6 - c21*omega + c15*omega*omega);
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Compute cumulants from central moments according to Eq. (20)-(23) in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+			      ////////////////////////////////////////////////////////////
+               //4.
+               LBMReal CUMcbb = mfcbb - ((mfcaa + c1o3) * mfabb + c2 * mfbba * mfbab) * OOrho;
+               LBMReal CUMbcb = mfbcb - ((mfaca + c1o3) * mfbab + c2 * mfbba * mfabb) * OOrho;
+               LBMReal CUMbbc = mfbbc - ((mfaac + c1o3) * mfbba + c2 * mfbab * mfabb) * OOrho;
+
+               LBMReal CUMcca = mfcca - (((mfcaa * mfaca + c2 * mfbba * mfbba) + c1o3 * (mfcaa + mfaca)) * OOrho - c1o9 * (drho * OOrho));
+               LBMReal CUMcac = mfcac - (((mfcaa * mfaac + c2 * mfbab * mfbab) + c1o3 * (mfcaa + mfaac)) * OOrho - c1o9 * (drho * OOrho));
+               LBMReal CUMacc = mfacc - (((mfaac * mfaca + c2 * mfabb * mfabb) + c1o3 * (mfaac + mfaca)) * OOrho - c1o9 * (drho * OOrho));
+               ////////////////////////////////////////////////////////////
+               //5.
+               LBMReal CUMbcc = mfbcc - ((mfaac * mfbca + mfaca * mfbac + c4 * mfabb * mfbbb + c2 * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac)) * OOrho;
+               LBMReal CUMcbc = mfcbc - ((mfaac * mfcba + mfcaa * mfabc + c4 * mfbab * mfbbb + c2 * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc)) * OOrho;
+               LBMReal CUMccb = mfccb - ((mfcaa * mfacb + mfaca * mfcab + c4 * mfbba * mfbbb + c2 * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab)) * OOrho;
+               ////////////////////////////////////////////////////////////
+               //6.
+               LBMReal CUMccc = mfccc + ((-c4 * mfbbb * mfbbb
+                     - (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                     - c4 * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
+                     - c2 * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb)) * OOrho
+                     + (c4 * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                     + c2 * (mfcaa * mfaca * mfaac)
+                     + c16 * mfbba * mfbab * mfabb) * OOrho * OOrho
+                     - c1o3 * (mfacc + mfcac + mfcca) * OOrho
+                     - c1o9 * (mfcaa + mfaca + mfaac) * OOrho
+                     + (c2 * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                     + (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa) + c1o3 * (mfaac + mfaca + mfcaa)) * OOrho * OOrho * c2o3
+                     + c1o27 * ((drho * drho - drho) * OOrho * OOrho));
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Compute linear combinations of second and third order cumulants
+			      //!
+			      ////////////////////////////////////////////////////////////
+               //2.
+               LBMReal mxxPyyPzz = mfcaa + mfaca + mfaac;
+               LBMReal mxxMyy = mfcaa - mfaca;
+               LBMReal mxxMzz = mfcaa - mfaac;
+			      ////////////////////////////////////////////////////////////
+			      //3.
+               LBMReal mxxyPyzz = mfcba + mfabc;
+               LBMReal mxxyMyzz = mfcba - mfabc;
+
+               LBMReal mxxzPyyz = mfcab + mfacb;
+               LBMReal mxxzMyyz = mfcab - mfacb;
+
+               LBMReal mxyyPxzz = mfbca + mfbac;
+               LBMReal mxyyMxzz = mfbca - mfbac;
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //incl. correction
+			      ////////////////////////////////////////////////////////////
+			      //! - Compute velocity  gradients from second order cumulants according to Eq. (27)-(32)
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //! Further explanations of the correction in viscosity in Appendix H of
+			      //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			      //! Note that the division by rho is omitted here as we need rho times the gradients later.
+			      //!
+               LBMReal Dxy = -c3 * omega * mfbba;
+               LBMReal Dxz = -c3 * omega * mfbab;
+               LBMReal Dyz = -c3 * omega * mfabb;
+               LBMReal dxux = c1o2 * (-omega) * (mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz * (mfaaa - mxxPyyPzz);
+               LBMReal dyuy = dxux + omega * c3o2 * mxxMyy;
+               LBMReal dzuz = dxux + omega * c3o2 * mxxMzz;
+			      ////////////////////////////////////////////////////////////
+			      //! - Relaxation of second order cumulants with correction terms according to Eq. (33)-(35) in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               mxxPyyPzz += OxxPyyPzz * (mfaaa - mxxPyyPzz) - c3 * (c1 - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
+               mxxMyy += omega * (-mxxMyy) - c3 * (c1 + c1o2 * (-omega)) * (vx2 * dxux - vy2 * dyuy);
+               mxxMzz += omega * (-mxxMzz) - c3 * (c1 + c1o2 * (-omega)) * (vx2 * dxux - vz2 * dzuz);
+
+               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+               ////no correction
+               //mxxPyyPzz += OxxPyyPzz*(mfaaa - mxxPyyPzz);
+               //mxxMyy += -(-omega) * (-mxxMyy);
+               //mxxMzz += -(-omega) * (-mxxMzz);
+               /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+               mfabb += omega * (-mfabb);
+               mfbab += omega * (-mfbab);
+               mfbba += omega * (-mfbba);
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //relax
+			      //////////////////////////////////////////////////////////////////////////
+			      // incl. limiter
+			      //! - Relaxation of third order cumulants including limiter according to Eq. (116)-(123)
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               wadjust = Oxyz + (c1 - Oxyz) * abs(mfbbb) / (abs(mfbbb) + qudricLimitD);
+               mfbbb += wadjust * (-mfbbb);
+               wadjust = OxyyPxzz + (c1 - OxyyPxzz) * abs(mxxyPyzz) / (abs(mxxyPyzz) + qudricLimitP);
+               mxxyPyzz += wadjust * (-mxxyPyzz);
+               wadjust = OxyyMxzz + (c1 - OxyyMxzz) * abs(mxxyMyzz) / (abs(mxxyMyzz) + qudricLimitM);
+               mxxyMyzz += wadjust * (-mxxyMyzz);
+               wadjust = OxyyPxzz + (c1 - OxyyPxzz) * abs(mxxzPyyz) / (abs(mxxzPyyz) + qudricLimitP);
+               mxxzPyyz += wadjust * (-mxxzPyyz);
+               wadjust = OxyyMxzz + (c1 - OxyyMxzz) * abs(mxxzMyyz) / (abs(mxxzMyyz) + qudricLimitM);
+               mxxzMyyz += wadjust * (-mxxzMyyz);
+               wadjust = OxyyPxzz + (c1 - OxyyPxzz) * abs(mxyyPxzz) / (abs(mxyyPxzz) + qudricLimitP);
+               mxyyPxzz += wadjust * (-mxyyPxzz);
+               wadjust = OxyyMxzz + (c1 - OxyyMxzz) * abs(mxyyMxzz) / (abs(mxyyMxzz) + qudricLimitM);
+               mxyyMxzz += wadjust * (-mxyyMxzz);
+               //////////////////////////////////////////////////////////////////////////
+               // no limiter
+               //mfbbb += OxyyMxzz * (-mfbbb);
+               //mxxyPyzz += OxyyPxzz * (-mxxyPyzz);
+               //mxxyMyzz += OxyyMxzz * (-mxxyMyzz);
+               //mxxzPyyz += OxyyPxzz * (-mxxzPyyz);
+               //mxxzMyyz += OxyyMxzz * (-mxxzMyyz);
+               //mxyyPxzz += OxyyPxzz * (-mxyyPxzz);
+               //mxyyMxzz += OxyyMxzz * (-mxyyMxzz);
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Compute inverse linear combinations of second and third order cumulants
+			      //!
+               mfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
+               mfaca = c1o3 * (-c2 * mxxMyy + mxxMzz + mxxPyyPzz);
+               mfaac = c1o3 * (mxxMyy - c2 * mxxMzz + mxxPyyPzz);
+
+               mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
+               mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
+               mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
+               mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
+               mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
+               mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
+               //////////////////////////////////////////////////////////////////////////
+
+			      //////////////////////////////////////////////////////////////////////////
+			      //4.
+			      // no limiter
+			      //! - Relax fourth order cumulants to modified equilibrium for fourth order convergence of diffusion according to Eq. (43)-(48)
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               CUMacc = -O4 * (c1 / omega - c1o2) * (dyuy + dzuz) * c2o3 * A + (c1 - O4) * (CUMacc);
+               CUMcac = -O4 * (c1 / omega - c1o2) * (dxux + dzuz) * c2o3 * A + (c1 - O4) * (CUMcac);
+               CUMcca = -O4 * (c1 / omega - c1o2) * (dyuy + dxux) * c2o3 * A + (c1 - O4) * (CUMcca);
+               CUMbbc = -O4 * (c1 / omega - c1o2) * Dxy * c1o3 * B + (c1 - O4) * (CUMbbc);
+               CUMbcb = -O4 * (c1 / omega - c1o2) * Dxz * c1o3 * B + (c1 - O4) * (CUMbcb);
+               CUMcbb = -O4 * (c1 / omega - c1o2) * Dyz * c1o3 * B + (c1 - O4) * (CUMcbb);
+
+               //////////////////////////////////////////////////////////////////////////
+               //5.
+               CUMbcc += O5 * (-CUMbcc);
+               CUMcbc += O5 * (-CUMcbc);
+               CUMccb += O5 * (-CUMccb);
+
+               //////////////////////////////////////////////////////////////////////////
+               //6.
+               CUMccc += O6 * (-CUMccc);
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Compute central moments from post collision cumulants according to Eq. (53)-(56) in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+
+			      //////////////////////////////////////////////////////////////////////////
+               //4.
+               mfcbb = CUMcbb + c1o3 * ((c3 * mfcaa + c1) * mfabb + c6 * mfbba * mfbab) * OOrho;
+               mfbcb = CUMbcb + c1o3 * ((c3 * mfaca + c1) * mfbab + c6 * mfbba * mfabb) * OOrho;
+               mfbbc = CUMbbc + c1o3 * ((c3 * mfaac + c1) * mfbba + c6 * mfbab * mfabb) * OOrho;
+
+               mfcca = CUMcca + (((mfcaa * mfaca + c2 * mfbba * mfbba) * c9 + c3 * (mfcaa + mfaca)) * OOrho - (drho * OOrho)) * c1o9;
+               mfcac = CUMcac + (((mfcaa * mfaac + c2 * mfbab * mfbab) * c9 + c3 * (mfcaa + mfaac)) * OOrho - (drho * OOrho)) * c1o9;
+               mfacc = CUMacc + (((mfaac * mfaca + c2 * mfabb * mfabb) * c9 + c3 * (mfaac + mfaca)) * OOrho - (drho * OOrho)) * c1o9;
+
+               //////////////////////////////////////////////////////////////////////////
+               //5.
+               mfbcc = CUMbcc + c1o3 * (c3 * (mfaac * mfbca + mfaca * mfbac + c4 * mfabb * mfbbb + c2 * (mfbab * mfacb + mfbba * mfabc)) + (mfbca + mfbac)) * OOrho;
+               mfcbc = CUMcbc + c1o3 * (c3 * (mfaac * mfcba + mfcaa * mfabc + c4 * mfbab * mfbbb + c2 * (mfabb * mfcab + mfbba * mfbac)) + (mfcba + mfabc)) * OOrho;
+               mfccb = CUMccb + c1o3 * (c3 * (mfcaa * mfacb + mfaca * mfcab + c4 * mfbba * mfbbb + c2 * (mfbab * mfbca + mfabb * mfcba)) + (mfacb + mfcab)) * OOrho;
+
+               //////////////////////////////////////////////////////////////////////////
+               //6.
+               mfccc = CUMccc - ((-c4 * mfbbb * mfbbb
+                     - (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca)
+                     - c4 * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc)
+                     - c2 * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb)) * OOrho
+                     + (c4 * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac)
+                     + c2 * (mfcaa * mfaca * mfaac)
+                     + c16 * mfbba * mfbab * mfabb) * OOrho * OOrho
+                     - c1o3 * (mfacc + mfcac + mfcca) * OOrho
+                     - c1o9 * (mfcaa + mfaca + mfaac) * OOrho
+                     + (c2 * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba)
+                     + (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa) + c1o3 * (mfaac + mfaca + mfcaa)) * OOrho * OOrho * c2o3
+                     + c1o27 * ((drho * drho - drho) * OOrho * OOrho));
+
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! -  Add acceleration (body force) to first order cumulants according to Eq. (85)-(87) in
+			      //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			      //!
+               mfbaa = -mfbaa;
+               mfaba = -mfaba;
+               mfaab = -mfaab;
+               ////////////////////////////////////////////////////////////////////////////////////
+
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
+			      //! <a href="https://doi.org/10.1016/j.camwa.2015.05.001"><b>[ M. Geier et al. (2015), DOI:10.1016/j.camwa.2015.05.001 ]</b></a>
+			      //! see also Eq. (88)-(96) in
+			      //! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+			      //!
+               ////////////////////////////////////////////////////////////////////////////////////
+               // X - Dir
+               backwardInverseChimeraWithK(mfaaa, mfbaa, mfcaa, vvx, vx2, c1, c1);
+               backwardChimera(mfaba, mfbba, mfcba, vvx, vx2);
+               backwardInverseChimeraWithK(mfaca, mfbca, mfcca, vvx, vx2, c3, c1o3);
+               backwardChimera(mfaab, mfbab, mfcab, vvx, vx2);
+               backwardChimera(mfabb, mfbbb, mfcbb, vvx, vx2);
+               backwardChimera(mfacb, mfbcb, mfccb, vvx, vx2);
+               backwardInverseChimeraWithK(mfaac, mfbac, mfcac, vvx, vx2, c3, c1o3);
+               backwardChimera(mfabc, mfbbc, mfcbc, vvx, vx2);
+               backwardInverseChimeraWithK(mfacc, mfbcc, mfccc, vvx, vx2, c9, c1o9);
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Y - Dir
+               backwardInverseChimeraWithK(mfaaa, mfaba, mfaca, vvy, vy2, c6, c1o6);
+               backwardChimera(mfaab, mfabb, mfacb, vvy, vy2);
+               backwardInverseChimeraWithK(mfaac, mfabc, mfacc, vvy, vy2, c18, c1o18);
+               backwardInverseChimeraWithK(mfbaa, mfbba, mfbca, vvy, vy2, c3o2, c2o3);
+               backwardChimera(mfbab, mfbbb, mfbcb, vvy, vy2);
+               backwardInverseChimeraWithK(mfbac, mfbbc, mfbcc, vvy, vy2, c9o2, c2o9);
+               backwardInverseChimeraWithK(mfcaa, mfcba, mfcca, vvy, vy2, c6, c1o6);
+               backwardChimera(mfcab, mfcbb, mfccb, vvy, vy2);
+               backwardInverseChimeraWithK(mfcac, mfcbc, mfccc, vvy, vy2, c18, c1o18);
+
+               ////////////////////////////////////////////////////////////////////////////////////
+               // Z - Dir
+               backwardInverseChimeraWithK(mfaaa, mfaab, mfaac, vvz, vz2, c36, c1o36);
+               backwardInverseChimeraWithK(mfaba, mfabb, mfabc, vvz, vz2, c9, c1o9);
+               backwardInverseChimeraWithK(mfaca, mfacb, mfacc, vvz, vz2, c36, c1o36);
+               backwardInverseChimeraWithK(mfbaa, mfbab, mfbac, vvz, vz2, c9, c1o9);
+               backwardInverseChimeraWithK(mfbba, mfbbb, mfbbc, vvz, vz2, c9o4, c4o9);
+               backwardInverseChimeraWithK(mfbca, mfbcb, mfbcc, vvz, vz2, c9, c1o9);
+               backwardInverseChimeraWithK(mfcaa, mfcab, mfcac, vvz, vz2, c36, c1o36);
+               backwardInverseChimeraWithK(mfcba, mfcbb, mfcbc, vvz, vz2, c9, c1o9);
+               backwardInverseChimeraWithK(mfcca, mfccb, mfccc, vvz, vz2, c36, c1o36);
+               ////////////////////////////////////////////////////////////////////////////////////
+
+               //////////////////////////////////////////////////////////////////////////
+               //proof correctness
+               //////////////////////////////////////////////////////////////////////////
+#ifdef  PROOF_CORRECTNESS
+               LBMReal drho_post = (mfaaa + mfaac + mfaca + mfcaa + mfacc + mfcac + mfccc + mfcca)
+                  + (mfaab + mfacb + mfcab + mfccb) + (mfaba + mfabc + mfcba + mfcbc) + (mfbaa + mfbac + mfbca + mfbcc)
+                  + (mfabb + mfcbb) + (mfbab + mfbcb) + (mfbba + mfbbc) + mfbbb;
+               LBMReal dif = drho - drho_post;
+#ifdef SINGLEPRECISION
+               if (dif > 10.0E-7 || dif < -10.0E-7)
+#else
+               if (dif > 10.0E-15 || dif < -10.0E-15)
+#endif
+               {
+                  UB_THROW(UbException(UB_EXARGS, "rho=" + UbSystem::toString(drho) + ", rho_post=" + UbSystem::toString(drho_post)
+                     + " dif=" + UbSystem::toString(dif)
+                     + " rho is not correct for node " + UbSystem::toString(x1) + "," + UbSystem::toString(x2) + "," + UbSystem::toString(x3)
+                     + " in " + block.lock()->toString() + " step = " + UbSystem::toString(step)));
+               }
+#endif
+			      ////////////////////////////////////////////////////////////////////////////////////
+			      //! - Write distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm
+			      //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a>
+			      //!
+               (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3) = mfabb;
+               (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3) = mfbab;
+               (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3) = mfbba;
+               (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3) = mfaab;
+               (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3) = mfcab;
+               (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3) = mfaba;
+               (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3) = mfcba;
+               (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3) = mfbaa;
+               (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3) = mfbca;
+               (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3) = mfaaa;
+               (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3) = mfcaa;
+               (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3) = mfaca;
+               (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3) = mfcca;
+
+               (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3) = mfcbb;
+               (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3) = mfbcb;
+               (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p) = mfbbc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3) = mfccb;
+               (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3) = mfacb;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p) = mfcbc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p) = mfabc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p) = mfbcc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p) = mfbac;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p) = mfacc;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p) = mfcac;
+               (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p) = mfaac;
+
+               (*this->restDistributions)(x1, x2, x3) = mfbbb;
+               //////////////////////////////////////////////////////////////////////////
+
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+
diff --git a/VirtualFluidsCore/LBM/CumulantK17LBMKernel.h b/VirtualFluidsCore/LBM/CumulantK17LBMKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..47b9a550a3f1b4424322cce5e28c6917945ed8d4
--- /dev/null
+++ b/VirtualFluidsCore/LBM/CumulantK17LBMKernel.h
@@ -0,0 +1,146 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file CumulantK17LBMKernel.h
+//! \ingroup LBM
+//! \author Konstantin Kutscher, Martin Geier
+//=======================================================================================
+
+#ifndef CumulantK17LBMKernel_h__
+#define CumulantK17LBMKernel_h__
+
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "D3Q27System.h"
+#include "basics/utilities/UbTiming.h"
+#include "basics/container/CbArray4D.h"
+#include "basics/container/CbArray3D.h"
+
+//! \brief   Compressible cumulant LBM kernel. 
+//! \details  LBM implementation that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model
+//!
+//! The model is publisched in
+//! <a href="http://dx.doi.org/10.1016/j.jcp.2017.05.040"><b>[ Geier et al., (2017), 10.1016/j.jcp.2017.05.040]</b></a>,
+//! <a href="http://dx.doi.org/10.1016/j.jcp.2017.07.004"><b>[ Geier et al., (2017), 10.1016/j.jcp.2017.07.004]</b></a> 
+//! 
+class CumulantK17LBMKernel : public LBMKernel
+{
+public:
+   CumulantK17LBMKernel();
+   virtual ~CumulantK17LBMKernel(void);
+   virtual void calculate(int step);
+   virtual SPtr<LBMKernel> clone();
+
+protected:
+   inline void forwardInverseChimeraWithK(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2, LBMReal Kinverse, LBMReal K);
+   inline void backwardInverseChimeraWithK(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2, LBMReal Kinverse, LBMReal K);
+   inline void forwardChimera(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2);
+   inline void backwardChimera(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2);
+
+   virtual void initDataSet();
+   LBMReal f[D3Q27System::ENDF + 1];
+
+   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
+   CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
+   CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr   restDistributions;
+
+   mu::value_type muX1, muX2, muX3;
+   mu::value_type muDeltaT;
+   mu::value_type muNu;
+   LBMReal forcingX1;
+   LBMReal forcingX2;
+   LBMReal forcingX3;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//! \brief forward chimera transformation \ref forwardInverseChimeraWithK 
+//! Transformation from distributions to central moments according to Eq. (6)-(14) in
+//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+//! Modified for lower round-off errors.
+////////////////////////////////////////////////////////////////////////////////
+inline void CumulantK17LBMKernel::forwardInverseChimeraWithK(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2, LBMReal Kinverse, LBMReal K)
+{
+   using namespace UbMath;
+   LBMReal m2 = mfa + mfc;
+   LBMReal m1 = mfc - mfa;
+   LBMReal m0 = m2 + mfb;
+   mfa = m0;
+   m0 *= Kinverse;
+   m0 += c1;
+   mfb = (m1 * Kinverse - m0 * vv) * K;
+   mfc = ((m2 - c2 * m1 * vv) * Kinverse + v2 * m0) * K;
+}
+////////////////////////////////////////////////////////////////////////////////
+//! \brief backward chimera transformation \ref backwardInverseChimeraWithK 
+//! Transformation from central moments to distributions according to Eq. (57)-(65) in
+//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+//! Modified for lower round-off errors.
+////////////////////////////////////////////////////////////////////////////////
+inline void CumulantK17LBMKernel::backwardInverseChimeraWithK(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2, LBMReal Kinverse, LBMReal K)
+{
+   using namespace UbMath;
+   LBMReal m0 = (((mfc - mfb) * c1o2 + mfb * vv) * Kinverse + (mfa * Kinverse + c1) * (v2 - vv) * c1o2) * K;
+   LBMReal m1 = (((mfa - mfc) - c2 * mfb * vv) * Kinverse + (mfa * Kinverse + c1) * (-v2)) * K;
+   mfc = (((mfc + mfb) * c1o2 + mfb * vv) * Kinverse + (mfa * Kinverse + c1) * (v2 + vv) * c1o2) * K;
+   mfa = m0;
+   mfb = m1;
+}
+////////////////////////////////////////////////////////////////////////////////
+//! \brief forward chimera transformation \ref forwardChimera 
+//! Transformation from distributions to central moments according to Eq. (6)-(14) in
+//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+//! for \f$ K_{abc}=0 \f$. This is to avoid unnessary floating point operations.
+//! Modified for lower round-off errors.
+////////////////////////////////////////////////////////////////////////////////
+inline void CumulantK17LBMKernel::forwardChimera(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2)
+{
+   using namespace UbMath;
+   LBMReal m1 = (mfa + mfc) + mfb;
+   LBMReal m2 = mfc - mfa;
+   mfc = (mfc + mfa) + (v2 * m1 - c2 * vv * m2);
+   mfb = m2 - vv * m1;
+   mfa = m1;
+}
+////////////////////////////////////////////////////////////////////////////////
+//! \brief backward chimera transformation \ref backwardChimera 
+//! Transformation from central moments to distributions according to Eq. (57)-(65) in
+//! <a href="https://doi.org/10.1016/j.jcp.2017.05.040"><b>[ M. Geier et al. (2017), DOI:10.1016/j.jcp.2017.05.040 ]</b></a>
+//! for \f$ K_{abc}=0 \f$. This is to avoid unnessary floating point operations.
+//! Modified for lower round-off errors.
+////////////////////////////////////////////////////////////////////////////////
+inline void CumulantK17LBMKernel::backwardChimera(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2)
+{
+   using namespace UbMath;
+   LBMReal ma = (mfc + mfa * (v2 - vv)) * c1o2 + mfb * (vv - c1o2);
+   LBMReal mb = ((mfa - mfc) - mfa * v2) - c2 * mfb * vv;
+   mfc = (mfc + mfa * (v2 + vv)) * c1o2 + mfb * (vv + c1o2);
+   mfb = mb;
+   mfa = ma;
+}
+
+#endif // CumulantK17LBMKernel_h__
\ No newline at end of file
diff --git a/VirtualFluidsCore/LBM/D3Q27System.cpp b/VirtualFluidsCore/LBM/D3Q27System.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e618055721c5b7940fcb75a37717d05c40327179
--- /dev/null
+++ b/VirtualFluidsCore/LBM/D3Q27System.cpp
@@ -0,0 +1,196 @@
+#include "D3Q27System.h"
+namespace D3Q27System
+{
+   using namespace UbMath;
+    //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18//falsch
+    //f:              REST, E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    //const int EX1[] = { 0,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
+    //const int EX2[] = { 0,  0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
+    //const int EX3[] = { 0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
+
+    //index             0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
+    //f:                E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    const int DX1[] = { 1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1,  0,  0,  0,  0,  1, -1,  1, -1,  1, -1,  1, -1 };
+    const int DX2[] = { 0,  0,  1, -1,  0,  0,  1, -1, -1,  1,  0,  0,  0,  0,  1, -1,  1, -1,  1,  1, -1, -1,  1,  1, -1, -1 };
+    const int DX3[] = { 0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1,  1,  1, -1, -1, -1, -1 };
+
+    ////index                0   1   2   3   4   5  6   7   8    9  10  11  12  13  14  15  16  17  18
+    ////f:                   E,  W,  N,  S,  T,  B, NE, SW, SE, NW, TE, BW, BE, TW, TN, BS, BN, TS, TNE TNW TSE TSW BNE BNW BSE BSW
+    const double WEIGTH[] = { c2o27, c2o27,  c2o27,  c2o27,  c2o27,  c2o27,  c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o54, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216, c1o216 , c8o27 };
+
+
+    const int INVDIR[] = {
+                           INV_E,
+                           INV_W,
+                           INV_N,
+                           INV_S,
+                           INV_T,
+                           INV_B,
+                           INV_NE,
+                           INV_SW,
+                           INV_SE,
+                           INV_NW,
+                           INV_TE,
+                           INV_BW,
+                           INV_BE,
+                           INV_TW,
+                           INV_TN,
+                           INV_BS,
+                           INV_BN,
+                           INV_TS,
+                           INV_TNE,
+                           INV_TNW,
+                           INV_TSE,
+                           INV_TSW,
+                           INV_BNE,
+                           INV_BNW,
+                           INV_BSE,
+                           INV_BSW };
+
+
+    // The x,y,z component for each normalized direction
+    const double cNorm[3][ENDDIR] = {
+        {
+            double(DX1[0]), double(DX1[1]),
+            double(DX1[2]), double(DX1[3]),
+            double(DX1[4]), double(DX1[5]),
+            double(DX1[6]) / std::sqrt(double(2)), double(DX1[7]) / std::sqrt(double(2)),
+            double(DX1[8]) / std::sqrt(double(2)), double(DX1[9]) / std::sqrt(double(2)),
+            double(DX1[10]) / std::sqrt(double(2)), double(DX1[11]) / std::sqrt(double(2)),
+            double(DX1[12]) / std::sqrt(double(2)), double(DX1[13]) / std::sqrt(double(2)),
+            double(DX1[14]), double(DX1[15]),
+            double(DX1[16]), double(DX1[17]),
+            double(DX1[18]) / std::sqrt(double(3)), double(DX1[19]) / std::sqrt(double(3)),
+            double(DX1[20]) / std::sqrt(double(3)), double(DX1[21]) / std::sqrt(double(3)),
+            double(DX1[22]) / std::sqrt(double(3)), double(DX1[23]) / std::sqrt(double(3)),
+            double(DX1[24]) / std::sqrt(double(3)), double(DX1[25]) / std::sqrt(double(3))
+        },{
+            double(DX2[0]), double(DX2[1]),
+            double(DX2[2]), double(DX2[3]),
+            double(DX2[4]), double(DX2[5]),
+            double(DX2[6]) / std::sqrt(double(2)), double(DX2[7]) / std::sqrt(double(2)),
+            double(DX2[8]) / std::sqrt(double(2)), double(DX2[9]) / std::sqrt(double(2)),
+            double(DX2[10]), double(DX2[11]),
+            double(DX2[12]), double(DX2[13]),
+            double(DX2[14]) / std::sqrt(double(2)), double(DX2[15]) / std::sqrt(double(2)),
+            double(DX2[16]) / std::sqrt(double(2)), double(DX2[17]) / std::sqrt(double(2)),
+            double(DX2[18]) / std::sqrt(double(3)), double(DX2[19]) / std::sqrt(double(3)),
+            double(DX2[20]) / std::sqrt(double(3)), double(DX2[21]) / std::sqrt(double(3)),
+            double(DX2[22]) / std::sqrt(double(3)), double(DX2[23]) / std::sqrt(double(3)),
+            double(DX2[24]) / std::sqrt(double(3)), double(DX2[25]) / std::sqrt(double(3))
+        },{
+            double(DX3[0]), double(DX3[1]),
+            double(DX3[2]), double(DX3[3]),
+            double(DX3[4]), double(DX3[5]),
+            double(DX3[6]), double(DX3[7]),
+            double(DX3[8]), double(DX3[9]),
+            double(DX3[10]) / std::sqrt(double(2)), double(DX3[11]) / std::sqrt(double(2)),
+            double(DX3[12]) / std::sqrt(double(2)), double(DX3[13]) / std::sqrt(double(2)),
+            double(DX3[14]) / std::sqrt(double(2)), double(DX3[15]) / std::sqrt(double(2)),
+            double(DX3[16]) / std::sqrt(double(2)), double(DX3[17]) / std::sqrt(double(2)),
+            double(DX3[18]) / std::sqrt(double(3)), double(DX3[19]) / std::sqrt(double(3)),
+            double(DX3[20]) / std::sqrt(double(3)), double(DX3[21]) / std::sqrt(double(3)),
+            double(DX3[22]) / std::sqrt(double(3)), double(DX3[23]) / std::sqrt(double(3)),
+            double(DX3[24]) / std::sqrt(double(3)), double(DX3[25]) / std::sqrt(double(3))
+        }
+    };
+
+}
+
+//const int FSTARTDIR = 0;
+//const int FENDDIR   = 25;   //D3Q27
+
+//const int STARTF = 0;
+//const int ENDF   = 26;   //D3Q27
+
+//const int EX1[ENDF+1];
+//const int EX2[ENDF+1];
+//const int EX3[ENDF+1];
+
+//const int STARTDIR = 0;
+//const int ENDDIR   = 26; //alle geometrischen richtungen
+
+//const int DX1[ENDDIR+1];
+//const int DX2[ENDDIR+1];
+//const int DX3[ENDDIR+1];
+
+
+//const int E    /*f1 */ = 0;
+//const int W    /*f2 */ = 1;
+//const int N    /*f3 */ = 2;
+//const int S    /*f4 */ = 3;
+//const int T    /*f5 */ = 4;
+//const int B    /*f6 */ = 5;
+//const int NE   /*f7 */ = 6;
+//const int SW   /*f8 */ = 7;
+//const int SE   /*f9 */ = 8;
+//const int NW   /*f10*/ = 9;
+//const int TE   /*f11*/ = 10;
+//const int BW   /*f12*/ = 11;
+//const int BE   /*f13*/ = 12;
+//const int TW   /*f14*/ = 13;
+//const int TN   /*f15*/ = 14;
+//const int BS   /*f16*/ = 15;
+//const int BN   /*f17*/ = 16;
+//const int TS   /*f18*/ = 17;
+//const int TNE          = 18;
+//const int TNW          = 19;
+//const int TSE          = 20;
+//const int TSW          = 21;
+//const int BNE          = 22;
+//const int BNW          = 23;
+//const int BSE          = 24;
+//const int BSW          = 25;
+//const int REST /*f0 */ = 26;
+
+//const int INV_E   = W;  
+//const int INV_W   = E;  
+//const int INV_N   = S;  
+//const int INV_S   = N;  
+//const int INV_T   = B;  
+//const int INV_B   = T;  
+//const int INV_NE  = SW; 
+//const int INV_SW  = NE; 
+//const int INV_SE  = NW; 
+//const int INV_NW  = SE; 
+//const int INV_TE  = BW; 
+//const int INV_BW  = TE; 
+//const int INV_BE  = TW; 
+//const int INV_TW  = BE; 
+//const int INV_TN  = BS; 
+//const int INV_BS  = TN; 
+//const int INV_BN  = TS; 
+//const int INV_TS  = BN; 
+//const int INV_TNE = BSW;
+//const int INV_TNW = BSE;
+//const int INV_TSE = BNW;
+//const int INV_TSW = BNE;
+//const int INV_BNE = TSW;
+//const int INV_BNW = TSE;
+//const int INV_BSE = TNW;
+//const int INV_BSW = TNE;
+
+//const int INVDIR[ENDDIR+1];
+
+//const int M_RHO     = 0;  
+//const int M_EN      = 1;  
+//const int M_EPS     = 2;  
+//const int M_JX1     = 3;  
+//const int M_QX1     = 4;  
+//const int M_JX2     = 5;  
+//const int M_QX2     = 6;  
+//const int M_JX3     = 7;  
+//const int M_QX3     = 8;  
+//const int M_3PX1X1  = 9;  
+//const int M_3PIX1X1 = 10; 
+//const int M_PWW     = 11; 
+//const int M_PIWW    = 12; 
+//const int M_PX1X2   = 13; 
+//const int M_PX2X3   = 14; 
+//const int M_PX1X3   = 15; 
+//const int M_MX1     = 16; 
+//const int M_MX2     = 17; 
+//const int M_MX3     = 18; 
+
+//const int STARTM = 0;
+//const int ENDM   = 18;   //D3Q27
diff --git a/VirtualFluidsCore/LBM/D3Q27System.h b/VirtualFluidsCore/LBM/D3Q27System.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e1426a06eb14bd59f8b4d9fe86e4df63ecb16a4
--- /dev/null
+++ b/VirtualFluidsCore/LBM/D3Q27System.h
@@ -0,0 +1,594 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file D3Q27System.h
+//! \ingroup LBM
+//! \author Konstantin Kutscher, Sebastian Geller, Sören Freudiger
+//=======================================================================================
+
+#ifndef D3Q27SYSTEM_H
+#define D3Q27SYSTEM_H
+
+#include <cmath>
+#include <string>
+#include <iostream>
+
+#include "UbException.h"
+#include "UbMath.h"
+#include "LBMSystem.h"
+
+//! \brief namespace for global system-functions
+namespace D3Q27System
+{
+   //////////////////////////////////////////////////////////////////////////
+   //DIRECTION STUFF
+   static const int FSTARTDIR = 0;
+   static const int FENDDIR   = 25;   //D3Q27
+
+   static const int STARTF = 0;
+   static const int ENDF   = 26;   //D3Q27
+
+   static const int STARTDIR = 0;
+   static const int ENDDIR   = 26; //all geometric directions
+
+   extern const int DX1[ENDDIR+1];
+   extern const int DX2[ENDDIR+1];
+   extern const int DX3[ENDDIR+1];
+   extern const double WEIGTH[ENDDIR+1];
+
+   extern const double cNorm[3][ENDDIR];
+   
+   static const int E    = 0;
+   static const int W    = 1;
+   static const int N    = 2;
+   static const int S    = 3;
+   static const int T    = 4;
+   static const int B    = 5;
+   static const int NE   = 6;
+   static const int SW   = 7;
+   static const int SE   = 8;
+   static const int NW   = 9;
+   static const int TE   = 10;
+   static const int BW   = 11;
+   static const int BE   = 12;
+   static const int TW   = 13;
+   static const int TN   = 14;
+   static const int BS   = 15;
+   static const int BN   = 16;
+   static const int TS   = 17;
+   static const int TNE  = 18;
+   static const int TNW  = 19;
+   static const int TSE  = 20;
+   static const int TSW  = 21;
+   static const int BNE  = 22;
+   static const int BNW  = 23;
+   static const int BSE  = 24;
+   static const int BSW  = 25;
+   static const int REST = 26;
+
+   static const int INV_E   = W;  
+   static const int INV_W   = E;  
+   static const int INV_N   = S;  
+   static const int INV_S   = N;  
+   static const int INV_T   = B;  
+   static const int INV_B   = T;  
+   static const int INV_NE  = SW; 
+   static const int INV_SW  = NE; 
+   static const int INV_SE  = NW; 
+   static const int INV_NW  = SE; 
+   static const int INV_TE  = BW; 
+   static const int INV_BW  = TE; 
+   static const int INV_BE  = TW; 
+   static const int INV_TW  = BE; 
+   static const int INV_TN  = BS; 
+   static const int INV_BS  = TN; 
+   static const int INV_BN  = TS; 
+   static const int INV_TS  = BN; 
+   static const int INV_TNE = BSW;
+   static const int INV_TNW = BSE;
+   static const int INV_TSE = BNW;
+   static const int INV_TSW = BNE;
+   static const int INV_BNE = TSW;
+   static const int INV_BNW = TSE;
+   static const int INV_BSE = TNW;
+   static const int INV_BSW = TNE;
+                                       
+   extern const int INVDIR[ENDDIR+1];
+
+   static const int ET_E   = 0;
+   static const int ET_W   = 0;
+   static const int ET_N   = 1;
+   static const int ET_S   = 1;
+   static const int ET_T   = 2;
+   static const int ET_B   = 2;
+   static const int ET_NE  = 3;
+   static const int ET_SW  = 3;
+   static const int ET_SE  = 4;
+   static const int ET_NW  = 4;
+   static const int ET_TE  = 5;
+   static const int ET_BW  = 5;
+   static const int ET_BE  = 6;
+   static const int ET_TW  = 6;
+   static const int ET_TN  = 7;
+   static const int ET_BS  = 7;
+   static const int ET_BN  = 8;
+   static const int ET_TS  = 8;
+   static const int ET_TNE = 9;
+   static const int ET_BSW = 9;
+   static const int ET_TNW = 10;
+   static const int ET_BSE = 10;
+   static const int ET_TSE = 11;
+   static const int ET_BNW = 11;
+   static const int ET_TSW = 12;
+   static const int ET_BNE = 12;
+
+   
+   //////////////////////////////////////////////////////////////////////////
+   //MACROSCOPIC VALUES                  
+   /*=====================================================================*/
+   static LBMReal getDensity(const LBMReal* const& f/*[27]*/)
+   {
+      return  ((f[TNE] + f[BSW])+(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])+ (f[TSW]+f[BNE]))
+             +(((f[NE] + f[SW]) + (f[SE] + f[NW]))+((f[TE] + f[BW])+(f[BE]+ f[TW]))
+             +((f[BN] + f[TS]) + (f[TN] + f[BS])))+((f[E] + f[W])+(f[N] + f[S])
+             +(f[T] + f[B]))+f[REST];
+   }
+   /*=====================================================================*/
+   //ATTENTION: does not apply to all models -> use certificate instead of static! to do
+   static LBMReal getPressure(const LBMReal* const& f/*[27]*/)
+   {
+      return  REAL_CAST( UbMath::c1o3 )*getDensity(f);
+   }
+   /*=====================================================================*/
+   static LBMReal getIncompVelocityX1(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
+             (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
+             (f[E]-f[W]));  
+   }
+   /*=====================================================================*/
+   static LBMReal getIncompVelocityX2(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
+             (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
+             (f[N]-f[S]));  
+   }
+   /*=====================================================================*/
+   static LBMReal getIncompVelocityX3(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE] - f[BSW]) + (f[TSE] - f[BNW])) + ((f[TNW] - f[BSE]) + (f[TSW] - f[BNE]))) +
+             (((f[TS] - f[BN]) + (f[TN] - f[BS])) + ((f[TW] - f[BE]) + (f[TE] - f[BW]))) +
+             (f[T] - f[B]));
+   }
+   /*=====================================================================*/
+   static void calcDensity(const LBMReal* const& f/*[27]*/, LBMReal& rho)
+   {
+      rho = ((f[TNE] + f[BSW])+(f[TSE]+f[BNW]))+((f[BSE]+f[TNW])+ (f[TSW]+f[BNE]))
+         +(((f[NE] + f[SW]) + (f[SE] + f[NW]))+((f[TE] + f[BW])+(f[BE]+ f[TW]))
+         +((f[BN] + f[TS]) + (f[TN] + f[BS])))+((f[E] + f[W])+(f[N] + f[S])
+         +(f[T] + f[B]))+f[REST];
+         
+   }
+   /*=====================================================================*/
+   static void calcIncompVelocityX1(const LBMReal* const& f/*[27]*/, LBMReal& vx1)
+   {
+      vx1 = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
+             (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
+             (f[E]-f[W]));
+   }
+   /*=====================================================================*/
+   static void calcIncompVelocityX2(const LBMReal* const& f/*[27]*/, LBMReal& vx2)
+   {
+      vx2 = ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
+             (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
+             (f[N]-f[S]));
+   }
+   /*=====================================================================*/
+   static void calcIncompVelocityX3(const LBMReal* const& f/*[27]*/, LBMReal& vx3)
+   {
+      vx3 =((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[TNW]-f[BSE]) + (f[TSW]-f[BNE]))) +
+             (((f[TS]-f[BN]) + (f[TN]-f[BS])) + ((f[TW]-f[BE]) + (f[TE]-f[BW]))) +
+             (f[T]-f[B]));
+   }
+   /*=====================================================================*/
+   static LBMReal getCompVelocityX1(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
+             (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
+             (f[E]-f[W]))/getDensity(f);  
+   }
+   /*=====================================================================*/
+   static LBMReal getCompVelocityX2(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
+             (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
+             (f[N]-f[S]))/getDensity(f);  
+  }
+   /*=====================================================================*/
+   static LBMReal getCompVelocityX3(const LBMReal* const& f/*[27]*/)
+   {
+      return ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[TNW]-f[BSE]) + (f[TSW]-f[BNE]))) +
+             (((f[TS]-f[BN]) + (f[TN]-f[BS])) + ((f[TW]-f[BE]) + (f[TE]-f[BW]))) +
+             (f[T]-f[B]))/getDensity(f);
+   }
+   /*=====================================================================*/
+   static void calcCompVelocityX1(const LBMReal* const& f/*[27]*/, LBMReal& vx1)
+   {
+      vx1 = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[BSE]-f[TNW]) + (f[BNE]-f[TSW]))) +
+            (((f[BE]-f[TW]) + (f[TE]-f[BW])) + ((f[SE]-f[NW]) + (f[NE]-f[SW]))) +
+            (f[E]-f[W]))/getDensity(f);  
+   }
+   /*=====================================================================*/
+   static void calcCompVelocityX2(const LBMReal* const& f/*[27]*/, LBMReal& vx2)
+   {
+      vx2 = ((((f[TNE]-f[BSW]) + (f[BNW]-f[TSE])) + ((f[TNW]-f[BSE]) + (f[BNE]-f[TSW]))) +
+            (((f[BN]-f[TS]) + (f[TN]-f[BS])) + ((f[NW]-f[SE]) + (f[NE]-f[SW]))) +
+            (f[N]-f[S]))/getDensity(f);  
+   }
+   /*=====================================================================*/
+   static void calcCompVelocityX3(const LBMReal* const& f/*[27]*/, LBMReal& vx3)
+   {
+      vx3 = ((((f[TNE]-f[BSW]) + (f[TSE]-f[BNW])) + ((f[TNW]-f[BSE]) + (f[TSW]-f[BNE]))) +
+            (((f[TS]-f[BN]) + (f[TN]-f[BS])) + ((f[TW]-f[BE]) + (f[TE]-f[BW]))) +
+            (f[T]-f[B]))/getDensity(f);
+   }
+   /*=====================================================================*/
+   static void calcIncompMacroscopicValues(const LBMReal* const& f/*[27]*/, LBMReal& rho, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3)
+   {
+      D3Q27System::calcDensity(f, rho);
+      D3Q27System::calcIncompVelocityX1(f, vx1);
+      D3Q27System::calcIncompVelocityX2(f, vx2);
+      D3Q27System::calcIncompVelocityX3(f, vx3);
+   }
+
+   /*=====================================================================*/
+   static void calcCompMacroscopicValues(const LBMReal* const& f/*[27]*/, LBMReal& drho, LBMReal& vx1, LBMReal& vx2, LBMReal& vx3)
+   {
+      D3Q27System::calcDensity(f, drho);
+      D3Q27System::calcIncompVelocityX1(f, vx1);
+      D3Q27System::calcIncompVelocityX2(f, vx2);
+      D3Q27System::calcIncompVelocityX3(f, vx3);
+      LBMReal rho = drho+UbMath::c1;
+      vx1/=rho;
+      vx2/=rho;
+      vx3/=rho;
+   }
+   //////////////////////////////////////////////////////////////////////////
+   static LBMReal getCompFeqForDirection(const int& direction, const LBMReal& drho,const LBMReal& vx1,const LBMReal& vx2,const LBMReal& vx3)
+   {
+      using namespace UbMath;
+
+      LBMReal cu_sq=1.5*(vx1*vx1+vx2*vx2+vx3*vx3);
+
+      ////-----
+      LBMReal rho = drho+c1;
+      switch (direction)
+      {
+      case REST: return REAL_CAST(c8o27*(drho+rho*(-cu_sq)));
+      case E: return REAL_CAST(c2o27*(drho+rho*(3.0*(vx1)+c9o2*(vx1)*(vx1)-cu_sq)));
+      case W: return REAL_CAST(c2o27*(drho+rho*(3.0*(-vx1)+c9o2*(-vx1)*(-vx1)-cu_sq)));
+      case N: return REAL_CAST(c2o27*(drho+rho*(3.0*(vx2)+c9o2*(vx2)*(vx2)-cu_sq)));
+      case S: return REAL_CAST(c2o27*(drho+rho*(3.0*(-vx2)+c9o2*(-vx2)*(-vx2)-cu_sq)));
+      case T: return REAL_CAST(c2o27*(drho+rho*(3.0*(vx3)+c9o2*(vx3)*(vx3)-cu_sq)));
+      case B: return REAL_CAST(c2o27*(drho+rho*(3.0*(-vx3)+c9o2*(-vx3)*(-vx3)-cu_sq)));
+      case NE: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx1+vx2)+c9o2*(vx1+vx2)*(vx1+vx2)-cu_sq)));
+      case SW: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq)));
+      case SE: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx1-vx2)+c9o2*(vx1-vx2)*(vx1-vx2)-cu_sq)));
+      case NW: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq)));
+      case TE: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx1+vx3)+c9o2*(vx1+vx3)*(vx1+vx3)-cu_sq)));
+      case BW: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq)));
+      case BE: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx1-vx3)+c9o2*(vx1-vx3)*(vx1-vx3)-cu_sq)));
+      case TW: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq)));
+      case TN: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx2+vx3)+c9o2*(vx2+vx3)*(vx2+vx3)-cu_sq)));
+      case BS: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq)));
+      case BN: return REAL_CAST(c1o54*(drho+rho*(3.0*(vx2-vx3)+c9o2*(vx2-vx3)*(vx2-vx3)-cu_sq)));
+      case TS: return REAL_CAST(c1o54*(drho+rho*(3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq)));
+      case TNE: return REAL_CAST(c1o216*(drho+rho*(3.0*(vx1+vx2+vx3)+c9o2*(vx1+vx2+vx3)*(vx1+vx2+vx3)-cu_sq)));
+      case BSW: return REAL_CAST(c1o216*(drho+rho*(3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq)));
+      case BNE: return REAL_CAST(c1o216*(drho+rho*(3.0*(vx1+vx2-vx3)+c9o2*(vx1+vx2-vx3)*(vx1+vx2-vx3)-cu_sq)));
+      case TSW: return REAL_CAST(c1o216*(drho+rho*(3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq)));
+      case TSE: return REAL_CAST(c1o216*(drho+rho*(3.0*(vx1-vx2+vx3)+c9o2*(vx1-vx2+vx3)*(vx1-vx2+vx3)-cu_sq)));
+      case BNW: return REAL_CAST(c1o216*(drho+rho*(3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq)));
+      case BSE: return REAL_CAST(c1o216*(drho+rho*(3.0*(vx1-vx2-vx3)+c9o2*(vx1-vx2-vx3)*(vx1-vx2-vx3)-cu_sq)));
+      case TNW: return REAL_CAST(c1o216*(drho+rho*(3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq)));
+      default: throw UbException(UB_EXARGS, "unknown dir");
+      }
+
+   }
+   //////////////////////////////////////////////////////////////////////////
+   static void calcCompFeq(LBMReal* const& feq/*[27]*/,const LBMReal& drho,const LBMReal& vx1,const LBMReal& vx2,const LBMReal& vx3)	
+   {
+      using namespace UbMath;
+
+      LBMReal cu_sq = 1.5*(vx1*vx1+vx2*vx2+vx3*vx3);
+      LBMReal rho = drho+c1;
+
+      feq[REST] = c8o27*(drho+rho*(-cu_sq));
+      feq[E] = c2o27*(drho+rho*(3.0*(vx1)+c9o2*(vx1)*(vx1)-cu_sq));
+      feq[W] = c2o27*(drho+rho*(3.0*(-vx1)+c9o2*(-vx1)*(-vx1)-cu_sq));
+      feq[N] = c2o27*(drho+rho*(3.0*(vx2)+c9o2*(vx2)*(vx2)-cu_sq));
+      feq[S] = c2o27*(drho+rho*(3.0*(-vx2)+c9o2*(-vx2)*(-vx2)-cu_sq));
+      feq[T] = c2o27*(drho+rho*(3.0*(vx3)+c9o2*(vx3)*(vx3)-cu_sq));
+      feq[B] = c2o27*(drho+rho*(3.0*(-vx3)+c9o2*(-vx3)*(-vx3)-cu_sq));
+      feq[NE] = c1o54*(drho+rho*(3.0*(vx1+vx2)+c9o2*(vx1+vx2)*(vx1+vx2)-cu_sq));
+      feq[SW] = c1o54*(drho+rho*(3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq));
+      feq[SE] = c1o54*(drho+rho*(3.0*(vx1-vx2)+c9o2*(vx1-vx2)*(vx1-vx2)-cu_sq));
+      feq[NW] = c1o54*(drho+rho*(3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq));
+      feq[TE] = c1o54*(drho+rho*(3.0*(vx1+vx3)+c9o2*(vx1+vx3)*(vx1+vx3)-cu_sq));
+      feq[BW] = c1o54*(drho+rho*(3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq));
+      feq[BE] = c1o54*(drho+rho*(3.0*(vx1-vx3)+c9o2*(vx1-vx3)*(vx1-vx3)-cu_sq));
+      feq[TW] = c1o54*(drho+rho*(3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq));
+      feq[TN] = c1o54*(drho+rho*(3.0*(vx2+vx3)+c9o2*(vx2+vx3)*(vx2+vx3)-cu_sq));
+      feq[BS] = c1o54*(drho+rho*(3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq));
+      feq[BN] = c1o54*(drho+rho*(3.0*(vx2-vx3)+c9o2*(vx2-vx3)*(vx2-vx3)-cu_sq));
+      feq[TS] = c1o54*(drho+rho*(3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq));
+      feq[TNE] = c1o216*(drho+rho*(3.0*(vx1+vx2+vx3)+c9o2*(vx1+vx2+vx3)*(vx1+vx2+vx3)-cu_sq));
+      feq[BSW] = c1o216*(drho+rho*(3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq));
+      feq[BNE] = c1o216*(drho+rho*(3.0*(vx1+vx2-vx3)+c9o2*(vx1+vx2-vx3)*(vx1+vx2-vx3)-cu_sq));
+      feq[TSW] = c1o216*(drho+rho*(3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq));
+      feq[TSE] = c1o216*(drho+rho*(3.0*(vx1-vx2+vx3)+c9o2*(vx1-vx2+vx3)*(vx1-vx2+vx3)-cu_sq));
+      feq[BNW] = c1o216*(drho+rho*(3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq));
+      feq[BSE] = c1o216*(drho+rho*(3.0*(vx1-vx2-vx3)+c9o2*(vx1-vx2-vx3)*(vx1-vx2-vx3)-cu_sq));
+      feq[TNW] = c1o216*(drho+rho*(3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq));
+   }
+   //////////////////////////////////////////////////////////////////////////
+   static LBMReal getIncompFeqForDirection(const int& direction,const LBMReal& drho, const LBMReal& vx1,const LBMReal& vx2,const LBMReal& vx3)	
+   {
+      using namespace UbMath;
+
+      LBMReal cu_sq=1.5f*(vx1*vx1+vx2*vx2+vx3*vx3);
+
+      switch(direction)    
+      {		 
+         case REST : return REAL_CAST( c8o27*(drho-cu_sq));
+         case E : return REAL_CAST( c2o27*(drho+3.0*( vx1   )+c9o2*( vx1   )*( vx1   )-cu_sq));
+         case W : return REAL_CAST( c2o27*(drho+3.0*(-vx1   )+c9o2*(-vx1   )*(-vx1   )-cu_sq));
+         case N : return REAL_CAST( c2o27*(drho+3.0*(    vx2)+c9o2*(    vx2)*(    vx2)-cu_sq));
+         case S : return REAL_CAST( c2o27*(drho+3.0*(   -vx2)+c9o2*(   -vx2)*(   -vx2)-cu_sq));
+         case T : return REAL_CAST( c2o27*(drho+3.0*( vx3   )+c9o2*(    vx3)*(    vx3)-cu_sq));
+         case B : return REAL_CAST( c2o27*(drho+3.0*(   -vx3)+c9o2*(   -vx3)*(   -vx3)-cu_sq));
+         case NE : return REAL_CAST( c1o54*(drho+3.0*( vx1+vx2)+c9o2*( vx1+vx2)*( vx1+vx2)-cu_sq));
+         case SW : return REAL_CAST( c1o54*(drho+3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq));
+         case SE : return REAL_CAST( c1o54*(drho+3.0*( vx1-vx2)+c9o2*( vx1-vx2)*( vx1-vx2)-cu_sq));
+         case NW : return REAL_CAST( c1o54*(drho+3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq));
+         case TE : return REAL_CAST( c1o54*(drho+3.0*( vx1+vx3)+c9o2*( vx1+vx3)*( vx1+vx3)-cu_sq));
+         case BW : return REAL_CAST( c1o54*(drho+3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq));
+         case BE : return REAL_CAST( c1o54*(drho+3.0*( vx1-vx3)+c9o2*( vx1-vx3)*( vx1-vx3)-cu_sq));
+         case TW : return REAL_CAST( c1o54*(drho+3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq));
+         case TN : return REAL_CAST( c1o54*(drho+3.0*( vx2+vx3)+c9o2*( vx2+vx3)*( vx2+vx3)-cu_sq));
+         case BS : return REAL_CAST( c1o54*(drho+3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq));
+         case BN : return REAL_CAST( c1o54*(drho+3.0*( vx2-vx3)+c9o2*( vx2-vx3)*( vx2-vx3)-cu_sq));
+         case TS : return REAL_CAST( c1o54*(drho+3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq));
+         case TNE : return REAL_CAST(c1o216*(drho+3.0*( vx1+vx2+vx3)+c9o2*( vx1+vx2+vx3)*( vx1+vx2+vx3)-cu_sq));
+         case BSW : return REAL_CAST(c1o216*(drho+3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq));
+         case BNE : return REAL_CAST(c1o216*(drho+3.0*( vx1+vx2-vx3)+c9o2*( vx1+vx2-vx3)*( vx1+vx2-vx3)-cu_sq));
+         case TSW : return REAL_CAST(c1o216*(drho+3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq));
+         case TSE : return REAL_CAST(c1o216*(drho+3.0*( vx1-vx2+vx3)+c9o2*( vx1-vx2+vx3)*( vx1-vx2+vx3)-cu_sq));
+         case BNW : return REAL_CAST(c1o216*(drho+3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq));
+         case BSE : return REAL_CAST(c1o216*(drho+3.0*( vx1-vx2-vx3)+c9o2*( vx1-vx2-vx3)*( vx1-vx2-vx3)-cu_sq));
+         case TNW : return REAL_CAST(c1o216*(drho+3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq));
+         default: throw UbException(UB_EXARGS,"unknown dir");
+      }
+   }
+   //////////////////////////////////////////////////////////////////////////
+   static void calcIncompFeq(LBMReal* const& feq/*[27]*/,const LBMReal& drho,const LBMReal& vx1,const LBMReal& vx2,const LBMReal& vx3)	
+   {
+      using namespace UbMath;
+
+      LBMReal cu_sq=1.5*(vx1*vx1+vx2*vx2+vx3*vx3);
+
+      feq[REST] =  c8o27*(drho-cu_sq);
+      feq[E] =  c2o27*(drho+3.0*( vx1   )+c9o2*( vx1   )*( vx1   )-cu_sq);
+      feq[W] =  c2o27*(drho+3.0*(-vx1   )+c9o2*(-vx1   )*(-vx1   )-cu_sq);
+      feq[N] =  c2o27*(drho+3.0*(    vx2)+c9o2*(    vx2)*(    vx2)-cu_sq);
+      feq[S] =  c2o27*(drho+3.0*(   -vx2)+c9o2*(   -vx2)*(   -vx2)-cu_sq);
+      feq[T] =  c2o27*(drho+3.0*( vx3   )+c9o2*(    vx3)*(    vx3)-cu_sq);
+      feq[B] =  c2o27*(drho+3.0*(   -vx3)+c9o2*(   -vx3)*(   -vx3)-cu_sq);
+      feq[NE] =  c1o54*(drho+3.0*( vx1+vx2)+c9o2*( vx1+vx2)*( vx1+vx2)-cu_sq);
+      feq[SW] =  c1o54*(drho+3.0*(-vx1-vx2)+c9o2*(-vx1-vx2)*(-vx1-vx2)-cu_sq);
+      feq[SE] =  c1o54*(drho+3.0*( vx1-vx2)+c9o2*( vx1-vx2)*( vx1-vx2)-cu_sq);
+      feq[NW] =  c1o54*(drho+3.0*(-vx1+vx2)+c9o2*(-vx1+vx2)*(-vx1+vx2)-cu_sq);
+      feq[TE] =  c1o54*(drho+3.0*( vx1+vx3)+c9o2*( vx1+vx3)*( vx1+vx3)-cu_sq);
+      feq[BW] =  c1o54*(drho+3.0*(-vx1-vx3)+c9o2*(-vx1-vx3)*(-vx1-vx3)-cu_sq);
+      feq[BE] =  c1o54*(drho+3.0*( vx1-vx3)+c9o2*( vx1-vx3)*( vx1-vx3)-cu_sq);
+      feq[TW] =  c1o54*(drho+3.0*(-vx1+vx3)+c9o2*(-vx1+vx3)*(-vx1+vx3)-cu_sq);
+      feq[TN] =  c1o54*(drho+3.0*( vx2+vx3)+c9o2*( vx2+vx3)*( vx2+vx3)-cu_sq);
+      feq[BS] =  c1o54*(drho+3.0*(-vx2-vx3)+c9o2*(-vx2-vx3)*(-vx2-vx3)-cu_sq);
+      feq[BN] =  c1o54*(drho+3.0*( vx2-vx3)+c9o2*( vx2-vx3)*( vx2-vx3)-cu_sq);
+      feq[TS] =  c1o54*(drho+3.0*(-vx2+vx3)+c9o2*(-vx2+vx3)*(-vx2+vx3)-cu_sq);
+      feq[TNE] = c1o216*(drho+3.0*( vx1+vx2+vx3)+c9o2*( vx1+vx2+vx3)*( vx1+vx2+vx3)-cu_sq);
+      feq[BSW] = c1o216*(drho+3.0*(-vx1-vx2-vx3)+c9o2*(-vx1-vx2-vx3)*(-vx1-vx2-vx3)-cu_sq);
+      feq[BNE] = c1o216*(drho+3.0*( vx1+vx2-vx3)+c9o2*( vx1+vx2-vx3)*( vx1+vx2-vx3)-cu_sq);
+      feq[TSW] = c1o216*(drho+3.0*(-vx1-vx2+vx3)+c9o2*(-vx1-vx2+vx3)*(-vx1-vx2+vx3)-cu_sq);
+      feq[TSE] = c1o216*(drho+3.0*( vx1-vx2+vx3)+c9o2*( vx1-vx2+vx3)*( vx1-vx2+vx3)-cu_sq);
+      feq[BNW] = c1o216*(drho+3.0*(-vx1+vx2-vx3)+c9o2*(-vx1+vx2-vx3)*(-vx1+vx2-vx3)-cu_sq);
+      feq[BSE] = c1o216*(drho+3.0*( vx1-vx2-vx3)+c9o2*( vx1-vx2-vx3)*( vx1-vx2-vx3)-cu_sq);
+      feq[TNW] = c1o216*(drho+3.0*(-vx1+vx2+vx3)+c9o2*(-vx1+vx2+vx3)*(-vx1+vx2+vx3)-cu_sq);   
+   }
+   //////////////////////////////////////////////////////////////////////////
+   static inline float getBoundaryVelocityForDirection(const int& direction, const float& bcVelocityX1,const float& bcVelocityX2,const float& bcVelocityX3)
+   {
+      using namespace UbMath;
+
+      switch(direction) 
+      {          
+      case E:   return (float)( UbMath::c4o9*(+bcVelocityX1) );
+      case W:   return (float)( UbMath::c4o9*(-bcVelocityX1) );
+      case N:   return (float)( UbMath::c4o9*(+bcVelocityX2) );
+      case S:   return (float)( UbMath::c4o9*(-bcVelocityX2) );
+      case T:   return (float)( UbMath::c4o9*(+bcVelocityX3) );
+      case B:   return (float)( UbMath::c4o9*(-bcVelocityX3) );
+      case NE:  return (float)( UbMath::c1o9*(+bcVelocityX1+bcVelocityX2             ) );
+      case SW:  return (float)( UbMath::c1o9*(-bcVelocityX1-bcVelocityX2             ) );
+      case SE:  return (float)( UbMath::c1o9*(+bcVelocityX1-bcVelocityX2             ) );
+      case NW:  return (float)( UbMath::c1o9*(-bcVelocityX1+bcVelocityX2             ) );
+      case TE:  return (float)( UbMath::c1o9*(+bcVelocityX1             +bcVelocityX3) );
+      case BW:  return (float)( UbMath::c1o9*(-bcVelocityX1             -bcVelocityX3) );
+      case BE:  return (float)( UbMath::c1o9*(+bcVelocityX1             -bcVelocityX3) );
+      case TW:  return (float)( UbMath::c1o9*(-bcVelocityX1             +bcVelocityX3) );
+      case TN:  return (float)( UbMath::c1o9*(             +bcVelocityX2+bcVelocityX3) );
+      case BS:  return (float)( UbMath::c1o9*(             -bcVelocityX2-bcVelocityX3) );
+      case BN:  return (float)( UbMath::c1o9*(             +bcVelocityX2-bcVelocityX3) );
+      case TS:  return (float)( UbMath::c1o9*(             -bcVelocityX2+bcVelocityX3) );
+      case TNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2+bcVelocityX3) );
+      case BSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case BNE: return (float)( UbMath::c1o36*(+bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case TSW: return (float)( UbMath::c1o36*(-bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case TSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2+bcVelocityX3) );
+      case BNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2-bcVelocityX3) );
+      case BSE: return (float)( UbMath::c1o36*(+bcVelocityX1-bcVelocityX2-bcVelocityX3) );
+      case TNW: return (float)( UbMath::c1o36*(-bcVelocityX1+bcVelocityX2+bcVelocityX3) );
+      default: throw UbException(UB_EXARGS,"unknown direction"); 
+      }
+   }
+   /*=====================================================================*/
+   static const int& getInvertDirection(const int& direction)
+   {  
+   #ifdef _DEBUG
+      if(direction<STARTDIR || direction>ENDDIR) 
+         throw UbException(UB_EXARGS,"unknown direction");
+   #endif
+      return INVDIR[direction];
+   }
+   /*=====================================================================*/
+   static void getLBMDirections(std::vector<int>& dirs, bool onlyLBdirs = false)
+   {
+      std::vector<int> D3Q27Dirs;
+      if(onlyLBdirs) /*FSTARTDIR->FENDDIR*/
+      {
+         dirs.resize(FENDDIR+1);
+         for(int dir=FSTARTDIR; dir<=FENDDIR; ++dir)
+            dirs[dir] = dir;
+      }
+      else /*STARTDIR->ENDDIR*/
+      {
+         dirs.resize(ENDDIR+1);
+         for(int dir=STARTDIR; dir<=ENDDIR; ++dir)
+            dirs[dir] = dir;
+      }
+   }
+//////////////////////////////////////////////////////////////////////////
+   static std::vector<int> getEX(const int& exn)
+   {
+      std::vector<int> ex;
+      ex.resize(ENDDIR+1);
+      switch (exn)
+      {
+      case 1:
+         for(int dir=STARTDIR; dir<ENDDIR; ++dir)
+            ex[dir] = DX1[dir];
+      	break;
+      case 2:
+         for(int dir=STARTDIR; dir<ENDDIR; ++dir)
+            ex[dir] = DX2[dir];
+         break;
+      case 3:
+         for(int dir=STARTDIR; dir<ENDDIR; ++dir)
+            ex[dir] = DX3[dir];
+         break;
+      }
+      return ex;
+   }
+//////////////////////////////////////////////////////////////////////////
+   static inline void calcDistanceToNeighbors(std::vector<double>& distNeigh, const double& deltaX1)
+   {
+      //distNeigh.resize(FENDDIR+1, UbMath::sqrt2*deltaX1);
+      double sqrt3 = UbMath::sqrt3;
+      double sqrt2 = UbMath::sqrt2;
+      distNeigh[E] = distNeigh[W] = distNeigh[N] = deltaX1;
+      distNeigh[S] = distNeigh[T] = distNeigh[B] = deltaX1;
+      distNeigh[NE] = distNeigh[NW] = distNeigh[SW] = distNeigh[SE] = sqrt2*deltaX1;
+      distNeigh[TE] = distNeigh[TN] = distNeigh[TW] = distNeigh[TS] = sqrt2*deltaX1;
+      distNeigh[BE] = distNeigh[BN] = distNeigh[BW] = distNeigh[BS] = sqrt2*deltaX1;
+      distNeigh[TNE] = distNeigh[TNW] = distNeigh[TSE] = distNeigh[TSW] = sqrt3*deltaX1;
+      distNeigh[BNE] = distNeigh[BNW] = distNeigh[BSE] = distNeigh[BSW] = sqrt3*deltaX1;
+   }
+//////////////////////////////////////////////////////////////////////////
+   static inline void calcDistanceToNeighbors(std::vector<double>& distNeigh, const double& deltaX1,const double& deltaX2,const double& deltaX3)
+   {
+      //distNeigh.resize(FENDDIR+1, UbMath::sqrt2*deltaX1);
+      double sqrt3 = UbMath::sqrt3;
+      double sqrt2 = UbMath::sqrt2;
+      distNeigh[E] = distNeigh[W] =  deltaX1;
+      distNeigh[N] = distNeigh[S] =  deltaX2;
+      distNeigh[T] = distNeigh[B] = deltaX3;
+      distNeigh[NE] = distNeigh[NW] = distNeigh[SW] = distNeigh[SE] = sqrt(deltaX1*deltaX1+deltaX2*deltaX2);
+      distNeigh[TE] = distNeigh[TN] = distNeigh[TW] = distNeigh[TS] = sqrt(deltaX1*deltaX1+deltaX3*deltaX3);
+      distNeigh[BE] = distNeigh[BN] = distNeigh[BW] = distNeigh[BS] = sqrt(deltaX2*deltaX2+deltaX3*deltaX3);
+      distNeigh[TNE] = distNeigh[TNW] = distNeigh[TSE] = distNeigh[TSW] = sqrt(deltaX1*deltaX1+deltaX2*deltaX2+deltaX3*deltaX3);
+      distNeigh[BNE] = distNeigh[BNW] = distNeigh[BSE] = distNeigh[BSW] = sqrt(deltaX1*deltaX1+deltaX2*deltaX2+deltaX3*deltaX3);
+   }
+//////////////////////////////////////////////////////////////////////////
+   static inline void initRayVectors(double* const& rayX1, double* const& rayX2, double* const&  rayX3)
+   {
+      using namespace UbMath;
+
+      int fdir;
+      double c1oS2 = UbMath::one_over_sqrt2;
+      double c1oS3 = UbMath::one_over_sqrt3;
+      fdir = E;  rayX1[fdir] =  1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+      fdir = W;  rayX1[fdir] = -1.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  0.0;
+      fdir = N;  rayX1[fdir] =  0.0;   rayX2[fdir] =  1.0;   rayX3[fdir] =  0.0;
+      fdir = S;  rayX1[fdir] =  0.0;   rayX2[fdir] = -1.0;   rayX3[fdir] =  0.0;
+      fdir = T;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] =  1.0;
+      fdir = B;  rayX1[fdir] =  0.0;   rayX2[fdir] =  0.0;   rayX3[fdir] = -1.0;
+      fdir = NE; rayX1[fdir] =  c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+      fdir = SW; rayX1[fdir] = -c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+      fdir = SE; rayX1[fdir] =  c1oS2; rayX2[fdir] = -c1oS2; rayX3[fdir] =  0.0;
+      fdir = NW; rayX1[fdir] = -c1oS2; rayX2[fdir] =  c1oS2; rayX3[fdir] =  0.0;
+      fdir = TE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+      fdir = BW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+      fdir = BE; rayX1[fdir] =  c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] = -c1oS2;
+      fdir = TW; rayX1[fdir] = -c1oS2; rayX2[fdir] = 0.0;    rayX3[fdir] =  c1oS2;
+      fdir = TN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] =  c1oS2;
+      fdir = BS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] = -c1oS2;
+      fdir = BN; rayX1[fdir] =  0.0;   rayX2[fdir] = c1oS2;  rayX3[fdir] = -c1oS2;
+      fdir = TS; rayX1[fdir] =  0.0;   rayX2[fdir] =-c1oS2;  rayX3[fdir] =  c1oS2;
+      fdir = TNE; rayX1[fdir] =  c1oS3; rayX2[fdir] =  c1oS3; rayX3[fdir] =  c1oS3;
+      fdir = TNW; rayX1[fdir] = -c1oS3; rayX2[fdir] =  c1oS3; rayX3[fdir] =  c1oS3;
+      fdir = TSE; rayX1[fdir] =  c1oS3; rayX2[fdir] = -c1oS3; rayX3[fdir] =  c1oS3;
+      fdir = TSW; rayX1[fdir] = -c1oS3; rayX2[fdir] = -c1oS3; rayX3[fdir] =  c1oS3;
+      fdir = BNE; rayX1[fdir] =  c1oS3; rayX2[fdir] =  c1oS3; rayX3[fdir] = -c1oS3;
+      fdir = BNW; rayX1[fdir] = -c1oS3; rayX2[fdir] =  c1oS3; rayX3[fdir] = -c1oS3;
+      fdir = BSE; rayX1[fdir] =  c1oS3; rayX2[fdir] = -c1oS3; rayX3[fdir] = -c1oS3;
+      fdir = BSW; rayX1[fdir] = -c1oS3; rayX2[fdir] = -c1oS3; rayX3[fdir] = -c1oS3;
+   }
+//////////////////////////////////////////////////////////////////////////
+   static inline LBMReal calcPress(const LBMReal* const f, LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3)
+   {
+      using namespace UbMath;
+      LBMReal OxxPyyPzz = c1;
+      return ((f[E]+f[W]+f[N]+f[S]+f[T]+f[B]+c2*(f[NE]+f[SW]+f[SE]+f[NW]+f[TE]+f[BW]+f[BE]+f[TW]+f[TN]+f[BS]+f[BN]+f[TS])+
+         c3*(f[TNE]+f[TSW]+f[TSE]+f[TNW]+f[BNE]+f[BSW]+f[BSE]+f[BNW])-(vx1*vx1+vx2*vx2+vx3*vx3))*(c1-c1o2*OxxPyyPzz)+OxxPyyPzz*c1o2*(rho))*c1o3;
+   }
+}
+
+#endif
+
+
+
diff --git a/VirtualFluidsCore/LBM/ILBMKernel.h b/VirtualFluidsCore/LBM/ILBMKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..526bdd2fe828e1280b6996bc7cba9bdd1be21e20
--- /dev/null
+++ b/VirtualFluidsCore/LBM/ILBMKernel.h
@@ -0,0 +1,63 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file ILBMKernel.h
+//! \ingroup LBM
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef I_LBMKERNEL_H
+#define I_LBMKERNEL_H
+
+#include <PointerDefinitions.h>
+
+class BCProcessor;
+class DataSet3D;
+
+//! Abstract class provides interface for LBM kernel
+class ILBMKernel
+{
+public:
+    virtual ~ILBMKernel() {};
+
+    virtual void calculate(int step) = 0;
+    virtual void swapDistributions() = 0;
+
+    virtual bool getCompressible() const = 0;
+    virtual SPtr<BCProcessor> getBCProcessor() const = 0;
+    virtual void setBCProcessor(SPtr<BCProcessor> bcProcessor) = 0;
+    virtual SPtr<DataSet3D> getDataSet() const = 0;
+    virtual double getCollisionFactor() const = 0;
+    virtual void setCollisionFactor(double collFactor) = 0;
+    virtual bool isInsideOfDomain(const int &x1, const int &x2, const int &x3) const = 0;
+    virtual int getGhostLayerWidth() const = 0;
+    virtual double getDeltaT() const = 0;
+    virtual bool getWithForcing() const = 0;
+};
+
+#endif
diff --git a/VirtualFluidsCore/LBM/LBMKernel.cpp b/VirtualFluidsCore/LBM/LBMKernel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcb20a0533198f39c92e264b7ea3b8475723fe1d
--- /dev/null
+++ b/VirtualFluidsCore/LBM/LBMKernel.cpp
@@ -0,0 +1,261 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBMKernel.cpp
+//! \ingroup LBM
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "LBMKernel.h"
+#include "DataSet3D.h"
+#include "BCProcessor.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+LBMKernel::LBMKernel() : ghostLayerWidth(1),
+                             deltaT(1.0),
+                             withForcing(false),
+                             withSpongeLayer(false),
+                             compressible(false)
+{
+   this->setForcingX1(0.0);
+   this->setForcingX2(0.0);
+   this->setForcingX3(0.0);
+   dataSet = SPtr<DataSet3D>(new DataSet3D());
+   this->nx[0] = 0;
+   this->nx[1] = 0;
+   this->nx[2] = 0;
+}
+//////////////////////////////////////////////////////////////////////////
+LBMKernel::~LBMKernel()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setBCProcessor(SPtr<BCProcessor> bcp)
+{
+   bcProcessor = bcp;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<BCProcessor> LBMKernel::getBCProcessor() const
+{
+   return bcProcessor;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setCollisionFactor(double collFactor) 
+{
+   this->collFactor = collFactor;
+}
+//////////////////////////////////////////////////////////////////////////
+double LBMKernel::getCollisionFactor() const
+{
+   return collFactor;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1(LBMReal forcingX1)
+{
+    this->muForcingX1.SetExpr( UbSystem::toString(forcingX1,LBMRealLim::digits10) );  
+    this->checkFunction(muForcingX1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2(LBMReal forcingX2)
+{
+   this->muForcingX2.SetExpr( UbSystem::toString(forcingX2,LBMRealLim::digits10) );  
+   this->checkFunction(muForcingX2);
+}
+void LBMKernel::setForcingX3(LBMReal forcingX3)
+{
+   this->muForcingX3.SetExpr( UbSystem::toString(forcingX3,LBMRealLim::digits10) );  
+   this->checkFunction(muForcingX3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1( const mu::Parser& parser)
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX1 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX2 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX3( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muForcingX3 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX1( const std::string& muParserString)  
+{ 
+   this->muForcingX1.SetExpr(muParserString); 
+   this->checkFunction(muForcingX1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setForcingX2( const std::string& muParserString)  
+{ 
+   this->muForcingX2.SetExpr(muParserString); 
+   this->checkFunction(muForcingX2); 
+}
+void LBMKernel::setForcingX3( const std::string& muParserString)  
+{ 
+   this->muForcingX3.SetExpr(muParserString); 
+   this->checkFunction(muForcingX3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::checkFunction(mu::Parser fct)
+{
+   double x1=1.0,x2=1.0,x3=1.0, dt=1.0, nue=1.0;
+   fct.DefineVar("x1",&x1); 
+   fct.DefineVar("x2",&x2); 
+   fct.DefineVar("x3",&x3);
+   fct.DefineVar("dt",&dt);
+   fct.DefineVar("nue",&nue);
+
+   try
+   {
+      fct.Eval();
+      fct.ClearVar();
+   }
+   catch(mu::ParserError& e)
+   {
+      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
+         +(std::string)", only x1,x2,x3,dx are allowed as variables" );
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setGhostLayerWidth(int witdh)
+{
+   ghostLayerWidth = witdh;
+}
+//////////////////////////////////////////////////////////////////////////
+int  LBMKernel::getGhostLayerWidth() const
+{
+   return ghostLayerWidth;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setIndex( int x1, int x2, int x3 )
+{
+   this->ix1 = x1;
+   this->ix2 = x2;
+   this->ix3 = x3;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<DataSet3D> LBMKernel::getDataSet() const
+{
+   return this->dataSet;
+}
+//////////////////////////////////////////////////////////////////////////
+LBMReal LBMKernel::getDeltaT() const
+{
+   return this->deltaT;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setDeltaT( LBMReal dt )
+{
+   deltaT = dt;
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getCompressible() const 
+{ 
+   return compressible; 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setCompressible(bool val) 
+{ 
+   compressible = val; 
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getWithForcing() const
+{
+   return withForcing;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setWithForcing( bool val )
+{
+   withForcing = val;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setBlock( SPtr<Block3D> block )
+{
+   this->block = block;
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Block3D> LBMKernel::getBlock() const
+{
+   return block.lock();
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::getWithSpongeLayer() const
+{
+   return withSpongeLayer;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setWithSpongeLayer( bool val )
+{
+   withSpongeLayer = val;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setSpongeLayer( const mu::Parser& parser )
+{
+   this->checkFunction(parser); 
+   this->muSpongeLayer = parser;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setSpongeLayer( const std::string& muParserString )
+{
+   this->muSpongeLayer.SetExpr(muParserString); 
+   this->checkFunction(muSpongeLayer); 
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setDataSet(SPtr<DataSet3D> dataSet)
+{
+   this->dataSet = dataSet;
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::swapDistributions()
+{
+   dataSet->getFdistributions()->swap();
+}
+//////////////////////////////////////////////////////////////////////////
+void LBMKernel::setNX(std::array<int, 3> nx)
+{
+   this->nx = nx;
+}
+//////////////////////////////////////////////////////////////////////////
+std::array<int, 3> LBMKernel::getNX()
+{
+   return nx;
+}
+//////////////////////////////////////////////////////////////////////////
+bool LBMKernel::isInsideOfDomain(const int& x1, const int& x2, const int& x3) const
+{
+    const SPtr<BCArray3D> bcArray = this->bcProcessor->getBCArray();
+    return bcArray->isInsideOfDomain(x1, x2, x3, ghostLayerWidth);
+}
diff --git a/VirtualFluidsCore/LBM/LBMKernel.h b/VirtualFluidsCore/LBM/LBMKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..b97ac3d8d6dbc6c6fc7d0612c6b3938ac395c721
--- /dev/null
+++ b/VirtualFluidsCore/LBM/LBMKernel.h
@@ -0,0 +1,139 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBMKernel.h
+//! \ingroup LBM
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef LBMKERNEL_H
+#define LBMKERNEL_H
+
+#include <PointerDefinitions.h>
+#include "LBMSystem.h"
+#include "ILBMKernel.h"
+#include <array>
+#include <limits>
+#include <MuParser/include/muParser.h>
+
+class BCProcessor;
+class DataSet3D;
+class Block3D;
+
+//! \brief A base class provides basic functionality for LBM kernel 
+class LBMKernel : public ILBMKernel, public enableSharedFromThis<LBMKernel>
+{
+public:
+    typedef std::numeric_limits<LBMReal> LBMRealLim;
+public:
+    LBMKernel();
+    virtual ~LBMKernel();
+
+    virtual SPtr<LBMKernel> clone() = 0;
+
+    virtual void calculate(int step) = 0;
+
+    void setBCProcessor(SPtr<BCProcessor> bcp);
+    SPtr<BCProcessor> getBCProcessor() const;
+
+    void setCollisionFactor(double collFactor);
+    double getCollisionFactor() const;
+
+    void setGhostLayerWidth(int witdh);
+    int  getGhostLayerWidth() const;
+
+    void setDataSet(SPtr<DataSet3D> dataSet);
+    SPtr<DataSet3D> getDataSet() const;
+
+    void setForcingX1(LBMReal forcingX1);
+    void setForcingX2(LBMReal forcingX2);
+    void setForcingX3(LBMReal forcingX3);
+
+    void setForcingX1(const mu::Parser& parser);
+    void setForcingX2(const mu::Parser& parser);
+    void setForcingX3(const mu::Parser& parser);
+
+    void setForcingX1(const std::string& muParserString);
+    void setForcingX2(const std::string& muParserString);
+    void setForcingX3(const std::string& muParserString);
+
+    void setIndex(int x1, int x2, int x3);
+
+    LBMReal getDeltaT() const;
+    void setDeltaT(LBMReal dt);
+
+    bool getCompressible() const;
+    void setCompressible(bool val);
+
+    bool getWithForcing() const;
+    void setWithForcing(bool val);
+
+    bool getWithSpongeLayer() const;
+    void setWithSpongeLayer(bool val);
+
+    void setSpongeLayer(const mu::Parser& parser);
+    void setSpongeLayer(const std::string& muParserString);
+
+    void setBlock(SPtr<Block3D> block);
+    SPtr<Block3D> getBlock() const;
+
+    bool isInsideOfDomain(const int &x1, const int &x2, const int &x3) const;
+
+    void swapDistributions() override;
+
+    void setNX(std::array<int, 3> nx);
+    std::array<int, 3> getNX();
+
+protected:
+    SPtr<DataSet3D> dataSet;
+    SPtr<BCProcessor> bcProcessor;
+    LBMReal collFactor;
+    int ghostLayerWidth;
+    bool compressible;
+
+    //forcing 
+    bool withForcing;
+    mu::Parser muForcingX1;
+    mu::Parser muForcingX2;
+    mu::Parser muForcingX3;
+    int ix1, ix2, ix3;
+    LBMReal deltaT;
+
+    //sponge layer
+    bool withSpongeLayer;
+    mu::Parser muSpongeLayer;
+
+    WPtr<Block3D> block;
+
+    std::array<int, 3> nx;
+
+private:
+    void checkFunction(mu::Parser fct);
+};
+
+#endif
diff --git a/VirtualFluidsCore/LBM/LBMSystem.cpp b/VirtualFluidsCore/LBM/LBMSystem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d025557036bdbc7642a1b6ca95ef4de242b6e95
--- /dev/null
+++ b/VirtualFluidsCore/LBM/LBMSystem.cpp
@@ -0,0 +1,39 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBMSystem.cpp
+//! \ingroup LBM
+//! \author Sebastian Geller
+//=======================================================================================
+
+#include "LBMSystem.h"
+
+namespace LBMSystem
+{
+   real SMAG_CONST = REAL_CAST(0.18);
+}
diff --git a/VirtualFluidsCore/LBM/LBMSystem.h b/VirtualFluidsCore/LBM/LBMSystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..06569fe75c6f12b9dd785a6b61d9974d3ec810d0
--- /dev/null
+++ b/VirtualFluidsCore/LBM/LBMSystem.h
@@ -0,0 +1,95 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBMSystem.h
+//! \ingroup LBM
+//! \author Sebastian Geller
+//=======================================================================================
+#ifndef LBMSYSTEM_H
+#define LBMSYSTEM_H
+
+#include <cmath>
+#include <string>
+#include <iostream>
+
+
+//! \brief namespace for global system-functions
+
+namespace LBMSystem
+{
+
+//#define SINGLEPRECISION
+
+#ifdef SINGLEPRECISION
+   typedef float real;
+   #define REAL_CAST(x) ( (LBMSystem::real)(x) )
+#else
+   typedef double real;
+   #define REAL_CAST(x) ( x )
+#endif
+
+   extern real SMAG_CONST;
+
+   //////////////////////////////////////////////////////////////////////////
+   //!get LBM deltaT is equal LBM DeltaX
+   //!deltaT is dependent from grid level 
+   //!for first grid level is deltaT = 1.0
+   //!for next grid level 1/2 etc.
+   static real getDeltaT(int level)
+   {
+      return REAL_CAST(1.0/REAL_CAST(1<<level)); 
+   }
+
+   //////////////////////////////////////////////////////////////////////////
+   //!calculate collision factor omega = 1.0/(3.0*viscosity/deltaT+0.5)
+   //!deltaT is dependent from grid level 
+   //!for first grid level is deltaT = 1.0
+   //!for next grid level 1/2 etc.
+   static real calcCollisionFactor(real viscosity, int level)
+   {
+      //return REAL_CAST(1.0/(3.0*viscosity/deltaT+0.5));
+      return REAL_CAST(1.0/(3.0*viscosity/(1.0/REAL_CAST(1<<level))+0.5));
+   }
+
+   //!bulk viscosity
+   static real calcOmega2(real viscosity, int level)
+   {
+      return REAL_CAST(1.0/(4.5*viscosity/(1.0/REAL_CAST(1<<level))+0.5));
+   }
+   //!bulk viscosity
+   static real calcOmega2(real viscosity, real deltaT)
+   {
+      return REAL_CAST(1.0/(4.5*viscosity/deltaT+0.5));
+   }
+}
+
+//some typedefs for global namespace
+typedef LBMSystem::real LBMReal;
+
+#endif
+
diff --git a/VirtualFluidsCore/LBM/LBMUnitConverter.h b/VirtualFluidsCore/LBM/LBMUnitConverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b1eb8b4e6703b3204591e31666cf07ba42d9ad5
--- /dev/null
+++ b/VirtualFluidsCore/LBM/LBMUnitConverter.h
@@ -0,0 +1,190 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file LBMUnitConverter.h
+//! \ingroup LBM
+//! \author Sören Freudiger
+//=======================================================================================
+
+#ifndef LBMUNITCONVERTER_H
+#define LBMUNITCONVERTER_H
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <cmath>
+
+#include <basics/utilities/UbException.h>
+
+//! \brief A class provides converter for LB units <-> SI units
+//! \details
+//! \code
+//! LBMUnitConverter conv(  100 /*L_World*/, 1484/*cs_water*/    , 1000/*rho_water*/
+//!                         , 1000/*L_LB*/   , 1./srqt(3.)/*cs_Lb*/, 1/*rho_Lb*/ );
+//! cout<<conv.toString()<<endl;
+//! 
+//! cout<<"100m       = "<< 100  * conv.getFactorLentghWToLb()   << "dx    " << std::endl;
+//! cout<<"1000dx     = "<< 1000 * conv.getFactorLentghLbToW()   << "m     " << std::endl;
+//! 
+//! cout<<"25m/s      = "<< 25   * conv.getFactorVelocityWToLb() << "dx/dt " << std::endl;
+//! cout<<"0.04 dx/dt = "<< 0.04 * conv.getFactorVelocityLbToW() << "m/s   " << std::endl;
+//! \endcode
+//! alternative
+//! \code
+//! LBMUnitConverter conv(, 100 /*L_World*/, LBMUnitConverter::WATER, 1000/*L_LB*/  );
+//! \endcode
+
+class LBMUnitConverter
+{
+public:
+
+   enum WORLD_MATERIAL { WATER  = 0, SEAWWATER  = 1, AIR_20C  = 2, OIL  = 3  }; 
+
+   LBMUnitConverter() :  factorLengthLbToW(1.0),
+                         factorTimeLbToW(1.0),
+                         factorMassLbToW(1.0), 
+                         refRhoLb(1.0)
+   {
+
+   }
+
+   LBMUnitConverter(   const double& refLengthWorld, const double& csWorld, const double& rhoWorld
+      , const double& refLengthLb   , const double& csLb = 1.0/std::sqrt(3.0)  , const double& rhoLb = 1.0   )
+   {
+      this->init(  refLengthWorld, csWorld, rhoWorld, csWorld, refLengthLb, rhoLb, csLb  );
+
+   }
+
+   LBMUnitConverter(  const double& refLengthWorld, WORLD_MATERIAL worldMaterial
+      , const double& refLengthLb   , const double& csLb = 1.0/std::sqrt(3.0) , const double& rhoLb = 1.0    )
+   {
+      double csWorld;
+      double rhoWorld;  
+
+      if     ( worldMaterial == WATER    ) { csWorld = 1484/*m/s*/; rhoWorld =  1000/*kg/m^3*/;  }
+      else if( worldMaterial == SEAWWATER) { csWorld = 1500/*m/s*/; rhoWorld =  1025/*kg/m^3*/;  }
+      else if( worldMaterial == AIR_20C  ) { csWorld =  343/*m/s*/; rhoWorld = 1.290/*kg/m^3*/;  }
+      else if( worldMaterial == OIL      ) { csWorld = 1740/*m/s*/; rhoWorld =  830/*kg/m^3*/;   }
+      else                                  throw UbException(UB_EXARGS,"unknown material");
+
+      this->init(  refLengthWorld, csWorld, rhoWorld, csWorld, refLengthLb, rhoLb, csLb  );
+
+   }
+
+   virtual ~LBMUnitConverter() {}
+
+   double  getRefRhoLb()             { return refRhoLb; }
+
+   double  getFactorLentghLbToW()    { return factorLengthLbToW;                                                       }
+   double  getFactorLentghWToLb()    { return 1.0/this->getFactorLentghLbToW();                                        }
+
+   double  getFactorTimeLbToW()      { return factorTimeLbToW;                                                         }
+   double  getFactorTimeWToLb()      { return 1.0/this->getFactorTimeLbToW();                                          }
+
+   double  getFactorVelocityLbToW()  { return factorLengthLbToW/factorTimeLbToW;                                       }
+   double  getFactorVelocityWToLb()  { return 1.0/this->getFactorVelocityLbToW();                                      }
+
+   double  getFactorViscosityLbToW() { return factorLengthLbToW*factorLengthLbToW/factorTimeLbToW;                     }
+   double  getFactorViscosityWToLb() { return 1.0/this->getFactorViscosityLbToW();                                     }
+
+   double  getFactorDensityLbToW()   { return this->factorMassLbToW/std::pow(factorLengthLbToW,3.0);                   }
+   double  getFactorDensityWToLb()   { return 1.0/this->getFactorDensityLbToW();                                       }
+
+   double  getFactorPressureLbToW()  { return this->factorMassLbToW/(std::pow(factorTimeLbToW,2.0)*factorLengthLbToW); }
+   double  getFactorPressureWToLb()  { return 1.0/this->getFactorPressureLbToW();                                      }
+
+   double  getFactorMassLbToW()      { return this->factorMassLbToW;                                                   }
+   double  getFactorMassWToLb()      { return 1.0/this->getFactorMassLbToW();                                          }
+
+   double  getFactorForceLbToW()     { return factorMassLbToW*factorLengthLbToW/(factorTimeLbToW*factorTimeLbToW);     }
+   double  getFactorForceWToLb()     { return 1.0/this->getFactorForceLbToW();                                         }
+
+   double  getFactorAccLbToW()       { return factorLengthLbToW/(factorTimeLbToW*factorTimeLbToW);                     }
+   double  getFactorAccWToLb()       { return 1.0/this->getFactorAccLbToW();                                           }
+
+   double  getFactorTimeLbToW(double deltaX)        const { return factorTimeWithoutDx * deltaX;             }
+
+   /*==========================================================*/
+   friend inline std::ostream& operator << (std::ostream& os, LBMUnitConverter c) 
+   {
+      os<<c.toString();
+      return os;
+   }
+   /*==========================================================*/
+   std::string toString() 
+   {
+      std::ostringstream out;
+      out<<"LB --> WORLD" << std::endl;
+      out<<" * lentgh 1[dx  ] = " << std::setw(12) << this->getFactorLentghLbToW()    << " [m   ] " << std::endl;
+      out<<" * time   1[dt  ] = " << std::setw(12) << this->getFactorTimeLbToW()      << " [s   ] " << std::endl;
+      out<<" * mass   1[mass] = " << std::setw(12) << this->getFactorMassLbToW()      << " [kg  ] " << std::endl;
+      out<<std::endl;                                                       
+      out<<"WORLD --> LB" << std::endl;                                     
+      out<<" * lentgh 1[m   ] = " << std::setw(12) << this->getFactorLentghWToLb()    << " [dx  ] " << std::endl;
+      out<<" * time   1[s   ] = " << std::setw(12) << this->getFactorTimeWToLb()      << " [dt  ] " << std::endl;
+      out<<" * mass   1[kg  ] = " << std::setw(12) << this->getFactorMassWToLb()      << " [mass] " << std::endl;
+      out<<std::endl;
+      out<<"LB --> WORLD (combined units)" << std::endl;
+      out<<" * velocity     1 [dx/dt    ] = " << std::setw(12) << this->getFactorVelocityLbToW()  << " [m/s      ]" << std::endl;
+      out<<" * density      1 [mass/dx^3] = " << std::setw(12) << this->getFactorDensityLbToW()   << " [kg/m^3   ]" << std::endl;
+      out<<" * pressure     1 [F_lb/dx^2] = " << std::setw(12) << this->getFactorPressureLbToW()  << " [N/m^2    ]" << std::endl;
+      out<<" * viscosity    1 [dx^2/dt  ] = " << std::setw(12) << this->getFactorViscosityLbToW() << " [m^2/s    ]" << std::endl;
+      out<<" * force        1 [F_lb     ] = " << std::setw(12) << this->getFactorForceLbToW()     << " [N        ]" << std::endl;
+      out<<" * acceleration 1 [dx/dt^2  ] = " << std::setw(12) << this->getFactorAccLbToW()       << " [m/s^2    ]" << std::endl;
+      out<<std::endl;                                                                       
+      out<<"WORLD --> LB (combined units)" << std::endl;                                    
+      out<<" * velocity     1 [m/s      ] = " << std::setw(12) << this->getFactorVelocityWToLb()  << " [dx/dt    ]" << std::endl;
+      out<<" * density      1 [kg/m^3   ] = " << std::setw(12) << this->getFactorDensityWToLb()   << " [mass/dx^3]" << std::endl;
+      out<<" * pressure     1 [N/m^2    ] = " << std::setw(12) << this->getFactorPressureWToLb()  << " [F_lb/dx^2]" << std::endl;
+      out<<" * viscosity    1 [m^2/s    ] = " << std::setw(12) << this->getFactorViscosityWToLb() << " [dx^2/dt  ]" << std::endl;
+      out<<" * force        1 [N        ] = " << std::setw(12) << this->getFactorForceWToLb()     << " [F_lb     ]" << std::endl;
+      out<<" * acceleration 1 [m/s^2    ] = " << std::setw(12) << this->getFactorAccWToLb()       << " [dx/dt^2  ]" << std::endl;
+
+      return out.str();
+   }
+
+   void init(  const double& refLengthWorld, const double& csWorld, const double& rhoWorld, const double& vWorld, 
+               const double& refLengthLb, const double& rhoLb, const double& vLb  )
+   {
+      factorLengthLbToW = refLengthWorld / refLengthLb;
+      factorTimeLbToW   = vLb / vWorld * factorLengthLbToW;
+      factorMassLbToW   = rhoWorld/rhoLb*factorLengthLbToW*factorLengthLbToW*factorLengthLbToW;
+      factorTimeWithoutDx=vLb/vWorld;
+      this->refRhoLb = rhoLb;
+   }
+
+   protected:
+   double factorLengthLbToW;
+   double factorTimeLbToW;
+   double factorMassLbToW;
+   double refRhoLb;
+   double factorTimeWithoutDx;
+};
+
+#endif //LBMUNITCONVERTER_H
diff --git a/VirtualFluidsCore/Parallel/CMakePackage.txt b/VirtualFluidsCore/Parallel/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Parallel/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Parallel/Communicator.cpp b/VirtualFluidsCore/Parallel/Communicator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a53a558f4b72ccc97191940918e523ae217443ab
--- /dev/null
+++ b/VirtualFluidsCore/Parallel/Communicator.cpp
@@ -0,0 +1,45 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Communicator.cpp
+//! \ingroup Parallel
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "Communicator.h"
+#include <basics/utilities/UbException.h>
+
+SPtr<Communicator> Communicator::instance = SPtr<Communicator>();
+//////////////////////////////////////////////////////////////////////////
+SPtr<Communicator> Communicator::getInstance()
+{
+   if( !instance )
+      UB_THROW(UbException(UB_EXARGS,"Communicator isn't initialized correctly! You can not create a new instance of abstract Communicator class!"));
+   return instance;
+}
+
diff --git a/VirtualFluidsCore/Parallel/Communicator.h b/VirtualFluidsCore/Parallel/Communicator.h
new file mode 100644
index 0000000000000000000000000000000000000000..828c9f5c0f42e8c9bc9ac1a33cc298725b3509dc
--- /dev/null
+++ b/VirtualFluidsCore/Parallel/Communicator.h
@@ -0,0 +1,60 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Communicator.h
+//! \ingroup Parallel
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef COMMUNICATOR_H
+#define COMMUNICATOR_H
+
+#include <vector>
+#include <string>
+
+#include <PointerDefinitions.h>
+
+//! \brief An abstract class for communication between processes in parallel computation
+class Communicator
+{
+public:
+   virtual ~Communicator(){}
+   static SPtr<Communicator> getInstance();
+   virtual int getProcessID() = 0;
+   virtual int getNumberOfProcesses() = 0;
+   virtual bool isRoot() = 0;
+   virtual int getRoot() = 0;
+   virtual int getProcessRoot() = 0;
+protected:
+   Communicator(){}
+   Communicator( const Communicator& ){}
+   static SPtr<Communicator> instance;
+};
+
+#endif
+
diff --git a/VirtualFluidsCore/Parallel/NullCommunicator.cpp b/VirtualFluidsCore/Parallel/NullCommunicator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcd745d36279acf3b72773a92e1e6ad878d93915
--- /dev/null
+++ b/VirtualFluidsCore/Parallel/NullCommunicator.cpp
@@ -0,0 +1,75 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NullCommunicator.cpp
+//! \ingroup Parallel
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "NullCommunicator.h"
+
+NullCommunicator::NullCommunicator()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+NullCommunicator::~NullCommunicator()
+{
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<Communicator> NullCommunicator::getInstance()
+{
+   if( !Communicator::instance )
+      Communicator::instance = SPtr<Communicator>(new NullCommunicator());
+   return Communicator::instance;
+}
+//////////////////////////////////////////////////////////////////////////
+int NullCommunicator::getProcessID() 
+{
+   return 0;
+}
+//////////////////////////////////////////////////////////////////////////
+int NullCommunicator::getNumberOfProcesses()
+{
+   return 1;
+}
+//////////////////////////////////////////////////////////////////////////
+bool NullCommunicator::isRoot() 
+{
+   return true;
+}
+//////////////////////////////////////////////////////////////////////////
+int NullCommunicator::getRoot() 
+{
+   return 0;
+}
+//////////////////////////////////////////////////////////////////////////
+int NullCommunicator::getProcessRoot() 
+{
+   return 0;
+}
+
diff --git a/VirtualFluidsCore/Parallel/NullCommunicator.h b/VirtualFluidsCore/Parallel/NullCommunicator.h
new file mode 100644
index 0000000000000000000000000000000000000000..b554ebc00bbecf5442fcb5a5c2b410ae71af0152
--- /dev/null
+++ b/VirtualFluidsCore/Parallel/NullCommunicator.h
@@ -0,0 +1,60 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file NullCommunicator.h
+//! \ingroup Parallel
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef NullCommunicator_H
+#define NullCommunicator_H
+
+#include "Communicator.h"
+
+#include <PointerDefinitions.h>
+
+//! \brief A class implements Communicator for shared memory.
+//! \details NullCommunicator is only a place-holder. It is only one process in shared memory.
+class NullCommunicator : public Communicator
+{
+   private:
+   NullCommunicator();
+   NullCommunicator( const NullCommunicator& ){}
+public:
+   ~NullCommunicator();
+   static SPtr<Communicator> getInstance();
+   int getProcessID();
+   int getNumberOfProcesses();
+   bool isRoot();
+   int getRoot();
+   int getProcessRoot();
+protected:
+private:
+};
+
+#endif
diff --git a/VirtualFluidsCore/PointerDefinitions.h b/VirtualFluidsCore/PointerDefinitions.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5cabd1ff2f423413aca55cd6bcd8fb4fff806e9
--- /dev/null
+++ b/VirtualFluidsCore/PointerDefinitions.h
@@ -0,0 +1,53 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file PointerDefinitions.h
+//! \ingroup Core
+//! \author Soeren Peters
+//=======================================================================================
+#ifndef SHARED_POINTER_H
+#define SHARED_POINTER_H
+
+#include <memory>
+
+template <class T>
+using SPtr = std::shared_ptr<T>;
+
+template <class T>
+using WPtr = std::weak_ptr<T>;
+
+template <class T>
+using UPtr = std::unique_ptr<T>;
+
+template <class T>
+using RPtr = T*;
+
+template <class T>
+using enableSharedFromThis = std::enable_shared_from_this<T>;
+
+#endif
diff --git a/VirtualFluidsCore/Utilities/CMakePackage.txt b/VirtualFluidsCore/Utilities/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Utilities/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Utilities/MemoryUtil.h b/VirtualFluidsCore/Utilities/MemoryUtil.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8306083b15b5168702d028ff1687eb0938bc9ea
--- /dev/null
+++ b/VirtualFluidsCore/Utilities/MemoryUtil.h
@@ -0,0 +1,162 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file MemoryUtil.h
+//! \ingroup Utilities
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef _MEMORYUTIL_H_
+#define _MEMORYUTIL_H_
+
+#if defined(_WIN32) || defined(_WIN64)
+   #define MEMORYUTIL_WINDOWS
+   #include "windows.h"
+   #include "psapi.h"
+   #pragma comment(lib, "psapi.lib")
+#elif defined __APPLE__
+#define MEMORYUTIL_APPLE
+   #include "sys/types.h"
+   #include "sys/sysctl.h"
+   #include "stdlib.h"
+   #include "stdio.h"
+   #include "string.h"
+#elif (defined(__amd64) || defined(__amd64__) || defined(__unix__)) && !defined(__AIX__)
+   #define MEMORYUTIL_LINUX
+   #include "sys/types.h"
+   #include "sys/sysinfo.h"
+   #include "stdlib.h"
+   #include "stdio.h"
+   #include "string.h"
+#else
+   #error "MemoryUtil::UnknownMachine"
+#endif
+
+#if defined(__CYGWIN__)
+   #define MEMORYUTIL_CYGWIN
+#endif
+//////////////////////////////////////////////////////////////////////////
+//MemoryUtil
+//////////////////////////////////////////////////////////////////////////
+namespace Utilities
+{
+//////////////////////////////////////////////////////////////////////////
+   static long long getTotalPhysMem()
+   {
+      #if defined(MEMORYUTIL_WINDOWS)
+         MEMORYSTATUSEX memInfo;
+         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+         GlobalMemoryStatusEx(&memInfo);
+         DWORDLONG totalPhysMem = memInfo.ullTotalPhys;            
+      #elif defined(MEMORYUTIL_LINUX)
+         struct sysinfo memInfo;
+         sysinfo (&memInfo);
+         long long totalPhysMem = memInfo.totalram;
+         //Multiply in next statement to avoid int overflow on right hand side...
+         totalPhysMem *= memInfo.mem_unit;
+      #elif defined(MEMORYUTIL_APPLE)
+         long long totalPhysMem = 0;
+      #else
+         #error "MemoryUtil::getTotalPhysMem - UnknownMachine"
+      #endif
+
+      return (long long)totalPhysMem;
+   }
+//////////////////////////////////////////////////////////////////////////
+   static long long getPhysMemUsed()
+   {
+      #if defined(MEMORYUTIL_WINDOWS)
+         MEMORYSTATUSEX memInfo;
+         memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+         GlobalMemoryStatusEx(&memInfo);
+         DWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;          
+      #elif defined(MEMORYUTIL_LINUX)
+         struct sysinfo memInfo;
+         sysinfo (&memInfo);
+         long long physMemUsed = memInfo.totalram - memInfo.freeram;
+         //Multiply in next statement to avoid int overflow on right hand side...
+         physMemUsed *= memInfo.mem_unit;
+      #elif defined(MEMORYUTIL_APPLE)
+         long long physMemUsed = 0;
+      #else
+         #error "MemoryUtil::getPhysMemUsed - UnknownMachine"
+      #endif
+
+      return (long long)physMemUsed;
+   }
+//////////////////////////////////////////////////////////////////////////
+#if defined(MEMORYUTIL_LINUX) || defined(MEMORYUTIL_APPLE) || defined(MEMORYUTIL_CYGWIN)
+   static int parseLine(char* line){
+      int i = strlen(line);
+      while (*line < '0' || *line > '9') line++;
+      line[i-3] = '\0';
+      i = atoi(line);
+      return i;
+   }
+
+   static int getValue(){ //Note: this value is in KB!
+      FILE* file = fopen("/proc/self/status", "r");
+      int result = -1;
+      char line[128];
+
+
+      while (fgets(line, 128, file) != NULL){
+         if (strncmp(line, "VmRSS:", 6) == 0){
+            result = parseLine(line);
+            break;
+         }
+      }
+      fclose(file);
+      return result;
+   }
+#endif
+//////////////////////////////////////////////////////////////////////////
+   static long long getPhysMemUsedByMe()
+   {
+      #if defined(MEMORYUTIL_WINDOWS) && !defined(__CYGWIN__)
+         PROCESS_MEMORY_COUNTERS pmc;
+         GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+         SIZE_T physMemUsedByMe = pmc.WorkingSetSize;          
+      #elif defined(MEMORYUTIL_LINUX)
+         long long physMemUsedByMe = (long long)getValue() * (long long)1024;
+      #elif defined(MEMORYUTIL_APPLE)
+      long long physMemUsedByMe = 0;
+      #elif defined(MEMORYUTIL_CYGWIN)
+        long long physMemUsedByMe = (long long)getValue() * (long long)1024;
+      #else
+         #error "MemoryUtil::getPhysMemUsedByMe - UnknownMachine"
+      #endif
+
+      return (long long)physMemUsedByMe;
+   }
+//////////////////////////////////////////////////////////////////////////
+
+}
+
+#endif
+
diff --git a/VirtualFluidsCore/Visitors/Block3DVisitor.h b/VirtualFluidsCore/Visitors/Block3DVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a030629e680d7929e2a1b7e47cb8a802b087e85
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/Block3DVisitor.h
@@ -0,0 +1,90 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Block3DVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher, Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+
+#ifndef Block3DVisitor_h
+#define Block3DVisitor_h
+
+#include <PointerDefinitions.h>
+
+class Block3D;
+class Grid3D;
+
+//! Abstract class provides interface for visitor design pettern
+class Block3DVisitor
+{
+public:
+   Block3DVisitor() : startLevel(-1), stopLevel(-1)
+   {
+   }
+
+   Block3DVisitor(int startLevel, int stopLevel) : startLevel(startLevel), stopLevel(stopLevel)
+   {
+   }
+
+	virtual ~Block3DVisitor()
+   {
+   }
+	
+   virtual void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) = 0;
+   
+   int  getStartLevel() const; 
+   int  getStopLevel() const;
+   void setStartLevel(int level);
+   void setStopLevel(int level);
+
+private:
+   int  startLevel;
+   int  stopLevel;
+};
+//////////////////////////////////////////////////////////////////////////
+inline int  Block3DVisitor::getStartLevel() const
+{ 
+   return this->startLevel;  
+}
+//////////////////////////////////////////////////////////////////////////
+inline int  Block3DVisitor::getStopLevel() const
+{ 
+   return this->stopLevel;   
+}
+//////////////////////////////////////////////////////////////////////////
+inline void Block3DVisitor::setStartLevel(int level)
+{ 
+   this->startLevel = level; 
+}
+//////////////////////////////////////////////////////////////////////////
+inline void Block3DVisitor::setStopLevel(int level) 
+{ 
+   this->stopLevel = level;  
+}
+
+#endif 
diff --git a/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp b/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5135f2db7fc14fc33afe5c0d2b12a79ab58af91c
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.cpp
@@ -0,0 +1,130 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BoundaryConditionsBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "BoundaryConditionsBlockVisitor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "DataSet3D.h"
+#include "Grid3D.h"
+#include "BCAdapter.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+BoundaryConditionsBlockVisitor::BoundaryConditionsBlockVisitor() :
+Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+BoundaryConditionsBlockVisitor::~BoundaryConditionsBlockVisitor()
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void BoundaryConditionsBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+   if (block->getRank() == grid->getRank())
+   {
+      SPtr<ILBMKernel> kernel = block->getKernel();
+
+      if (!kernel)
+      {
+         throw UbException(UB_EXARGS, "LBMKernel in " + block->toString() + "is not exist!");
+      }
+
+      SPtr<BCProcessor> bcProcessor = kernel->getBCProcessor();
+
+      if (!bcProcessor)
+      {
+         throw UbException(UB_EXARGS,"Boundary Conditions Processor is not exist!" );
+      }
+
+      SPtr<BCArray3D> bcArray = bcProcessor->getBCArray();
+
+      bool compressible = kernel->getCompressible();
+      double collFactor = kernel->getCollisionFactor();
+      int level = block->getLevel();
+
+      int minX1 = 0;
+      int minX2 = 0;
+      int minX3 = 0;
+      int maxX1 = (int)bcArray->getNX1();
+      int maxX2 = (int)bcArray->getNX2();
+      int maxX3 = (int)bcArray->getNX3();
+      SPtr<BoundaryConditions> bcPtr;
+
+      bcProcessor->clearBC();
+
+      SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();
+
+      for (int x3 = minX3; x3 < maxX3; x3++)
+      {
+         for (int x2 = minX2; x2 < maxX2; x2++)
+         {
+            for (int x1 = minX1; x1 < maxX1; x1++)
+            {
+               if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3))
+               {
+                  if ((bcPtr = bcArray->getBC(x1, x2, x3)) != NULL)
+                  {
+                     char alg = bcPtr->getBcAlgorithmType();
+                     SPtr<BCAlgorithm> bca = bcMap[alg];
+                     
+                     if (bca)
+                     {
+                        bca = bca->clone();
+                        bca->setNodeIndex(x1, x2, x3);
+                        bca->setBcPointer(bcPtr);
+                        bca->addDistributions(distributions);
+                        bca->setCollFactor(collFactor);
+                        bca->setCompressible(compressible);
+                        bca->setBcArray(bcArray);
+                        bcProcessor->addBC(bca);
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void BoundaryConditionsBlockVisitor::addBC(SPtr<BCAdapter> bc)
+{
+   bcMap.insert(std::make_pair(bc->getBcAlgorithmType(), bc->getAlgorithm()));
+}
+
+
+
diff --git a/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h b/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a8023fb074e4ebe6b9a277896eefaa93b53ec6c
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/BoundaryConditionsBlockVisitor.h
@@ -0,0 +1,61 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file BoundaryConditionsBlockVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef BoundaryConditionBlockVisitor_h__
+#define BoundaryConditionBlockVisitor_h__
+
+#include <map>
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+
+
+class Grid3D;
+class Block3D;
+class BCAlgorithm;
+class BCAdapter;
+
+//! \brief set boundary conditions
+class BoundaryConditionsBlockVisitor : public Block3DVisitor
+{
+public:
+   BoundaryConditionsBlockVisitor();
+   virtual ~BoundaryConditionsBlockVisitor();
+   
+      void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override;
+   void addBC(SPtr<BCAdapter> bc);
+protected:
+private:
+   std::map<char, SPtr<BCAlgorithm> > bcMap;
+};
+#endif // BoundaryConditionBlockVisitor_h__
diff --git a/VirtualFluidsCore/Visitors/CMakePackage.txt b/VirtualFluidsCore/Visitors/CMakePackage.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b8416f010d2a7de30b8f70c9abf19a96dd8cf8f
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/CMakePackage.txt
@@ -0,0 +1,2 @@
+GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
+COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
diff --git a/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp b/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4fce3b53078b62a21af4a0374ab643d740af5ecd
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp
@@ -0,0 +1,111 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GenBlocksGridVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "GenBlocksGridVisitor.h"
+#include "Grid3DSystem.h"
+#include "CoordinateTransformation3D.h"
+#include "Block3D.h"
+#include "Grid3D.h"
+
+#include <geometry3d/GbObject3D.h>
+
+GenBlocksGridVisitor::GenBlocksGridVisitor(SPtr<GbObject3D> boundingBox) :
+   boundingBox(boundingBox)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::visit(const SPtr<Grid3D> grid)
+{
+    double orgX1 = boundingBox->getX1Minimum();
+    double orgX2 = boundingBox->getX2Minimum();
+    double orgX3 = boundingBox->getX3Minimum();
+
+    double dx = grid->getDeltaX(0);
+
+    UbTupleInt3 blockNX = grid->getBlockNX();
+
+    double blockLentghX1 = (double)val<1>(blockNX)*dx;
+    double blockLentghX2 = (double)val<2>(blockNX)*dx;
+    double blockLentghX3 = (double)val<3>(blockNX)*dx;
+
+    SPtr<CoordinateTransformation3D> trafo(new CoordinateTransformation3D(orgX1, orgX2, orgX3, blockLentghX1, blockLentghX2, blockLentghX3));
+    grid->setCoordinateTransformator(trafo);
+
+    genBlocks(grid);
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::fillExtentWithBlocks( SPtr<Grid3D> grid )
+{
+   for(int x3 =  val<3>(minInd); x3 <  val<3>(maxInd); x3++)
+   {
+      for(int x2 =  val<2>(minInd); x2 <  val<2>(maxInd); x2++)
+      {
+         for(int x1 =  val<1>(minInd); x1 <  val<1>(maxInd); x1++)
+         {
+            SPtr<Block3D> block( new Block3D(x1,x2,x3,0) );
+            grid->addBlock(block);
+         }
+      }
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+void GenBlocksGridVisitor::genBlocks(SPtr<Grid3D> grid)
+{
+    minInd = grid->getBlockIndexes(boundingBox->getX1Minimum(), boundingBox->getX2Minimum(), boundingBox->getX3Minimum());
+    double geoMaxX1 = boundingBox->getX1Maximum();
+    double geoMaxX2 = boundingBox->getX2Maximum();
+    double geoMaxX3 = boundingBox->getX3Maximum();
+    maxInd = grid->getBlockIndexes(geoMaxX1, geoMaxX2, geoMaxX3);
+    UbTupleDouble3 blockCoord = grid->getBlockWorldCoordinates(static_cast<int>(val<1>(maxInd)), static_cast<int>(val<2>(maxInd)), static_cast<int>(val<3>(maxInd)), 0);
+    //if (geoMaxX1 > val<1>(blockCoord))
+    //    val<1>(maxInd) += 1;
+    //if (geoMaxX2 > val<2>(blockCoord))
+    //    val<2>(maxInd) += 1;
+    //if (geoMaxX3 > val<3>(blockCoord))
+    //    val<3>(maxInd) += 1;
+
+    double dx = grid->getDeltaX(0);
+    if (fabs(geoMaxX1-val<1>(blockCoord)) > dx)
+       val<1>(maxInd) += 1;
+    if (fabs(geoMaxX2-val<2>(blockCoord)) > dx)
+       val<2>(maxInd) += 1;
+    if (fabs(geoMaxX3-val<3>(blockCoord)) > dx)
+       val<3>(maxInd) += 1;
+
+    this->fillExtentWithBlocks(grid);
+
+    grid->setNX1(val<1>(maxInd));
+    grid->setNX2(val<2>(maxInd));
+    grid->setNX3(val<3>(maxInd));
+}
diff --git a/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h b/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..a80e8a626ac44a819cbcc6e1af2068c8a6988a51
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.h
@@ -0,0 +1,62 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file GenBlocksGridVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef GenBlocksGridVisitor_h
+#define GenBlocksGridVisitor_h
+
+#include <PointerDefinitions.h>
+
+#include <basics/utilities/UbTuple.h>
+
+#include "Grid3DVisitor.h" 
+
+class GbObject3D;
+class Grid3D;
+
+//! \brief generate blocks
+class GenBlocksGridVisitor : public Grid3DVisitor
+{
+public:
+   GenBlocksGridVisitor(SPtr<GbObject3D> boundingBox);
+   virtual ~GenBlocksGridVisitor(){}
+
+   void visit(SPtr<Grid3D> grid);
+
+private:
+   UbTupleInt3 minInd, maxInd;
+   SPtr<GbObject3D> boundingBox;
+   void fillExtentWithBlocks(SPtr<Grid3D> grid);
+   void genBlocks(SPtr<Grid3D> grid);
+};
+
+#endif 
diff --git a/VirtualFluidsCore/Visitors/Grid3DVisitor.h b/VirtualFluidsCore/Visitors/Grid3DVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d2117f8b27880645606c2dc7a1457209b38a9b1
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/Grid3DVisitor.h
@@ -0,0 +1,52 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Grid3DVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher, Soeren Freudiger, Sebastian Geller
+//=======================================================================================
+
+#ifndef Grid3DVisitor_h
+#define Grid3DVisitor_h
+
+#include <PointerDefinitions.h>
+
+
+class Grid3D;
+
+//! Abstract class provides interface for visitor design pettern
+class Grid3DVisitor
+{
+public:
+   Grid3DVisitor() {}
+   virtual ~Grid3DVisitor() {}
+
+   virtual void visit(SPtr<Grid3D> grid) = 0;
+};
+
+#endif 
diff --git a/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp b/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9ecb9041b1cca71e5cfa3839897fe87049242804
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
@@ -0,0 +1,328 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file InitDistributionsBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher, Soeren Freudiger
+//=======================================================================================
+
+#include "InitDistributionsBlockVisitor.h"
+#include "LBMKernel.h"
+#include "BCProcessor.h"
+#include "Grid3DSystem.h"
+#include "DataSet3D.h"
+#include "EsoTwist3D.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "BCArray3D.h"
+
+InitDistributionsBlockVisitor::InitDistributionsBlockVisitor() 
+   : Block3DVisitor(0, Grid3DSystem::MAXLEVEL)
+{
+   this->setVx1(0.0);
+   this->setVx2(0.0);
+   this->setVx3(0.0);
+   this->setRho(0.0);
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muVx1 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( const mu::Parser& parser)
+{ 
+   this->checkFunction(parser); 
+   this->muVx2 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muVx3 = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( const mu::Parser& parser)  
+{ 
+   this->checkFunction(parser); 
+   this->muRho = parser;  
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( const std::string& muParserString)  
+{ 
+   this->muVx1.SetExpr(muParserString); 
+   this->checkFunction(muVx1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( const std::string& muParserString) 
+{ 
+   this->muVx2.SetExpr(muParserString); 
+   this->checkFunction(muVx2); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( const std::string& muParserString)  
+{ 
+   this->muVx3.SetExpr(muParserString); 
+   this->checkFunction(muVx3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( const std::string& muParserString)  
+{ 
+   this->muRho.SetExpr(muParserString); 
+   this->checkFunction(muRho); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx1( LBMReal vx1 ) 
+{ 
+   this->muVx1.SetExpr( UbSystem::toString(vx1,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx1); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx2( LBMReal vx2 ) 
+{ 
+   this->muVx2.SetExpr( UbSystem::toString(vx2,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx2); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setVx3( LBMReal vx3 ) 
+{ 
+   this->muVx3.SetExpr( UbSystem::toString(vx3,D3Q27RealLim::digits10) );  
+   this->checkFunction(muVx3); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::setRho( LBMReal rho ) 
+{ 
+   this->muRho.SetExpr( UbSystem::toString(rho,D3Q27RealLim::digits10) );  
+   this->checkFunction(muRho); 
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::visit(const SPtr<Grid3D> grid, SPtr<Block3D> block) 
+{
+   using namespace D3Q27System;
+
+   if(!block) UB_THROW( UbException(UB_EXARGS,"block is not exist") );
+
+   //UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
+   //UbTupleDouble3 nodeOffset   = grid->getNodeOffset(block);
+   double dx = grid->getDeltaX(block);
+
+   //define vars for functions
+   mu::value_type x1,x2,x3;
+   this->muVx1.DefineVar("x1",&x1); this->muVx1.DefineVar("x2",&x2); this->muVx1.DefineVar("x3",&x3);
+   this->muVx2.DefineVar("x1",&x1); this->muVx2.DefineVar("x2",&x2); this->muVx2.DefineVar("x3",&x3);
+   this->muVx3.DefineVar("x1",&x1); this->muVx3.DefineVar("x2",&x2); this->muVx3.DefineVar("x3",&x3);
+   this->muRho.DefineVar("x1",&x1); this->muRho.DefineVar("x2",&x2); this->muRho.DefineVar("x3",&x3);
+
+   //Funktionszeiger
+   typedef void (*CalcFeqsFct)(LBMReal* const& /*feq[27]*/,const LBMReal& /*(d)rho*/,const LBMReal& /*vx1*/,const LBMReal& /*vx2*/,const LBMReal& /*vx3*/);
+   CalcFeqsFct   calcFeqsFct   = NULL;
+   
+   LBMReal vx1,vx2,vx3,rho;
+
+   int gridRank = grid->getRank();
+   int blockRank = block->getRank();
+
+   if (blockRank == gridRank && block->isActive())
+   {
+       SPtr<ILBMKernel> kernel = block->getKernel();
+      if (!kernel)
+         throw UbException(UB_EXARGS, "The LBM kernel isn't exist in block: "+block->toString());
+
+      if(kernel->getCompressible()) 
+         calcFeqsFct   = &D3Q27System::calcCompFeq; 
+      else                                                        
+         calcFeqsFct   = &D3Q27System::calcIncompFeq; 
+
+      //UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
+
+      SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray();
+      SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();  
+
+      LBMReal o  = kernel->getCollisionFactor();
+
+      LBMReal f[D3Q27System::ENDF+1];
+
+      size_t nx1 = distributions->getNX1();
+      size_t nx2 = distributions->getNX2();
+      size_t nx3 = distributions->getNX3();
+
+      for(int ix3=0; ix3<bcArray->getNX3(); ix3++)
+         for(int ix2=0; ix2<bcArray->getNX2(); ix2++)
+            for(int ix1=0; ix1<bcArray->getNX1(); ix1++)
+            {
+               Vector3D coords = grid->getNodeCoordinates(block, ix1, ix2, ix3);
+               x1 = coords[0];
+               x2 = coords[1];
+               x3 = coords[2];
+
+               vx1 = muVx1.Eval();
+               vx2 = muVx2.Eval();
+               vx3 = muVx3.Eval();
+               rho = muRho.Eval();
+
+               //x-derivative
+               double deltaX=dx*0.5;
+               x1 = coords[0]+deltaX;
+               double vx1Plusx1 = muVx1.Eval();
+               double vx2Plusx1 = muVx2.Eval();
+               double vx3Plusx1 = muVx3.Eval();
+
+               x1 = coords[0]-deltaX;
+               double vx1Minusx1 = muVx1.Eval();
+               double vx2Minusx1 = muVx2.Eval();
+               double vx3Minusx1 = muVx3.Eval();
+
+               //y-derivative
+               x1 = coords[0];
+               x2 = coords[1]+deltaX;
+               double vx1Plusx2 = muVx1.Eval();
+               double vx2Plusx2 = muVx2.Eval();
+               double vx3Plusx2 = muVx3.Eval();
+
+               x2 = coords[1]-deltaX;
+               double vx1Minusx2 = muVx1.Eval();
+               double vx2Minusx2 = muVx2.Eval();
+               double vx3Minusx2 = muVx3.Eval();
+
+               //z-derivative
+               x2 = coords[1];
+               x3 = coords[2]+deltaX;
+               double vx1Plusx3 = muVx1.Eval();
+               double vx2Plusx3 = muVx2.Eval();
+               double vx3Plusx3 = muVx3.Eval();
+
+               x3 = coords[2]-deltaX;
+               double vx1Minusx3 = muVx1.Eval();
+               double vx2Minusx3 = muVx2.Eval();
+               double vx3Minusx3 = muVx3.Eval();
+
+               double ax=(vx1Plusx1-vx1Minusx1)/(2.0*deltaX)*dx;
+               double bx=(vx2Plusx1-vx2Minusx1)/(2.0*deltaX)*dx;
+               double cx=(vx3Plusx1-vx3Minusx1)/(2.0*deltaX)*dx;
+
+               double ay=(vx1Plusx2-vx1Minusx2)/(2.0*deltaX)*dx;
+               double by=(vx2Plusx2-vx2Minusx2)/(2.0*deltaX)*dx;
+               double cy=(vx3Plusx2-vx3Minusx2)/(2.0*deltaX)*dx;
+
+               double az=(vx1Plusx3-vx1Minusx3)/(2.0*deltaX)*dx;
+               double bz=(vx2Plusx3-vx2Minusx3)/(2.0*deltaX)*dx;
+               double cz=(vx3Plusx3-vx3Minusx3)/(2.0*deltaX)*dx;
+               double eps_new=1.0;
+               LBMReal op = 1.;
+
+               LBMReal feq[27];
+
+               calcFeqsFct(feq,rho,vx1,vx2,vx3);
+
+               double f_E    = eps_new *((5.*ax*o + 5.*by*o + 5.*cz*o - 8.*ax*op + 4.*by*op + 4.*cz*op)/(54.*o*op));
+               double f_N    = f_E + eps_new *((2.*(ax - by))/(9.*o));
+               double f_T    = f_E + eps_new *((2.*(ax - cz))/(9.*o));
+               double f_NE   = eps_new *(-(5.*cz*o + 3.*(ay + bx)*op - 2.*cz*op + ax*(5.*o + op) + by*(5.*o + op))/(54.*o*op));
+               double f_SE   = f_NE + eps_new *((  ay + bx )/(9.*o));
+               double f_TE   = eps_new *(-(5.*cz*o + by*(5.*o - 2.*op) + 3.*(az + cx)*op + cz*op + ax*(5.*o + op))/(54.*o*op));
+               double f_BE   = f_TE + eps_new *((  az + cx )/(9.*o));
+               double f_TN   = eps_new *(-(5.*ax*o + 5.*by*o + 5.*cz*o - 2.*ax*op + by*op + 3.*bz*op + 3.*cy*op + cz*op)/(54.*o*op));
+               double f_BN   = f_TN + eps_new *((  bz + cy )/(9.*o));
+               double f_ZERO = eps_new *((5.*(ax + by + cz))/(9.*op));
+               double f_TNE  = eps_new *(-(ay + az + bx + bz + cx + cy)/(72.*o));
+               double f_TSW  = - eps_new *((ay + bx)/(36.*o)) - f_TNE;
+               double f_TSE  = - eps_new *((az + cx)/(36.*o)) - f_TNE;
+               double f_TNW  = - eps_new *((bz + cy)/(36.*o)) - f_TNE;
+
+
+               f[E]    = f_E    + feq[E];
+               f[W]    = f_E    + feq[W];
+               f[N]    = f_N    + feq[N];
+               f[S]    = f_N    + feq[S];
+               f[T]    = f_T    + feq[T];
+               f[B]    = f_T    + feq[B];
+               f[NE]   = f_NE   + feq[NE];
+               f[SW]   = f_NE   + feq[SW];
+               f[SE]   = f_SE   + feq[SE];
+               f[NW]   = f_SE   + feq[NW];
+               f[TE]   = f_TE   + feq[TE];
+               f[BW]   = f_TE   + feq[BW];
+               f[BE]   = f_BE   + feq[BE];
+               f[TW]   = f_BE   + feq[TW];
+               f[TN]   = f_TN   + feq[TN];
+               f[BS]   = f_TN   + feq[BS];
+               f[BN]   = f_BN   + feq[BN];
+               f[TS]   = f_BN   + feq[TS];
+               f[TNE]  = f_TNE  + feq[TNE];
+               f[TNW]  = f_TNW  + feq[TNW];
+               f[TSE]  = f_TSE  + feq[TSE];
+               f[TSW]  = f_TSW  + feq[TSW];
+               f[BNE]  = f_TSW  + feq[BNE];
+               f[BNW]  = f_TSE  + feq[BNW];
+               f[BSE]  = f_TNW  + feq[BSE];
+               f[BSW]  = f_TNE  + feq[BSW];
+               f[REST] = f_ZERO + feq[REST];
+
+               //calcFeqsFct(f,rho,vx1,vx2,vx3);
+               //distributions->setDistribution(f, ix1, ix2, ix3);
+               distributions->setDistributionInv(f, ix1, ix2, ix3);
+
+               //distributions->swap();
+               //distributions->setDistribution(f, ix1, ix2, ix3);
+               //distributions->setDistributionInv(f, ix1, ix2, ix3);
+               //distributions->swap();
+
+            }
+   }
+
+   //variablen der functions loeschen, da die verwiesenen Objecte nach dem verlassen des scopes ungueltig sind!
+   this->muVx1.ClearVar();
+   this->muVx2.ClearVar();
+   this->muVx3.ClearVar();
+   this->muRho.ClearVar();
+
+}
+//////////////////////////////////////////////////////////////////////////
+void InitDistributionsBlockVisitor::checkFunction(mu::Parser fct)
+{
+   double x1=1.0,x2=1.0,x3=1.0;
+   fct.DefineVar("x1",&x1); 
+   fct.DefineVar("x2",&x2); 
+   fct.DefineVar("x3",&x3);
+
+   try
+   {
+      fct.Eval();
+      fct.ClearVar();
+   }
+   catch(mu::ParserError& e)
+   {
+      throw UbException(UB_EXARGS,"function: "+e.GetExpr() + (std::string)"error: "+e.GetMsg()
+         +(std::string)", only x1,x2,x3 are allowed as variables" );
+   }
+}
+//////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h b/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..be95e46b184cfa960a737a943b95cf6a09721453
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.h
@@ -0,0 +1,101 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file InitDistributionsBlockVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher, Soeren Freudiger
+//=======================================================================================
+
+#ifndef InitDistributionsBlockVisitor_H
+#define InitDistributionsBlockVisitor_H
+
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+#include "D3Q27System.h"
+
+#include <MuParser/include/muParser.h>
+
+class Grid3D;
+class Block3D;
+
+//! \brief A class implements an initialization of the flow area.
+//! \details 
+//! It is more flexible way to initialize flow area.
+//! You can define functions to calculate macroscopic values for feq. 
+//! x1,x2,x3 are automatically defined via this adapter and are the real world
+//! vertex coordinates.
+//!
+//!if function is invalid an UbException with detailed information is thrown
+//!
+//! Example:
+//! \code
+//! InitDistributionsBlockVisitor init;
+//! init.setVx1("0.01*x2");
+//! init.setVx2("0.01*x2^2");
+//! \endcode
+
+class InitDistributionsBlockVisitor : public Block3DVisitor
+{
+public:
+   typedef std::numeric_limits<LBMReal> D3Q27RealLim;
+
+public:
+   InitDistributionsBlockVisitor();
+   //////////////////////////////////////////////////////////////////////////
+   //automatic vars are: x1,x2, x3
+   //ussage example: setVx1("x1*0.01+x2*0.003")
+   //////////////////////////////////////////////////////////////////////////
+   void setVx1( const mu::Parser& parser);
+   void setVx2( const mu::Parser& parser);
+   void setVx3( const mu::Parser& parser);
+   void setRho( const mu::Parser& parser);
+
+   void setVx1( const std::string& muParserString);
+   void setVx2( const std::string& muParserString);
+   void setVx3( const std::string& muParserString);
+   void setRho( const std::string& muParserString);
+   //////////////////////////////////////////////////////////////////////////
+   void setVx1( LBMReal vx1 );
+   void setVx2( LBMReal vx2 );
+   void setVx3( LBMReal vx3 );
+   void setRho( LBMReal rho );
+
+   void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override;
+
+protected:
+   void checkFunction(mu::Parser fct);
+
+private:
+   mu::Parser muVx1;
+   mu::Parser muVx2;
+   mu::Parser muVx3;
+   mu::Parser muRho;
+};
+
+#endif //D3Q27INITDISTRIBUTIONSPATCHVISITOR_H
diff --git a/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.cpp b/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f90b778c3b238065caeea84c11c1927181d2d7a
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.cpp
@@ -0,0 +1,57 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetBcBlocksBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "SetBcBlocksBlockVisitor.h"
+
+#include "Interactor3D.h"
+#include "Grid3DSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+
+SetBcBlocksBlockVisitor::SetBcBlocksBlockVisitor(SPtr<Interactor3D> interactor) : 
+   Block3DVisitor(0, Grid3DSystem::MAXLEVEL), interactor(interactor)
+{
+
+}
+
+void SetBcBlocksBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+   if(block->getRank() == grid->getRank())
+   {
+      if (block->isActive())
+      {
+         interactor->setBCBlock(block);
+      }
+   }
+}
+
diff --git a/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.h b/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a01f5959c092939397a5c89608a97d12c16c8e9
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetBcBlocksBlockVisitor.h
@@ -0,0 +1,60 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetBcBlocksBlockVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef SetBcBlocksBlockVisitor_h__
+#define SetBcBlocksBlockVisitor_h__
+
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+
+class Grid3D;
+class Block3D;
+class Interactor3D;
+
+//! \brief A class sets blocks with boundary condition nodes in Interactor3D object.
+class SetBcBlocksBlockVisitor : public Block3DVisitor
+{
+public:
+   SetBcBlocksBlockVisitor(SPtr<Interactor3D> interactor);
+   virtual ~SetBcBlocksBlockVisitor() {}
+
+   virtual void visit(SPtr<Grid3D> grid, SPtr<Block3D> block);
+
+private:
+   SPtr<Interactor3D> interactor;
+};
+#endif // SetBcBlocksBlockVisitor_h__
+
+
+
diff --git a/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp b/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cec226de23250544396f59ec4960b64de22dc324
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.cpp
@@ -0,0 +1,109 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetConnectorsBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "SetConnectorsBlockVisitor.h"
+#include "D3Q27ETFullDirectConnector.h"
+#include "Grid3DSystem.h"
+#include "Communicator.h"
+#include "Grid3D.h"
+
+SetConnectorsBlockVisitor::SetConnectorsBlockVisitor(SPtr<Communicator> comm, bool fullConnector, int dirs, LBMReal nu) : Block3DVisitor(0, Grid3DSystem::MAXLEVEL),	comm(comm), fullConnector(fullConnector), dirs(dirs), nu(nu)
+{
+}
+//////////////////////////////////////////////////////////////////////////
+SetConnectorsBlockVisitor::~SetConnectorsBlockVisitor(void)
+{
+}
+//////////////////////////////////////////////////////////////////////////
+void SetConnectorsBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+	if(!block) return;
+
+	UBLOG(logDEBUG5, "D3Q27SetConnectorsBlockVisitor::visit() - start");
+   UBLOG(logDEBUG5, block->toString());
+
+	gridRank = comm->getProcessID();
+	grid->setRank(gridRank);
+
+	setSameLevelConnectors(grid, block);
+
+	UBLOG(logDEBUG5, "D3Q27SetConnectorsBlockVisitor::visit() - end");
+}
+//////////////////////////////////////////////////////////////////////////
+void SetConnectorsBlockVisitor::setSameLevelConnectors(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+   UBLOG(logDEBUG5, "D3Q27SetConnectorsBlockVisitor::setSameLevelConnectors() - start");
+	int blockRank = block->getRank();
+	if (gridRank == blockRank && block->isActive())
+	{
+		block->clearWeight();
+		std::vector<SPtr<Block3D>> neighbors; 
+		int ix1 = block->getX1();
+		int ix2 = block->getX2();
+		int ix3 = block->getX3();
+		int level = block->getLevel();
+
+		for( int dir = 0; dir < dirs; dir++)
+		{
+			SPtr<Block3D> neighBlock = grid->getNeighborBlock(dir, ix1, ix2, ix3, level);
+
+			if(neighBlock)
+			{
+				int neighBlockRank = neighBlock->getRank();
+				if(blockRank == neighBlockRank && neighBlock->isActive())
+				{
+					SPtr<Block3DConnector> connector;
+               connector = SPtr<Block3DConnector>(new D3Q27ETFullDirectConnector( block, neighBlock, dir));
+					block->setConnector(connector);
+				}
+				//else if(blockRank != neighBlockRank && neighBlock->isActive())
+				//{
+				//	setRemoteConnectors(block, neighBlock, dir, fullConnector);  
+
+				//	if(dir >=0 && dir<=5)
+				//	{
+				//		int weight = block->getWeight(neighBlockRank);
+				//		weight++;
+				//		block->setWeight(neighBlockRank, weight);
+				//	}
+				//}
+			}
+		}
+      
+  //    int weight = block->getNumberOfLocalConnectorsForSurfaces();
+		//weight = 6 - weight;
+		//block->addWeightForAll(weight);
+	}
+   UBLOG(logDEBUG5, "D3Q27SetConnectorsBlockVisitor::setSameLevelConnectors() - end");
+}
+
diff --git a/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h b/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a829103ccd8598fb2f1c1dddd9f19bf8644e861
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetConnectorsBlockVisitor.h
@@ -0,0 +1,65 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetConnectorsBlockVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef SETCONNECTORSBLOCKVISITOR_H
+#define SETCONNECTORSBLOCKVISITOR_H
+
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+#include "D3Q27System.h"
+
+class Grid3D;
+class Block3D;
+class Communicator;
+class InterpolationProcessor;
+
+//! \brief  A class sets connectors between blocks.
+class SetConnectorsBlockVisitor : public Block3DVisitor
+{
+public:
+	SetConnectorsBlockVisitor(SPtr<Communicator> comm, bool fullConnector, int dirs, LBMReal nu);
+	virtual ~SetConnectorsBlockVisitor();
+	void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override;
+	//////////////////////////////////////////////////////////////////////////
+protected:
+	void setSameLevelConnectors(SPtr<Grid3D> grid, SPtr<Block3D> block);
+   SPtr<Communicator> comm;
+	bool fullConnector;
+	int dirs;
+	int gridRank;
+	LBMReal nu;
+    SPtr<InterpolationProcessor> iProcessor;
+};
+
+#endif //SETCONNECTORSBLOCKVISITOR_H
diff --git a/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp b/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..494e62781f38588b5aed14d06192eddb1da501bc
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
@@ -0,0 +1,107 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetKernelBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "SetKernelBlockVisitor.h"
+#include "Grid3DSystem.h"
+#include "LBMSystem.h"
+#include "DataSet3D.h"
+#include "BCProcessor.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+#include "LBMKernel.h"
+
+//////////////////////////////////////////////////////////////////////////
+SetKernelBlockVisitor::SetKernelBlockVisitor(SPtr<LBMKernel> kernel, LBMReal nue, SetKernelBlockVisitor::Action action) : Block3DVisitor(0, Grid3DSystem::MAXLEVEL), kernel(kernel), nue(nue), action(action), dataSetFlag(true)
+{
+
+}
+//////////////////////////////////////////////////////////////////////////
+void SetKernelBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+   if(kernel && (block->getRank() == grid->getRank()))
+   {
+      LBMReal collFactor = LBMSystem::calcCollisionFactor(nue, block->getLevel());
+      kernel->setCollisionFactor(collFactor);
+      kernel->setIndex(block->getX1(), block->getX2(), block->getX3());
+      kernel->setDeltaT(LBMSystem::getDeltaT(block->getLevel()));
+      kernel->setBlock(block);
+      UbTupleInt3 blockNX = grid->getBlockNX();
+      kernel->setNX(std::array<int,3>{{val<1>(blockNX), val<2>(blockNX), val<3>(blockNX)}});
+      SPtr<LBMKernel> newKernel = kernel->clone();
+
+      switch (action)
+      {
+      case SetKernelBlockVisitor::NewKernel:
+         block->setKernel(newKernel);
+         break;
+      case SetKernelBlockVisitor::ChangeKernel:
+      {
+         SPtr<DataSet3D> dataSet = block->getKernel()->getDataSet();
+         if (!dataSet)
+         {
+            UB_THROW(UbException(UB_EXARGS, "It is not possible to change a DataSet in kernel! Old DataSet is not exist!"));
+         }
+
+         newKernel->setDataSet(dataSet);
+         
+         SPtr<BCProcessor> bcProc = block->getKernel()->getBCProcessor();
+         if (!bcProc)
+         {
+            UB_THROW(UbException(UB_EXARGS, "It is not possible to change a BCProcessor in kernel! Old BCProcessor is not exist!"));
+         }
+         newKernel->setBCProcessor(bcProc);
+         block->setKernel(newKernel);
+      }
+         break;
+
+      case SetKernelBlockVisitor::ChangeKernelWithData:
+      {
+         SPtr<BCProcessor> bcProc = block->getKernel()->getBCProcessor();
+         if (!bcProc)
+         {
+            UB_THROW(UbException(UB_EXARGS, "It is not possible to change a BCProcessor in kernel! Old BCProcessor is not exist!"));
+         }
+         newKernel->setBCProcessor(bcProc);
+         block->setKernel(newKernel);
+      }
+         break;
+      }
+
+   }
+}
+
+void SetKernelBlockVisitor::setNoDataSetFlag(bool flag)
+{
+   dataSetFlag = flag;
+}
+
diff --git a/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h b/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..42778ae1a9e45c8c35e008e41431b6291ff60fb7
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.h
@@ -0,0 +1,66 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetKernelBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef SetKernelBlockVisitor_h
+#define SetKernelBlockVisitor_h
+
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+#include "LBMSystem.h"
+
+class Grid3D;
+class Block3D;
+class LBMKernel;
+
+//! \brief A class generates new LBMKernel and associates it with a block.
+class SetKernelBlockVisitor : public Block3DVisitor
+{
+public:
+   enum Action { NewKernel, ChangeKernel, ChangeKernelWithData};
+
+   SetKernelBlockVisitor(SPtr<LBMKernel> kernel, LBMReal nue, SetKernelBlockVisitor::Action action = SetKernelBlockVisitor::NewKernel);
+   virtual ~SetKernelBlockVisitor() {}
+
+   void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override;
+
+   void setNoDataSetFlag(bool flag);
+
+private:
+   SPtr<LBMKernel> kernel;
+   LBMReal nue;
+   Action action;
+   bool dataSetFlag;
+};
+
+#endif
diff --git a/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.cpp b/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..472d53dee3356aa8930dc7191e312cac985ca20e
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.cpp
@@ -0,0 +1,56 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetSolidBlocksBlockVisitor.cpp
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include "SetSolidBlocksBlockVisitor.h"
+
+#include "Interactor3D.h"
+#include "Grid3DSystem.h"
+#include "Grid3D.h"
+#include "Block3D.h"
+
+SetSolidBlocksBlockVisitor::SetSolidBlocksBlockVisitor(SPtr<Interactor3D> interactor) :
+   Block3DVisitor(0, Grid3DSystem::MAXLEVEL), interactor(interactor)
+{
+
+}
+
+void SetSolidBlocksBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
+{
+   if (block->getRank() == grid->getRank())
+   {
+      if (block->isActive())
+      {
+         interactor->setSolidBlock(block);
+      }
+   }
+}
\ No newline at end of file
diff --git a/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.h b/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfac49c75737001ef7f2e84c149fd8b6d3a3fb2a
--- /dev/null
+++ b/VirtualFluidsCore/Visitors/SetSolidBlocksBlockVisitor.h
@@ -0,0 +1,58 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  \   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of 
+//  the License, or (at your option) any later version.
+//  
+//  VirtualFluids is distributed in the hope that it will be useful, but WITHOUT 
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+//  for more details.
+//  
+//  You should have received a copy of the GNU General Public License along
+//  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file SetSolidBlocksBlockVisitor.h
+//! \ingroup Visitors
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef SetSolidBlocksBlockVisitor_h__
+#define SetSolidBlocksBlockVisitor_h__
+
+#include <PointerDefinitions.h>
+
+#include "Block3DVisitor.h"
+
+class Grid3D;
+class Block3D;
+class Interactor3D;
+
+//! \brief A class sets blocks with solid nodes in Interactor3D object.
+class SetSolidBlocksBlockVisitor : public Block3DVisitor
+{
+public:
+   SetSolidBlocksBlockVisitor(SPtr<Interactor3D> interactor);
+   virtual ~SetSolidBlocksBlockVisitor() {}
+
+   virtual void visit(SPtr<Grid3D> grid, SPtr<Block3D> block);
+
+private:
+   SPtr<Interactor3D> interactor;
+}
+#endif // SetSolidBlocksBlockVisitor_h__
+;
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..1531494820a83fb71da2f9a8e05c0c852c30a48d
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,41 @@
+Software Requirements:
+======================
+
+CMake [cmake.org](https://cmake.org/):
+* minimum version 3.13
+    
+Paraview [www.paraview.org](https://www.paraview.org/):
+* any version, for example the most recent
+    
+C++ Compiler:
+* with C++11 support, for example gcc6.3 or Visual C++ 14.0
+    
+How to get VirtualFluidsCPU:
+==========================
+
+Option 1: use git
+1. checkout out https://git.irmb.bau.tu-bs.de/VirtualFluids/VirtualFluidsCPU.git with your credentials
+
+Option 2: without git
+1. go to git.irmb.tu-bs.de
+2. Log in with your credentials
+3. click on VirtualFluids/VirtualFluidsCPU
+4. click on the download symbol on the top right and download zip/tar.gz file
+
+How to build VirtualFluidsCPU:
+============================
+
+1. CMake the project
+2. set the output path in Applications/LidDrivenCavity/LidDrivenCavity.cpp
+3. build the project ("compile")
+4. run the generated executable (usually in <build directory>/Applications/LidDrivenCavity)
+
+VirtualFluidsCPU results files:
+===============================
+
+VirtualFluidsCPU generates a set of multiple output directories in the prescribed output path. The flow fields can be found in the _mq_ directory. To view the flow fields, it is most conveniant to open the _mq_collection.pvd_ file in Paraview. The _bc_ directory contains the boundary condition information, the _geo_ directory contains information on the geometry of the flow domain and the _blocks_ directory contains the block grid.
+
+Documentation:
+==============
+
+The doxygen generated documentation can be found [here](https://git.irmb.bau.tu-bs.de/doku/CPU).