diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c9338c55001604a041d734ca58c67671458b7b51..fe6e951ed121cc905de3b099d8639594dd440795 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -36,99 +36,87 @@ stages:
       - docker
 
 
-.build_serial_template: &build_serial_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "OFF"
-      WALBERLA_BUILD_WITH_OPENMP: "OFF"
-      CMAKE_BUILD_TYPE: "Release"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "OFF"
-      WALBERLA_BUILD_WITH_PARMETIS: "OFF"
-
-
-.build_mpionly_template: &build_mpionly_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "ON"
-      WALBERLA_BUILD_WITH_OPENMP: "OFF"
-      CMAKE_BUILD_TYPE: "Release"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "OFF"
-      WALBERLA_BUILD_WITH_PARMETIS: "OFF"
-
-
-.build_hybrid_template: &build_hybrid_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "ON"
-      WALBERLA_BUILD_WITH_OPENMP: "ON"
-      OMP_NUM_THREADS: "4"
-      OMP_WAIT_POLICY: "PASSIVE"
-      CMAKE_BUILD_TYPE: "Release"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "ON"
-      WALBERLA_BUILD_WITH_PARMETIS: "ON"
-
-.build_serial_dbg_template: &build_serial_dbg_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "OFF"
-      WALBERLA_BUILD_WITH_OPENMP: "OFF"
-      CMAKE_BUILD_TYPE: "DebugOptimized"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "OFF"
-      WALBERLA_BUILD_WITH_PARMETIS: "OFF"
-
-
-.build_mpionly_dbg_template: &build_mpionly_dbg_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "ON"
-      WALBERLA_BUILD_WITH_OPENMP: "OFF"
-      CMAKE_BUILD_TYPE: "DebugOptimized"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "OFF"
-      WALBERLA_BUILD_WITH_PARMETIS: "OFF"
-
-
-.build_hybrid_dbg_template: &build_hybrid_dbg_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "ON"
-      WALBERLA_BUILD_WITH_OPENMP: "ON"
-      OMP_NUM_THREADS: "4"
-      OMP_WAIT_POLICY: "PASSIVE"
-      CMAKE_BUILD_TYPE: "DebugOptimized"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "ON"
-      WALBERLA_BUILD_WITH_METIS: "ON"
-      WALBERLA_BUILD_WITH_PARMETIS: "ON"
-
-.build_hybrid_dbg_sp_template: &build_hybrid_dbg_sp_definition
-   <<: *build_definition
-   variables:
-      CTEST_EXCLUDE_LABELS: "longrun"
-      WALBERLA_BUILD_WITH_MPI: "ON"
-      WALBERLA_BUILD_WITH_OPENMP: "ON"
-      OMP_NUM_THREADS: "4"
-      OMP_WAIT_POLICY: "PASSIVE"
-      CMAKE_BUILD_TYPE: "DebugOptimized"
-      WALBERLA_BUFFER_DEBUG: "OFF"
-      WALBERLA_DOUBLE_ACCURACY: "OFF"
-      WALBERLA_BUILD_WITH_METIS: "OFF"
-      WALBERLA_BUILD_WITH_PARMETIS: "OFF"
+.variables: &build_serial_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "OFF"
+   WALBERLA_BUILD_WITH_OPENMP: "OFF"
+   CMAKE_BUILD_TYPE: "Release"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "OFF"
+   WALBERLA_BUILD_WITH_PARMETIS: "OFF"
+
+
+.variables: &build_mpionly_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "ON"
+   WALBERLA_BUILD_WITH_OPENMP: "OFF"
+   CMAKE_BUILD_TYPE: "Release"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "OFF"
+   WALBERLA_BUILD_WITH_PARMETIS: "OFF"
+
+
+.variables: &build_hybrid_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "ON"
+   WALBERLA_BUILD_WITH_OPENMP: "ON"
+   OMP_NUM_THREADS: "4"
+   OMP_WAIT_POLICY: "PASSIVE"
+   CMAKE_BUILD_TYPE: "Release"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "ON"
+   WALBERLA_BUILD_WITH_PARMETIS: "ON"
+
+
+.variables: &build_serial_dbg_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "OFF"
+   WALBERLA_BUILD_WITH_OPENMP: "OFF"
+   CMAKE_BUILD_TYPE: "DebugOptimized"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "OFF"
+   WALBERLA_BUILD_WITH_PARMETIS: "OFF"
+
+
+.variables: &build_mpionly_dbg_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "ON"
+   WALBERLA_BUILD_WITH_OPENMP: "OFF"
+   CMAKE_BUILD_TYPE: "DebugOptimized"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "OFF"
+   WALBERLA_BUILD_WITH_PARMETIS: "OFF"
+
+
+.variables: &build_hybrid_dbg_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "ON"
+   WALBERLA_BUILD_WITH_OPENMP: "ON"
+   OMP_NUM_THREADS: "4"
+   OMP_WAIT_POLICY: "PASSIVE"
+   CMAKE_BUILD_TYPE: "DebugOptimized"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "ON"
+   WALBERLA_BUILD_WITH_METIS: "ON"
+   WALBERLA_BUILD_WITH_PARMETIS: "ON"
+
+
+.variables: &build_hybrid_dbg_sp_variables
+   CTEST_EXCLUDE_LABELS: "longrun"
+   WALBERLA_BUILD_WITH_MPI: "ON"
+   WALBERLA_BUILD_WITH_OPENMP: "ON"
+   OMP_NUM_THREADS: "4"
+   OMP_WAIT_POLICY: "PASSIVE"
+   CMAKE_BUILD_TYPE: "DebugOptimized"
+   WALBERLA_BUFFER_DEBUG: "OFF"
+   WALBERLA_DOUBLE_ACCURACY: "OFF"
+   WALBERLA_BUILD_WITH_METIS: "OFF"
+   WALBERLA_BUILD_WITH_PARMETIS: "OFF"
 
 
 ###############################################################################
@@ -140,573 +128,981 @@ stages:
 
 
 intel_16_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_16_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:16
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
       - intel
 
 intel_17_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
       - intel
 
 intel_17_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
       - intel
 
 gcc_5_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_5_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:5
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 gcc_6_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_6_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:6
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_7_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_7_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 gcc_7_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
 gcc_7_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
 gcc_7_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
 gcc_7_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
 gcc_7_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
 clang_3.6_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.6_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.6_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.6_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.6
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.7_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.7_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.7_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.7_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.7
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.8_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.8
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - cuda
       - docker
 
 clang_3.9_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_3.9_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:3.9
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_4.0_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:4.0
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_serial:
-   <<: *build_serial_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_mpionly:
-   <<: *build_mpionly_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_hybrid:
-   <<: *build_hybrid_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_serial_dbg:
-   <<: *build_serial_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_mpionly_dbg:
-   <<: *build_mpionly_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_hybrid_dbg:
-   <<: *build_hybrid_dbg_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
 clang_5.0_hybrid_dbg_sp:
-   <<: *build_hybrid_dbg_sp_definition
+   <<: *build_definition
    image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:5.0
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
+   tags:
+      - docker
+
+clang_6.0_serial:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_serial_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
+   tags:
+      - docker
+
+clang_6.0_mpionly:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_mpionly_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   only:
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
+   tags:
+      - docker
+
+clang_6.0_hybrid:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_hybrid_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
+   tags:
+      - docker
+
+clang_6.0_serial_dbg:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_serial_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
+   tags:
+      - docker
+
+clang_6.0_mpionly_dbg:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_mpionly_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
+   tags:
+      - docker
+
+clang_6.0_hybrid_dbg:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_hybrid_dbg_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
+   tags:
+      - docker
+
+clang_6.0_hybrid_dbg_sp:
+   <<: *build_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
+   variables:
+      <<: *build_hybrid_dbg_sp_variables
+      WALBERLA_BUILD_WITH_CUDA: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
 
@@ -728,6 +1124,9 @@ doc:
       - cmake ..
       - cmake . -LAH
       - make doc
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
    tags:
       - docker
    artifacts:
@@ -752,7 +1151,8 @@ cppcheck:
    artifacts:
       untracked: true
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
 
@@ -780,7 +1180,8 @@ coverage:
       paths:
          - coverage/
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
    tags:
       - docker
    variables:
@@ -821,6 +1222,9 @@ msvc-14_Hybrid_Dbg:
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14_Hybrid_SP_Dbg:
    <<: *win_build_definition
@@ -832,7 +1236,8 @@ msvc-14_Hybrid_SP_Dbg:
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "OFF"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14_Hybrid:
    <<: *win_build_definition
@@ -844,7 +1249,8 @@ msvc-14_Hybrid:
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14_Serial_Dbg:
    <<: *win_build_definition
@@ -856,7 +1262,8 @@ msvc-14_Serial_Dbg:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14_Serial:
    <<: *win_build_definition
@@ -868,7 +1275,8 @@ msvc-14_Serial:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14_MpiOnly_Dbg:
    <<: *win_build_definition
@@ -880,7 +1288,8 @@ msvc-14_MpiOnly_Dbg:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14_MpiOnly:
    <<: *win_build_definition
@@ -892,7 +1301,8 @@ msvc-14_MpiOnly:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
       
 msvc-14.1_Hybrid_Dbg:
@@ -904,6 +1314,9 @@ msvc-14.1_Hybrid_Dbg:
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14.1_Hybrid_SP_Dbg:
    <<: *win_build_definition
@@ -914,6 +1327,9 @@ msvc-14.1_Hybrid_SP_Dbg:
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "OFF"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14.1_Hybrid:
    <<: *win_build_definition
@@ -924,6 +1340,9 @@ msvc-14.1_Hybrid:
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "ON"
       WALBERLA_DOUBLE_ACCURACY: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14.1_Serial_Dbg:
    <<: *win_build_definition
@@ -934,6 +1353,9 @@ msvc-14.1_Serial_Dbg:
       WALBERLA_BUILD_WITH_MPI: "OFF"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14.1_Serial:
    <<: *win_build_definition
@@ -945,7 +1367,8 @@ msvc-14.1_Serial:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
       
 msvc-14.1_MpiOnly_Dbg:
    <<: *win_build_definition
@@ -956,6 +1379,9 @@ msvc-14.1_MpiOnly_Dbg:
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
       
 msvc-14.1_MpiOnly:
    <<: *win_build_definition
@@ -967,7 +1393,8 @@ msvc-14.1_MpiOnly:
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_DOUBLE_ACCURACY: "ON"
    only:
-      - triggers
+      variables:
+         - $ENABLE_NIGHTLY_BUILDS
 
 
 ###############################################################################
@@ -990,7 +1417,7 @@ msvc-14.1_MpiOnly:
       - cmake .. -DWALBERLA_BUILD_TESTS=ON -DWALBERLA_BUILD_BENCHMARKS=ON -DWALBERLA_BUILD_TUTORIALS=ON -DWALBERLA_BUILD_TOOLS=ON -DWALBERLA_BUILD_WITH_MPI=$WALBERLA_BUILD_WITH_MPI -DWALBERLA_BUILD_WITH_PYTHON=$WALBERLA_BUILD_WITH_PYTHON -DWALBERLA_BUILD_WITH_OPENMP=$WALBERLA_BUILD_WITH_OPENMP -DWALBERLA_BUILD_WITH_CUDA=$WALBERLA_BUILD_WITH_CUDA -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DWARNING_ERROR=ON
       - cmake . -LAH
       - make -j $NUM_BUILD_CORES -l $NUM_CORES
-      - ctest -LE $CTEST_EXCLUDE_LABELS -C $CMAKE_BUILD_TYPE --output-on-failure -j $NUM_CORES
+      - ctest -LE "$CTEST_EXCLUDE_LABELS|cuda" -C $CMAKE_BUILD_TYPE --output-on-failure -j $NUM_CORES
    tags:
       - mac
 
@@ -998,41 +1425,53 @@ mac_Serial_Dbg:
    <<: *mac_build_definition
    variables:
       CMAKE_BUILD_TYPE: "DebugOptimized"
-      CTEST_EXCLUDE_LABELS: "longrun|cuda"
+      CTEST_EXCLUDE_LABELS: "longrun"
       WALBERLA_BUILD_WITH_MPI: "OFF"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_BUILD_WITH_PYTHON: "ON"
       WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
 
 mac_Serial:
    <<: *mac_build_definition
    variables:
       CMAKE_BUILD_TYPE: "Release"
-      CTEST_EXCLUDE_LABELS: "longrun|cuda"
+      CTEST_EXCLUDE_LABELS: "longrun"
       WALBERLA_BUILD_WITH_MPI: "OFF"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_BUILD_WITH_PYTHON: "ON"
       WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
 
 mac_MpiOnly_Dbg:
    <<: *mac_build_definition
    variables:
       CMAKE_BUILD_TYPE: "DebugOptimized"
-      CTEST_EXCLUDE_LABELS: "longrun|cuda"
+      CTEST_EXCLUDE_LABELS: "longrun"
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_BUILD_WITH_PYTHON: "ON"
       WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
 
 mac_MpiOnly:
    <<: *mac_build_definition
    variables:
       CMAKE_BUILD_TYPE: "Release"
-      CTEST_EXCLUDE_LABELS: "longrun|cuda"
+      CTEST_EXCLUDE_LABELS: "longrun"
       WALBERLA_BUILD_WITH_MPI: "ON"
       WALBERLA_BUILD_WITH_OPENMP: "OFF"
       WALBERLA_BUILD_WITH_PYTHON: "ON"
       WALBERLA_BUILD_WITH_CUDA: "ON"
+   except:
+      variables:
+         - $DISABLE_PER_COMMIT_BUILDS
 
 
 ###############################################################################
@@ -1089,3 +1528,64 @@ conda-py35-linux:
       - apt-get update
       - apt-get install -y build-essential
       - conda build --python=3.5 --user=lssfau utilities/conda/walberla
+
+
+###############################################################################
+##                                                                           ##
+##    Benchmarks                                                             ##
+##                                                                           ##
+###############################################################################
+
+.benchmark_template: &benchmark_definition
+   script:
+      - apt-get update --fix-missing
+      - apt-get install -y python3-influxdb python3-git
+      - $CXX --version
+      - cmake --version
+      - ccache --version
+      - mpirun --version
+      - export CCACHE_BASEDIR=$CI_PROJECT_DIR
+      - mkdir $CI_PROJECT_DIR/build
+      - cd $CI_PROJECT_DIR/build
+      - cmake .. -DWALBERLA_BUFFER_DEBUG=OFF -DWALBERLA_BUILD_TESTS=OFF -DWALBERLA_BUILD_BENCHMARKS=ON -DWALBERLA_BUILD_TUTORIALS=OFF -DWALBERLA_BUILD_TOOLS=OFF -DWALBERLA_BUILD_WITH_MPI=ON -DWALBERLA_BUILD_WITH_CUDA=OFF -DWALBERLA_BUILD_WITH_PYTHON=OFF -DWALBERLA_BUILD_WITH_OPENMP=OFF -DCMAKE_BUILD_TYPE=RELEASE -DMPIEXEC_PREFLAGS=$MPIEXEC_PREFLAGS -DWALBERLA_DOUBLE_ACCURACY=ON -DWARNING_ERROR=ON -DWALBERLA_BUILD_WITH_METIS=OFF -DWALBERLA_BUILD_WITH_PARMETIS=OFF -DWALBERLA_OPTIMIZE_FOR_LOCALHOST=ON -DWALBERLA_BUILD_WITH_FASTMATH=ON -DWALBERLA_BUILD_WITH_LTO=ON
+      - cmake . -LAH
+      - cd apps/benchmarks/PeriodicGranularGas
+      - make -j 20
+      - export PATH=$PATH:/usr/local/likwid/bin
+      - likwid-setFrequencies -t 0
+      - likwid-setFrequencies -g performance
+      - likwid-setFrequencies -x 3.3 -y 3.3 # set frequency to 3.3
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --DEM --syncNextNeighbor | tee PeriodicGranularGas_DEM_NN.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --DEM --syncShadowOwners | tee PeriodicGranularGas_DEM_SO.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticFrictionlessContact | tee PeriodicGranularGas_HCSITS_NN_IFC.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --ApproximateInelasticCoulombContactByDecoupling | tee PeriodicGranularGas_HCSITS_NN_AICCBD.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticCoulombContactByDecoupling | tee PeriodicGranularGas_HCSITS_NN_ICCBD.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncNextNeighbor --InelasticGeneralizedMaximumDissipationContact | tee PeriodicGranularGas_HCSITS_NN_IGMDC.txt
+      - mpirun --allow-run-as-root -np 8 --map-by core --bind-to core --report-bindings ./PeriodicGranularGas PeriodicGranularGas.cfg --HCSITS --syncShadowOwners --InelasticFrictionlessContact | tee PeriodicGranularGas_HCSITS_SO_IFC.txt
+      - python3 upload.py
+   only:
+      variables:
+         - $ENABLE_BENCHMARKS
+   tags:
+      - docker-benchmark
+   artifacts:
+      paths:
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_DEM_NN.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_DEM_SO.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_IFC.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_AICCBD.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_ICCBD.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_NN_IGMDC.txt
+         - $CI_PROJECT_DIR/build/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas_HCSITS_SO_IFC.txt
+
+benchmark_intel17:
+   <<: *benchmark_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/intel:17
+
+benchmark_gcc7:
+   <<: *benchmark_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/gcc:7
+
+benchmark_clang6:
+   <<: *benchmark_definition
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:6.0
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85125dcaf83ccf81a7ef108eb38f92b4b3ee89ed..0ee1e578c7a963ec1f5f40c907fce8aa647b1b6b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1027,31 +1027,22 @@ endif()
 option ( WALBERLA_THREAD_SAFE_LOGGING "Enables/Disables thread-safe logging" ON )
 
 if ( WALBERLA_BUILD_WITH_OPENMP )
-    if ( WALBERLA_CXX_COMPILER_IS_INTEL )
+    if ( WALBERLA_CXX_COMPILER_IS_INTEL AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "16.0.3" )
        add_flag ( CMAKE_C_FLAGS   "-openmp" )
        add_flag ( CMAKE_CXX_FLAGS "-openmp" )
-    elseif ( CMAKE_COMPILER_IS_GNUCXX )
-      add_flag ( CMAKE_C_FLAGS   "-fopenmp" )
-      add_flag ( CMAKE_CXX_FLAGS "-fopenmp" )
-    elseif ( WALBERLA_CXX_COMPILER_IS_CLANG )
-       add_flag ( CMAKE_C_FLAGS   "-fopenmp" )
-       add_flag ( CMAKE_CXX_FLAGS "-fopenmp" )
-    elseif ( WALBERLA_CXX_COMPILER_IS_MSVC )
-      add_flag ( CMAKE_C_FLAGS   "/openmp" )
-      add_flag ( CMAKE_CXX_FLAGS "/openmp" )
-    elseif ( WALBERLA_CXX_COMPILER_IS_IBM )
-      add_flag ( CMAKE_C_FLAGS   "-qsmp=omp" )
-      add_flag ( CMAKE_CXX_FLAGS "-qsmp=omp" )
-      # There has been an internal compiler error with the IBM compiler, so WALBERLA_THREAD_SAFE_LOGGING is disabled by default for this compiler
-      set ( WALBERLA_THREAD_SAFE_LOGGING OFF CACHE BOOL "Enables/Disables thread-safe logging" FORCE )
     elseif ( WALBERLA_CXX_COMPILER_IS_NEC )
-      add_flag ( CMAKE_C_FLAGS   "-Popenmp" )
-      add_flag ( CMAKE_CXX_FLAGS "-Popenmp" )
+       add_flag ( CMAKE_C_FLAGS   "-Popenmp" )
+       add_flag ( CMAKE_CXX_FLAGS "-Popenmp" )
+    else()
+       find_package( OpenMP )
+       add_flag ( CMAKE_C_FLAGS   "${OpenMP_C_FLAGS}" )
+       add_flag ( CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS}" )
+       list ( APPEND SERVICE_LIBS ${OpenMP_CXX_LIBRARIES} )
     endif()
 else()
     if ( WALBERLA_CXX_COMPILER_IS_CRAY )
-      add_flag ( CMAKE_C_FLAGS   "-h noomp" )
-      add_flag ( CMAKE_CXX_FLAGS "-h noomp" )
+       add_flag ( CMAKE_C_FLAGS   "-h noomp" )
+       add_flag ( CMAKE_CXX_FLAGS "-h noomp" )
     endif()
 endif()
 ############################################################################################################################
diff --git a/apps/benchmarks/CMakeLists.txt b/apps/benchmarks/CMakeLists.txt
index 47f77911653f7c8eec3d68550711810a8606e153..a81420b475e6378a3f453ebd4ae16c2c0c895e8d 100644
--- a/apps/benchmarks/CMakeLists.txt
+++ b/apps/benchmarks/CMakeLists.txt
@@ -4,6 +4,7 @@ add_subdirectory( CouetteFlow )
 add_subdirectory( ForcesOnSphereNearPlaneInShearFlow )
 add_subdirectory( NonUniformGrid )
 add_subdirectory( MotionSingleHeavySphere )
+add_subdirectory( PeriodicGranularGas )
 add_subdirectory( PoiseuilleChannel )
 add_subdirectory( SchaeferTurek )
-add_subdirectory( UniformGrid )
\ No newline at end of file
+add_subdirectory( UniformGrid )
diff --git a/apps/benchmarks/ComplexGeometry/test.conf b/apps/benchmarks/ComplexGeometry/test.conf
index 4279c514f08abb430d63735905e4433d8fc53f73..1b43bfc4e6f1dfe2eff8953a1680cbf68b5f6b97 100644
--- a/apps/benchmarks/ComplexGeometry/test.conf
+++ b/apps/benchmarks/ComplexGeometry/test.conf
@@ -1,12 +1,12 @@
 ComplexGeometry
 {
    meshFile        cube.obj;
-   coarseDx        0.2;
+   coarseDx        0.1;
    coarseOmega     1.6;
    coarseTimeSteps 1;
    numLevels       2;
    bodyForce       <0.0001, 0, 0>;
-   blockSize       <8,8,8>;
+   blockSize       <16,16,16>;
    domainBlowUp    <5,5,5>; // simulation domain is blow up factor times mesh size per dimension
    
    Boundaries {
diff --git a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
index 815e6cdf1504ad4fdab43a6bcb3bc351363a7ba9..b28601c50d2ce89cb65425fd707588387a2e1053 100644
--- a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
+++ b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
@@ -91,7 +91,6 @@
 #include "vtk/Initialization.h"
 #include "vtk/VTKOutput.h"
 
-#include <boost/bind.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/type_traits/is_same.hpp>
 
@@ -99,6 +98,7 @@
 #include <cmath>
 #include <cstdlib>
 #include <cstring>
+#include <functional>
 #include <iostream>
 #include <utility>
 #include <vector>
@@ -241,7 +241,7 @@ class BorderRefinementSelection
 public:
 
    BorderRefinementSelection( const Setup & setup, const uint_t level, const real_t bufferDistance ) :
-      setup_( setup ), level_( level ), bufferDistance_( bufferDistance ) {}
+      setup_( setup ), level_( level ), bufferDistance_( bufferDistance ) { WALBERLA_UNUSED(setup_); }
 
    void operator()( SetupBlockForest & forest )
    {
@@ -294,7 +294,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) );
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ),
                                                         real_c( setup.yBlocks * setup.yCells ),
@@ -736,11 +736,11 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    // evaluation
 
-   const auto exactSolutionFunction = boost::bind( exactVelocity, _1, blocks->getDomain(), setup.maxVelocity_L );
+   const auto exactSolutionFunction = std::bind( exactVelocity, std::placeholders::_1, blocks->getDomain(), setup.maxVelocity_L );
 
    auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId,
                                                                                                         flagFieldId, Fluid_Flag,
-                                                                                                        boost::bind( exactFlowRate, setup.flowRate_L ),
+                                                                                                        std::bind( exactFlowRate, setup.flowRate_L ),
                                                                                                         exactSolutionFunction );
    volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L );
    volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) );
diff --git a/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp b/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp
index 62cd5258d085e029eedce2f53940177244d7d187..64bc164815b875e0bfeb4774bdae1ecef440e514 100644
--- a/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp
+++ b/apps/benchmarks/ForcesOnSphereNearPlaneInShearFlow/ForcesOnSphereNearPlaneInShearFlow.cpp
@@ -62,6 +62,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace forces_on_sphere_near_plane_in_shear_flow
 {
 
@@ -177,7 +179,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], true, true, false );
@@ -576,7 +578,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_t( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create pe bodies
 
diff --git a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
index fc6a084ffb1451de776451618b6d60e4c1873040..825af2b2ddf3214a788d4bda7bc80656599f30f7 100644
--- a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
+++ b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
@@ -58,6 +58,7 @@
 #include "vtk/Initialization.h"
 #include "vtk/VTKOutput.h"
 
+#include <functional>
 #include <memory>
 
 
@@ -811,9 +812,9 @@ int main( int argc, char **argv )
    const real_t overlap = real_t( 1.5 ) * dx;
    std::function<void(void)> syncCall;
    if( XBlocks <= uint_t(4) )
-      syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+      syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
    else
-      syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+      syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
 
    real_t xParticle = real_t(0);
diff --git a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
index 38057f0f3d602175851e763e5a4b416c04701a8b..0602976bcbc2de7b99e78de14d9335d5bf8bbeb4 100644
--- a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
+++ b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
@@ -76,6 +76,7 @@
 #include "vtk/VTKOutput.h"
 
 #include <cstdlib>
+#include <functional>
 #include <iostream>
 
 
@@ -279,7 +280,7 @@ void createSetupBlockForest( blockforest::SetupBlockForest & sforest, const Conf
                                                              uint_c( 19 * sizeof(real_t) ) ) / numeric_cast< memory_t >( 1024 * 1024 );
 
    sforest.addRefinementSelectionFunction( refinementSelection );
-   sforest.addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) );
+   sforest.addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) );
 
    sforest.init( AABB( real_t(0), real_t(0), real_t(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ),
                                                         real_c( numberOfYBlocks * numberOfYCellsPerBlock ),
diff --git a/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt b/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d26f6314fd3d73bbac01b460da7240949a45350a
--- /dev/null
+++ b/apps/benchmarks/PeriodicGranularGas/CMakeLists.txt
@@ -0,0 +1,6 @@
+waLBerla_link_files_to_builddir( *.cfg )
+waLBerla_link_files_to_builddir( *.py )
+
+waLBerla_add_executable ( NAME PeriodicGranularGas
+                          FILES PeriodicGranularGas.cpp
+                          DEPENDS blockforest core pe )
diff --git a/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..e281e9b0ecd0abe2ee48313040696d09d86d9db1
--- /dev/null
+++ b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cfg
@@ -0,0 +1,22 @@
+
+PeriodicGranularGas
+{
+   simulationCorner < 0, 0, 0 >;
+   simulationDomain < 30, 30, 30 >;
+   blocks < 2, 2, 2 >;
+   isPeriodic < 1, 1, 1 >;
+
+   radius  0.5;
+   spacing 1.0;
+   vMax    0.0;
+
+   dt                0.1;
+   simulationSteps   1000;
+   visSpacing         100;
+
+   HCSITSmaxIterations 10;
+   HCSITSRelaxationParameter 0.7;
+   HCSITSErrorReductionParameter 0.8;
+   HCSITSRelaxationModelStr ApproximateInelasticCoulombContactByDecoupling;
+   globalLinearAcceleration < 0, 0, 0 >;
+}
diff --git a/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7efaeb660c56c92b7467a83b17312125fa403d19
--- /dev/null
+++ b/apps/benchmarks/PeriodicGranularGas/PeriodicGranularGas.cpp
@@ -0,0 +1,250 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file   PeriodicGranularGas.cpp
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include <pe/basic.h>
+#include <pe/vtk/SphereVtkOutput.h>
+
+#include <core/Abort.h>
+#include <core/Environment.h>
+#include <core/grid_generator/SCIterator.h>
+#include <core/logging/Logging.h>
+#include <core/waLBerlaBuildInfo.h>
+#include <vtk/VTKOutput.h>
+
+#include <functional>
+#include <memory>
+
+using namespace walberla;
+using namespace walberla::pe;
+using namespace walberla::timing;
+
+typedef boost::tuple<Sphere> BodyTuple ;
+
+int main( int argc, char ** argv )
+{
+   Environment env(argc, argv);
+
+   logging::Logging::instance()->setStreamLogLevel(logging::Logging::INFO);
+   logging::Logging::instance()->setFileLogLevel(logging::Logging::INFO);
+
+   WALBERLA_LOG_INFO_ON_ROOT( "config file: " << argv[1] )
+   WALBERLA_LOG_INFO_ON_ROOT( "waLBerla Revision: " << WALBERLA_GIT_SHA1 );
+
+   math::seedRandomGenerator( static_cast<unsigned int>(1337 * mpi::MPIManager::instance()->worldRank()) );
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** READING COMMANDLINE ARGUMENTS ***");
+   bool bDEM = false;
+   bool bHCSITS = false;
+
+   bool bNN = false;
+   bool bSO = false;
+
+   bool bInelasticFrictionlessContact = false;
+   bool bApproximateInelasticCoulombContactByDecoupling = false;
+   bool bInelasticCoulombContactByDecoupling = false;
+   bool bInelasticGeneralizedMaximumDissipationContact = false;
+
+   for( int i = 1; i < argc; ++i )
+   {
+      if( std::strcmp( argv[i], "--DEM" ) == 0 ) bDEM = true;
+      if( std::strcmp( argv[i], "--HCSITS" ) == 0 ) bHCSITS = true;
+
+      if( std::strcmp( argv[i], "--syncNextNeighbor" ) == 0 ) bNN = true;
+      if( std::strcmp( argv[i], "--syncShadowOwners" ) == 0 ) bSO = true;
+
+      if( std::strcmp( argv[i], "--InelasticFrictionlessContact" ) == 0 ) bInelasticFrictionlessContact = true;
+      if( std::strcmp( argv[i], "--ApproximateInelasticCoulombContactByDecoupling" ) == 0 ) bApproximateInelasticCoulombContactByDecoupling = true;
+      if( std::strcmp( argv[i], "--InelasticCoulombContactByDecoupling" ) == 0 ) bInelasticCoulombContactByDecoupling = true;
+      if( std::strcmp( argv[i], "--InelasticGeneralizedMaximumDissipationContact" ) == 0 ) bInelasticGeneralizedMaximumDissipationContact = true;
+   }
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** READING CONFIG FILE ***");
+   auto cfg = env.config();
+   if (cfg == NULL) WALBERLA_ABORT("No config specified!");
+   const Config::BlockHandle mainConf  = cfg->getBlock( "PeriodicGranularGas" );
+
+   int simulationSteps = mainConf.getParameter<int>("simulationSteps", 10 );
+   WALBERLA_LOG_INFO_ON_ROOT("simulationSteps: " << simulationSteps);
+
+   real_t dt = mainConf.getParameter<real_t>("dt", real_c(0.01) );
+   WALBERLA_LOG_INFO_ON_ROOT("dt: " << dt);
+
+   const int visSpacing = mainConf.getParameter<int>("visSpacing",  1000 );
+   WALBERLA_LOG_INFO_ON_ROOT("visSpacing: " << visSpacing);
+   const std::string path = mainConf.getParameter<std::string>("path",  "vtk_out" );
+   WALBERLA_LOG_INFO_ON_ROOT("path: " << path);
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** GLOBALBODYSTORAGE ***");
+   shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** BLOCKFOREST ***");
+   // create forest
+   shared_ptr< BlockForest > forest = createBlockForestFromConfig( mainConf );
+   if (!forest)
+   {
+      WALBERLA_LOG_INFO_ON_ROOT( "No BlockForest created ... exiting!");
+      return EXIT_SUCCESS;
+   }
+
+   WALBERLA_LOG_INFO_ON_ROOT("simulationDomain: " << forest->getDomain());
+
+   WALBERLA_LOG_INFO_ON_ROOT("blocks: " << Vector3<uint_t>(forest->getXSize(), forest->getYSize(), forest->getZSize()) );
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** BODYTUPLE ***");
+   // initialize body type ids
+   SetBodyTypeIDs<BodyTuple>::execute();
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** STORAGEDATAHANDLING ***");
+   // add block data
+   auto storageID           = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage");
+   auto ccdID               = forest->addBlockData(ccd::createHashGridsDataHandling( globalBodyStorage, storageID ), "CCD");
+   auto fcdID               = forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTuple, fcd::AnalyticCollideFunctor>(), "FCD");
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***");
+   std::unique_ptr<cr::ICR> cr;
+   if (bDEM)
+   {
+      cr = std::make_unique<cr::DEM>(globalBodyStorage, forest, storageID, ccdID, fcdID);
+      WALBERLA_LOG_INFO_ON_ROOT("Using DEM!");
+   } else if (bHCSITS)
+   {
+      cr = std::make_unique<cr::HCSITS>(globalBodyStorage, forest, storageID, ccdID, fcdID);
+      configure(mainConf, *static_cast<cr::HCSITS*>(cr.get()));
+      WALBERLA_LOG_INFO_ON_ROOT("Using HCSITS!");
+
+      cr::HCSITS* hcsits = static_cast<cr::HCSITS*>(cr.get());
+
+      if (bInelasticFrictionlessContact)
+      {
+         hcsits->setRelaxationModel(cr::HCSITS::InelasticFrictionlessContact);
+         WALBERLA_LOG_INFO_ON_ROOT("Using InelasticFrictionlessContact!");
+      } else if (bApproximateInelasticCoulombContactByDecoupling)
+      {
+         hcsits->setRelaxationModel(cr::HCSITS::ApproximateInelasticCoulombContactByDecoupling);
+         WALBERLA_LOG_INFO_ON_ROOT("Using ApproximateInelasticCoulombContactByDecoupling!");
+      } else if (bInelasticCoulombContactByDecoupling)
+      {
+         hcsits->setRelaxationModel(cr::HCSITS::InelasticCoulombContactByDecoupling);
+         WALBERLA_LOG_INFO_ON_ROOT("Using InelasticCoulombContactByDecoupling!");
+      } else if (bInelasticGeneralizedMaximumDissipationContact)
+      {
+         hcsits->setRelaxationModel(cr::HCSITS::InelasticGeneralizedMaximumDissipationContact);
+         WALBERLA_LOG_INFO_ON_ROOT("Using InelasticGeneralizedMaximumDissipationContact!");
+      } else
+      {
+         WALBERLA_ABORT("Friction model could not be determined!");
+      }
+   } else
+   {
+      WALBERLA_ABORT("Model could not be determined!");
+   }
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SYNCCALL ***");
+   std::function<void(void)> syncCallWithoutTT;
+   if (bNN)
+   {
+      syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      WALBERLA_LOG_INFO_ON_ROOT("Using NextNeighbor sync!");
+   } else if (bSO)
+   {
+      syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      WALBERLA_LOG_INFO_ON_ROOT("Using ShadowOwner sync!");
+   } else
+   {
+      WALBERLA_ABORT("Synchronization method could not be determined!");
+   }
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** VTK ***");
+   auto vtkDomainOutput = vtk::createVTKOutput_DomainDecomposition( forest, "domain_decomposition", 1, "vtk_out", "simulation_step" );
+   auto vtkSphereHelper = make_shared<SphereVtkOutput>(storageID, *forest) ;
+   auto vtkSphereOutput = vtk::createVTKOutput_PointData(vtkSphereHelper, "Bodies", 1, "vtk_out", "simulation_step", false, false);
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - START ***");
+   const real_t   static_cof  ( real_c(0.1) / 2 );   // Coefficient of static friction. Note: pe doubles the input coefficient of friction for material-material contacts.
+   const real_t   dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction.
+   MaterialID     material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 );
+
+   auto simulationDomain = forest->getDomain();
+   auto generationDomain = simulationDomain; // simulationDomain.getExtended(-real_c(0.5) * spacing);
+
+   const real_t spacing(1.0);
+   const real_t radius(0.5);
+   uint_t numParticles = uint_c(0);
+
+   for (auto& currentBlock : *forest)
+   {
+      for (auto it = grid_generator::SCIterator(currentBlock.getAABB().getIntersection(generationDomain), Vector3<real_t>(spacing, spacing, spacing) * real_c(0.5), spacing); it != grid_generator::SCIterator(); ++it)
+      {
+         SphereID sp = pe::createSphere( *globalBodyStorage, *forest, storageID, 0, *it, radius, material);
+         if (sp != NULL) ++numParticles;
+      }
+   }
+   mpi::reduceInplace(numParticles, mpi::SUM);
+   WALBERLA_LOG_INFO_ON_ROOT("#particles created: " << numParticles);
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SETUP - END ***");
+
+   // synchronize particles
+   syncCallWithoutTT();
+   syncCallWithoutTT();
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - START ***");
+   WALBERLA_MPI_BARRIER();
+   WcTimer timer;
+   for (int i=0; i < simulationSteps; ++i)
+   {
+      if( i % 200 == 0 )
+      {
+         WALBERLA_LOG_DEVEL_ON_ROOT( "Timestep " << i << " / " << simulationSteps );
+      }
+
+      cr->timestep( real_c(dt) );
+      syncCallWithoutTT();
+
+//      if( i % visSpacing == 0 )
+//      {
+//         vtkDomainOutput->write( );
+//         vtkSphereOutput->write( );
+//      }
+   }
+   WALBERLA_MPI_BARRIER();
+   timer.end();
+   WALBERLA_LOG_INFO_ON_ROOT("runtime: " << timer.average());
+   WALBERLA_LOG_INFO_ON_ROOT("*** SIMULATION - END ***");
+
+   WALBERLA_LOG_INFO_ON_ROOT("*** CHECKING RESULT - START ***");
+   for (auto& currentBlock : *forest)
+   {
+      Storage * storage = currentBlock.getData< Storage >( storageID );
+      BodyStorage& localStorage = (*storage)[0];
+
+      auto bodyIt = localStorage.begin();
+      for (auto it = grid_generator::SCIterator(currentBlock.getAABB().getIntersection(generationDomain), Vector3<real_t>(spacing, spacing, spacing) * real_c(0.5), spacing);
+           it != grid_generator::SCIterator();
+           ++it, ++bodyIt)
+      {
+         WALBERLA_CHECK_UNEQUAL(bodyIt, localStorage.end());
+         WALBERLA_CHECK_FLOAT_EQUAL(bodyIt->getPosition(), *it);
+      }
+   }
+   WALBERLA_LOG_INFO_ON_ROOT("*** CHECKING RESULT - END ***");
+
+   return EXIT_SUCCESS;
+}
diff --git a/apps/benchmarks/PeriodicGranularGas/upload.py b/apps/benchmarks/PeriodicGranularGas/upload.py
new file mode 100644
index 0000000000000000000000000000000000000000..799476c1d51d8d5a28a08c2a14b51c60df41f5ce
--- /dev/null
+++ b/apps/benchmarks/PeriodicGranularGas/upload.py
@@ -0,0 +1,187 @@
+import os
+import time
+import math
+import random
+import re
+from influxdb import InfluxDBClient
+from git import Repo
+
+
+def main():
+    try:
+        write_user_pw = os.environ["INFLUXDB_WRITE_USER"]
+    except KeyError:
+        import sys
+        print('Password for the InfluxDB write_user was not set.\n',
+              'See https://docs.gitlab.com/ee/ci/variables/#secret-variables', file=sys.stderr)
+        exc_info = sys.exc_info()
+        raise exc_info[0].with_traceback(exc_info[1], exc_info[2])
+
+    client = InfluxDBClient('i10grafana.informatik.uni-erlangen.de', 8086,
+                            'pe', write_user_pw, 'pe')
+
+    #repo = Repo(search_parent_directories=True)
+    #commit = repo.head.commit
+
+    with open("PeriodicGranularGas_DEM_NN.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'DEM',
+                'friction': 'Coulomb',
+                'sync'    : 'next neighbor'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_DEM_SO.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'DEM',
+                'friction': 'Coulomb',
+                'sync'    : 'shadow owner'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_HCSITS_NN_IFC.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'HCSITS',
+                'friction': 'InelasticFrictionlessContact',
+                'sync'    : 'next neighbor'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_HCSITS_NN_AICCBD.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'HCSITS',
+                'friction': 'ApproximateInelasticCoulombContactByDecoupling',
+                'sync'    : 'next neighbor'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_HCSITS_NN_ICCBD.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'HCSITS',
+                'friction': 'InelasticCoulombContactByDecoupling',
+                'sync'    : 'next neighbor'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_HCSITS_NN_IGMDC.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'HCSITS',
+                'friction': 'InelasticGeneralizedMaximumDissipationContact',
+                'sync'    : 'next neighbor'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+    #*************************************************
+
+    with open("PeriodicGranularGas_HCSITS_SO_IFC.txt") as f:
+        s = f.read()
+    m = re.search('runtime: (\d*.\d*)', s)
+
+    json_body = [
+        {
+            'measurement': 'pe_benchmark',
+            'tags': {
+                'host'    : os.uname()[1],
+                'image'   : os.environ["DOCKER_IMAGE_NAME"],
+                'model'   : 'HCSITS',
+                'friction': 'InelasticFrictionlessContact',
+                'sync'    : 'shadow owner'
+            },
+            'time': int(time.time()),
+            'fields': {'runtime': float(m.group(1))}
+        }
+    ]
+    print(float(m.group(1)))
+    client.write_points(json_body, time_precision='s')
+
+
+if __name__ == "__main__":
+    main()
diff --git a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
index d19c5f3c8bb803e8fdde12b549b9c40311817da9..bba9184c57e791c44511ff9ca7895325c086f77e 100644
--- a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
+++ b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
@@ -88,12 +88,11 @@
 #include "vtk/Initialization.h"
 #include "vtk/VTKOutput.h"
 
-#include <boost/bind.hpp>
-
 #include <algorithm>
 #include <cmath>
 #include <cstdlib>
 #include <cstring>
+#include <functional>
 #include <iostream>
 #include <utility>
 #include <vector>
@@ -303,7 +302,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadAndMemoryAssignment, _1, memoryPerBlock ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) );
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ),
                                                         real_c( setup.yBlocks * setup.yCells ),
@@ -847,12 +846,12 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
                                                  
    // evaluation 
    
-   const auto exactSolutionFunction = setup.circularProfile ? boost::bind( exactPipeVelocity, _1, blocks, setup ) :
-                                                              boost::bind( exactPlatesVelocity, _1, blocks, setup );
+   const auto exactSolutionFunction = setup.circularProfile ? std::bind( exactPipeVelocity, std::placeholders::_1, blocks, setup ) :
+                                                              std::bind( exactPlatesVelocity, std::placeholders::_1, blocks, setup );
 
    auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId,
                                                                                                         flagFieldId, Fluid_Flag,
-                                                                                                        boost::bind( exactFlowRate, setup.flowRate_L ),
+                                                                                                        std::bind( exactFlowRate, setup.flowRate_L ),
                                                                                                         exactSolutionFunction );
    volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L );
    volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) );
diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
index ed907fc37b06df8e3e54691bebc52bc7ea7c495f..b7f9d2997a06c2fb7acca0d2c685fade0cdc4fd5 100644
--- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
+++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
@@ -106,12 +106,12 @@
 #include <boost/mpl/equal_to.hpp>
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/or.hpp>
-#include <boost/bind.hpp>
 
 #include <algorithm>
 #include <cmath>
 #include <cstdlib>
 #include <cstring>
+#include <functional>
 #include <iostream>
 #include <utility>
 #include <vector>
@@ -656,7 +656,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.xCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( boost::bind( workloadMemoryAndSUIDAssignment, _1, memoryPerBlock, boost::cref( setup ) ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadMemoryAndSUIDAssignment, std::placeholders::_1, memoryPerBlock, std::cref( setup ) ) );
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0),
                        setup.H * ( real_c(setup.xBlocks) * real_c(setup.xCells) ) / ( real_c(setup.yzBlocks) * real_c(setup.yzCells) ), setup.H, setup.H ),
@@ -2602,7 +2602,8 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
          adaptiveRefinementLog = oss.str();
       }
 
-      minTargetLevelDeterminationFunctions.add( boost::bind( keepInflowOutflowAtTheSameLevel, _1, _2, _3, boost::cref(setup) ) );
+      minTargetLevelDeterminationFunctions.add( std::bind( keepInflowOutflowAtTheSameLevel, std::placeholders::_1, std::placeholders::_2, 
+                                                           std::placeholders::_3, std::cref(setup) ) );
 
       if( Is2D< LatticeModel_T >::value )
          minTargetLevelDeterminationFunctions.add( pseudo2DTargetLevelCorrection );
@@ -3171,7 +3172,7 @@ int main( int argc, char **argv )
       refinementSelectionFunctions.add( cylinderRefinementSelection );
    }
 
-   refinementSelectionFunctions.add( boost::bind( setInflowOutflowToSameLevel, _1, setup ) );
+   refinementSelectionFunctions.add( std::bind( setInflowOutflowToSameLevel, std::placeholders::_1, setup ) );
 
    if( setup.pseudo2D )
       refinementSelectionFunctions.add( Pseudo2DRefinementSelectionCorrection );
diff --git a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
index de0512d8dd7e24c7ae85cf706293d63e28b2a368..b175c7c1d1810a0a6bd484949f745c7358b28201 100644
--- a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
+++ b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
@@ -889,7 +889,7 @@ int main( int argc, char **argv ) {
 
    // connect to pe
    const real_t overlap = real_t(1.5) * dx;
-   auto syncCall = boost::bind(pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()),
+   auto syncCall = std::bind(pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()),
                                bodyStorageID, static_cast<WcTimingTree *>(NULL), overlap, false);
    shared_ptr<CollisionPropertiesEvaluator> collisionPropertiesEvaluator = walberla::make_shared<CollisionPropertiesEvaluator>(*cr);
 
@@ -1196,7 +1196,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1204,7 +1204,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::IKernel) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -1214,7 +1214,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1222,7 +1222,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::ITrilinear) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -1232,7 +1232,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1240,7 +1240,7 @@ int main( int argc, char **argv ) {
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       }
    }
@@ -1260,7 +1260,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1268,7 +1268,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1279,7 +1279,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1287,7 +1287,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1298,7 +1298,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1306,7 +1306,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1320,7 +1320,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1328,7 +1328,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1339,7 +1339,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1347,7 +1347,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1358,7 +1358,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1366,7 +1366,7 @@ int main( int argc, char **argv ) {
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1376,7 +1376,7 @@ int main( int argc, char **argv ) {
    {
       typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T;
       shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance );
-      lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval);
+      lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval);
    }
    else
    {
diff --git a/apps/tutorials/basics/02_Sweeps.cpp b/apps/tutorials/basics/02_Sweeps.cpp
index 03ef87b5efb2d6a099c0919a8d87a44bd6ea3f0c..95c0cf1abc238e0015c9d2cc7fd175946e8894bc 100644
--- a/apps/tutorials/basics/02_Sweeps.cpp
+++ b/apps/tutorials/basics/02_Sweeps.cpp
@@ -24,7 +24,7 @@
 #include "gui/Gui.h"
 #include "timeloop/SweepTimeloop.h"
 
-#include <boost/bind.hpp>
+#include <functional>
 
 
 using namespace walberla;
@@ -125,7 +125,7 @@ int main( int argc, char ** argv )
 
    // registering the function sweep
    auto pointerToTwoArgFunction = & simpleSweep;
-   auto pointerToOneArgFunction = boost::bind( pointerToTwoArgFunction, _1, fieldID );
+   auto pointerToOneArgFunction = std::bind( pointerToTwoArgFunction, std::placeholders::_1, fieldID );
    timeloop.add() << Sweep( pointerToOneArgFunction, "BogusAlgorithm" );
 
    // registering the class sweep
diff --git a/apps/tutorials/pe/02_ConfinedGasExtended.cpp b/apps/tutorials/pe/02_ConfinedGasExtended.cpp
index b5ac5193e8d090e2834a47514d037109b662781b..f0e4edc205c368ad609c2683a652defcadc8f5f7 100644
--- a/apps/tutorials/pe/02_ConfinedGasExtended.cpp
+++ b/apps/tutorials/pe/02_ConfinedGasExtended.cpp
@@ -33,6 +33,8 @@
 #include <postprocessing/sqlite/SQLite.h>
 #include <vtk/VTKOutput.h>
 
+#include <functional>
+
 using namespace walberla;
 using namespace walberla::pe;
 using namespace walberla::timing;
@@ -152,20 +154,20 @@ int main( int argc, char ** argv )
    std::function<void(void)> syncCall;
    if (!syncShadowOwners)
    {
-      syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, &tt, real_c(0.0), false );
+      syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false );
    } else
    {
-      syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, &tt, real_c(0.0), false );
+      syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false );
    }
 
    //! [Bind Sync Call]
    std::function<void(void)> syncCallWithoutTT;
    if (!syncShadowOwners)
    {
-      syncCallWithoutTT = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
    } else
    {
-      syncCallWithoutTT = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
    }
    //! [Bind Sync Call]
    
diff --git a/cmake/waLBerlaFunctions.cmake b/cmake/waLBerlaFunctions.cmake
index d4b9a01f587732b6dbe8dce3e55092a3913c2125..196d3f4777ad4b4efd6d688f5c99361c107ef2a6 100644
--- a/cmake/waLBerlaFunctions.cmake
+++ b/cmake/waLBerlaFunctions.cmake
@@ -1,30 +1,29 @@
-
 include ( waLBerlaHelperFunctions         )
 include ( waLBerlaModuleDependencySystem  )
 
 
 set ( WALBERLA_GLOB_FILES *.cpp
-                          *.c  
-                          *.h 
-                          *.cu 
+                          *.c
+                          *.h
+                          *.cu
       CACHE INTERNAL "File endings to glob for source files" )
 
 
 #######################################################################################################################
 #
 # Creates a walberla module library
-#  
+#
 #
 # Keywords:
 #   DEPENDS [required]   list of modules, that this module depends on
 #   FILES   [optional]   list of all source and header files belonging to that module
 #                        if this is not given, all source and header files in the directory are added.
 #                        Careful: when file was added or deleted, cmake has to be run again
-#   EXCLUDE [optional]   Files that should not be included in the module (but are located in module directory). 
+#   EXCLUDE [optional]   Files that should not be included in the module (but are located in module directory).
 #                        This makes only sense if FILES was not specified, and all files have been added automatically.
 #   BUILD_ONLY_IF_FOUND  Before building the module test if all libraries specified here are availbable.
 #   [optional]           This is done using the ${arg}_FOUND variable.
-#                        Example: waLBerla_add_module( DEPENDS someModule BUILD_ONLY_IF_FOUND pe) 
+#                        Example: waLBerla_add_module( DEPENDS someModule BUILD_ONLY_IF_FOUND pe)
 #                                 This module is only built if PE_FOUND is true.
 #
 #######################################################################################################################
@@ -34,11 +33,11 @@ function ( waLBerla_add_module )
     set( oneValueArgs )
     set( multiValueArgs DEPENDS EXCLUDE FILES BUILD_ONLY_IF_FOUND )
     cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
-    
+
     # Module name is the directory relative to WALBERLA_MODULE_DIRS
     get_current_module_name ( moduleName )
     get_module_library_name ( moduleLibraryName ${moduleName} )
-    
+
     # Test if all required libraries are available
     # this is detected using the _FOUND variable
     foreach ( externalName ${ARG_BUILD_ONLY_IF_FOUND} )
@@ -49,7 +48,7 @@ function ( waLBerla_add_module )
         endif()
     endforeach()
 
-    # Take source files either from parameter or search all source files 
+    # Take source files either from parameter or search all source files
     file ( GLOB_RECURSE allFiles "*" )  # Find all files
     if ( ARG_FILES )
         foreach( sourceFile ${ARG_FILES} )
@@ -60,7 +59,7 @@ function ( waLBerla_add_module )
         file ( GLOB_RECURSE sourceFiles ${WALBERLA_GLOB_FILES} )  # Find all source files
     endif()
 
-    # Remove exclude files from the sources 
+    # Remove exclude files from the sources
     if ( ARG_EXCLUDE )
         foreach ( fileToExclude ${ARG_EXCLUDE} )
             get_filename_component( fileToExclude ${fileToExclude} ABSOLUTE )
@@ -77,17 +76,17 @@ function ( waLBerla_add_module )
     endif ( )
 
     # Dependency Check
-    check_dependencies( missingDeps additionalDeps FILES ${sourceFiles} EXPECTED_DEPS ${ARG_DEPENDS} ${moduleName} ) 
+    check_dependencies( missingDeps additionalDeps FILES ${sourceFiles} EXPECTED_DEPS ${ARG_DEPENDS} ${moduleName} )
     if ( missingDeps )
         message ( WARNING "The module ${moduleName} depends on ${missingDeps} which are not listed as dependencies!" )
     endif()
 
-    set( hasSourceFiles FALSE ) 
- 	foreach ( sourceFile ${sourceFiles} ) 
+    set( hasSourceFiles FALSE )
+ 	foreach ( sourceFile ${sourceFiles} )
  	   if ( ${sourceFile} MATCHES "\\.(c|cpp|cu)" )
- 	      set( hasSourceFiles TRUE ) 
- 	   endif( ) 
- 	endforeach( ) 
+ 	      set( hasSourceFiles TRUE )
+ 	   endif( )
+ 	endforeach( )
 
     if ( hasSourceFiles )
         set( generatedSourceFiles )
@@ -103,11 +102,11 @@ function ( waLBerla_add_module )
         else()
             add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ${otherFiles} )
         endif( CUDA_FOUND )
-        
+
         set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE )
- 	else( ) 
- 	   add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${generatedSourceFiles} ${otherFiles} )  # dummy IDE target 
- 	endif( )  
+ 	else( )
+ 	   add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${generatedSourceFiles} ${otherFiles} )  # dummy IDE target
+ 	endif( )
 
     waLBerla_register_dependency ( ${moduleName} ${ARG_DEPENDS} )
 
@@ -117,36 +116,36 @@ function ( waLBerla_add_module )
     if( WALBERLA_GROUP_PROJECTS )
        set_property( TARGET  ${moduleLibraryName}  PROPERTY  FOLDER  "SRC" )
     endif()
-    
+
     # Install rule for library
     get_target_property( module_type ${moduleLibraryName} TYPE )
-    if( ${module_type} MATCHES LIBRARY )      
+    if( ${module_type} MATCHES LIBRARY )
        install ( TARGETS ${moduleLibraryName}  RUNTIME DESTINATION bin
                                                LIBRARY DESTINATION lib
                                                ARCHIVE DESTINATION lib )
     endif( )
-    
+
     # Install rule for header
-    install ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ 
-              DESTINATION "walberla/${moduleName}" 
+    install ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
+              DESTINATION "walberla/${moduleName}"
               FILES_MATCHING PATTERN "*.h"
-              PATTERN "*.in.h"     EXCLUDE 
+              PATTERN "*.in.h"     EXCLUDE
               PATTERN "CMakeFiles" EXCLUDE )
-              
-    # Install generated headers if necessary              
-    if ( NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} )      
-        install ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ 
-                  DESTINATION "walberla/${moduleName}" 
+
+    # Install generated headers if necessary
+    if ( NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} )
+        install ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
+                  DESTINATION "walberla/${moduleName}"
                   FILES_MATCHING PATTERN "*.h"
-                  PATTERN "*.in.h"     EXCLUDE 
+                  PATTERN "*.in.h"     EXCLUDE
                   PATTERN "CMakeFiles" EXCLUDE )
-    endif()              
-    
-    
+    endif()
+
+
     # Report module statistics - which is later on written out to a json file
     # This file is used in the doxygen documentation to display a module graph
     #waLBerla_module_statistics ( FILES ${sourceFiles} DEPENDS ${ARG_DEPENDS} )
-    
+
 endfunction ( waLBerla_add_module )
 #######################################################################################################################
 
@@ -160,7 +159,7 @@ endfunction ( waLBerla_add_module )
 # The application is linked against all waLBerla modules that are listed after DEPENDS
 #
 #
-#   NAME    [required]   Name of application 
+#   NAME    [required]   Name of application
 #   GROUP   [optional]   IDE group name (e.g. VS)
 #   DEPENDS [required]   list of modules, that this application depends on
 #   FILES   [optional]   list of all source and header files belonging to that application
@@ -178,9 +177,9 @@ function ( waLBerla_add_executable )
     cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
     if( NOT ARG_NAME )
-      message ( FATAL_ERROR "waLBerla_add_executable called without a NAME" )   
+      message ( FATAL_ERROR "waLBerla_add_executable called without a NAME" )
     endif()
-    
+
     # Skip this app, if it depends on modules that have not been built ( because they for example depend on PE)
     foreach ( depMod ${ARG_DEPENDS} )
         get_module_library_name ( depModLibraryName ${depMod} )
@@ -189,8 +188,8 @@ function ( waLBerla_add_executable )
             return()
         endif()
     endforeach()
-        
-    # Take source files either from parameter or search all source files 
+
+    # Take source files either from parameter or search all source files
     set( sourceFiles )
     if ( ARG_FILES )
         foreach( sourceFile ${ARG_FILES} )
@@ -218,14 +217,14 @@ function ( waLBerla_add_executable )
         message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled")
         return()
     endif()
-       
+
 
     if ( CUDA_FOUND )
         cuda_add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} )
     else()
         add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} )
     endif()
-    
+
     set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE )
 
     target_link_modules  ( ${ARG_NAME} ${ARG_DEPENDS}  )
@@ -238,7 +237,7 @@ function ( waLBerla_add_executable )
         endif()
         set_property( TARGET  ${ARG_NAME}  PROPERTY  FOLDER  ${ARG_GROUP} )
     endif()
-    
+
 endfunction ( waLBerla_add_executable )
 
 #######################################################################################################################
@@ -257,20 +256,20 @@ function ( waLBerla_compile_test )
     set( oneValueArgs NAME )
     set( multiValueArgs FILES DEPENDS )
     cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
-    
+
     # Module name is the directory relative to WALBERLA_MODULE_DIRS
     get_current_module_name ( moduleName )
-    
+
     # Filename of first source file is used as name for testcase if no name was given
     if( NOT ARG_NAME )
         list( GET ARG_FILES 0 ARG_NAME )
         get_filename_component( ARG_NAME ${ARG_NAME} NAME_WE )
     endif()
-    
-    waLBerla_add_executable ( NAME ${ARG_NAME} GROUP "TESTS/${moduleName}" 
+
+    waLBerla_add_executable ( NAME ${ARG_NAME} GROUP "TESTS/${moduleName}"
                               DEPENDS ${ARG_DEPENDS} ${moduleName} FILES ${ARG_FILES} )
-    
-    
+
+
 endfunction ( waLBerla_compile_test )
 #######################################################################################################################
 
@@ -280,9 +279,9 @@ endfunction ( waLBerla_compile_test )
 #######################################################################################################################
 #
 # Links all files in current source dir matching a globbing expression to the build directory
-#  
+#
 # first parameter is glob expression
-# 
+#
 # Typical usage: link all parameter files in same folder as the binary was produced
 #                Assuming the parameter files end with prm, write this to your CMakeLists in the
 #                app or test folder:
@@ -293,15 +292,15 @@ endfunction ( waLBerla_compile_test )
 #######################################################################################################################
 
 function ( waLBerla_link_files_to_builddir globExpression )
-    
+
     # don't need links for in-source builds
     if( CMAKE_CURRENT_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" )
         return()
     endif()
-    
+
     file( GLOB filesToLink RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${globExpression} )
-    
-    foreach( f ${filesToLink} )        
+
+    foreach( f ${filesToLink} )
         if( CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows" )
             configure_file( ${f} ${f} COPYONLY )
         else()
@@ -309,9 +308,9 @@ function ( waLBerla_link_files_to_builddir globExpression )
                              ${CMAKE_CURRENT_SOURCE_DIR}/${f}
                              ${CMAKE_CURRENT_BINARY_DIR}/${f} )
         endif()
-        
+
     endforeach()
-    
+
 endfunction ( waLBerla_link_files_to_builddir )
 
 
@@ -319,37 +318,37 @@ endfunction ( waLBerla_link_files_to_builddir )
 
 #######################################################################################################################
 #
-# Adds an executable to CTest. 
-# 
+# Adds an executable to CTest.
+#
 # Wrapper around add_test, that handles test labels and parallel runs
 # Adds the module name as test label, plus optional user defined labels.
 #
 #   NAME      [required] Name of test
-#   PROCESSES [optional] Number of MPI processes, that are used to start this test. 
+#   PROCESSES [optional] Number of MPI processes, that are used to start this test.
 #                        If walberla is built without MPI, and PROCESSES > 1, the test is not added
 #                        Defaults to 1
 #   COMMAND   [optional] The command that is executed. Use this to start with parameter files or other
-#                        command line options. 
+#                        command line options.
 #                        Defaults to $<TARGET_FILE:${NAME}> (for this syntax see cmake documentation of add_test )
-#   LABELS    [optional] Additional test labels. 
+#   LABELS    [optional] Additional test labels.
 #
 #######################################################################################################################
 
 function ( waLBerla_execute_test )
-    
+
    set( options NO_MODULE_LABEL )
    set( oneValueArgs NAME PROCESSES )
    set( multiValueArgs COMMAND LABELS CONFIGURATIONS DEPENDS_ON_TARGETS )
    cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
 
    if( NOT ARG_NAME )
-      message ( FATAL_ERROR "waLBerla_execute_test called without a NAME" )   
+      message ( FATAL_ERROR "waLBerla_execute_test called without a NAME" )
    endif()
-   
+
    if( NOT ARG_COMMAND AND NOT TARGET ${ARG_NAME} )
       message ( STATUS "Skipping test ${ARG_NAME} since the corresponding target is not built" )
       return()
-   endif() 
+   endif()
 
    foreach( dependency_target ${ARG_DEPENDS_ON_TARGETS} )
       if( NOT TARGET ${dependency_target} )
@@ -357,7 +356,7 @@ function ( waLBerla_execute_test )
          return()
       endif()
    endforeach( dependency_target )
-   
+
    if( NOT ARG_PROCESSES )
       set ( numProcesses 1 )
    else()
@@ -369,27 +368,28 @@ function ( waLBerla_execute_test )
    endif()
 
    if( WALBERLA_BUILD_WITH_MPI )
-      list( INSERT  ARG_COMMAND  0  ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${numProcesses} ${MPIEXEC_PREFLAGS} )
+      if( CMAKE_VERSION VERSION_LESS 3.10.0 )
+	set ( MPIEXEC_EXECUTABLE ${MPIEXEC} )
+      endif()
+      list( INSERT  ARG_COMMAND  0  ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${numProcesses} ${MPIEXEC_PREFLAGS} )
    elseif( numProcesses GREATER 1 )
       return()
-   endif() 
-   
+   endif()
+
    if( ARG_CONFIGURATIONS )
       add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} CONFIGURATIONS ${ARG_CONFIGURATIONS} )
    else()
       add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} )
    endif()
-   
+
    if( ARG_NO_MODULE_LABEL )
       set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${ARG_LABELS}" )
    else()
-      get_current_module_name ( moduleName  )   
+      get_current_module_name ( moduleName  )
       set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${moduleName} ${ARG_LABELS}" )
    endif()
 
    set_tests_properties ( ${ARG_NAME} PROPERTIES PROCESSORS ${numProcesses} )
-   
+
 endfunction ( waLBerla_execute_test )
 #######################################################################################################################
-
-
diff --git a/src/blockforest/BlockNeighborhoodSection.h b/src/blockforest/BlockNeighborhoodSection.h
index f39b5d1f2029ceed24aff5b79fcabd389ee6d1be..161e2f2e41ee782cbad25de3cea39b400b345847 100644
--- a/src/blockforest/BlockNeighborhoodSection.h
+++ b/src/blockforest/BlockNeighborhoodSection.h
@@ -25,7 +25,7 @@
 #include "core/debug/Debug.h"
 #include "stencil/Directions.h"
 
-
+#include <array>
 
 namespace walberla {
 namespace blockforest {
@@ -94,31 +94,28 @@ inline uint_t getBlockMaxNeighborhoodSectionSize( const uint_t sectionIndex )
 
 
 
-inline const uint_t * getFaceNeighborhoodSectionIndices()
+inline const std::array<uint_t, 6> & getFaceNeighborhoodSectionIndices()
 {
-   static const uint_t faces[] = { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) };
+   static std::array<uint_t, 6> faces{ { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) } };
    return faces;
 }
 
 
-
-inline const uint_t * getEdgeNeighborhoodSectionIndices()
+inline const std::array<uint_t,12> & getEdgeNeighborhoodSectionIndices()
 {
-   static const uint_t edges[] = { uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11),
-                                   uint_t(14), uint_t(16), uint_t(18), uint_t(20), uint_t(22), uint_t(24) };
+   static std::array<uint_t,12> edges{{ uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11),
+                                        uint_t(14), uint_t(16), uint_t(18), uint_t(20), uint_t(22), uint_t(24) }};
    return edges;
 }
 
 
-
-inline const uint_t * getCornerNeighborhoodSectionIndices()
+inline const std::array<uint_t, 8> & getCornerNeighborhoodSectionIndices()
 {
-   static const uint_t corners[] = { uint_t( 0), uint_t( 2), uint_t( 6), uint_t( 8),
-                                     uint_t(17), uint_t(19), uint_t(23), uint_t(25) };
+   static std::array<uint_t, 8> corners {{ uint_t( 0), uint_t( 2), uint_t( 6), uint_t( 8),
+                                           uint_t(17), uint_t(19), uint_t(23), uint_t(25) }};
    return corners;
 }
 
 
-
 } // namespace blockforest
 } // namespace walberla
diff --git a/src/blockforest/Initialization.cpp b/src/blockforest/Initialization.cpp
index 8704ae5f02d045a560c50f3b493f1419409147ed..dea96fed6a823ed0a910c4d12b30b18a736fe63a 100644
--- a/src/blockforest/Initialization.cpp
+++ b/src/blockforest/Initialization.cpp
@@ -31,6 +31,8 @@
 
 #include "stencil/D3Q19.h"
 
+#include <functional>
+
 namespace walberla {
 namespace blockforest {
 
@@ -500,7 +502,7 @@ createUniformBlockGrid( const AABB& domainAABB,
                                                                numeric_cast< memory_t >( maxBlocksPerProcess );
 
    GlobalLoadBalancing::MetisConfiguration< SetupBlock > metisConfig( includeMetis, forceMetis,
-                                                                      boost::bind( cellWeightedCommunicationCost,_1,_2,
+                                                                      std::bind( cellWeightedCommunicationCost, std::placeholders::_1, std::placeholders::_2,
                                                                                    numberOfXCellsPerBlock,
                                                                                    numberOfYCellsPerBlock,
                                                                                    numberOfZCellsPerBlock ) );
diff --git a/src/blockforest/SetupBlockForest.cpp b/src/blockforest/SetupBlockForest.cpp
index 9ae11ce9cb13d6b669c3792acde13e74ae02199f..3c4b40652e59ffcba3e0a383a3178aff509aba8a 100644
--- a/src/blockforest/SetupBlockForest.cpp
+++ b/src/blockforest/SetupBlockForest.cpp
@@ -546,7 +546,7 @@ void SetupBlockForest::getBlocks( std::vector< SetupBlock* >& blocks, const uint
 
 void SetupBlockForest::mapPointToPeriodicDomain( real_t & px, real_t & py, real_t & pz ) const
 {
-   boost::array< bool, 3 > periodic;
+   std::array< bool, 3 > periodic;
    periodic[0] = periodic_[0];
    periodic[1] = periodic_[1];
    periodic[2] = periodic_[2];
diff --git a/src/blockforest/StructuredBlockForest.h b/src/blockforest/StructuredBlockForest.h
index 82f4e810d1444d18ebbb1f47e9cd19a42d2ab2c2..ac021fe66acce0eb8a24fa662b625ad906170762 100644
--- a/src/blockforest/StructuredBlockForest.h
+++ b/src/blockforest/StructuredBlockForest.h
@@ -24,6 +24,7 @@
 #include "BlockForest.h"
 #include "domain_decomposition/StructuredBlockStorage.h"
 
+#include <functional>
 
 namespace walberla {
 namespace blockforest {
@@ -205,7 +206,7 @@ inline StructuredBlockForest::StructuredBlockForest( const shared_ptr< BlockFore
    blockForest_( blockForest ) {
 
    blockForest_->addRefreshCallbackFunctionBeforeBlockDataIsUnpacked(
-            BlockForest::RefreshCallbackWrappper( boost::bind( resetCellDecompositionInStorage, boost::ref(*this) ) ) );
+            BlockForest::RefreshCallbackWrappper( std::bind( resetCellDecompositionInStorage, std::ref(*this) ) ) );
 
    blockCells_[0] = blockXCells;
    blockCells_[1] = blockYCells;
diff --git a/src/blockforest/communication/NonUniformBufferedScheme.h b/src/blockforest/communication/NonUniformBufferedScheme.h
index e2eca543d736d543748d115ee645f91b12323e01..3e206f36d1aa4bfca2eebf14859dd22b68da72bd 100644
--- a/src/blockforest/communication/NonUniformBufferedScheme.h
+++ b/src/blockforest/communication/NonUniformBufferedScheme.h
@@ -36,10 +36,9 @@
 #include "core/selectable/IsSetSelected.h"
 #include "core/uid/SUID.h"
 
-#include <boost/bind.hpp>
-#include <functional>
 
 #include <map>
+#include <functional>
 #include <set>
 #include <vector>
 
@@ -110,7 +109,7 @@ public:
    //@{
 
    void startCommunication() { startCommunicateEqualLevel(); startCommunicateCoarseToFine(); startCommunicateFineToCoarse(); }
-   std::function<void()>  getStartCommunicateFunctor() { return boost::bind( &NonUniformBufferedScheme::startCommunication, this ); }
+   std::function<void()>  getStartCommunicateFunctor() { return std::bind( &NonUniformBufferedScheme::startCommunication, this ); }
 
    inline void startCommunicateEqualLevel();
    inline void startCommunicateCoarseToFine();
@@ -121,7 +120,7 @@ public:
    inline void startCommunicateFineToCoarse( const uint_t fineLevel );
    
    void wait() { waitCommunicateEqualLevel(); waitCommunicateCoarseToFine(); waitCommunicateFineToCoarse(); }
-   std::function<void() >  getWaitFunctor() { return boost::bind( &NonUniformBufferedScheme::wait, this ); }
+   std::function<void() >  getWaitFunctor() { return std::bind( &NonUniformBufferedScheme::wait, this ); }
 
    inline void waitCommunicateEqualLevel();
    inline void waitCommunicateCoarseToFine();
@@ -659,13 +658,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint
                      localBuffers.push_back( buffer );
                      const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1);
 
-                     VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
-                                                      EQUAL_LEVEL, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir );
+                     VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
+                                                      EQUAL_LEVEL, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir );
 
                      threadsafeLocalCommunication.push_back( pack );
 
-                     VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
-                                                        EQUAL_LEVEL, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir  );
+                     VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
+                                                        EQUAL_LEVEL, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir  );
 
                      if( (*packInfo)->threadsafeReceiving() )
                         threadsafeLocalCommunicationUnpack.push_back( unpack );
@@ -674,7 +673,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint
                   }
                   else
                   {
-                     VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalEqualLevel,
+                     VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalEqualLevel,
                                                                             *packInfo, block, neighbor, *dir );
                      if( (*packInfo)->threadsafeReceiving() )
                         threadsafeLocalCommunication.push_back( localCommunicationFunction );
@@ -688,10 +687,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint
                auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) );
 
                if( !packInfos_.empty() )
-                  sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) );
+                  sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) );
 
                for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-                  sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataEqualLevel, *packInfo, block, *dir, _1 ) );
+                  sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataEqualLevel, *packInfo, block, *dir, std::placeholders::_1 ) );
             }
          }
       }
@@ -700,8 +699,8 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint
 
       for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender )
       {
-         bufferSystem->addSendingFunction  ( int_c(sender->first), boost::bind(  NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) );
-         bufferSystem->addReceivingFunction( int_c(sender->first), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) );
+         bufferSystem->addSendingFunction  ( int_c(sender->first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) );
+         bufferSystem->addReceivingFunction( int_c(sender->first), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
       }
 
       setupBeforeNextCommunication = char(0);
@@ -785,13 +784,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui
                            localBuffers.push_back( buffer );
                            const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1);
 
-                           VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
-                                                            COARSE_TO_FINE, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir );
+                           VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
+                                                            COARSE_TO_FINE, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir );
 
                            threadsafeLocalCommunication.push_back( pack );
 
-                           VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
-                                                              COARSE_TO_FINE, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir  );
+                           VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
+                                                              COARSE_TO_FINE, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir  );
 
                            if( (*packInfo)->threadsafeReceiving() )
                               threadsafeLocalCommunicationUnpack.push_back( unpack );
@@ -800,7 +799,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui
                         }
                         else
                         {
-                           VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalCoarseToFine,
+                           VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalCoarseToFine,
                                                                                   *packInfo, block, neighbor, *dir );
                            if( (*packInfo)->threadsafeReceiving() )
                               threadsafeLocalCommunication.push_back( localCommunicationFunction );
@@ -814,10 +813,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui
                      auto nProcess = block->getNeighborProcess( neighborIdx, n );
 
                      if( !packInfos_.empty() )
-                        sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) );
+                        sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) );
 
                      for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-                        sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataCoarseToFine, *packInfo, block, receiverId, *dir, _1 ) );
+                        sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataCoarseToFine, *packInfo, block, receiverId, *dir, std::placeholders::_1 ) );
                   }
                }
             }
@@ -844,10 +843,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui
       resetBufferSystem( bufferSystem );
 
       for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender )
-         bufferSystem->addSendingFunction( int_c(sender->first), boost::bind(  NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) );
+         bufferSystem->addSendingFunction( int_c(sender->first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) );
 
       for( auto receiver = ranksToReceiveFrom.begin(); receiver != ranksToReceiveFrom.end(); ++receiver )
-         bufferSystem->addReceivingFunction( int_c(*receiver), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) );
+         bufferSystem->addReceivingFunction( int_c(*receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
 
       setupBeforeNextCommunication = char(0);
    }
@@ -931,13 +930,13 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui
                         localBuffers.push_back( buffer );
                         const uint_t bufferIndex = uint_c( localBuffers.size() ) - uint_t(1);
 
-                        VoidFunction pack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
-                                                         FINE_TO_COARSE, index, bufferIndex, boost::cref( *packInfo ), block, neighbor, *dir );
+                        VoidFunction pack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferPacking, this,
+                                                         FINE_TO_COARSE, index, bufferIndex, std::cref( *packInfo ), block, neighbor, *dir );
 
                         threadsafeLocalCommunication.push_back( pack );
 
-                        VoidFunction unpack = boost::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
-                                                           FINE_TO_COARSE, index, bufferIndex, boost::cref( *packInfo ), neighbor, block, *dir  );
+                        VoidFunction unpack = std::bind( &NonUniformBufferedScheme<Stencil>::localBufferUnpacking, this,
+                                                           FINE_TO_COARSE, index, bufferIndex, std::cref( *packInfo ), neighbor, block, *dir  );
 
                         if( (*packInfo)->threadsafeReceiving() )
                            threadsafeLocalCommunicationUnpack.push_back( unpack );
@@ -946,7 +945,7 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui
                      }
                      else
                      {
-                        VoidFunction localCommunicationFunction = boost::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalFineToCoarse,
+                        VoidFunction localCommunicationFunction = std::bind( &blockforest::communication::NonUniformPackInfo::communicateLocalFineToCoarse,
                                                                                *packInfo, block, neighbor, *dir );
                         if( (*packInfo)->threadsafeReceiving() )
                            threadsafeLocalCommunication.push_back( localCommunicationFunction );
@@ -960,10 +959,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui
                   auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) );
 
                   if( !packInfos_.empty() )
-                     sendFunctions[ nProcess ].push_back( boost::bind( NonUniformBufferedScheme<Stencil>::writeHeader, _1, block->getId(), receiverId, *dir ) );
+                     sendFunctions[ nProcess ].push_back( std::bind( NonUniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, block->getId(), receiverId, *dir ) );
 
                   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-                     sendFunctions[ nProcess ].push_back( boost::bind( &blockforest::communication::NonUniformPackInfo::packDataFineToCoarse, *packInfo, block, receiverId, *dir, _1 ) );
+                     sendFunctions[ nProcess ].push_back( std::bind( &blockforest::communication::NonUniformPackInfo::packDataFineToCoarse, *packInfo, block, receiverId, *dir, std::placeholders::_1 ) );
                }
             }
          }
@@ -989,10 +988,10 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui
       resetBufferSystem( bufferSystem );
 
       for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender )
-         bufferSystem->addSendingFunction( int_c(sender->first), boost::bind(  NonUniformBufferedScheme<Stencil>::send, _1, sender->second ) );
+         bufferSystem->addSendingFunction( int_c(sender->first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) );
 
       for( auto receiver = ranksToReceiveFrom.begin(); receiver != ranksToReceiveFrom.end(); ++receiver )
-         bufferSystem->addReceivingFunction( int_c(*receiver), boost::bind( &NonUniformBufferedScheme<Stencil>::receive, this, _1 ) );
+         bufferSystem->addReceivingFunction( int_c(*receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
 
       setupBeforeNextCommunication = char(0);
    }
diff --git a/src/blockforest/communication/UniformBufferedScheme.h b/src/blockforest/communication/UniformBufferedScheme.h
index 393301f6c78039790a97c6f752798e344c1c07a0..1abd5a95592d12247a944137679446bf788e9c43 100644
--- a/src/blockforest/communication/UniformBufferedScheme.h
+++ b/src/blockforest/communication/UniformBufferedScheme.h
@@ -38,9 +38,7 @@
 #include "core/selectable/IsSetSelected.h"
 #include "core/uid/SUID.h"
 
-#include <boost/bind.hpp>
 #include <functional>
-
 #include <map>
 #include <vector>
 
@@ -321,13 +319,13 @@ void UniformBufferedScheme<Stencil>::startCommunication()
                      localBuffers_.push_back( buffer );
                      const uint_t index = uint_c( localBuffers_.size() ) - uint_t(1);
 
-                     VoidFunction pack = boost::bind( &UniformBufferedScheme<Stencil>::localBufferPacking, this,
-                                                      index, boost::cref( *packInfo ), block, *dir );
+                     VoidFunction pack = std::bind( &UniformBufferedScheme<Stencil>::localBufferPacking, this,
+                                                      index, std::cref( *packInfo ), block, *dir );
 
                      threadsafeLocalCommunication_.push_back( pack );
 
-                     VoidFunction unpack = boost::bind( &UniformBufferedScheme<Stencil>::localBufferUnpacking, this,
-                                                        index, boost::cref( *packInfo ), neighbor, *dir  );
+                     VoidFunction unpack = std::bind( &UniformBufferedScheme<Stencil>::localBufferUnpacking, this,
+                                                        index, std::cref( *packInfo ), neighbor, *dir  );
 
                      if( (*packInfo)->threadsafeReceiving() )
                         threadsafeLocalCommunicationUnpack_.push_back( unpack );
@@ -336,7 +334,7 @@ void UniformBufferedScheme<Stencil>::startCommunication()
                   }
                   else
                   {
-                     VoidFunction localCommunicationFunction = boost::bind( &walberla::communication::UniformPackInfo::communicateLocal,
+                     VoidFunction localCommunicationFunction = std::bind( &walberla::communication::UniformPackInfo::communicateLocal,
                                                                             *packInfo, block, neighbor, *dir );
                      if( (*packInfo)->threadsafeReceiving() )
                         threadsafeLocalCommunication_.push_back( localCommunicationFunction );
@@ -350,11 +348,11 @@ void UniformBufferedScheme<Stencil>::startCommunication()
                auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) );
 
                if( !packInfos_.empty() )
-                  sendFunctions[ nProcess ].push_back( boost::bind( UniformBufferedScheme<Stencil>::writeHeader, _1, nBlockId, *dir ) );
+                  sendFunctions[ nProcess ].push_back( std::bind( UniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, nBlockId, *dir ) );
 
                for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-                  sendFunctions[ nProcess ].push_back( boost::bind( &walberla::communication::UniformPackInfo::packData,
-                                                                     *packInfo, block, *dir, _1 ) );
+                  sendFunctions[ nProcess ].push_back( std::bind( &walberla::communication::UniformPackInfo::packData,
+                                                                     *packInfo, block, *dir,  std::placeholders::_1 ) );
             }
          }
       }
@@ -368,8 +366,8 @@ void UniformBufferedScheme<Stencil>::startCommunication()
 
       for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender )
       {
-         bufferSystem_.addSendingFunction  ( int_c(sender->first), boost::bind(  UniformBufferedScheme<Stencil>::send, _1, sender->second ) );
-         bufferSystem_.addReceivingFunction( int_c(sender->first), boost::bind( &UniformBufferedScheme<Stencil>::receive, this, _1 ) );
+         bufferSystem_.addSendingFunction  ( int_c(sender->first), std::bind(  UniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) );
+         bufferSystem_.addReceivingFunction( int_c(sender->first), std::bind( &UniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
       }
 
       setupBeforeNextCommunication_ = false;
@@ -539,13 +537,13 @@ void UniformBufferedScheme<Stencil>::localBufferUnpacking( const uint_t index, c
 template< typename Stencil >
 std::function<void()> UniformBufferedScheme<Stencil>::getStartCommunicateFunctor()
 {
-   return boost::bind( &UniformBufferedScheme::startCommunication, this );
+   return std::bind( &UniformBufferedScheme::startCommunication, this );
 }
 
 template< typename Stencil >
 std::function<void()> UniformBufferedScheme<Stencil>::getWaitFunctor()
 {
-   return boost::bind( &UniformBufferedScheme::wait, this );
+   return std::bind( &UniformBufferedScheme::wait, this );
 }
 
 
diff --git a/src/blockforest/communication/UniformDirectScheme.h b/src/blockforest/communication/UniformDirectScheme.h
index 16d6e9fdda939275ba60ce3ef22aa98b5db9f143..86393089342eb96c0134148a3518647b0cb2d7d0 100644
--- a/src/blockforest/communication/UniformDirectScheme.h
+++ b/src/blockforest/communication/UniformDirectScheme.h
@@ -32,6 +32,8 @@
 
 #include <vector>
 #include <map>
+#include <functional>
+
 #include "communication/UniformMPIDatatypeInfo.h"
 
 namespace walberla {
@@ -112,8 +114,8 @@ public:
    void startCommunication();
    void wait();
 
-   std::function<void()> getStartCommunicateFunctor() { return boost::bind( &UniformDirectScheme::startCommunication, this ); }
-   std::function<void()> getWaitFunctor()             { return boost::bind( &UniformDirectScheme::wait,               this ); }
+   std::function<void()> getStartCommunicateFunctor() { return std::bind( &UniformDirectScheme::startCommunication, this ); }
+   std::function<void()> getWaitFunctor()             { return std::bind( &UniformDirectScheme::wait,               this ); }
    //@}
    //*******************************************************************************************************************
 
diff --git a/src/blockforest/loadbalancing/DynamicCurve.h b/src/blockforest/loadbalancing/DynamicCurve.h
index d9767ecf055e8b1106bbcd2746381c5be4b89db1..d72b60726f0b1dab41e8e5708051b1bc7b238a22 100644
--- a/src/blockforest/loadbalancing/DynamicCurve.h
+++ b/src/blockforest/loadbalancing/DynamicCurve.h
@@ -792,8 +792,9 @@ void DynamicCurveBalance< PhantomData_T >::balanceWeighted( const std::vector< s
          long double weight( 0 );
          int numBlocks( 0 );
          while( c < blocks.size() &&
-                std::abs( pWeight - weight - numeric_cast< long double >( allBlocks[ uint_c( blocks[c].first ) ][ blocks[c].second ].second ) ) <=
-                std::abs( pWeight - weight ) &&
+                ( isIdentical(weight, 0.0l) || 
+                  std::abs( pWeight - weight - numeric_cast< long double >( allBlocks[ uint_c( blocks[c].first ) ][ blocks[c].second ].second ) ) <=
+                  std::abs( pWeight - weight ) ) &&
                 numBlocks < maxBlocksPerProcess_ )
          {
             targets[ uint_c( blocks[c].first ) ][ blocks[c].second ] = pid_c(p);
diff --git a/src/blockforest/loadbalancing/DynamicDiffusive.h b/src/blockforest/loadbalancing/DynamicDiffusive.h
index b914bda506fbd87db247e4bc6389727ed13a5142..d9037070bad849a6a751f2ed4d72c26cba33bbd0 100644
--- a/src/blockforest/loadbalancing/DynamicDiffusive.h
+++ b/src/blockforest/loadbalancing/DynamicDiffusive.h
@@ -409,8 +409,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                      const uint_t level = levelwise_ ? block->getLevel() : uint_t(0);
                      if( level == l && targetProcess[i].second == blockforest.getProcess() )
                      {
-                        const uint_t * faces = blockforest::getFaceNeighborhoodSectionIndices();
-                        for( uint_t j = uint_t(0); j != uint_t(6); ++j )
+                        auto faces = blockforest::getFaceNeighborhoodSectionIndices();
+                        for( uint_t j = uint_t(0); j != faces.size(); ++j )
                         {
                            const uint_t sectionIndex = faces[j];
                            const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
@@ -427,8 +427,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                               }
                            }
                         }
-                        const uint_t * edges = blockforest::getEdgeNeighborhoodSectionIndices();
-                        for( uint_t j = uint_t(0); j != uint_t(12); ++j )
+                        auto edges = blockforest::getEdgeNeighborhoodSectionIndices();
+                        for( uint_t j = uint_t(0); j != edges.size(); ++j )
                         {
                            const uint_t sectionIndex = edges[j];
                            const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
@@ -445,8 +445,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                               }
                            }
                         }
-                        const uint_t * corners = blockforest::getCornerNeighborhoodSectionIndices();
-                        for( uint_t j = uint_t(0); j != uint_t(8); ++j )
+                        auto corners = blockforest::getCornerNeighborhoodSectionIndices();
+                        for( uint_t j = uint_t(0); j != corners.size(); ++j )
                         {
                            const uint_t sectionIndex = corners[j];
                            const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
@@ -655,8 +655,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
          {
             if( regardConnectivity_ && iteration < disregardConnectivityStart_ )
             {
-               const uint_t * faces = blockforest::getFaceNeighborhoodSectionIndices();
-               for( uint_t j = uint_t(0); j != uint_t(6); ++j )
+               auto faces = blockforest::getFaceNeighborhoodSectionIndices();
+               for( uint_t j = uint_t(0); j != faces.size(); ++j )
                {
                   const uint_t sectionIndex = faces[j];
                   const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
@@ -675,8 +675,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                      }
                   }
                }
-               const uint_t * edges = blockforest::getEdgeNeighborhoodSectionIndices();
-               for( uint_t j = uint_t(0); j != uint_t(12); ++j )
+               auto edges = blockforest::getEdgeNeighborhoodSectionIndices();
+               for( uint_t j = uint_t(0); j != edges.size(); ++j )
                {
                   const uint_t sectionIndex = edges[j];
                   const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
@@ -695,8 +695,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                      }
                   }
                }
-               const uint_t * corners = blockforest::getCornerNeighborhoodSectionIndices();
-               for( uint_t j = uint_t(0); j != uint_t(8); ++j )
+               auto corners = blockforest::getCornerNeighborhoodSectionIndices();
+               for( uint_t j = uint_t(0); j != corners.size(); ++j )
                {
                   const uint_t sectionIndex = corners[j];
                   const uint_t sectionSize = block->getNeighborhoodSectionSize( sectionIndex );
diff --git a/src/blockforest/loadbalancing/DynamicParMetis.cpp b/src/blockforest/loadbalancing/DynamicParMetis.cpp
index 0ec01197de2e98535cf4e0dc225ef3453518e718..0e215b6f92bc7b8bd835d165b2b76b7892e9c06b 100644
--- a/src/blockforest/loadbalancing/DynamicParMetis.cpp
+++ b/src/blockforest/loadbalancing/DynamicParMetis.cpp
@@ -136,21 +136,6 @@ bool DynamicParMetis::operator()( std::vector< std::pair< const PhantomBlock *,
    MPI_Group_incl(allGroup, int_c(ranks.size()), &ranks[0], &subGroup);
    MPI_Comm_create( MPIManager::instance()->comm(), subGroup, &subComm);
 
-   if ( targetProcess.size() != 0)
-   {
-      int subRank;
-      int subSize;
-      MPI_Comm_rank(subComm, &subRank);
-      MPI_Comm_size(subComm, &subSize);
-      WALBERLA_CHECK_GREATER_EQUAL(subRank, 0);
-      WALBERLA_CHECK_LESS(subRank, subSize);
-   } else
-   {
-      int subRank;
-      MPI_Comm_rank(subComm, &subRank);
-      WALBERLA_CHECK_EQUAL(subRank, MPI_UNDEFINED);
-   }
-
    int64_t edgecut = 0;
    WALBERLA_CHECK_EQUAL( phantomForest.getNumberOfBlocks(), targetProcess.size() );
    std::vector<int64_t> part( targetProcess.size(), int64_c( MPIManager::instance()->rank() ) );
diff --git a/src/blockforest/loadbalancing/StaticCurve.cpp b/src/blockforest/loadbalancing/StaticCurve.cpp
index 9bb9c184dcc24b10cfd1bc93f388d59523911301..e90ec3bc10ac72a04ebbfe9ce6609552c4276158 100644
--- a/src/blockforest/loadbalancing/StaticCurve.cpp
+++ b/src/blockforest/loadbalancing/StaticCurve.cpp
@@ -123,9 +123,9 @@ uint_t StaticLevelwiseCurveBalanceWeighted::operator()( SetupBlockForest & fores
       {
          const workload_t pWeight = totalWeight / workload_c( numberOfProcesses - p );
          workload_t weight( 0 );
-         while( c < blocksOnLevel.size() &&
+         while( c < blocksOnLevel.size() && ( isIdentical(weight, workload_t(0)) ||
                 std::abs( pWeight - weight - blocksOnLevel[c]->getWorkload() ) <=
-                std::abs( pWeight - weight ) )
+                std::abs( pWeight - weight ) ) )
          {
             blocksOnLevel[c]->assignTargetProcess(p);
 
diff --git a/src/blockforest/python/CommunicationExport.impl.h b/src/blockforest/python/CommunicationExport.impl.h
index 934058546dff76d23f794f89a63880b42fc7192d..09041944f0ba0cf342c4a80fcf42e9e23abd207f 100644
--- a/src/blockforest/python/CommunicationExport.impl.h
+++ b/src/blockforest/python/CommunicationExport.impl.h
@@ -106,7 +106,7 @@ namespace internal
                                                       const int tag )
    {
       UniformBufferedSchemeCreator creator( bf, stencil, tag );
-      python_coupling::for_each_noncopyable_type< Stencils >  ( boost::ref(creator) );
+      python_coupling::for_each_noncopyable_type< Stencils >  ( std::ref(creator) );
 
       if ( creator.getResult() == boost::python::object() )
       {
@@ -185,7 +185,7 @@ namespace internal
                                                     const std::string & stencil, const int tag )
    {
       UniformDirectSchemeCreator creator( bf, stencil, tag );
-      python_coupling::for_each_noncopyable_type< Stencils >  ( boost::ref(creator) );
+      python_coupling::for_each_noncopyable_type< Stencils >  ( std::ref(creator) );
 
       if ( creator.getResult() == boost::python::object() )
       {
diff --git a/src/core/Abort.cpp b/src/core/Abort.cpp
index 910dcb209f178dcdd1595477f8339eb08726d06a..1ff3ad2cb045f2132518f6a854fd79f48053a1a8 100644
--- a/src/core/Abort.cpp
+++ b/src/core/Abort.cpp
@@ -63,7 +63,7 @@ void Abort::defaultAbort( const std::string & logMessage, const std::string & ca
 
 
 #ifdef _OPENMP
-   #pragma omp critical (abort)
+   #pragma omp critical (Abort_abort)
    {
 #endif
 
diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h
index b0442f52466f8fcbe13ef68656a9b99ad449cbb2..4c348dfe7f6e934fb9fb5403abfd5761e256a9ae 100644
--- a/src/core/DataTypes.h
+++ b/src/core/DataTypes.h
@@ -42,7 +42,6 @@ namespace walberla {
 template <typename> struct never_true : std::false_type {};
 
 
-
 // shared ptr
 
 using std::shared_ptr;
@@ -50,9 +49,6 @@ using std::weak_ptr;
 using std::make_shared;
 using std::dynamic_pointer_cast;
 
-// functions, use this when "function" namespace is no longer needed
-//using std::function;
-//using std::bind;
 
 // numeric cast (performs range checks in debug mode)
 
diff --git a/src/core/Environment.cpp b/src/core/Environment.cpp
index 6e69586542c142abe99a9a05eafdb1e6bf47eb6f..b39a0b304c58ebe65356a587ec4264c7fe3c2754 100644
--- a/src/core/Environment.cpp
+++ b/src/core/Environment.cpp
@@ -31,10 +31,9 @@
 #include "core/uid/SUID.h"
 
 #include <boost/algorithm/string.hpp>
-#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
 
 #include <algorithm>
+#include <functional>
 #include <sstream>
 #include <string>
 
@@ -85,7 +84,7 @@ void configureGlobalState( const shared_ptr<Config> & config ) {
 
       std::vector< std::string > states;
       boost::split( states, suids, boost::is_any_of(", \t") );
-      states.erase( std::remove_if( states.begin(), states.end(), boost::bind( &std::string::empty, _1 ) ), states.end() );
+      states.erase( std::remove_if( states.begin(), states.end(), std::bind( &std::string::empty, std::placeholders::_1 ) ), states.end() );
 
       Set<SUID> state;
       for( auto it = states.begin(); it != states.end(); ++it )
diff --git a/src/core/cell/CellInterval.cpp b/src/core/cell/CellInterval.cpp
index 78f4501f0e1b6fb6db813b81b7ab4cf132f1091b..83ab0e33df531b98fc0505d05213e31ed3066457 100644
--- a/src/core/cell/CellInterval.cpp
+++ b/src/core/cell/CellInterval.cpp
@@ -23,8 +23,6 @@
 #include "CellSet.h"
 #include "CellVector.h"
 
-#include <boost/foreach.hpp>
-
 
 namespace walberla {
 namespace cell {
@@ -51,7 +49,7 @@ bool CellInterval::overlaps( const CellVector& cellVector ) const
    if( empty() )
       return false;
 
-   BOOST_FOREACH( const Cell & cell, cellVector )
+   for( const Cell & cell : cellVector )
    {
       if( this->contains( cell ) )
          return true;
diff --git a/src/core/config/ConfigToBoostPropertyTree.cpp b/src/core/config/ConfigToBoostPropertyTree.cpp
index 7fcc13247d9a7770e386469e69dc290aa9411a41..e3b5e6b40bc0ead8cd49fce3aba4c432f407d710 100644
--- a/src/core/config/ConfigToBoostPropertyTree.cpp
+++ b/src/core/config/ConfigToBoostPropertyTree.cpp
@@ -21,7 +21,6 @@
 
 #include "ConfigToBoostPropertyTree.h"
 
-#include <boost/foreach.hpp>
 #include <boost/property_tree/ptree.hpp>
 
 
@@ -39,7 +38,7 @@ boost::property_tree::iptree configBlockHandleToBoostPropertyTree( const Config:
 	Config::Blocks blocks;
 	blockHandle.getBlocks(blocks);
 
-	BOOST_FOREACH( const Config::BlockHandle & handle, blocks )
+	for( const Config::BlockHandle & handle : blocks )
 		propTree.add_child( handle.getKey(), configBlockHandleToBoostPropertyTree( handle ) );
 
 	return propTree;
diff --git a/src/core/debug/Debug.h b/src/core/debug/Debug.h
index 3ea4bcd054c16039fb2adedfaf4e8043ed38ff5c..b29d2824e157033614e5cbf09ae4a6a076c70edd 100644
--- a/src/core/debug/Debug.h
+++ b/src/core/debug/Debug.h
@@ -26,8 +26,8 @@
 #ifndef NDEBUG
 #   include "CheckFunctions.h"
 #   include <functional>
-#   include <boost/bind.hpp>
 #   include <string>
+#   include "core/Macros.h"
 #endif
 
 
@@ -265,7 +265,7 @@ private:
 /// \endcond
 
 #define WALBERLA_ASSERT_SECTION(condition) if(true)\
-   if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),boost::bind(walberla::debug::myAssert,__FILE__,__LINE__)))
+   if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),std::bind(walberla::debug::myAssert,__FILE__,__LINE__)))
 
 #else
 
diff --git a/src/core/math/GenericAABB.h b/src/core/math/GenericAABB.h
index aa8e15ac57be558db072a0aef155bde677c97d52..270a7a53f469dcb8e3ea0e9769002a77727f3b8e 100644
--- a/src/core/math/GenericAABB.h
+++ b/src/core/math/GenericAABB.h
@@ -167,6 +167,7 @@ public:
    inline void extend( const value_type e );
    inline void extend( const vector_type & e );
 
+   inline void setCenter( const vector_type & center );
    inline void translate( const vector_type & translation );
 
    inline void scale( const value_type factor );
diff --git a/src/core/math/GenericAABB.impl.h b/src/core/math/GenericAABB.impl.h
index 5709d770e51cf1f03ff81f3c9e322032b35325d6..00503076fc82fc8390cb60feb5ca5456edbf686c 100644
--- a/src/core/math/GenericAABB.impl.h
+++ b/src/core/math/GenericAABB.impl.h
@@ -33,7 +33,7 @@ template< typename T >
 GenericAABB< T >::GenericAABB() : minCorner_( value_type(0), value_type(0), value_type(0) ),
                                   maxCorner_( value_type(0), value_type(0), value_type(0) )
 {
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
    WALBERLA_ASSERT( empty() );
 }
 
@@ -51,7 +51,7 @@ inline GenericAABB< T >::GenericAABB( const GenericAABB< U > & other )
    : minCorner_( other.minCorner() ),
      maxCorner_( other.maxCorner() )
 {
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -78,7 +78,7 @@ GenericAABB< T >::GenericAABB( const vector_type & corner0, const vector_type &
       }
    }
 
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -130,7 +130,7 @@ GenericAABB< T >::GenericAABB( const value_type x0, const value_type y0, const v
       maxCorner_[2] = z0;
    }
 
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -160,7 +160,7 @@ GenericAABB< T >::GenericAABB( InputIterator first, InputIterator last )
       init();
    }
 
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -177,7 +177,7 @@ template< typename T >
 GenericAABB< T >::GenericAABB( const vector_type & theMinCorner, const vector_type & theMaxCorner, MinMaxCornerGivenT )
     : minCorner_( theMinCorner ), maxCorner_( theMaxCorner )
 {
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -200,7 +200,7 @@ GenericAABB< T >::GenericAABB( const GenericAABB & lhs, const GenericAABB & rhs
                  std::max( minCorner_[1], std::min( lhs.maxCorner_[1], rhs.maxCorner_[1] ) ),
                  std::max( minCorner_[2], std::min( lhs.maxCorner_[2], rhs.maxCorner_[2] ) ) )
 {
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -222,7 +222,7 @@ GenericAABB< T >::GenericAABB( const value_type minX, const value_type minY, con
                                const value_type maxX, const value_type maxY, const value_type maxZ, MinMaxCornerGivenT )
    : minCorner_( minX, minY, minZ ), maxCorner_( maxX, maxY, maxZ )
 {
-   WALBERLA_ASSERT( checkInvariant() );
+   WALBERLA_ASSERT( checkInvariant(), *this );
 }
 
 
@@ -491,7 +491,6 @@ template< typename T >
 typename GenericAABB< T >::value_type GenericAABB< T >::volume() const
 {
    WALBERLA_ASSERT( checkInvariant() );
-
    return ( maxCorner_[0] - minCorner_[0] ) * ( maxCorner_[1] - minCorner_[1] ) * ( maxCorner_[2] - minCorner_[2] );
 }
 
@@ -1563,6 +1562,21 @@ void GenericAABB< T >::extend( const vector_type & e )
 
 
 
+/**
+ * \brief Sets center of this GenericAABB
+ *
+ * AABB gets translated such that its center matches the given center.
+ *
+ * \param new center location
+ */
+template< typename T >
+void GenericAABB< T >::setCenter( const vector_type & center )
+{
+   translate(center - this->center());
+}
+
+
+
 /**
  * \brief Translates this GenericAABB
  *
diff --git a/src/core/math/Matrix3.h b/src/core/math/Matrix3.h
index 27a29b9450d6c9d95630440b7ffc346d6e0fa630..fe3c0e00cac880cb6d59b29af401e87226dc7c92 100644
--- a/src/core/math/Matrix3.h
+++ b/src/core/math/Matrix3.h
@@ -1839,3 +1839,30 @@ namespace mpi {
       };
 }
 }
+
+//======================================================================================================================
+//
+//  MPI Datatype
+//
+//======================================================================================================================
+
+namespace walberla {
+
+   template< typename T>
+   struct MPITrait< Matrix3<T> >
+   {
+      static inline MPI_Datatype type()
+      {
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
+         static bool initialized = false;
+
+         if( ! initialized ) {
+            MPI_Type_contiguous(9, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
+            initialized = true;
+         }
+         return datatype;
+      }
+   };
+} // namespace walberla
diff --git a/src/core/math/Random.cpp b/src/core/math/Random.cpp
index 72707f208e5053cba44daed005e2685f86333e8b..5acdc01d34fbe236fcb94fb98fa952a92564eaa2 100644
--- a/src/core/math/Random.cpp
+++ b/src/core/math/Random.cpp
@@ -43,7 +43,7 @@ std::mt19937 & getGenerator() // std::mt19937_64
 void seedRandomGenerator( const std::mt19937::result_type & seed )
 {
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    internal::getGenerator().seed( seed );
 }
diff --git a/src/core/math/Random.h b/src/core/math/Random.h
index ec61aa51d65b76f3a10c243086d08a48eb166590..d63d2e7ede6338606219e743d7fc44444ca23010 100644
--- a/src/core/math/Random.h
+++ b/src/core/math/Random.h
@@ -59,7 +59,7 @@ INT intRandom( const INT min, const INT max, std::mt19937 & generator )
 
    INT value;
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    { value = distribution( generator ); }
 
@@ -76,7 +76,7 @@ inline char intRandom<char>( const char min, const char max, std::mt19937 & gene
 
    char value;
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    { value = static_cast<char>( distribution( generator ) ); }
 
@@ -93,7 +93,7 @@ inline unsigned char intRandom<unsigned char>( const unsigned char min, const un
 
    unsigned char value;
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    { value = static_cast<unsigned char>( distribution( generator ) ); }
 
@@ -110,7 +110,7 @@ inline signed char intRandom<signed char>( const signed char min, const signed c
 
    signed char value;
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    { value = static_cast<signed char>( distribution( generator ) ); }
 
@@ -168,7 +168,7 @@ REAL realRandom( const REAL min = REAL(0), const REAL max = REAL(1), std::mt1993
 
    REAL value;
 #ifdef _OPENMP
-   #pragma omp critical (random)
+   #pragma omp critical (Random_random)
 #endif
    { value = distribution( generator ); }
 
diff --git a/src/core/math/Vector2.h b/src/core/math/Vector2.h
index 1ad6f9cab05d9eda80a0684d736e5921ba26b5d0..145bf302fb636ab269fbc8930c4fd74d5bf4844b 100644
--- a/src/core/math/Vector2.h
+++ b/src/core/math/Vector2.h
@@ -1696,13 +1696,13 @@ namespace walberla {
    {
       static inline MPI_Datatype type()
       {
-         static mpi::Datatype datatype;
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
          static bool initialized = false;
 
          if( ! initialized ) {
-            MPI_Datatype newDatatype;
-            MPI_Type_contiguous(2, MPITrait<T>::type(), &newDatatype );
-            datatype.init( newDatatype );
+            MPI_Type_contiguous(2, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
             initialized = true;
          }
          return datatype;
diff --git a/src/core/math/Vector3.h b/src/core/math/Vector3.h
index f5b1ea819cff09f5813a162574ee318ab8bd7fa7..662d2dfa59c9d32eb89efdac064f01d03437b568 100644
--- a/src/core/math/Vector3.h
+++ b/src/core/math/Vector3.h
@@ -1895,13 +1895,13 @@ namespace walberla {
    {
       static inline MPI_Datatype type()
       {
-         static mpi::Datatype datatype;
+         // cannot use mpi::Datatype here because its destructor calls MPI_Type_free and static variables are destroyed after the MPI_Finalize
+         static MPI_Datatype datatype;
          static bool initialized = false;
 
          if( ! initialized ) {
-            MPI_Datatype newDatatype;
-            MPI_Type_contiguous(3, MPITrait<T>::type(), &newDatatype );
-            datatype.init( newDatatype );
+            MPI_Type_contiguous(3, MPITrait<T>::type(), &datatype );
+            MPI_Type_commit( &datatype );
             initialized = true;
          }
          return datatype;
diff --git a/src/core/math/extern/exprtk.h b/src/core/math/extern/exprtk.h
index 1a4423e4a4edffd3b4df85173811eaede9c45c45..f55657a617e1d7815b9f154fd073dcf843eed2ac 100644
--- a/src/core/math/extern/exprtk.h
+++ b/src/core/math/extern/exprtk.h
@@ -2,7 +2,7 @@
  ******************************************************************
  *           C++ Mathematical Expression Toolkit Library          *
  *                                                                *
- * Author: Arash Partow (1999-2017)                               *
+ * Author: Arash Partow (1999-2018)                               *
  * URL: http://www.partow.net/programming/exprtk/index.html       *
  *                                                                *
  * Copyright notice:                                              *
@@ -67,7 +67,7 @@ namespace exprtk
    #define exprtk_error_location             \
    "exprtk.hpp:" + details::to_str(__LINE__) \
 
-   #if __GNUC__  >= 7
+   #if defined(__GNUC__) && (__GNUC__  >= 7)
 
       #define exprtk_disable_fallthrough_begin                      \
       _Pragma ("GCC diagnostic push")                               \
@@ -83,8 +83,12 @@ namespace exprtk
 
    namespace details
    {
-      typedef unsigned char uchar_t;
-      typedef char           char_t;
+      typedef unsigned char     uchar_t;
+      typedef char               char_t;
+      typedef uchar_t*        uchar_ptr;
+      typedef char_t*          char_ptr;
+      typedef uchar_t const* uchar_cptr;
+      typedef char_t const*   char_cptr;
 
       inline bool is_whitespace(const char_t c)
       {
@@ -283,6 +287,11 @@ namespace exprtk
          return result;
       }
 
+      inline std::string to_str(std::size_t i)
+      {
+         return to_str(static_cast<int>(i));
+      }
+
       inline bool is_hex_digit(const std::string::value_type digit)
       {
          return (('0' <= digit) && (digit <= '9')) ||
@@ -384,7 +393,7 @@ namespace exprtk
             return (*this);
          }
 
-         inline build_string& operator << (const char_t* s)
+         inline build_string& operator << (char_cptr s)
          {
             data_ += std::string(s);
             return (*this);
@@ -577,77 +586,62 @@ namespace exprtk
                              const typename std::iterator_traits<Iterator>::value_type& zero_or_more,
                              const typename std::iterator_traits<Iterator>::value_type& zero_or_one)
       {
-         if (0 == std::distance(data_begin,data_end))
-         {
-            return false;
-         }
-
          Iterator d_itr = data_begin;
          Iterator p_itr = pattern_begin;
-         Iterator c_itr = data_begin;
-         Iterator m_itr = data_begin;
 
-         while ((data_end != d_itr) && (zero_or_more != (*p_itr)))
+         while ((p_itr != pattern_end) && (d_itr != data_end))
          {
-            if ((!Compare::cmp((*p_itr),(*d_itr))) && (zero_or_one != (*p_itr)))
+            if (zero_or_more == *p_itr)
             {
-               return false;
-            }
+               while ((p_itr != pattern_end) && (*p_itr == zero_or_more || *p_itr == zero_or_one))
+               {
+                  ++p_itr;
+               }
 
-            ++p_itr;
-            ++d_itr;
-         }
+               if (p_itr == pattern_end)
+                  return true;
 
-         while (data_end != d_itr)
-         {
-            if (zero_or_more == (*p_itr))
-            {
-               if (pattern_end == (++p_itr))
+               const typename std::iterator_traits<Iterator>::value_type c = *(p_itr++);
+
+               while ((d_itr != data_end) && !Compare::cmp(c,*d_itr))
                {
-                  return true;
+                  ++d_itr;
                }
 
-               m_itr = p_itr;
-               c_itr = d_itr;
-               ++c_itr;
+               ++d_itr;
             }
-            else if ((Compare::cmp((*p_itr),(*d_itr))) || (zero_or_one == (*p_itr)))
+            else if ((*p_itr == zero_or_one) || Compare::cmp(*p_itr, *d_itr))
             {
-               ++p_itr;
                ++d_itr;
+               ++p_itr;
             }
             else
-            {
-               p_itr = m_itr;
-               d_itr = c_itr++;
-            }
+               return false;
          }
 
-         while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) { ++p_itr; }
-
-         return (p_itr == pattern_end);
+         return (d_itr == data_end) && (p_itr == pattern_end);
       }
 
       inline bool wc_match(const std::string& wild_card,
                            const std::string& str)
       {
-         return match_impl<const char_t*,cs_match>(wild_card.data(),
-                                                   wild_card.data() + wild_card.size(),
-                                                   str.data(),
-                                                   str.data() + str.size(),
-                                                   '*',
-                                                   '?');
+         return match_impl<char_cptr,cs_match>(wild_card.data(),
+                                               wild_card.data() + wild_card.size(),
+                                               str.data(),
+                                               str.data() + str.size(),
+                                               '*',
+                                               '?');
       }
 
       inline bool wc_imatch(const std::string& wild_card,
                             const std::string& str)
       {
-         return match_impl<const char_t*,cis_match>(wild_card.data(),
-                                                    wild_card.data() + wild_card.size(),
-                                                    str.data(),
-                                                    str.data() + str.size(),
-                                                    '*',
-                                                    '?');
+         return match_impl<char_cptr,cis_match>(wild_card.data(),
+                                                wild_card.data() + wild_card.size(),
+                                                str.data(),
+                                                str.data() + str.size(),
+                                                '*',
+                                                '?');
       }
 
       inline bool sequence_match(const std::string& pattern,
@@ -728,7 +722,7 @@ namespace exprtk
                                       1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016
                                     };
 
-     static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
+      static const std::size_t pow10_size = sizeof(pow10) / sizeof(double);
 
       namespace numeric
       {
@@ -749,22 +743,28 @@ namespace exprtk
          namespace details
          {
             struct unknown_type_tag { unknown_type_tag() {} };
-            struct real_type_tag    { real_type_tag() {}    };
+            struct real_type_tag    { real_type_tag   () {} };
             struct complex_type_tag { complex_type_tag() {} };
-            struct int_type_tag     { int_type_tag() {}     };
+            struct int_type_tag     { int_type_tag    () {} };
 
             template <typename T>
-            struct number_type { typedef unknown_type_tag type; };
+            struct number_type
+            {
+               typedef unknown_type_tag type;
+               number_type() {}
+            };
 
-            #define exprtk_register_real_type_tag(T)                          \
-            template<> struct number_type<T> { typedef real_type_tag type; }; \
+            #define exprtk_register_real_type_tag(T)             \
+            template<> struct number_type<T>                     \
+            { typedef real_type_tag type; number_type() {} };    \
 
-            #define exprtk_register_complex_type_tag(T)     \
-            template<> struct number_type<std::complex<T> > \
-            { typedef complex_type_tag type; };             \
+            #define exprtk_register_complex_type_tag(T)          \
+            template<> struct number_type<std::complex<T> >      \
+            { typedef complex_type_tag type; number_type() {} }; \
 
-            #define exprtk_register_int_type_tag(T)                          \
-            template<> struct number_type<T> { typedef int_type_tag type; }; \
+            #define exprtk_register_int_type_tag(T)              \
+            template<> struct number_type<T>                     \
+            { typedef int_type_tag type; number_type() {} };     \
 
             exprtk_register_real_type_tag(double     )
             exprtk_register_real_type_tag(long double)
@@ -984,7 +984,15 @@ namespace exprtk
             template <typename T>
             inline T root_impl(const T v0, const T v1, real_type_tag)
             {
-               return std::pow(v0,T(1) / v1);
+               if (v1 < T(0))
+                  return std::numeric_limits<T>::quiet_NaN();
+
+               const std::size_t n = static_cast<std::size_t>(v1);
+
+               if ((v0 < T(0)) && (0 == (n % 2)))
+                  return std::numeric_limits<T>::quiet_NaN();
+
+               return std::pow(v0, T(1) / n);
             }
 
             template <typename T>
@@ -1297,6 +1305,9 @@ namespace exprtk
             template <typename T> inline T  frac_impl(const T v, real_type_tag) { return (v - static_cast<long long>(v)); }
             template <typename T> inline T trunc_impl(const T v, real_type_tag) { return T(static_cast<long long>(v));    }
 
+            template <typename T> inline T const_pi_impl(real_type_tag) { return T(numeric::constant::pi); }
+            template <typename T> inline T const_e_impl (real_type_tag) { return T(numeric::constant::e);  }
+
             template <typename T> inline T   abs_impl(const T v, int_type_tag) { return ((v >= T(0)) ? v : -v); }
             template <typename T> inline T   exp_impl(const T v, int_type_tag) { return std::exp  (v); }
             template <typename T> inline T   log_impl(const T v, int_type_tag) { return std::log  (v); }
@@ -1351,161 +1362,161 @@ namespace exprtk
          template <typename T>
          inline int to_int32(const T v)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return to_int32_impl(v, num_type);
          }
 
          template <typename T>
          inline long long int to_int64(const T v)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return to_int64_impl(v, num_type);
          }
 
          template <typename T>
          inline bool is_nan(const T v)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return is_nan_impl(v, num_type);
          }
 
          template <typename T>
          inline T min(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return min_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T max(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return max_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T equal(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return equal_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T nequal(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return nequal_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T modulus(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return modulus_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T pow(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return pow_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T logn(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return logn_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T root(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return root_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T roundn(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return roundn_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T hypot(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return hypot_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T atan2(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return atan2_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T shr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return shr_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T shl(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return shl_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T and_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return and_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T nand_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return nand_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T or_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return or_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T nor_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return nor_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T xor_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return xor_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline T xnor_opr(const T v0, const T v1)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return xnor_impl(v0, v1, num_type);
          }
 
          template <typename T>
          inline bool is_integer(const T v)
          {
-            typename details::number_type<T>::type num_type;
+            const typename details::number_type<T>::type num_type;
             return is_integer_impl(v, num_type);
          }
 
@@ -1545,13 +1556,13 @@ namespace exprtk
          template <typename T> struct fast_exp<T, 1> { static inline T result(T v) { return v;         } };
          template <typename T> struct fast_exp<T, 0> { static inline T result(T  ) { return T(1);      } };
 
-         #define exprtk_define_unary_function(FunctionName)   \
-         template <typename T>                                \
-         inline T FunctionName (const T v)                    \
-         {                                                    \
-            typename details::number_type<T>::type num_type;  \
-            return  FunctionName##_impl(v,num_type);          \
-         }                                                    \
+         #define exprtk_define_unary_function(FunctionName)        \
+         template <typename T>                                     \
+         inline T FunctionName (const T v)                         \
+         {                                                         \
+            const typename details::number_type<T>::type num_type; \
+            return  FunctionName##_impl(v,num_type);               \
+         }                                                         \
 
          exprtk_define_unary_function(abs  )
          exprtk_define_unary_function(acos )
@@ -1776,7 +1787,7 @@ namespace exprtk
          if ((3 != length) && (inf_length != length))
             return false;
 
-         const char_t* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
+         char_cptr inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc;
 
          while (end != itr)
          {
@@ -1964,8 +1975,8 @@ namespace exprtk
       {
          const typename numeric::details::number_type<T>::type num_type;
 
-         const char_t* begin = s.data();
-         const char_t* end   = s.data() + s.size();
+         char_cptr begin = s.data();
+         char_cptr end   = s.data() + s.size();
 
          return string_to_real(begin, end, t, num_type);
       }
@@ -2204,9 +2215,7 @@ namespace exprtk
             {
                scan_token();
 
-               if (token_list_.empty())
-                  return true;
-               else if (token_list_.back().is_error())
+               if (!token_list_.empty() && token_list_.back().is_error())
                   return false;
             }
 
@@ -2296,8 +2305,8 @@ namespace exprtk
 
          inline std::string substr(const std::size_t& begin, const std::size_t& end)
          {
-            const char_t* begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
-            const char_t* end_itr   = ((base_itr_ +   end) < s_end_) ? (base_itr_ +   end) : s_end_;
+            details::char_cptr begin_itr = ((base_itr_ + begin) < s_end_) ? (base_itr_ + begin) : s_end_;
+            details::char_cptr end_itr   = ((base_itr_ +   end) < s_end_) ? (base_itr_ +   end) : s_end_;
 
             return std::string(begin_itr,end_itr);
          }
@@ -2314,11 +2323,28 @@ namespace exprtk
 
       private:
 
-         inline bool is_end(const char_t* itr)
+         inline bool is_end(details::char_cptr itr)
          {
             return (s_end_ == itr);
          }
 
+         inline bool is_comment_start(details::char_cptr itr)
+         {
+            #ifndef exprtk_disable_comments
+            const char_t c0 = *(itr + 0);
+            const char_t c1 = *(itr + 1);
+
+            if ('#' == c0)
+               return true;
+            else if (!is_end(itr + 1))
+            {
+               if (('/' == c0) && ('/' == c1)) return true;
+               if (('/' == c0) && ('*' == c1)) return true;
+            }
+            #endif
+            return false;
+         }
+
          inline void skip_whitespace()
          {
             while (!is_end(s_itr_) && details::is_whitespace(*s_itr_))
@@ -2348,47 +2374,72 @@ namespace exprtk
                   return (0 != mode);
                }
 
-               static inline bool comment_end(const char_t c0, const char_t c1, const int mode)
+               static inline bool comment_end(const char_t c0, const char_t c1, int& mode)
                {
-                  return (
-                           ((1 == mode) && ('\n' == c0)) ||
-                           ((2 == mode) && ( '*' == c0) && ('/' == c1))
-                         );
+                  if (
+                       ((1 == mode) && ('\n' == c0)) ||
+                       ((2 == mode) && ( '*' == c0) && ('/' == c1))
+                     )
+                  {
+                     mode = 0;
+                     return true;
+                  }
+                  else
+                     return false;
                }
             };
 
             int mode      = 0;
             int increment = 0;
 
-            if (is_end(s_itr_) || is_end((s_itr_ + 1)))
+            if (is_end(s_itr_))
                return;
             else if (!test::comment_start(*s_itr_, *(s_itr_ + 1), mode, increment))
                return;
 
+            details::char_cptr cmt_start = s_itr_;
+
             s_itr_ += increment;
 
-            while (!is_end(s_itr_) && !test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
+            while (!is_end(s_itr_))
             {
-               ++s_itr_;
+               if ((1 == mode) && test::comment_end(*s_itr_, 0, mode))
+               {
+                  ++s_itr_;
+                  return;
+               }
+
+               if ((2 == mode))
+               {
+                  if (!is_end((s_itr_ + 1)) && test::comment_end(*s_itr_, *(s_itr_ + 1), mode))
+                  {
+                     s_itr_ += 2;
+                     return;
+                  }
+               }
+
+                ++s_itr_;
             }
 
-            if (!is_end(s_itr_))
+            if (2 == mode)
             {
-               s_itr_ += mode;
-
-               skip_whitespace();
-               skip_comments  ();
+               token_t t;
+               t.set_error(token::e_error, cmt_start, cmt_start + mode, base_itr_);
+               token_list_.push_back(t);
             }
             #endif
          }
 
          inline void scan_token()
          {
-            skip_whitespace();
-            skip_comments  ();
-
-            if (is_end(s_itr_))
+            if (details::is_whitespace(*s_itr_))
+            {
+               skip_whitespace();
+               return;
+            }
+            else if (is_comment_start(s_itr_))
             {
+               skip_comments();
                return;
             }
             else if (details::is_operator_char(*s_itr_))
@@ -2502,7 +2553,7 @@ namespace exprtk
 
          inline void scan_symbol()
          {
-            const char_t* initial_itr = s_itr_;
+            details::char_cptr initial_itr = s_itr_;
 
             while (!is_end(s_itr_))
             {
@@ -2553,11 +2604,11 @@ namespace exprtk
                (15) .1234e-3
             */
 
-            const char_t* initial_itr = s_itr_;
-            bool dot_found            = false;
-            bool e_found              = false;
-            bool post_e_sign_found    = false;
-            bool post_e_digit_found   = false;
+            details::char_cptr initial_itr = s_itr_;
+            bool dot_found                 = false;
+            bool e_found                   = false;
+            bool post_e_sign_found         = false;
+            bool post_e_digit_found        = false;
             token_t t;
 
             while (!is_end(s_itr_))
@@ -2640,7 +2691,7 @@ namespace exprtk
 
          inline void scan_special_function()
          {
-            const char_t* initial_itr = s_itr_;
+            details::char_cptr initial_itr = s_itr_;
             token_t t;
 
             // $fdd(x,x,x) = at least 11 chars
@@ -2676,7 +2727,7 @@ namespace exprtk
          #ifndef exprtk_disable_string_capabilities
          inline void scan_string()
          {
-            const char_t* initial_itr = s_itr_ + 1;
+            details::char_cptr initial_itr = s_itr_ + 1;
             token_t t;
 
             if (std::distance(s_itr_,s_end_) < 2)
@@ -2714,7 +2765,7 @@ namespace exprtk
                         Note: The following 'awkward' conditional is
                               due to various broken msvc compilers.
                      */
-                     #if _MSC_VER == 1600
+                     #if defined(_MSC_VER) && (_MSC_VER == 1600)
                      const bool within_range = !is_end(s_itr_ + 2) &&
                                                !is_end(s_itr_ + 3) ;
                      #else
@@ -2780,9 +2831,9 @@ namespace exprtk
          token_list_itr_t token_itr_;
          token_list_itr_t store_token_itr_;
          token_t eof_token_;
-         const char_t* base_itr_;
-         const char_t* s_itr_;
-         const char_t* s_end_;
+         details::char_cptr base_itr_;
+         details::char_cptr s_itr_;
+         details::char_cptr s_end_;
 
          friend class token_scanner;
          friend class token_modifier;
@@ -3307,7 +3358,7 @@ namespace exprtk
 
                   return true;
                }
-               // '- -' --> '-'
+               // '- -' --> '+'
                else if ((t0.type == lexer::token::e_sub) && (t1.type == lexer::token::e_sub))
                {
                   /*
@@ -3577,7 +3628,6 @@ namespace exprtk
                add_invalid(lexer::token::e_string ,lexer::token::e_string );
                add_invalid(lexer::token::e_number ,lexer::token::e_string );
                add_invalid(lexer::token::e_string ,lexer::token::e_number );
-               add_invalid(lexer::token::e_string ,lexer::token::e_ternary);
                add_invalid_set1(lexer::token::e_assign );
                add_invalid_set1(lexer::token::e_shr    );
                add_invalid_set1(lexer::token::e_shl    );
@@ -3696,7 +3746,7 @@ namespace exprtk
                         case lexer::token::e_sub     : return false;
                         case lexer::token::e_colon   : return false;
                         case lexer::token::e_ternary : return false;
-                        default                      : return true;
+                        default                      : return true ;
                      }
                   }
                }
@@ -3710,7 +3760,7 @@ namespace exprtk
                      case lexer::token::e_eof     : return false;
                      case lexer::token::e_colon   : return false;
                      case lexer::token::e_ternary : return false;
-                     default                      : return true;
+                     default                      : return true ;
                   }
                }
                else if (details::is_left_bracket(static_cast<char>(t)))
@@ -4204,6 +4254,11 @@ namespace exprtk
            data_(reinterpret_cast<value_t*>(ts_.data))
          {}
 
+         type_view(const type_store_t& ts)
+         : ts_(const_cast<type_store_t&>(ts)),
+           data_(reinterpret_cast<value_t*>(ts_.data))
+         {}
+
          inline std::size_t size() const
          {
             return ts_.size;
@@ -5544,7 +5599,7 @@ namespace exprtk
 
          virtual std::string str () const = 0;
 
-         virtual const char_t* base() const = 0;
+         virtual char_cptr   base() const = 0;
 
          virtual std::size_t size() const = 0;
       };
@@ -5587,7 +5642,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return value_.data();
          }
@@ -5893,10 +5948,8 @@ namespace exprtk
                                 else
                                    return ((T(2) * arg1  <= (arg2 + arg0)) ? arg0 : arg2);
 
-               default        : {
-                                   exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
-                                   return std::numeric_limits<T>::quiet_NaN();
-                                }
+               default        : exprtk_debug(("trinary_node::value() - Error: Invalid operation\n"));
+                                return std::numeric_limits<T>::quiet_NaN();
             }
          }
 
@@ -7494,7 +7547,7 @@ namespace exprtk
             return ref();
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &(*value_)[0];
          }
@@ -7574,7 +7627,7 @@ namespace exprtk
             return (*value_);
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &(*value_)[0];
          }
@@ -7652,7 +7705,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return value_.data();
          }
@@ -7782,7 +7835,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &value_[0];
          }
@@ -7921,7 +7974,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &value_[0];
          }
@@ -8009,7 +8062,7 @@ namespace exprtk
             return str0_node_ptr_->str();
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
            return str0_node_ptr_->base();
          }
@@ -8069,12 +8122,12 @@ namespace exprtk
                if (0 == str0_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str0_range_ptr_ = &(range_ptr->range_ref());
+               str0_range_ptr_ = &(range->range_ref());
             }
 
             if (is_generally_string_node(binary_node<T>::branch_[1].first))
@@ -8084,12 +8137,12 @@ namespace exprtk
                if (0 == str1_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str1_range_ptr_ = &(range_ptr->range_ref());
+               str1_range_ptr_ = &(range->range_ref());
             }
 
             initialised_ = str0_base_ptr_  &&
@@ -8123,11 +8176,11 @@ namespace exprtk
                   const std::size_t size1    = range1.cache_size();
                   const std::size_t max_size = std::min(size0,size1);
 
-                  char_t* s0 = const_cast<char_t*>(str0_base_ptr_->base() + str0_r0);
-                  char_t* s1 = const_cast<char_t*>(str1_base_ptr_->base() + str1_r0);
+                  char_ptr s0 = const_cast<char_ptr>(str0_base_ptr_->base() + str0_r0);
+                  char_ptr s1 = const_cast<char_ptr>(str1_base_ptr_->base() + str1_r0);
 
                   loop_unroll::details lud(max_size);
-                  const char_t* upper_bound = s0 + lud.upper_bound;
+                  char_cptr upper_bound = s0 + lud.upper_bound;
 
                   while (s0 < upper_bound)
                   {
@@ -8285,13 +8338,13 @@ namespace exprtk
 
       struct asn_assignment
       {
-         static inline void execute(std::string& s, const char_t* data, const std::size_t size)
+         static inline void execute(std::string& s, char_cptr data, const std::size_t size)
          { s.assign(data,size); }
       };
 
       struct asn_addassignment
       {
-         static inline void execute(std::string& s, const char_t* data, const std::size_t size)
+         static inline void execute(std::string& s, char_cptr data, const std::size_t size)
          { s.append(data,size); }
       };
 
@@ -8334,12 +8387,12 @@ namespace exprtk
                if (0 == str1_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str1_range_ptr_ = &(range_ptr->range_ref());
+               str1_range_ptr_ = &(range->range_ref());
             }
 
             initialised_ = str0_base_ptr_  &&
@@ -8377,7 +8430,7 @@ namespace exprtk
             return str0_node_ptr_->str();
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
            return str0_node_ptr_->base();
          }
@@ -8443,12 +8496,12 @@ namespace exprtk
 
                str0_base_ptr_ = dynamic_cast<str_base_ptr>(binary_node<T>::branch_[0].first);
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str0_range_ptr_ = &(range_ptr->range_ref());
+               str0_range_ptr_ = &(range->range_ref());
             }
 
             if (is_generally_string_node(binary_node<T>::branch_[1].first))
@@ -8458,12 +8511,12 @@ namespace exprtk
                if (0 == str1_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str1_range_ptr_ = &(range_ptr->range_ref());
+               str1_range_ptr_ = &(range->range_ref());
             }
 
             initialised_ = str0_base_ptr_  &&
@@ -8498,7 +8551,7 @@ namespace exprtk
 
                   std::copy(str1_base_ptr_->base() + s1_r0,
                             str1_base_ptr_->base() + s1_r0 + size,
-                            const_cast<char_t*>(base() + s0_r0));
+                            const_cast<char_ptr>(base() + s0_r0));
                }
             }
 
@@ -8510,7 +8563,7 @@ namespace exprtk
             return str0_node_ptr_->str();
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
            return str0_node_ptr_->base();
          }
@@ -8664,7 +8717,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &value_[0];
          }
@@ -8784,7 +8837,7 @@ namespace exprtk
             return value_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return &value_[0];
          }
@@ -8877,7 +8930,7 @@ namespace exprtk
                   }
                   else
                   {
-                     arg_list_.clear();
+                     arg_list_     .clear();
                      delete_branch_.clear();
                      return;
                   }
@@ -8918,7 +8971,7 @@ namespace exprtk
             return str_base_ptr_->str();
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
             return str_base_ptr_->base();
          }
@@ -11443,7 +11496,7 @@ namespace exprtk
                      return false;
 
                   ts.size = sbn->size();
-                  ts.data = reinterpret_cast<void*>(const_cast<char_t*>(sbn->base()));
+                  ts.data = reinterpret_cast<void*>(const_cast<char_ptr>(sbn->base()));
                   ts.type = type_store_t::e_string;
 
                   range_list_[i].data      = ts.data;
@@ -11464,7 +11517,7 @@ namespace exprtk
                      )
                   {
                      ts.size = rp.const_size();
-                     ts.data = static_cast<char_t*>(ts.data) + rp.n0_c.second;
+                     ts.data = static_cast<char_ptr>(ts.data) + rp.n0_c.second;
                      range_list_[i].range = reinterpret_cast<range_t*>(0);
                   }
                   else
@@ -11546,10 +11599,10 @@ namespace exprtk
                      ts.size = rp.cache_size();
                      #ifndef exprtk_disable_string_capabilities
                      if (ts.type == type_store_t::e_string)
-                        ts.data = const_cast<char_t*>(rdt.str_node->base()) + rp.cache.first;
+                        ts.data = const_cast<char_ptr>(rdt.str_node->base()) + rp.cache.first;
                      else
                      #endif
-                        ts.data = static_cast<char_t*>(rdt.data) + (rp.cache.first * rdt.type_size);
+                        ts.data = static_cast<char_ptr>(rdt.data) + (rp.cache.first * rdt.type_size);
                   }
                   else
                      return false;
@@ -11629,7 +11682,7 @@ namespace exprtk
             return ret_string_;
          }
 
-         const char_t* base() const
+         char_cptr base() const
          {
            return &ret_string_[0];
          }
@@ -14965,12 +15018,12 @@ namespace exprtk
                if (0 == str0_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[0].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str0_range_ptr_ = &(range_ptr->range_ref());
+               str0_range_ptr_ = &(range->range_ref());
             }
 
             if (is_generally_string_node(binary_node<T>::branch_[1].first))
@@ -14980,12 +15033,12 @@ namespace exprtk
                if (0 == str1_base_ptr_)
                   return;
 
-               irange_ptr range_ptr = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
+               irange_ptr range = dynamic_cast<irange_ptr>(binary_node<T>::branch_[1].first);
 
-               if (0 == range_ptr)
+               if (0 == range)
                   return;
 
-               str1_range_ptr_ = &(range_ptr->range_ref());
+               str1_range_ptr_ = &(range->range_ref());
             }
          }
 
@@ -15448,70 +15501,70 @@ namespace exprtk
                    typename T1, typename T2>
          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2) const
          {
-            return (new node_type(t1,t2));
+            return (new node_type(t1, t2));
          }
 
          template <typename node_type,
                    typename T1, typename T2>
          inline expression_node<typename node_type::value_type>* allocate_cr(const T1& t1, T2& t2) const
          {
-            return (new node_type(t1,t2));
+            return (new node_type(t1, t2));
          }
 
          template <typename node_type,
                    typename T1, typename T2>
          inline expression_node<typename node_type::value_type>* allocate_rc(T1& t1, const T2& t2) const
          {
-            return (new node_type(t1,t2));
+            return (new node_type(t1, t2));
          }
 
          template <typename node_type,
                    typename T1, typename T2>
          inline expression_node<typename node_type::value_type>* allocate_rr(T1& t1, T2& t2) const
          {
-            return (new node_type(t1,t2));
+            return (new node_type(t1, t2));
          }
 
          template <typename node_type,
                    typename T1, typename T2>
          inline expression_node<typename node_type::value_type>* allocate_tt(T1 t1, T2 t2) const
          {
-            return (new node_type(t1,t2));
+            return (new node_type(t1, t2));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3>
          inline expression_node<typename node_type::value_type>* allocate_ttt(T1 t1, T2 t2, T3 t3) const
          {
-            return (new node_type(t1,t2,t3));
+            return (new node_type(t1, t2, t3));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3, typename T4>
          inline expression_node<typename node_type::value_type>* allocate_tttt(T1 t1, T2 t2, T3 t3, T4 t4) const
          {
-            return (new node_type(t1,t2,t3,t4));
+            return (new node_type(t1, t2, t3, t4));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3>
          inline expression_node<typename node_type::value_type>* allocate_rrr(T1& t1, T2& t2, T3& t3) const
          {
-            return (new node_type(t1,t2,t3));
+            return (new node_type(t1, t2, t3));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3, typename T4>
          inline expression_node<typename node_type::value_type>* allocate_rrrr(T1& t1, T2& t2, T3& t3, T4& t4) const
          {
-            return (new node_type(t1,t2,t3,t4));
+            return (new node_type(t1, t2, t3, t4));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3, typename T4, typename T5>
          inline expression_node<typename node_type::value_type>* allocate_rrrrr(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const
          {
-            return (new node_type(t1,t2,t3,t4,t5));
+            return (new node_type(t1, t2, t3, t4, t5));
          }
 
          template <typename node_type,
@@ -15519,7 +15572,7 @@ namespace exprtk
          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
                                                                           const T3& t3) const
          {
-            return (new node_type(t1,t2,t3));
+            return (new node_type(t1, t2, t3));
          }
 
          template <typename node_type,
@@ -15528,7 +15581,7 @@ namespace exprtk
          inline expression_node<typename node_type::value_type>* allocate(const T1& t1, const T2& t2,
                                                                           const T3& t3, const T4& t4) const
          {
-            return (new node_type(t1,t2,t3,t4));
+            return (new node_type(t1, t2, t3, t4));
          }
 
          template <typename node_type,
@@ -15538,7 +15591,7 @@ namespace exprtk
                                                                           const T3& t3, const T4& t4,
                                                                           const T5& t5) const
          {
-            return (new node_type(t1,t2,t3,t4,t5));
+            return (new node_type(t1, t2, t3, t4, t5));
          }
 
          template <typename node_type,
@@ -15548,7 +15601,7 @@ namespace exprtk
                                                                           const T3& t3, const T4& t4,
                                                                           const T5& t5, const T6& t6) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6));
+            return (new node_type(t1, t2, t3, t4, t5, t6));
          }
 
          template <typename node_type,
@@ -15560,7 +15613,7 @@ namespace exprtk
                                                                           const T5& t5, const T6& t6,
                                                                           const T7& t7) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6,t7));
+            return (new node_type(t1, t2, t3, t4, t5, t6, t7));
          }
 
          template <typename node_type,
@@ -15573,7 +15626,7 @@ namespace exprtk
                                                                           const T5& t5, const T6& t6,
                                                                           const T7& t7, const T8& t8) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8));
+            return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8));
          }
 
          template <typename node_type,
@@ -15587,7 +15640,7 @@ namespace exprtk
                                                                           const T7& t7, const T8& t8,
                                                                           const T9& t9) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9));
+            return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9));
          }
 
          template <typename node_type,
@@ -15602,14 +15655,14 @@ namespace exprtk
                                                                           const T7& t7, const  T8&  t8,
                                                                           const T9& t9, const T10& t10) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10));
+            return (new node_type(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10));
          }
 
          template <typename node_type,
                    typename T1, typename T2, typename T3>
          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2, T3 t3) const
          {
-            return (new node_type(t1,t2,t3));
+            return (new node_type(t1, t2, t3));
          }
 
          template <typename node_type,
@@ -15618,7 +15671,7 @@ namespace exprtk
          inline expression_node<typename node_type::value_type>* allocate_type(T1 t1, T2 t2,
                                                                                T3 t3, T4 t4) const
          {
-            return (new node_type(t1,t2,t3,t4));
+            return (new node_type(t1, t2, t3, t4));
          }
 
          template <typename node_type,
@@ -15629,7 +15682,7 @@ namespace exprtk
                                                                                T3 t3, T4 t4,
                                                                                T5 t5) const
          {
-            return (new node_type(t1,t2,t3,t4,t5));
+            return (new node_type(t1, t2, t3, t4, t5));
          }
 
          template <typename node_type,
@@ -15640,7 +15693,7 @@ namespace exprtk
                                                                                T3 t3, T4 t4,
                                                                                T5 t5, T6 t6) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6));
+            return (new node_type(t1, t2, t3, t4, t5, t6));
          }
 
          template <typename node_type,
@@ -15652,7 +15705,7 @@ namespace exprtk
                                                                                T5 t5, T6 t6,
                                                                                T7 t7) const
          {
-            return (new node_type(t1,t2,t3,t4,t5,t6,t7));
+            return (new node_type(t1, t2, t3, t4, t5, t6, t7));
          }
 
          template <typename T>
@@ -15975,6 +16028,7 @@ namespace exprtk
    {
    public:
 
+      typedef T (*ff00_functor)();
       typedef T (*ff01_functor)(T);
       typedef T (*ff02_functor)(T,T);
       typedef T (*ff03_functor)(T,T,T);
@@ -15993,6 +16047,16 @@ namespace exprtk
 
    protected:
 
+       struct freefunc00 : public exprtk::ifunction<T>
+       {
+          using exprtk::ifunction<T>::operator();
+
+          freefunc00(ff00_functor ff) : exprtk::ifunction<T>(0), f(ff) {}
+          inline T operator() ()
+          { return f(); }
+          ff00_functor f;
+       };
+
       struct freefunc01 : public exprtk::ifunction<T>
       {
          using exprtk::ifunction<T>::operator();
@@ -17021,11 +17085,11 @@ namespace exprtk
       inline bool add_function(const std::string& function_name, ff##NN##_functor function) \
       {                                                                                     \
          if (!valid())                                                                      \
-            return false;                                                                   \
-         else if (!valid_symbol(function_name))                                             \
-            return false;                                                                   \
-         else if (symbol_exists(function_name))                                             \
-            return false;                                                                   \
+         { return false; }                                                                  \
+         if (!valid_symbol(function_name))                                                  \
+         { return false; }                                                                  \
+         if (symbol_exists(function_name))                                                  \
+         { return false; }                                                                  \
                                                                                             \
          exprtk::ifunction<T>* ifunc = new freefunc##NN(function);                          \
                                                                                             \
@@ -17034,14 +17098,14 @@ namespace exprtk
          return add_function(function_name,(*local_data().free_function_list_.back()));     \
       }                                                                                     \
 
-      exprtk_define_freefunction(01) exprtk_define_freefunction(02)
-      exprtk_define_freefunction(03) exprtk_define_freefunction(04)
-      exprtk_define_freefunction(05) exprtk_define_freefunction(06)
-      exprtk_define_freefunction(07) exprtk_define_freefunction(08)
-      exprtk_define_freefunction(09) exprtk_define_freefunction(10)
-      exprtk_define_freefunction(11) exprtk_define_freefunction(12)
-      exprtk_define_freefunction(13) exprtk_define_freefunction(14)
-      exprtk_define_freefunction(15)
+      exprtk_define_freefunction(00) exprtk_define_freefunction(01)
+      exprtk_define_freefunction(02) exprtk_define_freefunction(03)
+      exprtk_define_freefunction(04) exprtk_define_freefunction(05)
+      exprtk_define_freefunction(06) exprtk_define_freefunction(07)
+      exprtk_define_freefunction(08) exprtk_define_freefunction(09)
+      exprtk_define_freefunction(10) exprtk_define_freefunction(11)
+      exprtk_define_freefunction(12) exprtk_define_freefunction(13)
+      exprtk_define_freefunction(14) exprtk_define_freefunction(15)
 
       #undef exprtk_define_freefunction
 
@@ -17189,12 +17253,13 @@ namespace exprtk
       {
          return add_pi      () &&
                 add_epsilon () &&
-                add_infinity();
+                add_infinity() ;
       }
 
       inline bool add_pi()
       {
-         static const T local_pi = T(details::numeric::constant::pi);
+         const typename details::numeric::details::number_type<T>::type num_type;
+         static const T local_pi = details::numeric::details::const_pi_impl<T>(num_type);
          return add_constant("pi",local_pi);
       }
 
@@ -17542,7 +17607,7 @@ namespace exprtk
               size(0)
             {}
 
-            data_pack(void* ptr, data_type dt, std::size_t sz = 0)
+            data_pack(void* ptr, const data_type dt, const std::size_t sz = 0)
             : pointer(ptr),
               type(dt),
               size(sz)
@@ -17657,6 +17722,13 @@ namespace exprtk
          control_block_->ref_count++;
       }
 
+      expression(const symbol_table<T>& symbol_table)
+      : control_block_(0)
+      {
+         set_expression(new details::null_node<T>());
+         symbol_table_list_.push_back(symbol_table);
+      }
+
       inline expression<T>& operator=(const expression<T>& e)
       {
          if (this != &e)
@@ -17945,7 +18017,7 @@ namespace exprtk
          std::size_t column_no;
       };
 
-      inline type make_error(error_mode mode,
+      inline type make_error(const error_mode mode,
                              const std::string& diagnostic   = "",
                              const std::string& src_location = "")
       {
@@ -17958,7 +18030,7 @@ namespace exprtk
          return t;
       }
 
-      inline type make_error(error_mode mode,
+      inline type make_error(const error_mode mode,
                              const lexer::token& tk,
                              const std::string& diagnostic   = "",
                              const std::string& src_location = "")
@@ -18129,11 +18201,11 @@ namespace exprtk
       typedef typename expression<T>::symtab_list_t     symbol_table_list_t;
       typedef details::vector_holder<T>*                  vector_holder_ptr;
 
-      typedef typename details::functor_t<T>         functor_t;
-      typedef typename functor_t::qfunc_t quaternary_functor_t;
-      typedef typename functor_t::tfunc_t    trinary_functor_t;
-      typedef typename functor_t::bfunc_t     binary_functor_t;
-      typedef typename functor_t::ufunc_t      unary_functor_t;
+      typedef typename details::functor_t<T>            functor_t;
+      typedef typename functor_t::qfunc_t    quaternary_functor_t;
+      typedef typename functor_t::tfunc_t       trinary_functor_t;
+      typedef typename functor_t::bfunc_t        binary_functor_t;
+      typedef typename functor_t::ufunc_t         unary_functor_t;
 
       typedef details::operator_type operator_t;
 
@@ -20410,6 +20482,7 @@ namespace exprtk
                                            static const std::string s_ilike = "ilike";
                                            static const std::string s_and1  =     "&";
                                            static const std::string s_or1   =     "|";
+                                           static const std::string s_not   =   "not";
 
                                            if (details::imatch(current_token().value,s_and))
                                            {
@@ -20474,6 +20547,10 @@ namespace exprtk
                                               current_state.set(e_level04, e_level04, details::e_ilike);
                                               break;
                                            }
+                                           else if (details::imatch(current_token().value,s_not))
+                                           {
+                                              break;
+                                           }
                                         }
 
                                         break_loop = true;
@@ -20953,7 +21030,7 @@ namespace exprtk
       }
 
       template <std::size_t MaxNumberofParameters>
-      inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters])
+      inline std::size_t parse_base_function_call(expression_node_ptr (&param_list)[MaxNumberofParameters], const std::string& function_name = "")
       {
          std::fill_n(param_list, MaxNumberofParameters, reinterpret_cast<expression_node_ptr>(0));
 
@@ -20966,7 +21043,19 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR022 - Expected a '(' at start of function call, instead got: '" + current_token().value + "'",
+                          "ERR022 - Expected a '(' at start of function call to '" + function_name  +
+                          "', instead got: '" + current_token().value + "'",
+                          exprtk_error_location));
+
+            return 0;
+         }
+
+         if (token_is(token_t::e_rbracket, e_hold))
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR023 - Expected at least one input parameter for function call '" + function_name + "'",
                           exprtk_error_location));
 
             return 0;
@@ -20981,7 +21070,10 @@ namespace exprtk
             if (0 == param_list[param_index])
                return 0;
             else if (token_is(token_t::e_rbracket))
+            {
+               sd.delete_ptr = false;
                break;
+            }
             else if (token_is(token_t::e_comma))
                continue;
             else
@@ -20989,14 +21081,23 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR023 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
+                             "ERR024 - Expected a ',' between function input parameters, instead got: '" + current_token().value + "'",
                              exprtk_error_location));
 
                return 0;
             }
          }
 
-         sd.delete_ptr = false;
+         if (sd.delete_ptr)
+         {
+            set_error(
+               make_error(parser_error::e_syntax,
+                          current_token(),
+                          "ERR025 - Invalid number of input parameters passed to function '" + function_name  + "'",
+                          exprtk_error_location));
+
+            return 0;
+         }
 
          return (param_index + 1);
       }
@@ -21005,7 +21106,8 @@ namespace exprtk
       {
          typedef std::pair<base_ops_map_t::iterator,base_ops_map_t::iterator> map_range_t;
 
-         const std::string operation_name = current_token().value;
+         const std::string operation_name   = current_token().value;
+         const token_t     diagnostic_token = current_token();
 
          map_range_t itr_range = base_ops_map_.equal_range(operation_name);
 
@@ -21013,8 +21115,8 @@ namespace exprtk
          {
             set_error(
                make_error(parser_error::e_syntax,
-                          current_token(),
-                          "ERR024 - No entry found for base operation: " + operation_name,
+                          diagnostic_token,
+                          "ERR026 - No entry found for base operation: " + operation_name,
                           exprtk_error_location));
 
             return error_node();
@@ -21023,13 +21125,9 @@ namespace exprtk
          static const std::size_t MaxNumberofParameters = 4;
          expression_node_ptr param_list[MaxNumberofParameters] = {0};
 
-         const std::size_t parameter_count = parse_base_function_call(param_list);
+         const std::size_t parameter_count = parse_base_function_call(param_list, operation_name);
 
-         if (0 == parameter_count)
-         {
-            return error_node();
-         }
-         else if (parameter_count <= MaxNumberofParameters)
+         if ((parameter_count > 0) && (parameter_count <= MaxNumberofParameters))
          {
             for (base_ops_map_t::iterator itr = itr_range.first; itr != itr_range.second; ++itr)
             {
@@ -21059,13 +21157,13 @@ namespace exprtk
 
          for (std::size_t i = 0; i < MaxNumberofParameters; ++i)
          {
-            free_node(node_allocator_,param_list[i]);
+            free_node(node_allocator_, param_list[i]);
          }
 
          set_error(
             make_error(parser_error::e_syntax,
-                       current_token(),
-                       "ERR025 - Invalid number of parameters for call to function: '" + operation_name + "'",
+                       diagnostic_token,
+                       "ERR027 - Invalid number of input parameters for call to function: '" + operation_name + "'",
                        exprtk_error_location));
 
          return error_node();
@@ -21085,7 +21183,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR026 - Expected ',' between if-statement condition and consequent",
+                          "ERR028 - Expected ',' between if-statement condition and consequent",
                           exprtk_error_location));
             result = false;
          }
@@ -21094,7 +21192,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR027 - Failed to parse consequent for if-statement",
+                          "ERR029 - Failed to parse consequent for if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21103,7 +21201,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR028 - Expected ',' between if-statement consequent and alternative",
+                          "ERR030 - Expected ',' between if-statement consequent and alternative",
                           exprtk_error_location));
             result = false;
          }
@@ -21112,7 +21210,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR029 - Failed to parse alternative for if-statement",
+                          "ERR031 - Failed to parse alternative for if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21121,7 +21219,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR030 - Expected ')' at the end of if-statement",
+                          "ERR032 - Expected ')' at the end of if-statement",
                           exprtk_error_location));
             result = false;
          }
@@ -21143,7 +21241,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR031 - Return types of ternary if-statement differ",
+                             "ERR033 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21178,7 +21276,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR032 - Failed to parse body of consequent for if-statement",
+                             "ERR034 - Failed to parse body of consequent for if-statement",
                              exprtk_error_location));
 
                result = false;
@@ -21201,7 +21299,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR033 - Expected ';' at the end of the consequent for if-statement",
+                                "ERR035 - Expected ';' at the end of the consequent for if-statement",
                                 exprtk_error_location));
 
                   result = false;
@@ -21212,7 +21310,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR034 - Failed to parse body of consequent for if-statement",
+                             "ERR036 - Failed to parse body of consequent for if-statement",
                              exprtk_error_location));
 
                result = false;
@@ -21232,7 +21330,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR035 - Failed to parse body of the 'else' for if-statement",
+                                   "ERR037 - Failed to parse body of the 'else' for if-statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21245,7 +21343,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR036 - Failed to parse body of if-else statement",
+                                   "ERR038 - Failed to parse body of if-else statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21258,7 +21356,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR037 - Expected ';' at the end of the 'else-if' for the if-statement",
+                                   "ERR039 - Expected ';' at the end of the 'else-if' for the if-statement",
                                    exprtk_error_location));
 
                      result = false;
@@ -21269,7 +21367,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR038 - Failed to parse body of the 'else' for if-statement",
+                                "ERR040 - Failed to parse body of the 'else' for if-statement",
                                 exprtk_error_location));
 
                   result = false;
@@ -21288,13 +21386,13 @@ namespace exprtk
                if (consq_is_str && alter_is_str)
                {
                   return expression_generator_
-                           .conditional_string(condition,consequent,alternative);
+                           .conditional_string(condition, consequent, alternative);
                }
 
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR039 - Return types of ternary if-statement differ",
+                             "ERR041 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21304,15 +21402,15 @@ namespace exprtk
 
          if (!result)
          {
-            free_node(node_allocator_,  condition);
-            free_node(node_allocator_, consequent);
-            free_node(node_allocator_,alternative);
+            free_node(node_allocator_,   condition);
+            free_node(node_allocator_,  consequent);
+            free_node(node_allocator_, alternative);
 
             return error_node();
          }
          else
             return expression_generator_
-                      .conditional(condition,consequent,alternative);
+                      .conditional(condition, consequent, alternative);
       }
 
       inline expression_node_ptr parse_conditional_statement()
@@ -21326,7 +21424,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR040 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
+                          "ERR042 - Expected '(' at start of if-statement, instead got: '" + current_token().value + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -21336,7 +21434,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR041 - Failed to parse condition for if-statement",
+                          "ERR043 - Failed to parse condition for if-statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21368,7 +21466,7 @@ namespace exprtk
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR042 - Invalid if-statement",
+                       "ERR044 - Invalid if-statement",
                        exprtk_error_location));
 
          free_node(node_allocator_,condition);
@@ -21389,7 +21487,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR043 - Encountered invalid condition branch for ternary if-statement",
+                          "ERR045 - Encountered invalid condition branch for ternary if-statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21399,7 +21497,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR044 - Expected '?' after condition of ternary if-statement",
+                          "ERR046 - Expected '?' after condition of ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21409,7 +21507,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR045 - Failed to parse consequent for ternary if-statement",
+                          "ERR047 - Failed to parse consequent for ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21419,7 +21517,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR046 - Expected ':' between ternary if-statement consequent and alternative",
+                          "ERR048 - Expected ':' between ternary if-statement consequent and alternative",
                           exprtk_error_location));
 
             result = false;
@@ -21429,7 +21527,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR047 - Failed to parse alternative for ternary if-statement",
+                          "ERR049 - Failed to parse alternative for ternary if-statement",
                           exprtk_error_location));
 
             result = false;
@@ -21452,7 +21550,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR048 - Return types of ternary if-statement differ",
+                             "ERR050 - Return types of ternary if-statement differ",
                              exprtk_error_location));
 
                result = false;
@@ -21489,7 +21587,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR049 - Expected '(' at start of while-loop condition statement",
+                          "ERR051 - Expected '(' at start of while-loop condition statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21499,7 +21597,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR050 - Failed to parse condition for while-loop",
+                          "ERR052 - Failed to parse condition for while-loop",
                           exprtk_error_location));
 
             return error_node();
@@ -21509,7 +21607,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR051 - Expected ')' at end of while-loop condition statement",
+                          "ERR053 - Expected ')' at end of while-loop condition statement",
                           exprtk_error_location));
 
             result = false;
@@ -21524,7 +21622,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR052 - Failed to parse body of while-loop"));
+                             "ERR054 - Failed to parse body of while-loop"));
                result = false;
             }
             else if (0 == (result_node = expression_generator_.while_loop(condition,
@@ -21534,7 +21632,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR053 - Failed to synthesize while-loop",
+                             "ERR055 - Failed to synthesize while-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21543,9 +21641,9 @@ namespace exprtk
 
          if (!result)
          {
-            free_node(node_allocator_,     branch);
-            free_node(node_allocator_,  condition);
-            free_node(node_allocator_,result_node);
+            free_node(node_allocator_,      branch);
+            free_node(node_allocator_,   condition);
+            free_node(node_allocator_, result_node);
 
             brkcnt_list_.pop_front();
 
@@ -21610,7 +21708,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR054 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
+                                "ERR056 - Expected '" + token_t::to_str(seperator) + "' in body of repeat until loop",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21634,7 +21732,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR055 - Failed to parse body of repeat until loop",
+                             "ERR057 - Failed to parse body of repeat until loop",
                              exprtk_error_location));
 
                return error_node();
@@ -21648,7 +21746,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR056 - Expected '(' before condition statement of repeat until loop",
+                          "ERR058 - Expected '(' before condition statement of repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,branch);
@@ -21662,7 +21760,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR057 - Failed to parse condition for repeat until loop",
+                          "ERR059 - Failed to parse condition for repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,branch);
@@ -21674,7 +21772,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR058 - Expected ')' after condition of repeat until loop",
+                          "ERR060 - Expected ')' after condition of repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,    branch);
@@ -21695,7 +21793,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR059 - Failed to synthesize repeat until loop",
+                          "ERR061 - Failed to synthesize repeat until loop",
                           exprtk_error_location));
 
             free_node(node_allocator_,condition);
@@ -21731,7 +21829,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR060 - Expected '(' at start of for-loop",
+                          "ERR062 - Expected '(' at start of for-loop",
                           exprtk_error_location));
 
             return error_node();
@@ -21751,7 +21849,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR061 - Expected a variable at the start of initialiser section of for-loop",
+                                "ERR063 - Expected a variable at the start of initialiser section of for-loop",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21761,7 +21859,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR062 - Expected variable assignment of initialiser section of for-loop",
+                                "ERR064 - Expected variable assignment of initialiser section of for-loop",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21776,7 +21874,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR063 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
+                                "ERR065 - For-loop variable '" + loop_counter_symbol+ "' is being shadowed by a previous declaration",
                                 exprtk_error_location));
 
                   return error_node();
@@ -21808,7 +21906,7 @@ namespace exprtk
                         set_error(
                            make_error(parser_error::e_syntax,
                                       current_token(),
-                                      "ERR064 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
+                                      "ERR066 - Failed to add new local variable '" + loop_counter_symbol + "' to SEM",
                                       exprtk_error_location));
 
                         sem_.free_element(nse);
@@ -21830,7 +21928,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR065 - Failed to parse initialiser of for-loop",
+                             "ERR067 - Failed to parse initialiser of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21840,7 +21938,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR066 - Expected ';' after initialiser of for-loop",
+                             "ERR068 - Expected ';' after initialiser of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21854,7 +21952,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR067 - Failed to parse condition of for-loop",
+                             "ERR069 - Failed to parse condition of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21864,7 +21962,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR068 - Expected ';' after condition section of for-loop",
+                             "ERR070 - Expected ';' after condition section of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21878,7 +21976,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR069 - Failed to parse incrementor of for-loop",
+                             "ERR071 - Failed to parse incrementor of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21888,7 +21986,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR070 - Expected ')' after incrementor section of for-loop",
+                             "ERR072 - Expected ')' after incrementor section of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21904,7 +22002,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR071 - Failed to parse body of for-loop",
+                             "ERR073 - Failed to parse body of for-loop",
                              exprtk_error_location));
 
                result = false;
@@ -21956,7 +22054,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR072 - Expected keyword 'switch'",
+                          "ERR074 - Expected keyword 'switch'",
                           exprtk_error_location));
 
             return error_node();
@@ -21971,7 +22069,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR073 - Expected '{' for call to switch statement",
+                          "ERR075 - Expected '{' for call to switch statement",
                           exprtk_error_location));
 
             return error_node();
@@ -21984,7 +22082,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR074 - Expected either a 'case' or 'default' statement",
+                             "ERR076 - Expected either a 'case' or 'default' statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22001,7 +22099,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR075 - Expected ':' for case of switch statement",
+                             "ERR077 - Expected ':' for case of switch statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22016,7 +22114,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR076 - Expected ';' at end of case for switch statement",
+                             "ERR078 - Expected ';' at end of case for switch statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22042,7 +22140,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR077 - Expected ':' for default of switch statement",
+                                "ERR079 - Expected ':' for default of switch statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -22064,7 +22162,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR078 - Expected ';' at end of default for switch statement",
+                                "ERR080 - Expected ';' at end of default for switch statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -22080,7 +22178,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR079 - Expected '}' at end of switch statement",
+                          "ERR081 - Expected '}' at end of switch statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22103,7 +22201,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR080 - Expected token '[*]'",
+                          "ERR082 - Expected token '[*]'",
                           exprtk_error_location));
 
             return error_node();
@@ -22118,7 +22216,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR081 - Expected '{' for call to [*] statement",
+                          "ERR083 - Expected '{' for call to [*] statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22131,7 +22229,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR082 - Expected a 'case' statement for multi-switch",
+                             "ERR084 - Expected a 'case' statement for multi-switch",
                              exprtk_error_location));
 
                return error_node();
@@ -22149,7 +22247,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR083 - Expected ':' for case of [*] statement",
+                             "ERR085 - Expected ':' for case of [*] statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22165,7 +22263,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR084 - Expected ';' at end of case for [*] statement",
+                             "ERR086 - Expected ';' at end of case for [*] statement",
                              exprtk_error_location));
 
                return error_node();
@@ -22194,7 +22292,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR085 - Expected '}' at end of [*] statement",
+                          "ERR087 - Expected '}' at end of [*] statement",
                           exprtk_error_location));
 
             return error_node();
@@ -22224,19 +22322,19 @@ namespace exprtk
          {
             return parse_multi_switch_statement();
          }
-         else if (details::imatch(symbol,"avg" )) opt_type = details::e_avg ;
-         else if (details::imatch(symbol,"mand")) opt_type = details::e_mand;
-         else if (details::imatch(symbol,"max" )) opt_type = details::e_max ;
-         else if (details::imatch(symbol,"min" )) opt_type = details::e_min ;
-         else if (details::imatch(symbol,"mor" )) opt_type = details::e_mor ;
-         else if (details::imatch(symbol,"mul" )) opt_type = details::e_prod;
-         else if (details::imatch(symbol,"sum" )) opt_type = details::e_sum ;
+         else if (details::imatch(symbol, "avg" )) opt_type = details::e_avg ;
+         else if (details::imatch(symbol, "mand")) opt_type = details::e_mand;
+         else if (details::imatch(symbol, "max" )) opt_type = details::e_max ;
+         else if (details::imatch(symbol, "min" )) opt_type = details::e_min ;
+         else if (details::imatch(symbol, "mor" )) opt_type = details::e_mor ;
+         else if (details::imatch(symbol, "mul" )) opt_type = details::e_prod;
+         else if (details::imatch(symbol, "sum" )) opt_type = details::e_sum ;
          else
          {
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR086 - Unsupported vararg function: " + symbol,
+                          "ERR088 - Unsupported vararg function: " + symbol,
                           exprtk_error_location));
 
             return error_node();
@@ -22253,7 +22351,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR087 - Expected '(' for call to vararg function: " + symbol,
+                          "ERR089 - Expected '(' for call to vararg function: " + symbol,
                           exprtk_error_location));
 
             return error_node();
@@ -22275,7 +22373,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR088 - Expected ',' for call to vararg function: " + symbol,
+                             "ERR090 - Expected ',' for call to vararg function: " + symbol,
                              exprtk_error_location));
 
                return error_node();
@@ -22296,7 +22394,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR089 - Expected '[' as start of string range definition",
+                          "ERR091 - Expected '[' as start of string range definition",
                           exprtk_error_location));
 
             free_node(node_allocator_,expression);
@@ -22324,7 +22422,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR090 - Failed to generate string range node",
+                          "ERR092 - Failed to generate string range node",
                           exprtk_error_location));
 
             free_node(node_allocator_,expression);
@@ -22460,7 +22558,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR091 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
+                             "ERR093 - Expected '" + token_t::to_str(close_bracket) + "' for call to multi-sequence" +
                              ((!source.empty()) ? std::string(" section of " + source): ""),
                              exprtk_error_location));
 
@@ -22507,7 +22605,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR092 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
+                             "ERR094 - Expected '" + details::to_str(seperator) + "' for call to multi-sequence section of " + source,
                              exprtk_error_location));
 
                return error_node();
@@ -22541,7 +22639,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR093 - Expected '[' for start of range",
+                          "ERR095 - Expected '[' for start of range",
                           exprtk_error_location));
 
             return false;
@@ -22562,7 +22660,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR094 - Failed parse begin section of range",
+                             "ERR096 - Failed parse begin section of range",
                              exprtk_error_location));
 
                return false;
@@ -22586,7 +22684,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR095 - Range lower bound less than zero! Constraint: r0 >= 0",
+                                "ERR097 - Range lower bound less than zero! Constraint: r0 >= 0",
                                 exprtk_error_location));
 
                   return false;
@@ -22603,7 +22701,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR096 - Expected ':' for break  in range",
+                             "ERR098 - Expected ':' for break  in range",
                              exprtk_error_location));
 
                rp.free();
@@ -22626,7 +22724,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR097 - Failed parse end section of range",
+                             "ERR099 - Failed parse end section of range",
                              exprtk_error_location));
 
                rp.free();
@@ -22652,7 +22750,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR098 - Range upper bound less than zero! Constraint: r1 >= 0",
+                                "ERR100 - Range upper bound less than zero! Constraint: r1 >= 0",
                                 exprtk_error_location));
 
                   return false;
@@ -22669,7 +22767,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR099 - Expected ']' for start of range",
+                             "ERR101 - Expected ']' for start of range",
                              exprtk_error_location));
 
                rp.free();
@@ -22690,7 +22788,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR100 - Invalid range, Constraint: r0 <= r1",
+                             "ERR102 - Invalid range, Constraint: r0 <= r1",
                              exprtk_error_location));
 
                return false;
@@ -22731,7 +22829,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR101 - Unknown string symbol",
+                             "ERR103 - Unknown string symbol",
                              exprtk_error_location));
 
                return error_node();
@@ -22845,7 +22943,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR102 - Overflow in range for string: '" + const_str + "'[" +
+                             "ERR104 - Overflow in range for string: '" + const_str + "'[" +
                              (rp.n0_c.first ? details::to_str(static_cast<int>(rp.n0_c.second)) : "?") + ":" +
                              (rp.n1_c.first ? details::to_str(static_cast<int>(rp.n1_c.second)) : "?") + "]",
                              exprtk_error_location));
@@ -22889,7 +22987,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR103 - Symbol '" + symbol+ " not a vector",
+                             "ERR105 - Symbol '" + symbol+ " not a vector",
                              exprtk_error_location));
 
                return error_node();
@@ -22915,7 +23013,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR104 - Failed to parse index for vector: '" + symbol + "'",
+                          "ERR106 - Failed to parse index for vector: '" + symbol + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -22925,7 +23023,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR105 - Expected ']' for index of vector: '" + symbol + "'",
+                          "ERR107 - Expected ']' for index of vector: '" + symbol + "'",
                           exprtk_error_location));
 
             free_node(node_allocator_,index_expr);
@@ -22944,7 +23042,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR106 - Index of " + details::to_str(index) + " out of range for "
+                             "ERR108 - Index of " + details::to_str(index) + " out of range for "
                              "vector '" + symbol + "' of size " + details::to_str(vec_size),
                              exprtk_error_location));
 
@@ -22976,7 +23074,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR107 - Zero parameter call to vararg function: "
+                                "ERR109 - Zero parameter call to vararg function: "
                                 + vararg_function_name + " not allowed",
                                 exprtk_error_location));
 
@@ -23001,7 +23099,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR108 - Expected ',' for call to vararg function: "
+                                   "ERR110 - Expected ',' for call to vararg function: "
                                    + vararg_function_name,
                                    exprtk_error_location));
 
@@ -23015,7 +23113,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR109 - Zero parameter call to vararg function: "
+                          "ERR111 - Zero parameter call to vararg function: "
                           + vararg_function_name + " not allowed",
                           exprtk_error_location));
 
@@ -23027,7 +23125,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR110 - Invalid number of parameters to call to vararg function: "
+                          "ERR112 - Invalid number of parameters to call to vararg function: "
                           + vararg_function_name + ", require at least "
                           + details::to_str(static_cast<int>(vararg_function->min_num_args())) + " parameters",
                           exprtk_error_location));
@@ -23039,7 +23137,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR111 - Invalid number of parameters to call to vararg function: "
+                          "ERR113 - Invalid number of parameters to call to vararg function: "
                           + vararg_function_name + ", require no more than "
                           + details::to_str(static_cast<int>(vararg_function->max_num_args())) + " parameters",
                           exprtk_error_location));
@@ -23102,7 +23200,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR112 - Failed parameter type check for function '" + function_name_ + "', "
+                                "ERR114 - Failed parameter type check for function '" + function_name_ + "', "
                                 "Expected '" + param_seq_list_[0] + "'  call set: '" + param_seq +"'",
                                 exprtk_error_location));
             }
@@ -23123,7 +23221,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 parser_.current_token(),
-                                "ERR113 - Failed parameter type check for function '" + function_name_ + "', "
+                                "ERR115 - Failed parameter type check for function '" + function_name_ + "', "
                                 "Best match: '" + param_seq_list_[max_diff_index] + "'  call set: '" + param_seq +"'",
                                 exprtk_error_location));
             }
@@ -23208,7 +23306,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR114 - Invalid parameter sequence of '" + err_param_seq +
+                                   "ERR116 - Invalid parameter sequence of '" + err_param_seq +
                                    "'  for function: " + function_name_,
                                    exprtk_error_location));
 
@@ -23230,7 +23328,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    parser_.current_token(),
-                                   "ERR115 - Invalid parameter sequence of '" + err_param_seq +
+                                   "ERR117 - Invalid parameter sequence of '" + err_param_seq +
                                    "'  for function: " + function_name_,
                                    exprtk_error_location));
                   return;
@@ -23264,7 +23362,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR116 - Type checker instantiation failure for generic function: " + function_name,
+                          "ERR118 - Type checker instantiation failure for generic function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23279,7 +23377,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR117 - Mismatch in zero parameter condition for generic function: "
+                          "ERR119 - Mismatch in zero parameter condition for generic function: "
                           + function_name,
                           exprtk_error_location));
 
@@ -23298,7 +23396,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR118 - Zero parameter call to generic function: "
+                                "ERR120 - Zero parameter call to generic function: "
                                 + function_name + " not allowed",
                                 exprtk_error_location));
 
@@ -23330,7 +23428,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR119 - Expected ',' for call to generic function: " + function_name,
+                                   "ERR121 - Expected ',' for call to generic function: " + function_name,
                                    exprtk_error_location));
 
                      return error_node();
@@ -23347,7 +23445,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR120 - Zero parameter call to generic function: "
+                          "ERR122 - Zero parameter call to generic function: "
                           + function_name + " not allowed",
                           exprtk_error_location));
 
@@ -23364,7 +23462,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR121 - Expected ',' for call to generic function: " + function_name,
+                          "ERR123 - Expected ',' for call to generic function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23432,7 +23530,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR122 - Expected ',' for call to string function: " + function_name,
+                                   "ERR124 - Expected ',' for call to string function: " + function_name,
                                    exprtk_error_location));
 
                      return error_node();
@@ -23448,7 +23546,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR123 - Expected ',' for call to string function: " + function_name,
+                          "ERR125 - Expected ',' for call to string function: " + function_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23472,7 +23570,7 @@ namespace exprtk
       template <typename Type, std::size_t NumberOfParameters>
       struct parse_special_function_impl
       {
-         static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type)
+         static inline expression_node_ptr process(parser<Type>& p,const details::operator_type opt_type, const std::string& sf_name)
          {
             expression_node_ptr branch[NumberOfParameters];
             expression_node_ptr result  = error_node();
@@ -23488,7 +23586,7 @@ namespace exprtk
                p.set_error(
                     make_error(parser_error::e_syntax,
                                p.current_token(),
-                               "ERR124 - Expected '(' for special function",
+                               "ERR126 - Expected '(' for special function '" + sf_name + "'",
                                exprtk_error_location));
 
                return error_node();
@@ -23509,7 +23607,7 @@ namespace exprtk
                      p.set_error(
                           make_error(parser_error::e_syntax,
                                      p.current_token(),
-                                     "ERR125 - Expected ',' before next parameter of special function",
+                                     "ERR127 - Expected ',' before next parameter of special function '" + sf_name + "'",
                                      exprtk_error_location));
 
                      return p.error_node();
@@ -23518,7 +23616,15 @@ namespace exprtk
             }
 
             if (!p.token_is(token_t::e_rbracket))
+            {
+               p.set_error(
+                    make_error(parser_error::e_syntax,
+                               p.current_token(),
+                               "ERR128 - Invalid number of parameters for special function '" + sf_name + "'",
+                               exprtk_error_location));
+
                return p.error_node();
+            }
             else
                result = p.expression_generator_.special_function(opt_type,branch);
 
@@ -23530,30 +23636,32 @@ namespace exprtk
 
       inline expression_node_ptr parse_special_function()
       {
+         const std::string sf_name = current_token().value;
+
          // Expect: $fDD(expr0,expr1,expr2) or $fDD(expr0,expr1,expr2,expr3)
          if (
-              !details::is_digit(current_token().value[2]) ||
-              !details::is_digit(current_token().value[3])
+              !details::is_digit(sf_name[2]) ||
+              !details::is_digit(sf_name[3])
             )
          {
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR126 - Invalid special function[1]: " + current_token().value,
+                          "ERR129 - Invalid special function[1]: " + sf_name,
                           exprtk_error_location));
 
             return error_node();
          }
 
-         const int id = (current_token().value[2] - '0') * 10 +
-                        (current_token().value[3] - '0');
+         const int id = (sf_name[2] - '0') * 10 +
+                        (sf_name[3] - '0');
 
          if (id >= details::e_sffinal)
          {
             set_error(
                make_error(parser_error::e_token,
                           current_token(),
-                          "ERR127 - Invalid special function[2]: " + current_token().value,
+                          "ERR130 - Invalid special function[2]: " + sf_name,
                           exprtk_error_location));
 
             return error_node();
@@ -23565,8 +23673,8 @@ namespace exprtk
 
          switch (NumberOfParameters)
          {
-            case 3  : return parse_special_function_impl<T,3>::process((*this),opt_type);
-            case 4  : return parse_special_function_impl<T,4>::process((*this),opt_type);
+            case 3  : return parse_special_function_impl<T,3>::process((*this), opt_type, sf_name);
+            case 4  : return parse_special_function_impl<T,4>::process((*this), opt_type, sf_name);
             default : return error_node();
          }
       }
@@ -23585,7 +23693,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR128 - Break call within a break call is not allowed",
+                          "ERR131 - Break call within a break call is not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -23608,7 +23716,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR129 - Failed to parse return expression for 'break' statement",
+                                "ERR132 - Failed to parse return expression for 'break' statement",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23618,7 +23726,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR130 - Expected ']' at the completion of break's return expression",
+                                "ERR133 - Expected ']' at the completion of break's return expression",
                                 exprtk_error_location));
 
                   free_node(node_allocator_,return_expr);
@@ -23636,7 +23744,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR131 - Invalid use of 'break', allowed only in the scope of a loop",
+                          "ERR134 - Invalid use of 'break', allowed only in the scope of a loop",
                           exprtk_error_location));
          }
 
@@ -23659,7 +23767,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR132 - Invalid use of 'continue', allowed only in the scope of a loop",
+                          "ERR135 - Invalid use of 'continue', allowed only in the scope of a loop",
                           exprtk_error_location));
 
             return error_node();
@@ -23676,7 +23784,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR133 - Expected '[' as part of vector size definition",
+                          "ERR136 - Expected '[' as part of vector size definition",
                           exprtk_error_location));
 
             return error_node();
@@ -23686,7 +23794,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR134 - Failed to determine size of vector '" + vec_name + "'",
+                          "ERR137 - Failed to determine size of vector '" + vec_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -23698,7 +23806,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR135 - Expected a literal number as size of vector '" + vec_name + "'",
+                          "ERR138 - Expected a literal number as size of vector '" + vec_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -23717,7 +23825,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR136 - Invalid vector size. Must be an integer greater than zero, size: " +
+                          "ERR139 - Invalid vector size. Must be an integer greater than zero, size: " +
                           details::to_str(details::numeric::to_int32(vector_size)),
                           exprtk_error_location));
 
@@ -23737,7 +23845,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR137 - Expected ']' as part of vector size definition",
+                          "ERR140 - Expected ']' as part of vector size definition",
                           exprtk_error_location));
 
             return error_node();
@@ -23749,7 +23857,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR138 - Expected ':=' as part of vector definition",
+                             "ERR141 - Expected ':=' as part of vector definition",
                              exprtk_error_location));
 
                return error_node();
@@ -23763,7 +23871,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR139 - Failed to parse single vector initialiser",
+                                "ERR142 - Failed to parse single vector initialiser",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23776,7 +23884,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR140 - Expected ']' to close single value vector initialiser",
+                                "ERR143 - Expected ']' to close single value vector initialiser",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23823,7 +23931,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR141 - Expected '{' as part of vector initialiser list",
+                                   "ERR144 - Expected '{' as part of vector initialiser list",
                                    exprtk_error_location));
 
                      return error_node();
@@ -23843,7 +23951,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR142 - Expected '{' as part of vector initialiser list",
+                                   "ERR145 - Expected '{' as part of vector initialiser list",
                                    exprtk_error_location));
 
                      return error_node();
@@ -23861,7 +23969,7 @@ namespace exprtk
                      set_error(
                         make_error(parser_error::e_syntax,
                                    current_token(),
-                                   "ERR143 - Expected ',' between vector initialisers",
+                                   "ERR146 - Expected ',' between vector initialisers",
                                    exprtk_error_location));
 
                      return error_node();
@@ -23883,7 +23991,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR144 - Expected ';' at end of vector definition",
+                                "ERR147 - Expected ';' at end of vector definition",
                                 exprtk_error_location));
 
                   return error_node();
@@ -23895,7 +24003,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR145 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
+                             "ERR148 - Initialiser list larger than the number of elements in the vector: '" + vec_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -23915,7 +24023,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR146 - Illegal redefinition of local vector: '" + vec_name + "'",
+                             "ERR149 - Illegal redefinition of local vector: '" + vec_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -23949,7 +24057,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR147 - Failed to add new local vector '" + vec_name + "' to SEM",
+                             "ERR150 - Failed to add new local vector '" + vec_name + "' to SEM",
                              exprtk_error_location));
 
                sem_.free_element(nse);
@@ -24004,7 +24112,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR148 - Illegal redefinition of local variable: '" + str_name + "'",
+                             "ERR151 - Illegal redefinition of local variable: '" + str_name + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24036,7 +24144,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR149 - Failed to add new local string variable '" + str_name + "' to SEM",
+                             "ERR152 - Failed to add new local string variable '" + str_name + "' to SEM",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24082,7 +24190,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR150 - Illegal variable definition",
+                          "ERR153 - Illegal variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24103,7 +24211,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR151 - Expected a symbol for variable definition",
+                          "ERR154 - Expected a symbol for variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24113,7 +24221,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR152 - Illegal redefinition of reserved keyword: '" + var_name + "'",
+                          "ERR155 - Illegal redefinition of reserved keyword: '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24123,7 +24231,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR153 - Illegal redefinition of variable '" + var_name + "'",
+                          "ERR156 - Illegal redefinition of variable '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24133,7 +24241,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR154 - Illegal redefinition of local variable: '" + var_name + "'",
+                          "ERR157 - Illegal redefinition of local variable: '" + var_name + "'",
                           exprtk_error_location));
 
             return error_node();
@@ -24153,7 +24261,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR155 - Failed to parse initialisation expression",
+                             "ERR158 - Failed to parse initialisation expression",
                              exprtk_error_location));
 
                return error_node();
@@ -24171,7 +24279,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR156 - Expected ';' after variable definition",
+                             "ERR159 - Expected ';' after variable definition",
                              exprtk_error_location));
 
                free_node(node_allocator_,initialisation_expression);
@@ -24199,7 +24307,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR157 - Illegal redefinition of local variable: '" + var_name + "'",
+                             "ERR160 - Illegal redefinition of local variable: '" + var_name + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
@@ -24231,7 +24339,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR158 - Failed to add new local variable '" + var_name + "' to SEM",
+                             "ERR161 - Failed to add new local variable '" + var_name + "' to SEM",
                              exprtk_error_location));
 
                free_node(node_allocator_, initialisation_expression);
@@ -24268,7 +24376,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR159 - Expected a '{}' for uninitialised var definition",
+                          "ERR162 - Expected a '{}' for uninitialised var definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24278,7 +24386,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR160 - Expected ';' after uninitialised variable definition",
+                          "ERR163 - Expected ';' after uninitialised variable definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24295,7 +24403,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR161 - Illegal redefinition of local variable: '" + var_name + "'",
+                             "ERR164 - Illegal redefinition of local variable: '" + var_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24325,7 +24433,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR162 - Failed to add new local variable '" + var_name + "' to SEM",
+                             "ERR165 - Failed to add new local variable '" + var_name + "' to SEM",
                              exprtk_error_location));
 
                sem_.free_element(nse);
@@ -24358,7 +24466,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR163 - Expected '(' at start of swap statement",
+                          "ERR166 - Expected '(' at start of swap statement",
                           exprtk_error_location));
 
             return error_node();
@@ -24377,7 +24485,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR164 - Expected a symbol for variable or vector element definition",
+                          "ERR167 - Expected a symbol for variable or vector element definition",
                           exprtk_error_location));
 
             return error_node();
@@ -24389,7 +24497,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR165 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
+                             "ERR168 - First parameter to swap is an invalid vector element: '" + var0_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24422,7 +24530,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR166 - First parameter to swap is an invalid variable: '" + var0_name + "'",
+                             "ERR169 - First parameter to swap is an invalid variable: '" + var0_name + "'",
                              exprtk_error_location));
 
                return error_node();
@@ -24436,7 +24544,7 @@ namespace exprtk
             set_error(
                 make_error(parser_error::e_syntax,
                            current_token(),
-                           "ERR167 - Expected ',' between parameters to swap",
+                           "ERR170 - Expected ',' between parameters to swap",
                            exprtk_error_location));
 
             if (variable0_generated)
@@ -24454,7 +24562,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR168 - Expected a symbol for variable or vector element definition",
+                          "ERR171 - Expected a symbol for variable or vector element definition",
                           exprtk_error_location));
 
             if (variable0_generated)
@@ -24471,7 +24579,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR169 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
+                             "ERR172 - Second parameter to swap is an invalid vector element: '" + var1_name + "'",
                              exprtk_error_location));
 
                if (variable0_generated)
@@ -24509,7 +24617,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR170 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
+                             "ERR173 - Second parameter to swap is an invalid variable: '" + var1_name + "'",
                              exprtk_error_location));
 
                if (variable0_generated)
@@ -24528,7 +24636,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR171 - Expected ')' at end of swap statement",
+                          "ERR174 - Expected ')' at end of swap statement",
                           exprtk_error_location));
 
             if (variable0_generated)
@@ -24585,7 +24693,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR172 - Return call within a return call is not allowed",
+                          "ERR175 - Return call within a return call is not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -24609,7 +24717,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR173 - Expected '[' at start of return statement",
+                          "ERR176 - Expected '[' at start of return statement",
                           exprtk_error_location));
 
             return error_node();
@@ -24632,7 +24740,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR174 - Expected ',' between values during call to return",
+                                "ERR177 - Expected ',' between values during call to return",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24644,7 +24752,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR175 - Zero parameter return statement not allowed",
+                          "ERR178 - Zero parameter return statement not allowed",
                           exprtk_error_location));
 
             return error_node();
@@ -24659,7 +24767,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              prev_token,
-                             "ERR176 - Invalid ']' found during return call",
+                             "ERR179 - Invalid ']' found during return call",
                              exprtk_error_location));
 
                return error_node();
@@ -24712,7 +24820,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR177 - Invalid sequence of variable '"+ symbol + "' and bracket",
+                             "ERR180 - Invalid sequence of variable '"+ symbol + "' and bracket",
                              exprtk_error_location));
 
                return false;
@@ -24760,7 +24868,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR178 - Invalid sequence of brackets",
+                             "ERR181 - Invalid sequence of brackets",
                              exprtk_error_location));
 
                return false;
@@ -24857,7 +24965,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR179 - Failed to generate node for function: '" + symbol + "'",
+                                "ERR182 - Failed to generate node for function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24883,7 +24991,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR180 - Failed to generate node for vararg function: '" + symbol + "'",
+                                "ERR183 - Failed to generate node for vararg function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24909,7 +25017,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR181 - Failed to generate node for generic function: '" + symbol + "'",
+                                "ERR184 - Failed to generate node for generic function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24936,7 +25044,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR182 - Failed to generate node for string function: '" + symbol + "'",
+                                "ERR185 - Failed to generate node for string function: '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -24962,7 +25070,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_syntax,
                                 current_token(),
-                                "ERR183 - Invalid use of reserved symbol '" + symbol + "'",
+                                "ERR186 - Invalid use of reserved symbol '" + symbol + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25025,7 +25133,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_symtab,
                                 current_token(),
-                                "ERR184 - Failed to create variable: '" + symbol + "'" +
+                                "ERR187 - Failed to create variable: '" + symbol + "'" +
                                 (error_message.empty() ? "" : " - " + error_message),
                                 exprtk_error_location));
 
@@ -25045,7 +25153,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_symtab,
                                 current_token(),
-                                "ERR185 - Failed to resolve symbol: '" + symbol + "'" +
+                                "ERR188 - Failed to resolve symbol: '" + symbol + "'" +
                                 (error_message.empty() ? "" : " - " + error_message),
                                 exprtk_error_location));
                }
@@ -25057,7 +25165,7 @@ namespace exprtk
          set_error(
             make_error(parser_error::e_syntax,
                        current_token(),
-                       "ERR186 - Undefined symbol: '" + symbol + "'",
+                       "ERR189 - Undefined symbol: '" + symbol + "'",
                        exprtk_error_location));
 
          return error_node();
@@ -25164,7 +25272,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_symtab,
                           current_token(),
-                          "ERR187 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value,
+                          "ERR190 - Variable or function detected, yet symbol-table is invalid, Symbol: " + current_token().value,
                           exprtk_error_location));
 
             return error_node();
@@ -25188,7 +25296,7 @@ namespace exprtk
                   set_error(
                      make_error(parser_error::e_numeric,
                                 current_token(),
-                                "ERR188 - Failed generate node for scalar: '" + current_token().value + "'",
+                                "ERR191 - Failed generate node for scalar: '" + current_token().value + "'",
                                 exprtk_error_location));
 
                   return error_node();
@@ -25202,7 +25310,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_numeric,
                              current_token(),
-                             "ERR189 - Failed to convert '" + current_token().value + "' to a number",
+                             "ERR192 - Failed to convert '" + current_token().value + "' to a number",
                              exprtk_error_location));
 
                return error_node();
@@ -25229,7 +25337,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR190 - Expected ')' instead of: '" + current_token().value + "'",
+                             "ERR193 - Expected ')' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25254,7 +25362,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR191 - Expected ']' instead of: '" + current_token().value + "'",
+                             "ERR194 - Expected ']' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25279,7 +25387,7 @@ namespace exprtk
                set_error(
                   make_error(parser_error::e_syntax,
                              current_token(),
-                             "ERR192 - Expected '}' instead of: '" + current_token().value + "'",
+                             "ERR195 - Expected '}' instead of: '" + current_token().value + "'",
                              exprtk_error_location));
 
                free_node(node_allocator_,branch);
@@ -25319,7 +25427,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR193 - Premature end of expression[1]",
+                          "ERR196 - Premature end of expression[1]",
                           exprtk_error_location));
 
             return error_node();
@@ -25329,7 +25437,7 @@ namespace exprtk
             set_error(
                make_error(parser_error::e_syntax,
                           current_token(),
-                          "ERR194 - Premature end of expression[2]",
+                          "ERR197 - Premature end of expression[2]",
                           exprtk_error_location));
 
             return error_node();
@@ -26022,19 +26130,19 @@ namespace exprtk
                return false;
             else
                return (
-                        (details::e_lt     == operation) ||
-                        (details::e_lte    == operation) ||
-                        (details::e_gt     == operation) ||
-                        (details::e_gte    == operation) ||
-                        (details::e_eq     == operation) ||
-                        (details::e_ne     == operation) ||
-                        (details::e_equal  == operation) ||
-                        (details::e_and    == operation) ||
-                        (details::e_nand   == operation) ||
-                        (details::  e_or   == operation) ||
-                        (details:: e_nor   == operation) ||
-                        (details:: e_xor   == operation) ||
-                        (details::e_xnor   == operation)
+                        (details::e_lt    == operation) ||
+                        (details::e_lte   == operation) ||
+                        (details::e_gt    == operation) ||
+                        (details::e_gte   == operation) ||
+                        (details::e_eq    == operation) ||
+                        (details::e_ne    == operation) ||
+                        (details::e_equal == operation) ||
+                        (details::e_and   == operation) ||
+                        (details::e_nand  == operation) ||
+                        (details::  e_or  == operation) ||
+                        (details:: e_nor  == operation) ||
+                        (details:: e_xor  == operation) ||
+                        (details::e_xnor  == operation)
                       );
          }
 
@@ -26228,8 +26336,8 @@ namespace exprtk
          {
             if ((0 == condition) || (0 == consequent))
             {
-               free_node(*node_allocator_, condition  );
-               free_node(*node_allocator_, consequent );
+               free_node(*node_allocator_,   condition);
+               free_node(*node_allocator_,  consequent);
                free_node(*node_allocator_, alternative);
 
                return error_node();
@@ -26240,7 +26348,7 @@ namespace exprtk
                // True branch
                if (details::is_true(condition))
                {
-                  free_node(*node_allocator_, condition  );
+                  free_node(*node_allocator_,   condition);
                   free_node(*node_allocator_, alternative);
 
                   return consequent;
@@ -26248,7 +26356,7 @@ namespace exprtk
                // False branch
                else
                {
-                  free_node(*node_allocator_, condition );
+                  free_node(*node_allocator_,  condition);
                   free_node(*node_allocator_, consequent);
 
                   if (alternative)
@@ -26260,11 +26368,11 @@ namespace exprtk
             else if ((0 != consequent) && (0 != alternative))
             {
                return node_allocator_->
-                        allocate<conditional_node_t>(condition,consequent,alternative);
+                        allocate<conditional_node_t>(condition, consequent, alternative);
             }
             else
                return node_allocator_->
-                        allocate<cons_conditional_node_t>(condition,consequent);
+                        allocate<cons_conditional_node_t>(condition, consequent);
          }
 
          #ifndef exprtk_disable_string_capabilities
@@ -26274,8 +26382,8 @@ namespace exprtk
          {
             if ((0 == condition) || (0 == consequent))
             {
-               free_node(*node_allocator_, condition  );
-               free_node(*node_allocator_, consequent );
+               free_node(*node_allocator_,   condition);
+               free_node(*node_allocator_,  consequent);
                free_node(*node_allocator_, alternative);
 
                return error_node();
@@ -26286,7 +26394,7 @@ namespace exprtk
                // True branch
                if (details::is_true(condition))
                {
-                  free_node(*node_allocator_, condition  );
+                  free_node(*node_allocator_,   condition);
                   free_node(*node_allocator_, alternative);
 
                   return consequent;
@@ -26294,7 +26402,7 @@ namespace exprtk
                // False branch
                else
                {
-                  free_node(*node_allocator_, condition );
+                  free_node(*node_allocator_,  condition);
                   free_node(*node_allocator_, consequent);
 
                   if (alternative)
@@ -26306,7 +26414,7 @@ namespace exprtk
             }
             else if ((0 != consequent) && (0 != alternative))
                return node_allocator_->
-                        allocate<conditional_string_node_t>(condition,consequent,alternative);
+                        allocate<conditional_string_node_t>(condition, consequent, alternative);
             else
                return error_node();
          }
@@ -26333,7 +26441,7 @@ namespace exprtk
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
                free_node(*node_allocator_, condition);
-               free_node(*node_allocator_, branch   );
+               free_node(*node_allocator_,    branch);
 
                return result;
             }
@@ -26370,7 +26478,7 @@ namespace exprtk
                }
 
                free_node(*node_allocator_, condition);
-               free_node(*node_allocator_, branch   );
+               free_node(*node_allocator_,    branch);
 
                return error_node();
             }
@@ -26407,16 +26515,16 @@ namespace exprtk
                   result = node_allocator_->allocate<details::null_node<Type> >();
 
                free_node(*node_allocator_, initialiser);
-               free_node(*node_allocator_, condition  );
+               free_node(*node_allocator_,   condition);
                free_node(*node_allocator_, incrementor);
-               free_node(*node_allocator_, loop_body  );
+               free_node(*node_allocator_,   loop_body);
 
                return result;
             }
             else if (details::is_null_node(condition))
             {
                free_node(*node_allocator_, initialiser);
-               free_node(*node_allocator_, condition  );
+               free_node(*node_allocator_,   condition);
                free_node(*node_allocator_, incrementor);
 
                return loop_body;
@@ -28432,12 +28540,12 @@ namespace exprtk
                         {
                            case details::e_div : new_cobnode = expr_gen.node_allocator_->
                                                     template allocate_tt<typename details::cob_node<Type,details::mul_op<Type> > >
-                                                       (c / cobnode->c(),cobnode->move_branch(0));
+                                                       (c / cobnode->c(), cobnode->move_branch(0));
                                                  break;
 
                            case details::e_mul : new_cobnode = expr_gen.node_allocator_->
                                                     template allocate_tt<typename details::cob_node<Type,details::div_op<Type> > >
-                                                       (c / cobnode->c(),cobnode->move_branch(0));
+                                                       (c / cobnode->c(), cobnode->move_branch(0));
                                                  break;
 
                            default             : return error_node();
@@ -28486,11 +28594,11 @@ namespace exprtk
             {
                const Type c = static_cast<details::literal_node<Type>*>(branch[1])->value();
 
-               details::free_node(*(expr_gen.node_allocator_),branch[1]);
+               details::free_node(*(expr_gen.node_allocator_), branch[1]);
 
                if (std::equal_to<T>()(T(0),c) && (details::e_mul == operation))
                {
-                  free_node(*expr_gen.node_allocator_,branch[0]);
+                  free_node(*expr_gen.node_allocator_, branch[0]);
 
                   return expr_gen(T(0));
                }
@@ -35656,9 +35764,7 @@ namespace exprtk
          {
             scoped_bft<func_1param> sb(*this);
             base_func::update(v0);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35672,9 +35778,7 @@ namespace exprtk
          {
             scoped_bft<func_2param> sb(*this);
             base_func::update(v0, v1);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35688,9 +35792,7 @@ namespace exprtk
          {
             scoped_bft<func_3param> sb(*this);
             base_func::update(v0, v1, v2);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35704,9 +35806,7 @@ namespace exprtk
          {
             scoped_bft<func_4param> sb(*this);
             base_func::update(v0, v1, v2, v3);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35720,9 +35820,7 @@ namespace exprtk
          {
             scoped_bft<func_5param> sb(*this);
             base_func::update(v0, v1, v2, v3, v4);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35736,9 +35834,7 @@ namespace exprtk
          {
             scoped_bft<func_6param> sb(*this);
             base_func::update(v0, v1, v2, v3, v4, v5);
-            T result = this->value(base_func::expression);
-
-            return result;
+            return this->value(base_func::expression);
          }
       };
 
@@ -35785,8 +35881,6 @@ namespace exprtk
                       const Sequence<std::string,Allocator>& var_list,
                       const bool override = false)
       {
-         const std::size_t n = var_list.size();
-
          const typename std::map<std::string,expression_t>::iterator itr = expr_map_.find(name);
 
          if (expr_map_.end() != itr)
@@ -35804,6 +35898,8 @@ namespace exprtk
 
          if (compile_expression(name,expression,var_list))
          {
+            const std::size_t n = var_list.size();
+
             fp_map_[n][name]->setup(expr_map_[name]);
 
             return true;
@@ -35869,7 +35965,7 @@ namespace exprtk
 
       inline bool add(const function& f, const bool override = false)
       {
-         return add(f.name_,f.expression_,f.v_,override);
+         return add(f.name_, f.expression_, f.v_,override);
       }
 
    private:
@@ -36493,8 +36589,8 @@ namespace exprtk
             return false;                                                         \
          }                                                                        \
 
-         exprtk_register_function("print"   , p)
-         exprtk_register_function("println" ,pl)
+         exprtk_register_function("print"  ,  p)
+         exprtk_register_function("println", pl)
          #undef exprtk_register_function
 
          return true;
@@ -38160,9 +38256,9 @@ namespace exprtk
    namespace information
    {
       static const char* library = "Mathematical Expression Toolkit";
-      static const char* version = "2.7182818284590452353602874713526624977572470936"
-                                   "999595749669676277240766303535475945713821785251";
-      static const char* date    = "20170505";
+      static const char* version = "2.71828182845904523536028747135266249775724709369"
+                                   "9959574966967627724076630353547594571382178525166";
+      static const char* date    = "20180101";
 
       static inline std::string data()
       {
diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h
index b05128c4a193aebd46f9f31fec2ed89dc41c30ec..bf51bd9f83ad3390976f72fea1502799c337317c 100644
--- a/src/core/mpi/BufferDataTypeExtensions.h
+++ b/src/core/mpi/BufferDataTypeExtensions.h
@@ -33,6 +33,7 @@
 #include <boost/integer.hpp>
 #include <boost/uuid/uuid.hpp>
 
+#include <array>
 #include <deque>
 #include <limits>
 #include <list>
@@ -82,6 +83,51 @@ struct BufferSizeTrait< std::pair<T1,T2> > {
 // ----------------------------- Standard Container Support  -----------------------------------------------------------
 // ---------------------------------------------------------------------------------------------------------------------
 
+template< typename T,     // Element type of SendBuffer
+          typename G,     // Growth policy of SendBuffer
+          typename Cont > // Container
+void sendNonResizableContainer( GenericSendBuffer<T,G> & buf, const Cont & container )
+{
+  buf.addDebugMarker( "ar" );
+  for( const auto & it : container )
+    buf << it;
+}
+
+template< typename T,     // Element type of RecvBuffer
+          typename Cont > // Container
+void recvNonResizableContainer( GenericRecvBuffer<T> & buf, Cont & container )
+{
+  buf.readDebugMarker( "ar" );
+  for( auto & it : container )
+    buf >> it;
+}
+
+template< typename T,     // Element type of SendBuffer
+          typename G,     // Growth policy of SendBuffer
+          typename CT,    // Element type
+          std::size_t N > // Array size
+GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const std::array<CT, N> & array )
+{
+  sendNonResizableContainer(buf, array);
+  return buf;
+}
+
+template< typename T,     // Element type of RecvBuffer
+          typename CT,    // Element type
+          std::size_t N > // Array size
+GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, std::array<CT, N> & array )
+{
+  recvNonResizableContainer(buf, array);
+  return buf;
+}
+
+template<typename T, std::size_t N>
+struct BufferSizeTrait< std::array< T, N > > {
+    static const bool constantSize = true;
+    static const uint_t size = N * sizeof(T) + BUFFER_DEBUG_OVERHEAD;
+};
+
+
 template< typename T,    // Element type of SendBuffer
           typename G,    // Growth policy of SendBuffer
           typename Cont> // Container
diff --git a/src/core/ptrvector/Algorithm.h b/src/core/ptrvector/Algorithm.h
deleted file mode 100644
index c00063d702e55c804b1b02ceadf44845a1ff1069..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/Algorithm.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file Algorithm.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <boost/type_traits/is_base_of.hpp>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  POLYMORPHIC COUNT
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Counts the pointer to objects with dynamic type \a D.
- *
- * \param first Iterator to the first pointer of the pointer range.
- * \param last Iterator to the pointer one past the last pointer of the pointer range.
- * \return The number of objects with dynamic type \a D.
- *
- * This function traverses the range \f$ [first,last) \f$ of pointers to objects with static
- * type \a S and counts all polymorphic pointers to objects of dynamic type \a D. Note that
- * in case \a D is not a type derived from \a S, a compile time error is created!
- */
-template< typename D    // Dynamic type of the objects
-        , typename S >  // Static type of the objects
-inline size_t polymorphicCount( S *const * first, S *const * last )
-{
-   static_assert(boost::is_base_of<S, D>::value && !boost::is_base_of<D, S>::value, "D has to be strictly derived from S");
-
-   size_t count( 0 );
-   for( S *const * it=first; it!=last; ++it )
-      if( dynamic_cast<D*>( *it ) ) ++count;
-   return count;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  POLYMORPHIC FIND
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Finds the next pointer to an object with dynamic type \a D.
- *
- * \param first Iterator to the first pointer of the pointer range.
- * \param last Iterator to the pointer one past the last pointer of the pointer range.
- * \return The next pointer to an object with dynamic type \a D.
- *
- * This function traverses the range \f$ [first,last) \f$ of pointers to objects with static
- * type \a S until it finds the next polymorphic pointer to an object of dynamic type \a D.
- * Note that in case \a D is not a type derived from \a S, a compile time error is created!
- */
-template< typename D    // Dynamic type of the objects
-        , typename S >  // Static type of the objects
-inline S *const * polymorphicFind( S *const * first, S *const * last )
-{
-   static_assert(boost::is_base_of<S, D>::value && !boost::is_base_of<D, S>::value, "D has to be strictly derived from S");
-
-   while( first != last && !dynamic_cast<D*>( *first ) ) ++first;
-   return first;
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/Null.h b/src/core/ptrvector/Null.h
deleted file mode 100644
index 0f08813a0244eacfe1f82e9f9249308e924c932c..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/Null.h
+++ /dev/null
@@ -1,289 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file Null.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Safe C++ NULL pointer implementation.
- * \ingroup util
- *
- * This implementation offers a remedy for the use of the NULL pointer in C++. For this, the
- * NULL macro is replaced by an instance of the Null class, which can only be assigned and
- * compared with pointers and pointers-to-member. Therefore the use of NULL regains the type
- * safety it lost in C++ due to the strict C++ type system.\n
- * The NULL pointer is used exactly as before:
-
-   \code
-   int* pi = NULL;
-   if( pi == NULL ) {...}
-   \endcode
- */
-class Null
-{
-public:
-   //**Constructor*********************************************************************************
-   /*!\name Constructor */
-   //@{
-   inline Null();
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   // No explicitly declared destructor.
-   //**********************************************************************************************
-
-   //**Conversion operators************************************************************************
-   /*!\name Conversion operators */
-   //@{
-   template< typename T >
-   inline operator T*() const;
-
-   template< typename T, typename C >
-   inline operator T C::*() const;
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   template< typename T >
-   inline bool equal( const T* rhs ) const;
-
-   template< typename T, typename C >
-   inline bool equal( const T C::* rhs ) const;
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Forbidden operations************************************************************************
-   /*!\name Forbidden operations */
-   //@{
-   Null( const Null& n );             //!< Copy constructor (private & undefined)
-   Null& operator=( const Null& n );  //!< Copy assignment operator (private & undefined)
-   void* operator&() const;           //!< Address operator (private & undefined)
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief The default constructor of the Null class.
- */
-inline Null::Null()
-{}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONVERSION OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Conversion operator to a pointer.
- *
- * This conversion operator offers a type safe conversion of zero to a pointer of any kind.
- */
-template< typename T >
-inline Null::operator T*() const
-{
-   return 0;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion operator to a pointer-to-member.
- *
- * This conversion operator offers the type safe conversion of zero to a pointer-to-member of
- * any kind.
- */
-template< typename T, typename C >
-inline Null::operator T C::*() const
-{
-   return 0;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Comparison between Null and a pointer.
- *
- * The function offers a type safe comparison between zero and an arbitrary pointer.
- */
-template< typename T >
-inline bool Null::equal( const T* rhs ) const
-{
-   return rhs == 0;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Comparison between Null and a pointer-to-member.
- *
- * The function offers a type safe comparison between zero and an arbitrary pointer-to-member.
- */
-template< typename T, typename C >
-inline bool Null::equal( const T C::* rhs ) const
-{
-   return rhs == 0;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  GLOBAL OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name Null operators */
-//@{
-template< typename T >
-inline bool operator==( const Null& lhs, const T& rhs );
-
-template< typename T >
-inline bool operator==( const T& lhs, const Null& rhs );
-
-template< typename T >
-inline bool operator!=( const Null& lhs, const T& rhs );
-
-template< typename T >
-inline bool operator!=( const T& lhs, const Null& rhs );
-//@}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Equality comparison between Null and a pointer or pointer-to-member.
- *
- * This operator takes a reference to an object of type T instead of a pointer of a pointer-
- * to-member to avoid the ambiguity with the built-in pointer comparison operators. However,
- * only pointers and pointers-to-member can be compared to Null.
- */
-template< typename T >
-inline bool operator==( const Null& lhs, const T& rhs )
-{
-   return lhs.equal( rhs );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Equality comparison between a pointer or pointer-to-member and Null.
- *
- * This operator takes a reference to an object of type T instead of a pointer of a pointer-
- * to-member to avoid the ambiguity with the built-in pointer comparison operators. However,
- * only pointers and pointers-to-member can be compared to Null.
- */
-template< typename T >
-inline bool operator==( const T& lhs, const Null& rhs )
-{
-   return rhs.equal( lhs );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inequality comparison between Null and a pointer or pointer-to-member.
- *
- * This operator takes a reference to an object of type T instead of a pointer of a pointer-
- * to-member to avoid the ambiguity with the built-in pointer comparison operators. However,
- * only pointers and pointers-to-member can be compared to Null.
- */
-template< typename T >
-inline bool operator!=( const Null& lhs, const T& rhs )
-{
-   return !lhs.equal( rhs );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inequality comparison between a pointer or pointer-to-member and Null.
- *
- * This operator takes a reference to an object of type T instead of a pointer of a pointer-
- * to-member to avoid the ambiguity with the built-in pointer comparison operators. However,
- * only pointers and pointers-to-member can be compared to Null.
- */
-template< typename T >
-inline bool operator!=( const T& lhs, const Null& rhs )
-{
-   return !rhs.equal( lhs );
-}
-//*************************************************************************************************
-
-} // namespace
-
-
-
-
-////=================================================================================================
-////
-////  NULL DEFINITION
-////
-////=================================================================================================
-
-//#ifdef NULL
-//#  undef NULL
-//#endif
-
-////*************************************************************************************************
-///*!\brief Global NULL pointer.
-// * \ingroup util
-// *
-// * This instance of the Null class replaces the NULL macro to ensure a type-safe NULL pointer.
-// */
-//const walberla::Null NULL;
-////*************************************************************************************************
diff --git a/src/core/ptrvector/PtrIterator.h b/src/core/ptrvector/PtrIterator.h
deleted file mode 100644
index a6ecef7f3b6194ead74e78f2b52e030dd3c9b704..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/PtrIterator.h
+++ /dev/null
@@ -1,548 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file PtrIterator.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <iterator>
-#include <core/ptrvector/Null.h>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Implementation of an iterator for pointer vectors.
- * \ingroup util
- *
- * The PtrIterator class follows the example of the random-access iterator classes of the STL.
- * However, the focus of this iterator implementation is the use with (polymorphic) pointers.
- * Since the physics engine makes heavy use of polymorphic pointers, this implementation eases
- * the use of iterators over a range of pointers and improves the semantics on these pointers.\n
- *
- * In contrast to the STL iterators, the PtrIterator class slightly changes the meaning of the
- * access operators. Consider the following example:
-
-   \code
-   // Definition of class A
-   class A
-   {
-    public:
-      A( int i=0 ):i_(i) {}
-
-      void set( int i )       { i_ = i; }
-      int  get()        const { return i_; }
-
-    private:
-      int i_;
-   };
-
-   // Definition of a pointer vector for class A
-   typedef PtrVector<A>  AVector;
-
-   AVector vector;
-   AVector::Iterator it = vector.begin();
-
-   // The subscript operator returns a handle to the underlying object
-   A* a1 = it[0];
-
-   // The dereference operator returns a handle to the underlying object
-   A* a2 = *it;
-
-   // The member access operator offers direct access to the underlying object
-   it->set( 2 );
-   \endcode
-
- * The constant iterators (iterator over constant objects) prohibit the access to non-const
- * member functions. Therefore the following operation results in a compile-time error:
-
-   \code
-   AVector vector;
-   AVector::ConstIterator it = vector.begin();
-
-   it->set( 2 );  // Compile-time error!
-   \endcode
- */
-template< typename Type >
-class PtrIterator
-{
-public:
-   //**Type definitions****************************************************************************
-   // pe naming convention
-   typedef std::random_access_iterator_tag  IteratorCategory;   //!< The iterator category.
-   typedef Type*                            ValueType;          //!< Type of the underlying pointers.
-   typedef Type* const                      PointerType;        //!< Pointer return type.
-   typedef ValueType const&                 ReferenceType;      //!< Reference return type.
-   typedef ValueType const*                 IteratorType;       //!< Type of the internal pointer.
-   typedef std::ptrdiff_t                   DifferenceType;     //!< Difference between two iterators.
-
-   // STL iterator requirements
-   typedef IteratorCategory                 iterator_category;  //!< The iterator category.
-   typedef ValueType                        value_type;         //!< Type of the underlying pointers.
-   typedef PointerType                      pointer;            //!< Pointer return type.
-   typedef ReferenceType                    reference;          //!< Reference return type.
-   typedef DifferenceType                   difference_type;    //!< Difference between two iterators.
-   //**********************************************************************************************
-
-   //**Constructors********************************************************************************
-   /*!\name Constructors */
-   //@{
-            inline PtrIterator();
-   explicit inline PtrIterator( const IteratorType& it );
-
-   template< typename Other >
-   inline PtrIterator( const PtrIterator<Other>& it );
-
-   // No explicitly declared copy constructor.
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   // No explicitly declared destructor.
-   //**********************************************************************************************
-
-   //**Copy assignment operator********************************************************************
-   // No explicitly declared copy assignment operator.
-   //**********************************************************************************************
-
-   //**Operators***********************************************************************************
-   /*!\name Operators */
-   //@{
-   inline PtrIterator&   operator++();
-   inline PtrIterator    operator++( int );
-   inline PtrIterator&   operator--();
-   inline PtrIterator    operator--( int );
-   inline PtrIterator&   operator+=( DifferenceType n );
-   inline PtrIterator    operator+ ( DifferenceType n )      const;
-   inline PtrIterator&   operator-=( DifferenceType n );
-   inline PtrIterator    operator- ( DifferenceType n )      const;
-   inline DifferenceType operator- ( const PtrIterator& it ) const;
-   //@}
-   //**********************************************************************************************
-
-   //**Access operators****************************************************************************
-   /*!\name Access operators */
-   //@{
-   inline PointerType& operator[]( DifferenceType n ) const;
-   inline PointerType& operator*()                    const;
-   inline PointerType& operator->()                   const;
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline const IteratorType& base() const;
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   IteratorType it_;  //!< Pointer to the current memory location.
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Default constructor for PtrIterator.
- */
-template< typename Type >
-inline PtrIterator<Type>::PtrIterator()
-   : it_(NULL)  // Pointer to the current memory location
-{}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Standard constructor for PtrIterator.
- *
- * \param it The value of the iterator.
- */
-template< typename Type >
-inline PtrIterator<Type>::PtrIterator( const IteratorType& it )
-   : it_(it)  // Pointer to the current memory location
-{}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion constructor from different PtrIterator instances.
- *
- * \param it The foreign PtrIterator instance to be copied.
- */
-template< typename Type >
-template< typename Other >
-inline PtrIterator<Type>::PtrIterator( const PtrIterator<Other>& it )
-   : it_( it.base() )  // Pointer to the current memory location
-{}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Pre-increment operator.
- *
- * \return Reference to the incremented pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type>& PtrIterator<Type>::operator++()
-{
-   ++it_;
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Post-increment operator.
- *
- * \return The incremented pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type> PtrIterator<Type>::operator++( int )
-{
-   PtrIterator tmp( *this );
-   ++it_;
-   return tmp;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Pre-decrement operator.
- *
- * \return Reference to the decremented pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type>& PtrIterator<Type>::operator--()
-{
-   --it_;
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Post-decrement operator.
- *
- * \return The decremented pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type> PtrIterator<Type>::operator--( int )
-{
-   PtrIterator tmp( *this );
-   --it_;
-   return tmp;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Shifting the iterator by \a n elements to the higher elements.
- *
- * \param n The number of elements.
- * \return Reference to the shifted pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type>& PtrIterator<Type>::operator+=( DifferenceType n )
-{
-   it_ += n;
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Shifting the iterator by \a n elements to the higher elements.
- *
- * \param n The number of elements.
- * \return The shifted pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type> PtrIterator<Type>::operator+( DifferenceType n ) const
-{
-   return PtrIterator( it_ + n );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Shifting the iterator by \a n elements to the lower elements.
- *
- * \param n The number of elements.
- * \return Reference to the shifted pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type>& PtrIterator<Type>::operator-=( DifferenceType n )
-{
-   it_ -= n;
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Shifting the iterator by \a n elements to the lower elements.
- *
- * \param n The number of elements.
- * \return The shifted pointer iterator.
- */
-template< typename Type >
-inline PtrIterator<Type> PtrIterator<Type>::operator-( DifferenceType n ) const
-{
-   return PtrIterator( it_ - n );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Calculating the number of elements between two pointer iterators.
- *
- * \param it The right hand side iterator.
- * \return The number of elements between the two pointer iterators.
- */
-template< typename Type >
-inline typename PtrIterator<Type>::DifferenceType PtrIterator<Type>::operator-( const PtrIterator& it ) const
-{
-   return it_ - it.it_;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ACCESS OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Subscript operator for the direct element access.
- *
- * \param index Access index. Accesses the element \a index elements away from the current iterator position.
- * \return Handle to the accessed element.
- */
-template< typename Type >
-inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator[]( DifferenceType index ) const
-{
-   return it_[index];
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a handle to the element at the current iterator position.
- *
- * \return Handle to the element at the current iterator position.
- */
-template< typename Type >
-inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator*() const
-{
-   return *it_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Direct access to the element at the current iterator position.
- *
- * \return Reference to the element at the current iterator position.
- */
-template< typename Type >
-inline typename PtrIterator<Type>::PointerType& PtrIterator<Type>::operator->() const
-{
-   return *it_;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Access to the underlying member of the pointer iterator.
- *
- * \return Pointer to the current memory location.
- */
-template< typename Type >
-inline const typename PtrIterator<Type>::IteratorType& PtrIterator<Type>::base() const
-{
-   return it_;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  GLOBAL OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name PtrIterator operators */
-//@{
-template< typename TypeL, typename TypeR >
-inline bool operator==( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-
-template< typename TypeL, typename TypeR >
-inline bool operator!=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-
-template< typename TypeL, typename TypeR >
-inline bool operator<( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-
-template< typename TypeL, typename TypeR >
-inline bool operator>( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-
-template< typename TypeL, typename TypeR >
-inline bool operator<=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-
-template< typename TypeL, typename TypeR >
-inline bool operator>=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs );
-//@}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Equality comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the iterators point to the same element, \a false if not.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator==( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() == rhs.base();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inequality comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the iterators don't point to the same element, \a false if they do.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator!=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() != rhs.base();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Less-than comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the left-hand side iterator points to a lower element, \a false if not.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator<( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() < rhs.base();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Greater-than comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the left-hand side iterator points to a higher element, \a false if not.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator>( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() > rhs.base();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Less-or-equal-than comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator<=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() <= rhs.base();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Greater-or-equal-than comparison between two PtrIterator objects.
- *
- * \param lhs The left-hand side pointer iterator.
- * \param rhs The right-hand side pointer iterator.
- * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not.
- */
-template< typename TypeL, typename TypeR >
-inline bool operator>=( const PtrIterator<TypeL>& lhs, const PtrIterator<TypeR>& rhs )
-{
-   return lhs.base() >= rhs.base();
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/PtrVector.h b/src/core/ptrvector/PtrVector.h
deleted file mode 100644
index 2e62290407295ed080e6b619f7242e709ee952fe..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/PtrVector.h
+++ /dev/null
@@ -1,2604 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file PtrVector.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <algorithm>
-#include <stdexcept>
-#include <core/debug/Debug.h>
-#include <core/ptrvector/Algorithm.h>
-#include <core/ptrvector/Null.h>
-#include <core/ptrvector/policies/PtrDelete.h>
-#include <core/ptrvector/policies/OptimalGrowth.h>
-#include <core/ptrvector/PtrIterator.h>
-#include <core/Template.h>
-
-#include <boost/type_traits/is_base_of.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Implementation of a vector for (polymorphic) pointers.
- * \ingroup util
- *
- * \section basics Basic usage
- *
- * The \a std::vector is one of the standard libraries most useful tools. It is the standard
- * solution for a dynamically allocated, automatically growing, and memory managed array. It
- * provides fast random access to its elements, since a vector guarantees that the elements
- * lie adjacent in memory and manages the dynamically allocated memory according to the RAII
- * idiom.\n
- * Yet there are some situations, where users of \a std::vector experience several drawbacks,
- * especially when \a std::vector is used in combination with pointers. For instance, a
- * \a const_iterator over a range of pointers will not allow the stored pointers to change,
- * but the objects behind the pointers remain changeable. The following example illustrates
- * that it is possible to change the values of \a double values through an iterator-to-const:
-
-   \code
-   typedef std::vector<double*>  Doubles;
-
-   Doubles doubles;  // Creating a vector for pointers to double values
-
-   // Filling the vector with pointers to double values. All values are initialized with 1.
-   for( size_t i=0; i<10; ++i )
-      doubles.push_back( new double( 1.0 ) );
-
-   // Accessing the first rigid body
-   Doubles::const_iterator first = doubles.begin();
-   **first = 2.0;  // Changes the double value through an iterator-to-const
-   \endcode
-
- * The basic reason for this behavior is that \a std::vector is unaware of the fact that it
- * stores pointers instead of objects and therefore the pointer are considered constant, not
- * the objects behind the pointer.\n
- * Another drawback of \a std::vector is the fact that during destruction of a vector object
- * the dynamically allocated bodies are not deleted. Again, \a std::vector is unaware of the
- * special property of pointers and therefore does not apply any kind of deletion policy. It
- * basically calls the default destructor for pointers, which in turn does nothing and
- * especially does not destroy the attached objects.\n
- * A different approach is taken by the Boost \a ptr_vector. A \a ptr_vector is perfectly
- * aware of the fact that is stores pointers to dynamically objects (and in consequence may
- * only be used with pointers to dynamically allocated objects) and takes full responsibility
- * for these resources. However, in order to accomplish this task, \a ptr_vector completely
- * abstracts from the fact that it stores pointers and provides a view as if it would contain
- * objects instead of pointers. However, unfortunately this strict memory management creates
- * problems in the context of \b walberla, where vectors to pointers are used both internally
- * (including proper resource management) and outside by the user (without any resource
- * management).\n
- * \b walberla provides a special vector container for pointers, which is
- * a cross of the functionalities of the \a std::vector and \a ptr_vector. The \b walberla PtrVector
- * is not a RAII class in the classical sense (as for instance the Boost \a ptr_vector) since
- * it does not strictly encapsule the resource management. As in the case of \a std::vector,
- * it still is the responsibility of a user of PtrVector to manage the resources accordingly.
- * However, it perfectly fits the requirements of \b walberla: PtrVector can be used internally
- * to store pointers to dynamically allocated objects and resources within RAII classes, and
- * outside of \b walberla by a user as storage for handles to resources that are managed elsewhere.
- * In contrast to the \a boost::ptr_vector, the PtrVector provides full access to the contained
- * pointers, but its iterators work similar to the \a ptr_vector
- * iterator and only provide access to the objects behind the pointers, creating the illusion
- * that objects are stored instead of pointers:
-
-   \code
-   typedef walberla::PtrVector<double>  Doubles;
-   Doubles doubles;  // Creating an empty PtrVector for pointers to double values
-
-   doubles.pushBack( new double(1.0) ); // A new pointer-to-double is added to the vector
-
-   double_vector::iterator first = doubles.begin();
-   *first = 2.0;  // No indirection needed
-
-   Doubles::ConstIterator second( first+1 );
-   *second = 3.0;  // Compile time error! It is not possible to change double
-                   // values via an iterator-to-const
-   \endcode
-
- * Notice the differences in the usage of the iterator in contrast to the \a std::vector and
- * \a boost::ptr_vector. In contrast to them the functions of PtrVector follow the naming
- * convention of the \b walberla physics engine (i.e. pushBack instead of push_back). In addition,
- * the underlying iterator adds an additional dereference to all access operators, which eases
- * the access to the underlying objects:
-
-   \code
-   // STL style:
-   **first = 2.0;
-
-   // walberla style:
-   *first = 2.0;
-   \endcode
-
- * A noteworthy difference between the STL vector and the pointer vector is the used template
- * argument: instead of the pointer type, the \b walberla pointer vector is only provided with the
- * type of the underlying objects:
-
-   \code
-   // STL style:
-   std::vector<double*> vector;
-
-   // walberla style:
-   walberla::PtrVector<double> vector;
-   \endcode
-
- * Additionally, the \b walberla pointer vector offers some limited possibilities to configure the
- * memory management and the growth of the internal storage, and implements special features
- * for polymorphic pointers, as for instance a convenient way to iterate over a subset of
- * polymorphic objects contained in the pointer vector.\n\n
- *
- *
- * \section polymorphic Polymorphic pointers
- *
- * For polymorphic pointers, the PtrVector class additionally offers two special iterators to
- * iterate over all objects of a specific type: the CastIterator and ConstCastIterator.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of function f for non-const pointer vectors
-   void f( PtrVector<A>& vector )
-   {
-      PtrVector<A>::CastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::CastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-         ...
-   }
-
-   // Definition of function f for const pointer vectors
-   void f( const PtrVector<A>& vector )
-   {
-      PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::ConstCastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-   }
-   \endcode
-
- * In the example, the cast iterators are used to iterate over all objects of type \a B within
- * the pointer vector, where \a B must be a type derived from \a A. The attempt to use these
- * iterators for types that are not derived from \a A results in a compile time error. Note that
- * the usage of the cast iterators is computationally more expensive than the use of the standard
- * iterators. Therefore these iterators should not be used unless a down-cast is really necessary,
- * e.g. in order to access a type specific function.\n\n
- *
- *
- * \section container Using a pointer vector within other container classes
- *
- * If a pointer vector is used within an other container and is used to store polymorphic pointers,
- * you might face the problem of not being able to create type definitions for the cast iterators.
- * Whereas it is possible to create typedefs for the standard iterators, it is unfortunately not
- * possible (yet) to create type definitions for template classes. In order to create a new return
- * type within the container, the following approach could be taken:
-
-   \code
-   template< typename A >
-   class Container
-   {
-    public:
-      template< typename C >
-      struct CastIterator : public PtrVector<A>::CastIterator<C>
-      {
-         CastIterator( const PtrVector<A>::CastIterator<C>& it )
-            : PtrVector<A>::CastIterator<C>( it )  // Initializing the base class
-         {}
-      };
-
-      template< typename C >
-      CastIterator<C> begin();
-
-      template< typename C >
-      CastIterator<C> end();
-
-    private:
-      PtrVector<A> vector_;
-   };
-   \endcode
-
- * Instead of a typedef within the Container class, a new class CastIterator is derived from the
- * PtrVector::CastIterator class. This approach acts similar as the typedef as a user can now
- * use the Container as follows:
-
-   \code
-   class A { ... };
-   class B : public A { ... };
-
-   Container<A>::CastIterator<B> begin;
-   \endcode
-
- * This provides the same abstraction from the internal implementation as the desired typedef. The
- * same approach could be taken for a ConstCastIterator definition. However, to keep the code
- * footprint small you should consider using the original type instead.\n\n
- *
- *
- * \section adaptions Adapting a pointer vector
- *
- * The growth and deletion behavior of the PtrVector class can be adapted to any specific task. The
- * second template argument of the PtrVector specifies the growth rate. The following growth rates
- * can be selected:
- *
- *  - ConstantGrowth
- *  - LinearGrowth
- *  - OptimalGrowth (the default behavior)
- *
- * The third template argument of the PtrVector specifies the deletion behavior for the case that
- * the pointer vector is destroyed. Note that the deletion behavior has only limited effect on
- * the memory management of the contained resources. For instance, copying a PtrVector always
- * results in a shallow copy, i.e., the contained resources are not copied/cloned. Therefore the
- * deletion policy should be considered a convenience functionality in the context of a resource
- * managing class. The following policies can be selected:
- *
- *  - NoDelete : No deletion of the contained pointers (the default behavior).
- *  - PtrDelete : Applies \a delete to all contained pointers.
- *  - ArrayDelete : Applies \a delete[] to all contained pointers.\n\n
- */
-template< typename T                    // Type
-        , typename D = PtrDelete        // Deletion policy
-        , typename G = OptimalGrowth >  // Growth policy
-class PtrVector
-{
-private:
-   //**Friend declarations*************************************************************************
-   /*! \cond internal */
-   template< typename T2, typename D2, typename G2 > friend class PtrVector;
-   /*! \endcond */
-   //**********************************************************************************************
-
-public:
-   //**Type definitions****************************************************************************
-   typedef T*                    ValueType;           //!< Type of the underlying values.
-   typedef T*                    PointerType;         //!< Pointer to a non-const object.
-   typedef const T*              ConstPointerType;    //!< Pointer to a const object.
-   typedef T*&                   ReferenceType;       //!< Reference to a non-const object.
-   typedef T*const&              ConstReferenceType;  //!< Reference to a const object.
-   typedef size_t                SizeType;            //!< Size type of the pointer vector.
-   typedef PtrIterator<T>        Iterator;            //!< Iterator over non-const objects.
-   typedef PtrIterator<const T>  ConstIterator;       //!< Iterator over const objects.
-   typedef D                     DeletionPolicy;      //!< Type of the deletion policy.
-   typedef G                     GrowthPolicy;        //!< Type of the growth policy.
-
-   // STL iterator requirements
-   typedef ValueType             value_type;          //!< Type of the underlying values.
-   typedef PointerType           pointer;             //!< Pointer to a non-const object.
-   typedef ConstPointerType      const_pointer;       //!< Pointer to a const object.
-   typedef ReferenceType         reference;           //!< Reference to a non-const object.
-   typedef ConstReferenceType    const_reference;     //!< Reference to a const object.
-   typedef SizeType              size_type;           //!< Size type of the pointer vector.
-   //**********************************************************************************************
-
-   //**Forward declarations for nested classes*****************************************************
-   template< typename C > class CastIterator;
-   template< typename C > class ConstCastIterator;
-   //**********************************************************************************************
-
-   //**Constructors********************************************************************************
-   /*!\name Constructors */
-   //@{
-   explicit inline PtrVector( SizeType initCapacity = 0 );
-            inline PtrVector( const PtrVector& pv );
-
-   template< typename T2, typename D2, typename G2 >
-            inline PtrVector( const PtrVector<T2,D2,G2>& pv );
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   /*!\name Destructor */
-   //@{
-   inline ~PtrVector();
-   //@}
-   //**********************************************************************************************
-
-   //**Assignment operators************************************************************************
-   /*!\name Assignment operators */
-   //@{
-   PtrVector& operator=( const PtrVector& pv );
-
-   template< typename T2, typename D2, typename G2 >
-   PtrVector& operator=( const PtrVector<T2,D2,G2>& pv );
-   //@}
-   //**********************************************************************************************
-
-   //**Get functions*******************************************************************************
-   /*!\name Get functions */
-   //@{
-                          inline SizeType maxSize()  const;
-                          inline SizeType size()     const;
-   template< typename C > inline SizeType size()     const;
-                          inline SizeType capacity() const;
-                          inline bool     isEmpty()  const;
-   //@}
-   //**********************************************************************************************
-
-   //**Access functions****************************************************************************
-   /*!\name Access functions */
-   //@{
-   inline ReferenceType      operator[]( SizeType index );
-   inline ConstReferenceType operator[]( SizeType index ) const;
-   inline ReferenceType      front();
-   inline ConstReferenceType front() const;
-   inline ReferenceType      back();
-   inline ConstReferenceType back()  const;
-   //@}
-   //**********************************************************************************************
-
-   //**Iterator functions**************************************************************************
-   /*!\name Iterator functions */
-   //@{
-                          inline Iterator             begin();
-                          inline ConstIterator        begin() const;
-   template< typename C > inline CastIterator<C>      begin();
-   template< typename C > inline ConstCastIterator<C> begin() const;
-
-                          inline Iterator             end();
-                          inline ConstIterator        end()   const;
-   template< typename C > inline CastIterator<C>      end();
-   template< typename C > inline ConstCastIterator<C> end()   const;
-   //@}
-   //**********************************************************************************************
-
-   //**Element functions***************************************************************************
-   /*!\name Element functions */
-   //@{
-   inline void     pushBack   ( PointerType p );
-   inline void     popBack    ();
-   inline void     releaseBack();
-
-   template< typename IteratorType >
-   inline void     assign( IteratorType first, IteratorType last );
-
-   inline Iterator insert( Iterator pos, PointerType p );
-
-   template< typename IteratorType >
-   inline void     insert( Iterator pos, IteratorType first, IteratorType last );
-
-   /*! \cond internal */
-   template< typename IteratorType >
-   inline void     insert( Iterator pos, IteratorType* first, IteratorType* last );
-   /*! \endcond */
-
-                          inline Iterator        erase  ( Iterator pos );
-   template< typename C > inline CastIterator<C> erase  ( CastIterator<C> pos );
-                          inline Iterator        release( Iterator pos );
-   template< typename C > inline CastIterator<C> release( CastIterator<C> pos );
-                          inline void            clear  ();
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-          void reserve( SizeType newCapacity );
-   inline void swap( PtrVector& pv ) /* throw() */;
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Helper functions****************************************************************************
-   /*!\name Helper functions */
-   //@{
-   inline size_t calcCapacity ( size_t minCapacity ) const;
-   inline void   deleteElement( PointerType ptr )    const;
-   //@}
-   //**********************************************************************************************
-
-   //**Insertion helper functions******************************************************************
-   /*!\name Insertion helper functions */
-   //@{
-          void insert( T**const pos, PointerType p );
-
-   /*! \cond internal */
-   template< typename IteratorType >
-   inline void insert( Iterator pos, IteratorType first, IteratorType last, std::input_iterator_tag );
-
-   template< typename IteratorType >
-   inline void insert( Iterator pos, IteratorType first, IteratorType last, std::random_access_iterator_tag );
-   /*! \endcond */
-
-   template< typename IteratorType >
-          void insert( T** pos, IteratorType first, IteratorType last, SizeType n );
-   //@}
-   //**********************************************************************************************
-
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   SizeType size_;       //!< The current size of the pointer vector.
-   SizeType capacity_;   //!< The capacity of the pointer vector.
-   PointerType* begin_;  //!< Pointer to the first element of the pointer vector.
-   PointerType* end_;    //!< Pointer to the last element of the pointer vector.
-   //@}
-   //**********************************************************************************************
-
-public:
-   //**CastIterator/ConstCastIterator comparison operators*****************************************
-   // The following comparison operators cannot be defined as namespace or member functions
-   // but have to be injected into the surrounding scope via the Barton-Nackman trick since
-   // the template arguments of nested templates cannot be deduced (C++ standard 14.8.2.4/4).
-   /*!\name CastIterator/ConstCastIterator comparison operators */
-   //@{
-
-   //**********************************************************************************************
-   /*!\brief Equality comparison between two CastIterator objects.
-   //
-   // \param lhs The left hand side cast iterator.
-   // \param rhs The right hand side cast iterator.
-   // \return \a true if the iterators point to the same element, \a false if not.
-   */
-   template< typename L, typename R >
-   friend inline bool operator==( const CastIterator<L>& lhs, const CastIterator<R>& rhs )
-   {
-      return lhs.base() == rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Equality comparison between a CastIterator and a ConstCastIterator.
-   //
-   // \param lhs The left hand side cast iterator.
-   // \param rhs The right hand side constant cast iterator.
-   // \return \a true if the iterators point to the same element, \a false if not.
-   */
-   template< typename L, typename R >
-   friend inline bool operator==( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
-   {
-      return lhs.base() == rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Equality comparison between a ConstCastIterator and a CastIterator.
-   //
-   // \param lhs The left hand side constant cast iterator.
-   // \param rhs The right hand side cast iterator.
-   // \return \a true if the iterators point to the same element, \a false if not.
-   */
-   template< typename L, typename R >
-   friend inline bool operator==( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs )
-   {
-      return lhs.base() == rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Equality comparison between two ConstCastIterator objects.
-   //
-   // \param lhs The left hand side constant cast iterator.
-   // \param rhs The right hand side constant cast iterator.
-   // \return \a true if the iterators point to the same element, \a false if not.
-   */
-   template< typename L, typename R >
-   friend inline bool operator==( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
-   {
-      return lhs.base() == rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Inequality comparison between two CastIterator objects.
-   //
-   // \param lhs The left hand side cast iterator.
-   // \param rhs The right hand side cast iterator.
-   // \return \a true if the iterators don't point to the same element, \a false if they do.
-   */
-   template< typename L, typename R >
-   friend inline bool operator!=( const CastIterator<L>& lhs, const CastIterator<R>& rhs )
-   {
-      return lhs.base() != rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Inequality comparison between a CastIterator and a ConstCastIterator.
-   //
-   // \param lhs The left hand side cast iterator.
-   // \param rhs The right hand side constant cast iterator.
-   // \return \a true if the iterators don't point to the same element, \a false if they do.
-   */
-   template< typename L, typename R >
-   friend inline bool operator!=( const CastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
-   {
-      return lhs.base() != rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Inequality comparison between a ConstCastIterator and a CastIterator.
-   //
-   // \param lhs The left hand side constant cast iterator.
-   // \param rhs The right hand side cast iterator.
-   // \return \a true if the iterators don't point to the same element, \a false if they do.
-   */
-   template< typename L, typename R >
-   friend inline bool operator!=( const ConstCastIterator<L>& lhs, const CastIterator<R>& rhs )
-   {
-      return lhs.base() != rhs.base();
-   }
-   //**********************************************************************************************
-
-   //**********************************************************************************************
-   /*!\brief Inequality comparison between two ConstCastIterator objects.
-   //
-   // \param lhs The left hand side constant cast iterator.
-   // \param rhs The right hand side constant cast iterator.
-   // \return \a true if the iterators don't point to the same element, \a false if they do.
-   */
-   template< typename L, typename R >
-   friend inline bool operator!=( const ConstCastIterator<L>& lhs, const ConstCastIterator<R>& rhs )
-   {
-      return lhs.base() != rhs.base();
-   }
-   //**********************************************************************************************
-
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Standard constructor for PtrVector.
- *
- * \param initCapacity The initial capacity of the pointer vector.
- *
- * The default initial capacity of the pointer vector is specified by the selected growth policy.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline PtrVector<T,D,G>::PtrVector( SizeType initCapacity )
-   : size_( 0 )                               // Current size of the pointer vector
-   , capacity_( initCapacity )                // Capacity of the pointer vector
-   , begin_( new PointerType[initCapacity] )  // Pointer to the first element
-   , end_( begin_ )                           // Pointer to the last element
-{}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Copy constructor for PtrVector.
- *
- * \param pv The pointer vector to be copied.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline PtrVector<T,D,G>::PtrVector( const PtrVector& pv )
-   : size_( pv.size_ )                     // Current size of the pointer vector
-   , capacity_( pv.size_ )                 // Capacity of the pointer vector
-   , begin_( new PointerType[capacity_] )  // Pointer to the first element
-   , end_( begin_+size_ )                  // Pointer to the last element
-{
-   for( SizeType i=0; i<size_; ++i )
-      begin_[i] = pv.begin_[i];
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion constructor from different PtrVector instances.
- *
- * \param pv The pointer vector to be copied.
- */
-template< typename T     // Type of the pointer vector
-        , typename D     // Deletion policy of the pointer vector
-        , typename G >   // Growth policy of the pointer vector
-template< typename T2    // Type of the foreign pointer vector
-        , typename D2    // Deletion policy of the foreign pointer vector
-        , typename G2 >  // Growth policy of the foreign pointer vector
-inline PtrVector<T,D,G>::PtrVector( const PtrVector<T2,D2,G2>& pv )
-   : size_( pv.size_ )                     // Current size of the pointer vector
-   , capacity_( pv.size_ )                 // Capacity of the pointer vector
-   , begin_( new PointerType[capacity_] )  // Pointer to the first element
-   , end_( begin_+size_ )                  // Pointer to the last element
-{
-   for( SizeType i=0; i<size_; ++i )
-      begin_[i] = pv.begin_[i];
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  DESTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Destructor for PtrVector.
- *
- * In the destructor, the selected deletion policy is applied to all elements of the pointer
- * vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline PtrVector<T,D,G>::~PtrVector()
-{
-   for( PointerType* it=begin_; it!=end_; ++it )
-      deleteElement( *it );
-   delete [] begin_;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ASSIGNMENT OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Copy assignment operator for PtrVector.
- *
- * \param pv The pointer vector to be copied.
- * \return Reference to the assigned pointer vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-PtrVector<T,D,G>& PtrVector<T,D,G>::operator=( const PtrVector& pv )
-{
-   if( &pv == this ) return *this;
-
-   if( pv.size_ > capacity_ ) {
-      PointerType* newBegin( new PointerType[pv.size_] );
-      end_ = std::copy( pv.begin_, pv.end_, newBegin );
-      std::swap( begin_, newBegin );
-      delete [] newBegin;
-
-      size_ = pv.size_;
-      capacity_ = pv.size_;
-   }
-   else {
-      end_ = std::copy( pv.begin_, pv.end_, begin_ );
-      size_ = pv.size_;
-   }
-
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Assignment operator for different PtrVector instances.
- *
- * \param pv The pointer vector to be copied.
- * \return Reference to the assigned pointer vector.
- */
-template< typename T     // Type of the pointer vector
-        , typename D     // Deletion policy of the pointer vector
-        , typename G >   // Growth policy of the pointer vector
-template< typename T2    // Type of the foreign pointer vector
-        , typename D2    // Deletion policy of the foreign pointer vector
-        , typename G2 >  // Growth policy of the foreign pointer vector
-PtrVector<T,D,G>& PtrVector<T,D,G>::operator=( const PtrVector<T2,D2,G2>& pv )
-{
-   if( pv.size_ > capacity_ ) {
-      PointerType* newBegin( new PointerType[pv.size_] );
-      end_ = std::copy( pv.begin_, pv.end_, newBegin );
-      std::swap( begin_, newBegin );
-      delete [] newBegin;
-
-      size_ = pv.size_;
-      capacity_ = pv.size_;
-   }
-   else {
-      end_ = std::copy( pv.begin_, pv.end_, begin_ );
-      size_ = pv.size_;
-   }
-
-   return *this;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  GET FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns the maximum possible size of a pointer vector.
- *
- * \return The maximum possible size.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::maxSize() const
-{
-   return SizeType(-1) / sizeof(PointerType);
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the current size of the pointer vector.
- *
- * \return The current size.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::size() const
-{
-   return size_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the total number of objects of type \a C contained in the pointer vector.
- *
- * \return The total number of objects of type \a C.
- *
- * This function calculates the total number of objects of type \a C within the pointer vector,
- * where \a C is a type derived from the type \a T of objects contained in the pointer vector.
- * The attempt to use this function for types that are not derived from \a T results in a
- * compile time error.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of a pointer vector for class A
-   typedef PtrVector<A> AVector;
-   AVector vector;
-
-   AVector::SizeType total = vector.size();     // Calculating the total number of pointers
-   AVector::SizeType numB  = vector.size<B>();  // Calculating the total number of B objects
-   \endcode
-
- * \b Note: The total number of objects of type \a C is not cached inside the pointer vector
- * but is calculated each time the function is called. Using the templated version of size()
- * to calculate the total number objects of type \a C is therefore more expensive than using
- * the non-template version of size() to get the total number of pointers in the vector!
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::size() const
-{
-   // The polymorphicCount() function returns the number of objects with dynamic type 'C'
-   // contained in the range [begin,end). An equivalent code might look like this:
-   //
-   // SizeType count( 0 );
-   // for( PointerType* it=begin_; it!=end_; ++it )
-   //    if( dynamic_cast<C*>( *it ) ) ++count;
-   // return count;
-   //
-   // However, the specialization of polymorphicCount() for special type combinations is
-   // much more efficient (and easier) than the specialization of this function!
-   return polymorphicCount<C>( begin_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the capacity of the pointer vector.
- *
- * \return The capacity.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::SizeType PtrVector<T,D,G>::capacity() const
-{
-   return capacity_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns \a true if the pointer vector has no elements.
- *
- * \return \a true if the pointer vector is empty, \a false if it is not.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline bool PtrVector<T,D,G>::isEmpty() const
-{
-   return size_ == 0;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ACCESS FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Subscript operator for the direct access to the pointer vector elements.
- *
- * \param index Access index. The index has to be in the range \f$[0..size-1]\f$.
- * \return Handle to the accessed element.
- *
- * \b Note: No runtime check is performed to insure the validity of the access index.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::operator[]( SizeType index )
-{
-   return *(begin_+index);
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Subscript operator for the direct access to the pointer vector elements.
- *
- * \param index Access index. The index has to be in the range \f$[0..size-1]\f$.
- * \return Handle to the accessed element.
- *
- * \b Note: No runtime check is performed to insure the validity of the access index.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::operator[]( SizeType index ) const
-{
-   return *(begin_+index);
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a reference to the first element of the pointer vector.
- *
- * \return Handle to the first element.
- *
- * \b Note: No runtime check is performed if the first element exists!
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::front()
-{
-   WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" );
-   return *begin_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a reference to the first element of the pointer vector.
- *
- * \return Handle to the first element.
- *
- * \b Note: No runtime check is performed if the first element exists!
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::front() const
-{
-   WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the front element" );
-   return *begin_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a reference to the last element of the pointer vector.
- *
- * \return Handle to the last element.
- *
- * \b Note: No runtime check is performed if the last element exists!
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ReferenceType PtrVector<T,D,G>::back()
-{
-   WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" );
-   return *(end_-1);
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a reference to the last element of the pointer vector.
- *
- * \return Handle to the last element.
- *
- * \b Note: No runtime check is performed if the last element exists!
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ConstReferenceType PtrVector<T,D,G>::back() const
-{
-   WALBERLA_ASSERT( size_ > 0, "Pointer vector is empty, invalid access to the back element" );
-   return *(end_-1);
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ITERATOR FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the beginning of the pointer vector.
- *
- * \return Iterator to the beginning of the pointer vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::begin()
-{
-   return Iterator( begin_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the beginning of the pointer vector.
- *
- * \return Iterator to the beginning of the pointer vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ConstIterator PtrVector<T,D,G>::begin() const
-{
-   return ConstIterator( begin_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first element of type \a C within the pointer vector.
- *
- * \return Iterator to the first element of type \a C.
- *
- * This function returns an iterator to the first element of type \a C within in the pointer
- * vector, where \a C is a type derived from the type \a T of objects contained in the pointer
- * vector. In case there is no element of type \a C contained in the vector, an iterator just
- * past the last element of the pointer vector is returned. In combination with the according
- * end function (see example), this iterator allows to iterate over all objects of type \a C
- * in the range of the pointer vector. The attempt to use this function for types that are not
- * derived from \a T results in a compile time error.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of function f for non-const pointer vectors
-   void f( PtrVector<A>& vector )
-   {
-      PtrVector<A>::CastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::CastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-         ...
-   }
-
-   // Definition of function f for const pointer vectors
-   void f( const PtrVector<A>& vector )
-   {
-      PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::ConstCastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-   }
-   \endcode
-
- * \b Note: Using the templated versions of begin() and end() to traverse all elements of type
- * \a C in the element range of the pointer vector is more expensive than using the non-template
- * versions to traverse the entire range of elements. Use this function only if you require a
- * type-specific member of type \a C.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> PtrVector<T,D,G>::begin()
-{
-   return CastIterator<C>( begin_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first element of type \a C within the pointer vector.
- *
- * \return Iterator to the first element of type \a C.
- *
- * This function returns an iterator to the first element of type \a C within in the pointer
- * vector, where \a C is a type derived from the type \a T of objects contained in the pointer
- * vector. In case there is no element of type \a C contained in the vector, an iterator just
- * past the last element of the pointer vector is returned. In combination with the according
- * end function (see example), this iterator allows to iterate over all objects of type \a C
- * in the range of the pointer vector. The attempt to use this function for types that are not
- * derived from \a T results in a compile time error.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of function f for non-const pointer vectors
-   void f( PtrVector<A>& vector )
-   {
-      PtrVector<A>::CastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::CastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-         ...
-   }
-
-   // Definition of function f for const pointer vectors
-   void f( const PtrVector<A>& vector )
-   {
-      PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::ConstCastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-   }
-   \endcode
-
- * \b Note: Using the templated versions of begin() and end() to traverse all elements of type
- * \a C in the element range of the pointer vector is more expensive than using the non-template
- * version to traverse the entire range of elements. Use this function only if you require a
- * type-specific member of type \a C.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::begin() const
-{
-   return ConstCastIterator<C>( begin_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last element of the pointer vector.
- *
- * \return Iterator just past the last element of the pointer vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::end()
-{
-   return Iterator( end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last element of the pointer vector.
- *
- * \return Iterator just past the last element of the pointer vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::ConstIterator PtrVector<T,D,G>::end() const
-{
-   return ConstIterator( end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last element of the pointer vector.
- *
- * \return Iterator just past the last element of the pointer vector.
- *
- * This function returns an iterator just past the last element of the pointer vector. In
- * combination with the according begin function (see example), this iterator allows to iterate
- * over all objects of type \a C in the range of the pointer vector. The attempt to use this
- * function for types that are not derived from \a T results in a compile time error.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of function f for non-const pointer vectors
-   void f( PtrVector<A>& vector )
-   {
-      PtrVector<A>::CastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::CastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-         ...
-   }
-
-   // Definition of function f for const pointer vectors
-   void f( const PtrVector<A>& vector )
-   {
-      PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::ConstCastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-   }
-   \endcode
-
- * \b Note: Using the templated versions of begin() and end() to traverse all elements of type
- * \a C in the element range of the pointer vector is more expensive than using the non-template
- * versions to traverse the entire range of elements. Use this function only if you require a
- * type-specific member of type \a C.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C> PtrVector<T,D,G>::end()
-{
-   return CastIterator<C>( end_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last element of the pointer vector.
- *
- * \return Iterator just past the last element of the pointer vector.
- *
- * This function returns an iterator just past the last element of the pointer vector. In
- * combination with the according begin function (see example), this iterator allows to iterate
- * over all objects of type \a C in the range of the pointer vector. The attempt to use this
- * function for types that are not derived from \a T results in a compile time error.
-
-   \code
-   // Definition of class A and the derived type B
-   class A { ... };
-   class B : public A { ... };
-
-   // Definition of function f for non-const pointer vectors
-   void f( PtrVector<A>& vector )
-   {
-      PtrVector<A>::CastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::CastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-         ...
-   }
-
-   // Definition of function f for const pointer vectors
-   void f( const PtrVector<A>& vector )
-   {
-      PtrVector<A>::ConstCastIterator<B> begin = vector.begin<B>();
-      PtrVector<A>::ConstCastIterator<B> end   = vector.end<B>();
-
-      // Loop over all objects of type B contained in the vector
-      for( ; begin!=end; ++begin )
-   }
-   \endcode
-
- * \b Note: Using the templated versions of begin() and end() to traverse all elements of type
- * \a C in the element range of the pointer vector is more expensive than using the non-template
- * version to traverse the entire range of elements. Use this function only if you require a
- * type-specific member of type \a C.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C> PtrVector<T,D,G>::end() const
-{
-   return ConstCastIterator<C>( end_, end_ );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ELEMENT FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Adding an element to the end of the pointer vector.
- *
- * \param p The pointer to be added to the end of the pointer vector.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * The pushBack function runs in constant time.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::pushBack( PointerType p )
-{
-   if( size_ != capacity_ ) {
-      *end_ = p;
-      ++end_;
-      ++size_;
-   }
-   else {
-      insert( end_, p );
-   }
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Removing an element from the end of the pointer vector.
- *
- * \return void
- *
- * This function removes the element at the end of the pointer vector, i.e. the element
- * is deleted according to the deletion policy and removed from the vector. Note that in
- * case the deletion policy is NoDelete, this function is identical to the releaseBack()
- * function.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::popBack()
-{
-   deleteElement( *--end_ );
-   --size_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Releasing the element at the end of the pointer vector.
- *
- * \return void
- *
- * This function releases the element at the end of the pointer vector, i.e. the element is
- * removed without applying the deletion policy. Therefore the responsibility to delete the
- * element is passed to the function caller. Note that in case the deletion policy is NoDelete,
- * this function is identical to the popBack() function.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::releaseBack()
-{
-   --end_;
-   --size_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Assigning a range of elements to the pointer vector.
- *
- * \param first Iterator to the first element of the element range.
- * \param last Iterator to the element one past the last element of the element range.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * This functions assigns the elements in the range \f$ [first,last) \f$ to the pointer vector.
- * All elements previously contained in the pointer vector are removed. The assign function runs
- * in linear time.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-inline void PtrVector<T,D,G>::assign( IteratorType first, IteratorType last )
-{
-   clear();
-   insert( end(), first, last );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inserting an element into the pointer vector.
- *
- * \param pos The position before which the element is inserted.
- * \param p The pointer to be inserted into the pointer vector.
- * \return Iterator to the inserted element.
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * The insert function runs in linear time. Note however that inserting elements into a pointer
- * vector can be a relatively time-intensive operation.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::insert( Iterator pos, PointerType p )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   const auto diff( base - begin_ );
-
-   if( size_ != capacity_ && base == end_ ) {
-      *end_ = p;
-      ++end_;
-      ++size_;
-   }
-   else {
-      insert( base, p );
-   }
-
-   return Iterator( begin_+diff );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inserting a range of elements into the pointer vector.
- *
- * \param pos The position before which the elements are inserted.
- * \param first Iterator to the first element of the element range.
- * \param last Iterator to the element one past the last element of the element range.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector.
- * The insert function runs in linear time. Note however that inserting elements into a pointer
- * vector can be a relatively time-intensive operation.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last )
-{
-   insert( pos, first, last, typename IteratorType::iterator_category() );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Inserting a range of elements into the pointer vector.
- *
- * \param pos The position before which the elements are inserted.
- * \param first Pointer to the first element of the element range.
- * \param last Pointer to the element one past the last element of the element range.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector.
- * The insert function runs in linear time. Note however that inserting elements into a pointer
- * vector can be a relatively time-intensive operation.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType* first, IteratorType* last )
-{
-   insert( pos, first, last, std::random_access_iterator_tag() );
-}
-/*! \endcond */
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Removing an element from the pointer vector.
- *
- * \param pos The position of the element to be removed.
- * \return Iterator to the element after the erased element.
- *
- * This function erases an element from the pointer vector, i.e. the element is deleted
- * according to the deletion policy of the pointer vector and removed from the vector.
- * Note that in case the deletion policy is NoDelete, this function is identical to the
- * release() function.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::erase( Iterator pos )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   deleteElement( *base );
-   std::copy( base+1, end_, base );
-
-   --size_;
-   --end_;
-
-   return pos;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Removing an element from the pointer vector.
- *
- * \param pos The position of the element to be removed.
- * \return Iterator to the element after the erased element.
- *
- * This function erases an element from the pointer vector, i.e. the element is deleted
- * according to the deletion policy of the pointer vector and removed from the vector.
- * Note that in case the deletion policy is NoDelete, this function is identical to the
- * release() function.
- *
- * Note: The cast iterator \a pos is not invalidated but every other cast iterators including those
- * returned by end<C>() are.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>
-   PtrVector<T,D,G>::erase( CastIterator<C> pos )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   deleteElement( *base );
-   std::copy( base+1, end_, base );
-
-   --size_;
-   --end_;
-
-   return CastIterator<C>( base, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Releasing an element from the pointer vector.
- *
- * \param pos The position of the element to be released.
- * \return Iterator to the element after the released element.
- *
- * This function releases an element from the pointer vector, i.e. the element is removed
- * without applying the deletion policy. Therefore the responsibility to delete the element
- * is passed to the function caller.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline typename PtrVector<T,D,G>::Iterator PtrVector<T,D,G>::release( Iterator pos )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   std::copy( base+1, end_, base );
-
-   --size_;
-   --end_;
-
-   return pos;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Releasing an element from the pointer vector.
- *
- * \param pos The position of the element to be released.
- * \return Iterator to the element after the released element.
- *
- * This function releases an element from the pointer vector, i.e. the element is removed
- * without applying the deletion policy. Therefore the responsibility to delete the element
- * is passed to the function caller.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>
-   PtrVector<T,D,G>::release( CastIterator<C> pos )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   std::copy( base+1, end_, base );
-
-   --size_;
-   --end_;
-
-   return CastIterator<C>( base, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Removing all elements from the pointer vector.
- *
- * \return void
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::clear()
-{
-   for( PointerType* it=begin_; it!=end_; ++it )
-      deleteElement( *it );
-
-   end_  = begin_;
-   size_ = 0;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Setting the minimum capacity of the pointer vector.
- *
- * \param newCapacity The new minimum capacity of the pointer vector.
- * \return void
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-void PtrVector<T,D,G>::reserve( SizeType newCapacity )
-{
-   if( newCapacity > capacity_ )
-   {
-      // Calculating the new capacity
-      newCapacity = calcCapacity( newCapacity );
-
-      // Allocating a new array
-      PointerType* tmp = new PointerType[newCapacity];
-
-      // Replacing the old array
-      std::copy( begin_, end_, tmp );
-      std::swap( tmp, begin_ );
-      capacity_ = newCapacity;
-      end_ = begin_ + size_;
-      delete [] tmp;
-   }
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Swapping the contents of two pointer vectors.
- *
- * \param pv The pointer vector to be swapped.
- * \return void
- * \exception no-throw guarantee.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::swap( PtrVector& pv ) /* throw() */
-{
-   // By using the 'std::swap' function to swap all member variables,
-   // the function can give the nothrow guarantee.
-   std::swap( size_, pv.size_ );
-   std::swap( capacity_, pv.capacity_ );
-   std::swap( begin_, pv.begin_ );
-   std::swap( end_, pv.end_ );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  HELPER FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Calculating the new capacity of the vector based on its growth policy.
- *
- * \param minCapacity The minimum necessary capacity.
- * \return The new capacity.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline size_t PtrVector<T,D,G>::calcCapacity( size_t minCapacity ) const
-{
-   WALBERLA_ASSERT( minCapacity > capacity_, "Invalid new vector capacity" );
-   const size_t newCapacity( GrowthPolicy()( capacity_, minCapacity ) );
-   WALBERLA_ASSERT( newCapacity > capacity_, "Invalid new vector capacity" );
-   return newCapacity;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Deleting an element of the pointer vector according to the deletion policy.
- *
- * \param ptr The element to be deleted.
- * \return void
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void PtrVector<T,D,G>::deleteElement( PointerType ptr ) const
-{
-   DeletionPolicy()( ptr );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  INSERTION HELPER FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Inserting an element into the pointer vector.
- *
- * \param pos The position before which the element is inserted.
- * \param p The pointer to be inserted into the pointer vector.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-void PtrVector<T,D,G>::insert( T**const pos, PointerType p )
-{
-   if( size_ != capacity_ ) {
-      std::copy_backward( pos, end_, end_+1 );
-      *pos = p;
-      ++end_;
-      ++size_;
-   }
-   else if( size_ == maxSize() ) {
-      throw std::length_error( "Maximum pointer vector length exceeded!" );
-   }
-   else {
-      SizeType newCapacity( calcCapacity( capacity_+1 ) );
-      if( newCapacity > maxSize() || newCapacity < capacity_ ) newCapacity = maxSize();
-
-      PointerType* newBegin = new PointerType[newCapacity];
-      PointerType* newEnd = std::copy( begin_, pos, newBegin );
-      *newEnd = p;
-      ++newEnd;
-      end_ = std::copy( pos, end_, newEnd );
-
-      std::swap( newBegin, begin_ );
-      delete [] newBegin;
-      capacity_ = newCapacity;
-      ++size_;
-   }
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Inserting a range of elements into the pointer vector.
- *
- * \param pos The position before which the elements are inserted.
- * \param first Iterator to the first element of the element range.
- * \param last Iterator to the element one past the last element of the element range.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector.
- * The iterators are treated as input iterators.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last,
-                                      std::input_iterator_tag )
-{
-   for( ; first!=last; ++first ) {
-      pos = insert( pos, *first );
-      ++pos;
-   }
-}
-/*! \endcond */
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Inserting a range of elements into the pointer vector.
- *
- * \param pos The position before which the elements are inserted.
- * \param first Iterator to the first element of the element range.
- * \param last Iterator to the element one past the last element of the element range.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- *
- * This functions inserts the elements in the range \f$ [first,last) \f$ into the pointer vector.
- * The iterators are treated as random access iterators.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-inline void PtrVector<T,D,G>::insert( Iterator pos, IteratorType first, IteratorType last,
-                                      std::random_access_iterator_tag )
-{
-   T** const base = const_cast<T**>( pos.base() );
-   const SizeType diff( last - first );
-
-   if( size_+diff <= capacity_ && base == end_ ) {
-      for( ; first!=last; ++first, ++end_ ) {
-         *end_ = *first;
-      }
-      size_ += diff;
-   }
-   else {
-      insert( base, first, last, diff );
-   }
-}
-/*! \endcond */
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inserting a range of elements into the pointer vector.
- *
- * \param pos The position before which the elements are inserted.
- * \param first Iterator to the first element of the element range.
- * \param last Iterator to the element one past the last element of the element range.
- * \param n The number of elements to be inserted.
- * \return void
- * \exception std::length_error Maximum pointer vector length exceeded.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename IteratorType >
-void PtrVector<T,D,G>::insert( T** pos, IteratorType first, IteratorType last, SizeType n )
-{
-   const SizeType newSize( size_ + n );
-
-   if( newSize <= capacity_ ) {
-      std::copy_backward( pos, end_, end_+n );
-      for( ; first!=last; ++first, ++pos ) {
-         *pos = *first;
-      }
-      end_ += n;
-      size_ = newSize;
-   }
-   else if( newSize > maxSize() || newSize < size_ ) {
-      throw std::length_error( "Maximum pointer vector length exceeded!" );
-   }
-   else {
-      PointerType* newBegin = new PointerType[newSize];
-      PointerType* newEnd = std::copy( begin_, pos, newBegin );
-
-      for( ; first!=last; ++first, ++newEnd ) {
-         *newEnd = *first;
-      }
-
-      end_ = std::copy( pos, end_, newEnd );
-
-      std::swap( newBegin, begin_ );
-      delete [] newBegin;
-      capacity_ = newSize;
-      size_ = newSize;
-   }
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  GLOBAL OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name PtrVector operators */
-//@{
-template< typename T, typename D, typename G >
-inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs );
-
-template< typename T, typename D, typename G >
-inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs );
-
-template< typename T, typename D, typename G >
-inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */;
-//@}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Equality comparison between two pointer vectors.
- *
- * \param lhs The left hand side pointer vector.
- * \param rhs The right hand side pointer vector.
- * \return \a true if the two pointer vectors are equal, \a false if they are not.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline bool operator==( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs )
-{
-   return lhs.size() == rhs.size() && std::equal( lhs.begin(), lhs.end(), rhs.begin() );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Inequality comparison between two pointer vectors.
- *
- * \param lhs The left hand side pointer vector.
- * \param rhs The right hand side pointer vector.
- * \return \a true if the two pointer vectors are inequal, \a false if they are not.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline bool operator!=( const PtrVector<T,D,G>& lhs, const PtrVector<T,D,G>& rhs )
-{
-   return lhs.size() != rhs.size() || !std::equal( lhs.begin(), lhs.end(), rhs.begin() );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Swapping the contents of two pointer vectors.
- *
- * \param a The first pointer vector to be swapped.
- * \param b The second pointer vector to be swapped.
- * \return void
- * \exception no-throw guarantee.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-inline void swap( PtrVector<T,D,G>& a, PtrVector<T,D,G>& b ) /* throw() */
-{
-   a.swap( b );
-}
-//*************************************************************************************************
-
-
-
-
-
-
-
-
-//=================================================================================================
-//
-//  NESTED CLASS PTRVECTOR::CASTITERATOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Dynamic cast iterator for polymorphic pointer vectors.
- * \ingroup util
- *
- * The CastIterator class is part of the PtrVector class and represent a forward iterator
- * over all elements of type \a C contained in a range of elements of type \a T, where \a C
- * is a type derived from \a T.
-
-   \code
-   class A { ... };
-   class B : public class A { ... };
-
-   PtrVector<A>::CastIterator<B> begin;
-   PtrVector<A>::CastIterator<B> end;
-
-   // Loop over all elements of type B within the range [begin..end)
-   for( ; begin!=end; ++begin )
-      ...
-   \endcode
-
- * \b Note: Using a CastIterator is computationally more expensive than using a standard
- * iterator over all elements contained in the vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-class PtrVector<T,D,G>::CastIterator
-{
-public:
-   //**Type definitions****************************************************************************
-   // pe naming convention
-   typedef std::forward_iterator_tag  IteratorCategory;   //!< The iterator category.
-   typedef C*                         ValueType;          //!< Type of the underlying pointers.
-   typedef C*                         PointerType;        //!< Pointer return type.
-   typedef C* const&                  ReferenceType;      //!< Reference return type.
-   typedef ptrdiff_t                  DifferenceType;     //!< Difference between two iterators.
-   typedef T* const*                  IteratorType;       //!< Type of the internal pointer.
-
-   // STL iterator requirements
-   typedef IteratorCategory           iterator_category;  //!< The iterator category.
-   typedef ValueType                  value_type;         //!< Type of the underlying pointers.
-   typedef PointerType                pointer;            //!< Pointer return type.
-   typedef ReferenceType              reference;          //!< Reference return type.
-   typedef DifferenceType             difference_type;    //!< Difference between two iterators.
-   //**********************************************************************************************
-
-   //**Constructors********************************************************************************
-   /*!\name Constructors */
-   //@{
-   inline CastIterator();
-   inline CastIterator( IteratorType begin, IteratorType end );
-
-   template< typename Other >
-   inline CastIterator( const CastIterator<Other>& it );
-
-   // No explicitly declared copy constructor.
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   // No explicitly declared destructor.
-   //**********************************************************************************************
-
-   //**Copy assignment operator********************************************************************
-   // No explicitly declared copy assignment operator.
-   //**********************************************************************************************
-
-   //**Operators***********************************************************************************
-   /*!\name Operators */
-   //@{
-   inline CastIterator& operator++();
-   inline CastIterator  operator++( int );
-   //@}
-   //**********************************************************************************************
-
-   //**Access operators****************************************************************************
-   /*!\name Access operators */
-   //@{
-   inline PointerType operator*()  const;
-   inline PointerType operator->() const;
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline const IteratorType& base() const;
-   inline const IteratorType& stop() const;
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   IteratorType cur_;  //!< Pointer to the current memory location.
-   IteratorType end_;  //!< Pointer to the element one past the last element in the element range.
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Default constructor for CastIterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline PtrVector<T,D,G>::CastIterator<C>::CastIterator()
-   : cur_(NULL)  // Pointer to the current memory location
-   , end_(NULL)  // Pointer to the element one past the last element in the element range
-{
-   static_assert(boost::is_base_of<T, C>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Standard constructor for CastIterator.
- *
- * \param begin The beginning of the element range.
- * \param end The end of the element range.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline PtrVector<T,D,G>::CastIterator<C>::CastIterator( IteratorType begin, IteratorType end )
-   : cur_(begin)  // Pointer to the current memory location
-   , end_(end)    // Pointer to the element one past the last element in the element range
-{
-   static_assert(boost::is_base_of<T, C>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_,end). An equivalent code might look like this:
-   //
-   // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_;
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<C>( cur_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion constructor from different CastIterator instances.
- *
- * \param it The foreign CastIterator instance to be copied.
- */
-template< typename T        // Type
-        , typename D        // Deletion policy
-        , typename G >      // Growth policy
-template< typename C >      // Cast type
-template< typename Other >  // The foreign cast iterator type
-inline PtrVector<T,D,G>::CastIterator<C>::CastIterator( const CastIterator<Other>& it )
-   : cur_( it.base() )  // Pointer to the current memory location
-   , end_( it.stop() )  // Pointer to the element one past the last element in the element range
-{
-   static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-   static_assert(boost::is_convertible<Other*, C*>::value,  "Other must be convertible to C" );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Pre-increment operator.
- *
- * \return Reference to the incremented cast iterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>&
-   PtrVector<T,D,G>::CastIterator<C>::operator++()
-{
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_+1,end). An equivalent code might look like this:
-   //
-   // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {}
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<C>( ++cur_, end_ );
-
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Post-increment operator.
- *
- * \return The incremented cast iterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>
-   PtrVector<T,D,G>::CastIterator<C>::operator++( int )
-{
-   CastIterator tmp( *this );
-
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_+1,end). An equivalent code might look like this:
-   //
-   // while( ++cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) {}
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<C>( ++cur_, end_ );
-
-   return tmp;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ACCESS OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns a handle to the element at the current iterator position.
- *
- * \return Handle to the element at the current iterator position.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::PointerType
-   PtrVector<T,D,G>::CastIterator<C>::operator*() const
-{
-   return static_cast<C*>( *cur_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Direct access to the element at the current iterator position.
- *
- * \return Reference to the element at the current iterator position.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::PointerType
-   PtrVector<T,D,G>::CastIterator<C>::operator->() const
-{
-   return static_cast<C*>( *cur_ );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Direct access to the current memory location of the cast iterator.
- *
- * \return Pointer to the current memory location.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::IteratorType&
-   PtrVector<T,D,G>::CastIterator<C>::base() const
-{
-   return cur_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Direct access to the final memory location of the cast iterator.
- *
- * \return Pointer to the final memory location.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<C>::IteratorType&
-   PtrVector<T,D,G>::CastIterator<C>::stop() const
-{
-   return end_;
-}
-//*************************************************************************************************
-
-
-
-
-
-
-
-
-//=================================================================================================
-//
-//  NESTED CLASS PTRVECTOR::CONSTCASTITERATOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Dynamic cast iterator for polymorphic pointer vectors.
- * \ingroup util
- *
- * The ConstCastIterator class is part of the PtrVector class and represent a forward iterator
- * over all elements of type \a C contained in a range of elements of type \a T, where \a C
- * is a type derived from \a T. The ConstCastIterator is the counterpart of CastIterator for
- * constant vectors.
-
-   \code
-   class A { ... };
-   class B : public class A { ... };
-
-   PtrVector<A>::ConstCastIterator<B> begin;
-   PtrVector<A>::ConstCastIterator<B> end;
-
-   // Loop over all elements of type B within the range [begin..end)
-   for( ; begin!=end; ++begin )
-      ...
-   \endcode
-
- * \b Note: Using a ConstCastIterator is computationally more expensive than using a standard
- * iterator over all elements contained in the vector.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-class PtrVector<T,D,G>::ConstCastIterator
-{
-public:
-   //**Type definitions****************************************************************************
-   // pe naming convention
-   typedef std::forward_iterator_tag  IteratorCategory;   //!< The iterator category.
-   typedef const C*                   ValueType;          //!< Type of the underlying pointers.
-   typedef const C*                   PointerType;        //!< Pointer return type.
-   typedef const C* const&            ReferenceType;      //!< Reference return type.
-   typedef ptrdiff_t                  DifferenceType;     //!< Difference between two iterators.
-   typedef const T* const*            IteratorType;       //!< Type of the internal pointer.
-
-   // STL iterator requirements
-   typedef IteratorCategory           iterator_category;  //!< The iterator category.
-   typedef ValueType                  value_type;         //!< Type of the underlying pointers.
-   typedef PointerType                pointer;            //!< Pointer return type.
-   typedef ReferenceType              reference;          //!< Reference return type.
-   typedef DifferenceType             difference_type;    //!< Difference between two iterators.
-   //**********************************************************************************************
-
-   //**Constructors********************************************************************************
-   /*!\name Constructors */
-   //@{
-   inline ConstCastIterator();
-   inline ConstCastIterator( IteratorType begin, IteratorType end );
-
-   template< typename Other >
-   inline ConstCastIterator( const ConstCastIterator<Other>& it );
-
-   template< typename Other >
-   inline ConstCastIterator( const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<Other>& it );
-
-   // No explicitly declared copy constructor.
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   // No explicitly declared destructor.
-   //**********************************************************************************************
-
-   //**Copy assignment operator********************************************************************
-   // No explicitly declared copy assignment operator.
-   //**********************************************************************************************
-
-   //**Operators***********************************************************************************
-   /*!\name Operators */
-   //@{
-   inline ConstCastIterator& operator++();
-   inline ConstCastIterator  operator++( int );
-   //@}
-   //**********************************************************************************************
-
-   //**Access operators****************************************************************************
-   /*!\name Access operators */
-   //@{
-   inline PointerType operator*()  const;
-   inline PointerType operator->() const;
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline const IteratorType& base() const;
-   inline const IteratorType& stop() const;
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   IteratorType cur_;  //!< Pointer to the current memory location.
-   IteratorType end_;  //!< Pointer to the element one past the last element in the element range.
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Default constructor for ConstCastIterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator()
-   : cur_(NULL)  // Pointer to the current memory location
-   , end_(NULL)  // Pointer to the element one past the last element in the element range
-{
-   static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Standard constructor for ConstCastIterator.
- *
- * \param begin The beginning of the element range.
- * \param end The end of the element range.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( IteratorType begin, IteratorType end )
-   : cur_(begin)  // Pointer to the current memory location
-   , end_(end)    // Pointer to the element one past the last element in the element range
-{
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_,end). An equivalent code might look like this:
-   //
-   // while( cur_ != end_ && !dynamic_cast<C*>( *cur_ ) ) ++cur_;
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<C>( cur_, end_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion constructor from different ConstCastIterator instances.
- *
- * \param it The foreign ConstCastIterator instance to be copied.
- */
-template< typename T        // Type
-        , typename D        // Deletion policy
-        , typename G >      // Growth policy
-template< typename C >      // Cast type
-template< typename Other >  // The foreign constant cast iterator type
-inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( const ConstCastIterator<Other>& it )
-   : cur_( it.base() )  // Pointer to the current memory location
-   , end_( it.stop() )  // Pointer to the element one past the last element in the element range
-{
-    static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-    static_assert(boost::is_convertible<Other*, C*>::value,  "Other must be convertible to C" );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Conversion constructor from CastIterator instances.
- *
- * \param it The foreign CastIterator instance to be copied.
- */
-template< typename T        // Type
-        , typename D        // Deletion policy
-        , typename G >      // Growth policy
-template< typename C >      // Cast type
-template< typename Other >  // The foreign cast iterator type
-inline PtrVector<T,D,G>::ConstCastIterator<C>::ConstCastIterator( const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE CastIterator<Other>& it )
-   : cur_( it.base() )  // Pointer to the current memory location
-   , end_( it.stop() )  // Pointer to the element one past the last element in the element range
-{
-    static_assert(boost::is_base_of<C, T>::value && !boost::is_base_of<C, T>::value, "C has to be strictly derived from T");
-    static_assert(boost::is_convertible<Other*, C*>::value,  "Other must be convertible to C" );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Pre-increment operator.
- *
- * \return Reference to the incremented cast iterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>&
-   PtrVector<T,D,G>::ConstCastIterator<C>::operator++()
-{
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_+1,end). An equivalent code might look like this:
-   //
-   // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {}
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<const C>( ++cur_, end_ );
-
-   return *this;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Post-increment operator.
- *
- * \return The incremented cast iterator.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>
-   PtrVector<T,D,G>::ConstCastIterator<C>::operator++( int )
-{
-   ConstCastIterator tmp( *this );
-
-   // The polymorphicFind() function finds the next pointer to an object with dynamic type 'C'
-   // contained in the range [cur_+1,end). An equivalent code might look like this:
-   //
-   // while( ++cur_ != end_ && !dynamic_cast<const C*>( *cur_ ) ) {}
-   //
-   // However, the specialization of polymorphicFind() for special type combinations is much
-   // more efficient (and way easier!) than the specialization of this function!
-   cur_ = polymorphicFind<const C>( ++cur_, end_ );
-
-   return tmp;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ACCESS OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns a handle to the element at the current iterator position.
- *
- * \return Handle to the element at the current iterator position.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::PointerType
-   PtrVector<T,D,G>::ConstCastIterator<C>::operator*() const
-{
-   return static_cast<const C*>( *cur_ );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Direct access to the element at the current iterator position.
- *
- * \return Reference to the element at the current iterator position.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::PointerType
-   PtrVector<T,D,G>::ConstCastIterator<C>::operator->() const
-{
-   return static_cast<const C*>( *cur_ );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Direct access to the current memory location of the constant cast iterator.
- *
- * \return Pointer to the current memory location.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::IteratorType&
-   PtrVector<T,D,G>::ConstCastIterator<C>::base() const
-{
-   return cur_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Direct access to the final memory location of the constant cast iterator.
- *
- * \return Pointer to the final memory location.
- */
-template< typename T    // Type
-        , typename D    // Deletion policy
-        , typename G >  // Growth policy
-template< typename C >  // Cast type
-inline const typename PtrVector<T,D,G>::WALBERLA_TEMPLATE ConstCastIterator<C>::IteratorType&
-   PtrVector<T,D,G>::ConstCastIterator<C>::stop() const
-{
-   return end_;
-}
-//*************************************************************************************************
-}
diff --git a/src/core/ptrvector/policies/ArrayDelete.h b/src/core/ptrvector/policies/ArrayDelete.h
deleted file mode 100644
index bf6b605abc8d82a6612b9943aa596ba4fbb2bae6..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/ArrayDelete.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file ArrayDelete.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <boost/checked_delete.hpp>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Array-delete policy class.
- * \ingroup util
- *
- * The ArrayDelete policy functor class applies an array delete operation to the given argument.
- * Note that the array delete operation is NOT permitted for inclomplete types (i.e. declared
- * but undefined data types). The attempt to apply an ArrayDelete functor to a pointer to an
- * array of objects of incomplete type results in a compile time error!
- */
-struct ArrayDelete
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   template< typename Type >
-   inline void operator()( Type ptr ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Implementation of the array-delete policy.
- *
- * \param ptr The pointer to the array to be deleted.
- * \return void
- *
- * This function applies an array delete operation to the given argument. Note that the array
- * delete operation is NOT permitted for inclomplete types (i.e. declared but undefined data
- * types). The attempt to use this function for a pointer to an array of objects of incomplete
- * type results in a compile time error!
- */
-template< typename Type >
-inline void ArrayDelete::operator()( Type ptr ) const
-{
-   boost::checked_array_delete( ptr );
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/policies/ConstantGrowth.h b/src/core/ptrvector/policies/ConstantGrowth.h
deleted file mode 100644
index 2d20250ca78ac865eac5a1d362c35258f28ddaf2..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/ConstantGrowth.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file ConstantGrowth.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-#include <core/DataTypes.h>
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Constant growth policy class.
- * \ingroup util
- *
- * The ConstantGrowth policy class implements a constant growth strategy. It can be customized
- * for any purpose: the \a Growth template argument specifies the constant increase of the given
- * size.
- */
-template< size_t Growth >
-struct ConstantGrowth
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline size_t operator()( size_t oldSize, size_t minSize ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Specialization of the constant growth policy for 0 growth.
- * \ingroup util
- */
-template<>
-struct ConstantGrowth<0>;
-/*! \endcond */
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns a new size depending on the given old size and the required minimum size.
- *
- * \param old The old size.
- * \param minimum The required minimum size.
- * \return The new size (at least the required minimum size).
- */
-template< size_t Growth >
-inline size_t ConstantGrowth<Growth>::operator()( size_t old, size_t minimum ) const
-{
-   const size_t needed( math::max<size_t>( old+Growth, minimum ) );
-   return ( ( needed )?( 4 * ( (needed-1)/4+1 ) ):( 0 ) );
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/policies/LinearGrowth.h b/src/core/ptrvector/policies/LinearGrowth.h
deleted file mode 100644
index 314b79380525dda287747d986be18a28a15010c4..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/LinearGrowth.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file LinearGrowth.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <core/math/Utility.h>
-#include <core/DataTypes.h>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Linear growth policy class.
- * \ingroup util
- *
- * The LinearGrowth policy class implements a linear growth strategy. It can be customized for
- * any purpose: the \a Growth template argument specifies the factor of the size growth.
- */
-template< size_t Growth >
-struct LinearGrowth
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline size_t operator()( size_t oldSize, size_t minSize ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Specialization of the linear growth policy for 0 growth.
- * \ingroup util
- */
-template<>
-struct LinearGrowth<0>;
-/*! \endcond */
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*! \cond internal */
-/*!\brief Specialization of the linear growth policy for 1 growth.
- * \ingroup util
- */
-template<>
-struct LinearGrowth<1>;
-/*! \endcond */
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns a new size depending on the given old size and the required minimum size.
- *
- * \param old The old size.
- * \param minimum The required minimum size.
- * \return The new size (at least the required minimum size).
- */
-template< size_t Growth >
-inline size_t LinearGrowth<Growth>::operator()( size_t old, size_t minimum ) const
-{
-   const size_t needed( math::max<size_t>( old*Growth, minimum ) );
-   return ( ( needed )?( 4 * ( (needed-1)/4+1 ) ):( 0 ) );
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/policies/NoDelete.h b/src/core/ptrvector/policies/NoDelete.h
deleted file mode 100644
index 14b24aae3c1b48891a0b39ed02be7366b7d6a978..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/NoDelete.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file NoDelete.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief No-delete policy class.
- * \ingroup util
- */
-struct NoDelete
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   template< typename Type >
-   inline void operator()( const Type& ptr ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Implementation of the no-delete policy.
- *
- * \param ptr The pointer to delete.
- * \return void
- */
-template< typename Type >
-inline void NoDelete::operator()( const Type& /*ptr*/ ) const
-{}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/policies/OptimalGrowth.h b/src/core/ptrvector/policies/OptimalGrowth.h
deleted file mode 100644
index 59abed396b4ac6dccb2a35077f49f085e465c3c7..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/OptimalGrowth.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file OptimalGrowth.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <core/math/Utility.h>
-#include <core/DataTypes.h>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Optimal growth policy class.
- * \ingroup util
- *
- * The OptimalGrowth policy class implements the optimal growth strategy suggested by Andrew
- * Koenig for the std::vector class (see Andrew Koenig's column in the September 1998 issue of
- * JOOP (Journal of Object-Oriented Programming), or the Dr. Dobb's article 'C++ Made Easier:
- * How Vectors Grow', 2001). It applies an exponential growth strategy using a factor of 1.5
- * and additionally ensures that the sizes returns are always multiples of four.
- */
-struct OptimalGrowth
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline size_t operator()( size_t oldSize, size_t minSize ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns a new size depending on the given old size and the required minimum size.
- *
- * \param old The old size.
- * \param minimum The required minimum size.
- * \return The new size (at least the required minimum size).
- */
-inline size_t OptimalGrowth::operator()( size_t old, size_t minimum ) const
-{
-   const size_t needed( math::max( static_cast<size_t>( real_c(old)*1.5 ), minimum ) );
-   return ( ( needed )?( 4 * ( (needed-1)/4 + 1 ) ):( 0 ) );
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/ptrvector/policies/PtrDelete.h b/src/core/ptrvector/policies/PtrDelete.h
deleted file mode 100644
index 1940275e2ece96848af8982873160b8bb41c7cd8..0000000000000000000000000000000000000000
--- a/src/core/ptrvector/policies/PtrDelete.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file PtrDelete.h
-//! \ingroup core
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <boost/checked_delete.hpp>
-
-namespace walberla {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Pointer-delete policy class.
- * \ingroup util
- *
- * The PtrDelete policy functor class applies a delete operation to the given argument. Note that
- * the delete operation is NOT permitted for inclomplete types (i.e. declared but undefined data
- * types). The attempt to apply a PtrDelete functor to a pointer to an object of incomplete type
- * results in a compile time error!
- */
-struct PtrDelete
-{
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   template< typename Type >
-   inline void operator()( Type ptr ) const;
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Implementation of the pointer-delete policy.
- *
- * \param ptr The pointer to delete.
- * \return void
- *
- * This function applies a standard delete operation to the given argument. Note that the delete
- * operation is NOT permitted for inclomplete types (i.e. declared but undefined data types). The
- * attempt to use this function for a pointer to an object of incomplete type results in a compile
- * time error!
- */
-template< typename Type >
-inline void PtrDelete::operator()( Type ptr ) const
-{
-   boost::checked_delete( ptr );
-}
-//*************************************************************************************************
-
-} // namespace
diff --git a/src/core/timing/TimingNode.h b/src/core/timing/TimingNode.h
index 8ec0b3338a810f8618ff790e550329698096fd60..2f0597f7a591b12907932942e76f107b4f90015d 100644
--- a/src/core/timing/TimingNode.h
+++ b/src/core/timing/TimingNode.h
@@ -26,6 +26,7 @@
 
 #include "core/debug/Debug.h"
 #include "core/logging/Logging.h"
+#include "core/mpi/Gatherv.h"
 #include "core/mpi/MPIManager.h"
 #include "core/mpi/Reduce.h"
 #include "core/mpi/SetReduction.h"
@@ -253,6 +254,20 @@ void reduceInplace( TimingNode<TP>& tn, ReduceType rt = REDUCE_TOTAL, int target
          break;
    }
 
+   WALBERLA_ASSERT_EQUAL(vals.size(), valsSq.size());
+   WALBERLA_ASSERT_EQUAL(vals.size(), min.size());
+   WALBERLA_ASSERT_EQUAL(vals.size(), max.size());
+   WALBERLA_ASSERT_EQUAL(vals.size(), count.size());
+
+   WALBERLA_DEBUG_SECTION()
+   {
+      //checking if all timing trees contain the same number of elements
+      std::vector<uint32_t> lens;
+      lens.push_back(uint32_c(vals.size()));
+      lens = mpi::allGatherv(lens);
+      std::for_each(lens.begin(), lens.end(), [&](const uint32_t& v){WALBERLA_UNUSED(v); WALBERLA_ASSERT_EQUAL( v, vals.size(), "Different number of TimingTree nodes detected! All TimingTrees need to have the same timers for reduction!");});
+   }
+
    // Target vectors where reduced values are stored
    std::vector<double> minRed;
    std::vector<double> maxRed;
diff --git a/src/cuda/AddGPUFieldToStorage.impl.h b/src/cuda/AddGPUFieldToStorage.impl.h
index 03b90c728fe345259079ee7c67c176eec9ff64dc..1befc3e81bc4a04fd89c1ec9561e1e417023cc05 100644
--- a/src/cuda/AddGPUFieldToStorage.impl.h
+++ b/src/cuda/AddGPUFieldToStorage.impl.h
@@ -73,7 +73,7 @@ namespace cuda {
                                     uint_t nrOfGhostLayers,
                                     bool usePitchedMem )
    {
-      auto func = boost::bind ( internal::createGPUField<GPUField_T>, _1, _2, nrOfGhostLayers, fSize, layout, usePitchedMem );
+      auto func = std::bind ( internal::createGPUField<GPUField_T>, std::placeholders::_1, std::placeholders::_2, nrOfGhostLayers, fSize, layout, usePitchedMem );
       return bs->addStructuredBlockData< GPUField_T >( func, identifier );
    }
 
@@ -84,7 +84,7 @@ namespace cuda {
                                      const std::string & identifier,
                                      bool usePitchedMem )
    {
-      auto func = boost::bind ( internal::createGPUFieldFromCPUField<Field_T>, _1, _2, cpuFieldID, usePitchedMem );
+      auto func = std::bind ( internal::createGPUFieldFromCPUField<Field_T>, std::placeholders::_1, std::placeholders::_2, cpuFieldID, usePitchedMem );
       return bs->addStructuredBlockData< GPUField<typename Field_T::value_type> >( func, identifier );
    }
 
diff --git a/src/cuda/FieldCopy.h b/src/cuda/FieldCopy.h
index 07fd04c808032fccd21c3f00f98600294b124a9b..4f13fa999ffec19249183fecd2a4fe0939e2674e 100644
--- a/src/cuda/FieldCopy.h
+++ b/src/cuda/FieldCopy.h
@@ -52,7 +52,7 @@ namespace cuda {
    std::function<void()> fieldCpyFunctor( const shared_ptr< StructuredBlockStorage > & blocks,
                                             BlockDataID dstID, ConstBlockDataID srcID )
    {
-      return boost::bind( fieldCpy<DstType,SrcType>, blocks, dstID, srcID );
+      return std::bind( fieldCpy<DstType,SrcType>, blocks, dstID, srcID );
    }
 
 
@@ -68,7 +68,7 @@ namespace cuda {
    template<typename DstType, typename SrcType>
    std::function<void(IBlock*)> fieldCpyFunctor( BlockDataID dstID, ConstBlockDataID srcID )
    {
-      return boost::bind( fieldCpySweepFunction<DstType,SrcType>, dstID, srcID, _1 );
+      return std::bind( fieldCpySweepFunction<DstType,SrcType>, dstID, srcID, std::placeholders::_1 );
    }
 
 
diff --git a/src/domain_decomposition/BlockStorage.cpp b/src/domain_decomposition/BlockStorage.cpp
index b5148482f5fd27c1a5cfe9d358ffadaf65b0bf6d..9ee33473a1b8100cf8f88d162093502812334fe6 100644
--- a/src/domain_decomposition/BlockStorage.cpp
+++ b/src/domain_decomposition/BlockStorage.cpp
@@ -46,7 +46,7 @@ namespace domain_decomposition {
 //**********************************************************************************************************************
 void BlockStorage::mapToPeriodicDomain( real_t & x, real_t & y, real_t & z ) const
 {
-   boost::array< bool, 3 > periodic;
+   std::array< bool, 3 > periodic;
    periodic[0] = periodic_[0];
    periodic[1] = periodic_[1];
    periodic[2] = periodic_[2];
@@ -62,7 +62,7 @@ void BlockStorage::mapToPeriodicDomain( real_t & x, real_t & y, real_t & z ) con
 //**********************************************************************************************************************
 bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB & box2 ) const
 {
-   boost::array< bool, 3 > periodic;
+   std::array< bool, 3 > periodic;
    periodic[0] = periodic_[0];
    periodic[1] = periodic_[1];
    periodic[2] = periodic_[2];
@@ -73,12 +73,12 @@ bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB
 //**********************************************************************************************************************
 /*!
 *   For documentation, see documentation of free function
-*   'bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )'
+*   'bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )'
 */
 //**********************************************************************************************************************
 bool BlockStorage::periodicIntersect( const math::AABB & box1, const math::AABB & box2, const real_t dx ) const
 {
-   boost::array< bool, 3 > periodic;
+   std::array< bool, 3 > periodic;
    periodic[0] = periodic_[0];
    periodic[1] = periodic_[1];
    periodic[2] = periodic_[2];
diff --git a/src/domain_decomposition/MakeBlockDataInitFunction.h b/src/domain_decomposition/MakeBlockDataInitFunction.h
index 466f944c110341acdde00a786e45fa39d3764e05..de41cd696de30b312f47883cbc59987a3e6b71d2 100644
--- a/src/domain_decomposition/MakeBlockDataInitFunction.h
+++ b/src/domain_decomposition/MakeBlockDataInitFunction.h
@@ -23,7 +23,6 @@
 
 #include "IBlock.h"
 
-#include <boost/bind.hpp>
 #include <functional>
 
 
@@ -35,119 +34,19 @@ namespace domain_decomposition {
 /// \cond internal
 namespace internal
 {
-   template<class T>
-   T * newFunc( const IBlock* const ) {
-      return new T();
+   template<class T, typename... Args>
+   T * newFunc( const IBlock* const, Args&... args ) {
+      return new T(args...);
    }
-
-   template<class T, class P1>
-   T * newFunc( const IBlock* const , const P1 & p1 ) {
-      return new T(p1);
-   }
-
-   template<class T, class P1, class P2>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2 ) {
-      return new T(p1, p2);
-   }
-
-   template<class T, class P1, class P2, class P3>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3 ) {
-      return new T(p1, p2, p3);
-   }
-
-   template<class T, class P1, class P2, class P3, class P4>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4 ) {
-      return new T(p1, p2, p3, p4);
-   }
-
-   template<class T, class P1, class P2, class P3, class P4, class P5>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5 ) {
-      return new T(p1, p2, p3, p4, p5);
-   }
-
-   template<class T, class P1, class P2, class P3, class P4, class P5, class P6>
-   T * newFunc( const IBlock* const ,  const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6 ) {
-      return new T(p1, p2, p3, p4, p5, p6);
-   }
-
-   template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7 ) {
-      return new T(p1, p2, p3, p4, p5, p6,p7);
-   }
-
-   template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8 ) {
-      return new T(p1, p2, p3, p4, p5, p6, p7,p8 );
-   }
-
-   template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
-   T * newFunc( const IBlock* const , const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8, const P9 & p9 ) {
-      return new T(p1, p2, p3, p4, p5, p6, p7,p8, p9 );
-   }
-
 } // namespace internal
 /// \endcond
 
 
 
-template<class T>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction() {
-   return boost::bind( internal::newFunc<T>, _1);
-}
-
-template<class T, class P1>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1) {
-   return boost::bind( internal::newFunc<T,P1>, _1,p1);
-}
-
-template<class T, class P1, class P2>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2) {
-   return boost::bind( internal::newFunc<T,P1,P2>, _1,p1,p2);
-}
-
-template<class T, class P1, class P2, class P3>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3>, _1,p1,p2,p3);
-}
-
-template<class T, class P1, class P2, class P3, class P4>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4>, _1,p1,p2,p3,p4);
-}
-
-template<class T, class P1, class P2, class P3, class P4, class P5>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5>, _1,p1,p2,p3,p4,p5);
-}
-
-template<class T, class P1, class P2, class P3, class P4, class P5, class P6>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6>, _1,p1,p2,p3,p4,p5,p6);
-}
-
-template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7>, _1,p1,p2,p3,p4,p5,p6,p7);
-}
-
-template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
-std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7,P8>, _1,p1,p2,p3,p4,p5,p6,p7,p8);
-}
-
-template<class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
+template<class T, typename... Args>
 std::function< T* ( const IBlock* const block ) >
-makeBlockDataInitFunction(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6, const P7 & p7, const P8 & p8, const P9 & p9) {
-   return boost::bind( internal::newFunc<T,P1,P2,P3,P4,P5,P6,P7,P8,P9>, _1,p1,p2,p3,p4,p5,p6,p7,p8,p9);
+makeBlockDataInitFunction(Args&&... args) {
+   return std::bind( internal::newFunc<T,Args...>, std::placeholders::_1, std::forward<Args>(args)... );
 }
 
 
diff --git a/src/domain_decomposition/MapPointToPeriodicDomain.cpp b/src/domain_decomposition/MapPointToPeriodicDomain.cpp
index d63c0ccd219665c5bf0e4c5ed2f6c0ca00b98e01..82f365e0e5d9bd733f7207eb407a7a7cadc57036 100644
--- a/src/domain_decomposition/MapPointToPeriodicDomain.cpp
+++ b/src/domain_decomposition/MapPointToPeriodicDomain.cpp
@@ -29,7 +29,7 @@ namespace domain_decomposition {
 
 
 
-void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )
+void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )
 {
    if( periodic[0] )
    {
diff --git a/src/domain_decomposition/MapPointToPeriodicDomain.h b/src/domain_decomposition/MapPointToPeriodicDomain.h
index 39c39c314048840724d22047daf325dd993c1fef..21107b075bd2f35785642cd41a6e169f8145cbd9 100644
--- a/src/domain_decomposition/MapPointToPeriodicDomain.h
+++ b/src/domain_decomposition/MapPointToPeriodicDomain.h
@@ -25,7 +25,7 @@
 #include "core/math/AABB.h"
 #include "core/math/Vector3.h"
 
-#include <boost/array.hpp>
+#include <array>
 
 
 
@@ -42,12 +42,12 @@ namespace domain_decomposition {
 *   The min points of the domain are included in the simulation space, the max points are excluded!
 */
 //**********************************************************************************************************************
-void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z );
+void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z );
 
 
 
 /// see documetation of 'void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )'
-inline void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, Vector3< real_t > & p )
+inline void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, Vector3< real_t > & p )
 {
    mapPointToPeriodicDomain( periodic, domain, p[0], p[1], p[2] );
 }
@@ -55,7 +55,7 @@ inline void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic,
 
 
 /// see documetation of 'void mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, real_t & x, real_t & y, real_t & z )'
-inline Vector3< real_t > mapPointToPeriodicDomain( const boost::array< bool, 3 > & periodic, const AABB & domain, const Vector3< real_t > & p )
+inline Vector3< real_t > mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AABB & domain, const Vector3< real_t > & p )
 {
    Vector3< real_t > point( p );
    mapPointToPeriodicDomain( periodic, domain, point[0], point[1], point[2] );
diff --git a/src/domain_decomposition/PeriodicIntersect.cpp b/src/domain_decomposition/PeriodicIntersect.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..355e666c834a1fd7d13cb6d8364dd130cadbccea
--- /dev/null
+++ b/src/domain_decomposition/PeriodicIntersect.cpp
@@ -0,0 +1,102 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file PeriodicIntersect.cpp
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include "PeriodicIntersect.h"
+#include "MapPointToPeriodicDomain.h"
+
+namespace walberla {
+namespace domain_decomposition {
+
+bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )
+{
+   auto min1 = box1.minCorner();
+   auto min2 = box2.minCorner();
+   auto max1 = box1.maxCorner();
+   auto max2 = box2.maxCorner();
+
+   mapPointToPeriodicDomain(periodic, domain, min1);
+   mapPointToPeriodicDomain(periodic, domain, min2);
+   mapPointToPeriodicDomain(periodic, domain, max1);
+   mapPointToPeriodicDomain(periodic, domain, max2);
+
+   bool flag = false;
+
+   if (max1[0] > max2[0])
+   {
+      if ( (max1[0]-max2[0]) < box1.xSize() ) flag = true;
+   } else
+   {
+      if ( (max2[0]-max1[0]) < box2.xSize() ) flag = true;
+   }
+   if (min1[0] > min2[0])
+   {
+      if ( (min1[0]-min2[0]) < box2.xSize() ) flag = true;
+   } else
+   {
+      if ( (min2[0]-min1[0]) < box1.xSize() ) flag = true;
+   }
+
+   if (!flag) return false;
+   flag = false;
+
+   if (max1[1] > max2[1])
+   {
+      if ( (max1[1]-max2[1]) < box1.ySize() ) flag = true;
+   } else
+   {
+      if ( (max2[1]-max1[1]) < box2.ySize() ) flag = true;
+   }
+   if (min1[1] > min2[1])
+   {
+      if ( (min1[1]-min2[1]) < box2.ySize() ) flag = true;
+   } else
+   {
+      if ( (min2[1]-min1[1]) < box1.ySize() ) flag = true;
+   }
+
+   if (!flag) return false;
+   flag = false;
+
+   if (max1[2] > max2[2])
+   {
+      if ( (max1[2]-max2[2]) < box1.zSize() ) flag = true;
+   } else
+   {
+      if ( (max2[2]-max1[2]) < box2.zSize() ) flag = true;
+   }
+   if (min1[2] > min2[2])
+   {
+      if ( (min1[2]-min2[2]) < box2.zSize() ) flag = true;
+   } else
+   {
+      if ( (min2[2]-min1[2]) < box1.zSize() ) flag = true;
+   }
+
+   return flag;
+}
+
+bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx )
+{
+   return periodicIntersect(periodic, domain, box1.getExtended( dx ), box2);
+}
+
+
+} // namespace domain_decomposition
+} // namespace walberla
diff --git a/src/domain_decomposition/PeriodicIntersect.h b/src/domain_decomposition/PeriodicIntersect.h
index 6fc0680d2fa21a5b5f3f41621bce133852609490..4ef824d991aea406fb6ca76e97217cecd198233c 100644
--- a/src/domain_decomposition/PeriodicIntersect.h
+++ b/src/domain_decomposition/PeriodicIntersect.h
@@ -14,97 +14,23 @@
 //  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
 //! \file PeriodicIntersect.h
-//! \ingroup domain_decomposition
 //! \author Sebastian Eibl <sebastian.eibl@fau.de>
 //
 //======================================================================================================================
 
 #pragma once
 
-#include "MapPointToPeriodicDomain.h"
-
 #include "core/DataTypes.h"
 #include "core/math/AABB.h"
 #include "core/math/Vector3.h"
 
-#include <boost/array.hpp>
+#include <array>
 
 namespace walberla {
 namespace domain_decomposition {
 
-bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )
-{
-   auto min1 = box1.minCorner();
-   auto min2 = box2.minCorner();
-   auto max1 = box1.maxCorner();
-   auto max2 = box2.maxCorner();
-
-   mapPointToPeriodicDomain(periodic, domain, min1);
-   mapPointToPeriodicDomain(periodic, domain, min2);
-   mapPointToPeriodicDomain(periodic, domain, max1);
-   mapPointToPeriodicDomain(periodic, domain, max2);
-
-   bool flag = false;
-
-   if (max1[0] > max2[0])
-   {
-      if ( (max1[0]-max2[0]) < box1.xSize() ) flag = true;
-   } else
-   {
-      if ( (max2[0]-max1[0]) < box2.xSize() ) flag = true;
-   }
-   if (min1[0] > min2[0])
-   {
-      if ( (min1[0]-min2[0]) < box2.xSize() ) flag = true;
-   } else
-   {
-      if ( (min2[0]-min1[0]) < box1.xSize() ) flag = true;
-   }
-
-   if (!flag) return false;
-   flag = false;
-
-   if (max1[1] > max2[1])
-   {
-      if ( (max1[1]-max2[1]) < box1.ySize() ) flag = true;
-   } else
-   {
-      if ( (max2[1]-max1[1]) < box2.ySize() ) flag = true;
-   }
-   if (min1[1] > min2[1])
-   {
-      if ( (min1[1]-min2[1]) < box2.ySize() ) flag = true;
-   } else
-   {
-      if ( (min2[1]-min1[1]) < box1.ySize() ) flag = true;
-   }
-
-   if (!flag) return false;
-   flag = false;
-
-   if (max1[2] > max2[2])
-   {
-      if ( (max1[2]-max2[2]) < box1.zSize() ) flag = true;
-   } else
-   {
-      if ( (max2[2]-max1[2]) < box2.zSize() ) flag = true;
-   }
-   if (min1[2] > min2[2])
-   {
-      if ( (min1[2]-min2[2]) < box2.zSize() ) flag = true;
-   } else
-   {
-      if ( (min2[2]-min1[2]) < box1.zSize() ) flag = true;
-   }
-
-   return flag;
-}
-
-bool periodicIntersect( const boost::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx )
-{
-   return periodicIntersect(periodic, domain, box1.getExtended( dx ), box2);
-}
-
+bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 );
+bool periodicIntersect( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx );
 
 } // namespace domain_decomposition
 } // namespace walberla
diff --git a/src/domain_decomposition/PeriodicIntersectionVolume.cpp b/src/domain_decomposition/PeriodicIntersectionVolume.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac61fc474155c852de64162e52f05b391eead46d
--- /dev/null
+++ b/src/domain_decomposition/PeriodicIntersectionVolume.cpp
@@ -0,0 +1,53 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file PeriodicIntersectionVolume.cpp
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include "core/logging/Logging.h"
+#include "MapPointToPeriodicDomain.h"
+
+namespace walberla {
+namespace domain_decomposition {
+
+real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 )
+{
+   const auto diagonal = (domain.maxCorner() - domain.minCorner());
+   const auto halfDiagonal = real_t(0.5) * diagonal;
+   const auto center1 = box1.center();
+   auto center2 = box2.center();
+
+   for (size_t dim = 0; dim < 3; ++dim)
+   {
+      if (periodic[dim])
+      {
+         while ((center2[dim]-center1[dim])>halfDiagonal[dim]) center2[dim] -= diagonal[dim];
+         while ((center2[dim]-center1[dim])<-halfDiagonal[dim]) center2[dim] += diagonal[dim];
+      }
+   }
+
+   return box1.intersectionVolume(box2.getTranslated(center2 - box2.center()));
+}
+
+real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx )
+{
+   return periodicIntersectionVolume(periodic, domain, box1.getExtended( dx ), box2);
+}
+
+
+} // namespace domain_decomposition
+} // namespace walberla
diff --git a/src/domain_decomposition/PeriodicIntersectionVolume.h b/src/domain_decomposition/PeriodicIntersectionVolume.h
new file mode 100644
index 0000000000000000000000000000000000000000..15c13d70235e542e10f96b176c1e60c88c3e2c95
--- /dev/null
+++ b/src/domain_decomposition/PeriodicIntersectionVolume.h
@@ -0,0 +1,36 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file PeriodicIntersectionVolume.h
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include "core/DataTypes.h"
+#include "core/math/AABB.h"
+#include "core/math/Vector3.h"
+
+#include <array>
+
+namespace walberla {
+namespace domain_decomposition {
+
+real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB & box1, const math::AABB & box2 );
+real_t periodicIntersectionVolume( const std::array< bool, 3 > & periodic, const math::AABB & domain, const math::AABB& box1, const math::AABB & box2, const real_t dx );
+
+} // namespace domain_decomposition
+} // namespace walberla
diff --git a/src/domain_decomposition/StructuredBlockStorage.h b/src/domain_decomposition/StructuredBlockStorage.h
index 4315429d285f3189e82d367f75d0a2f48bd895c8..2d398ca3dcf3e363d1afae8b76efbcb449c7c6c1 100644
--- a/src/domain_decomposition/StructuredBlockStorage.h
+++ b/src/domain_decomposition/StructuredBlockStorage.h
@@ -29,7 +29,7 @@
 #include "core/cell/CellInterval.h"
 #include "core/debug/Debug.h"
 
-#include <boost/bind.hpp>
+#include <functional>
 
 
 namespace walberla {
@@ -112,7 +112,7 @@ public:
                             bdc.incompatibleSelectors_, bdc.identifier_ ); return *this; }
       template< typename T >
       StructuredBlockDataAdder & operator<<( const StructuredBlockDataCreator<T> & sbdc ) {
-         dataHandling_.add( walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( boost::bind( sbdc.function_, _1, &storage_ ) ) ),
+         dataHandling_.add( walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( std::bind( sbdc.function_,  std::placeholders::_1, &storage_ ) ) ),
                             sbdc.requiredSelectors_, sbdc.incompatibleSelectors_, sbdc.identifier_ ); return *this; }
       operator BlockDataID() { return storage_.getBlockStorage().addBlockData( dataHandling_, identifier_ ); }
    private:
@@ -1076,7 +1076,7 @@ inline BlockDataID StructuredBlockStorage::addStructuredBlockData(
       const std::string& identifier, const Set<SUID>& requiredSelectors, const Set<SUID>& incompatibleSelectors )
 {
    internal::SelectableBlockDataHandlingWrapper dataHandling(
-            walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( boost::bind( function, _1, this ) ) ),
+            walberla::make_shared< internal::BlockDataHandlingHelper<T> >( walberla::make_shared< internal::BlockDataHandlingFunctionAdaptor<T> >( std::bind( function,  std::placeholders::_1, this ) ) ),
             requiredSelectors, incompatibleSelectors, identifier );
 
 
diff --git a/src/field/StabilityChecker.h b/src/field/StabilityChecker.h
index 396a7c07725f3ec835389fa370bd92fabdd1d02e..74b4470ed093b8dbd6ab7d1fdb2d74a182bb79be 100644
--- a/src/field/StabilityChecker.h
+++ b/src/field/StabilityChecker.h
@@ -394,7 +394,7 @@ void StabilityChecker< Field_T, Filter_T >::operator()()
 
          vtkWriter->addCellDataWriter( walberla::make_shared< vtk::DumpBlockStructureProcess >( "process" ) );
          vtkWriter->addCellDataWriter( walberla::make_shared< vtk::DumpBlockStructureLevel >( "level" ) );
-         vtkWriter->addCellDataWriter( walberla::make_shared< FValueVTKWriter >( boost::ref( failedCells_ ), "F" ) );
+         vtkWriter->addCellDataWriter( walberla::make_shared< FValueVTKWriter >( std::ref( failedCells_ ), "F" ) );
          vtkWriter->addCellDataWriter( walberla::make_shared< LocalCoordVTKWriter >( "blockLocalCoordinate" ) );
          vtkWriter->addCellDataWriter( walberla::make_shared< GlobalCoordVTKWriter >( "globalCoordinate" ) );
 
diff --git a/src/field/adaptors/AdaptorCreators.h b/src/field/adaptors/AdaptorCreators.h
index af7f5e55bd0e4756f67820945b61eb2d31002bea..1c410ca91246600c385f5ba0a6691b7a67474462 100644
--- a/src/field/adaptors/AdaptorCreators.h
+++ b/src/field/adaptors/AdaptorCreators.h
@@ -23,7 +23,9 @@
 #pragma once
 
 #include "blockforest/BlockDataHandling.h"
-#include <boost/bind.hpp>
+
+#include <functional>
+
 
 
 namespace walberla {
diff --git a/src/field/allocation/FieldAllocator.h b/src/field/allocation/FieldAllocator.h
index 5be0ecf4b0dbd2b5e292d446dd13d62aae9aca23..4ab58c0fe1d82195f28a64627d4577fdd9db3336 100644
--- a/src/field/allocation/FieldAllocator.h
+++ b/src/field/allocation/FieldAllocator.h
@@ -48,6 +48,8 @@ namespace field {
    {
       public:
 
+         virtual ~FieldAllocator() = default;
+
          /**
           * \brief Allocate memory for a field of given sizes and initializes reference counter with one
           *
diff --git a/src/field/interpolators/NearestNeighborFieldInterpolator.h b/src/field/interpolators/NearestNeighborFieldInterpolator.h
index 45e9110de725173af89a4aed20e1d6290b5278a5..975c55edb4c52d0ea197391a88b271588bbf7729 100644
--- a/src/field/interpolators/NearestNeighborFieldInterpolator.h
+++ b/src/field/interpolators/NearestNeighborFieldInterpolator.h
@@ -121,7 +121,7 @@ public:
                            *interpolationResultBegin = baseField_(curCell, f);
                            ++interpolationResultBegin;
                         }
-                        break;
+                        return;
                      }
                   }
                }
diff --git a/src/field/iterators/IteratorMacros.h b/src/field/iterators/IteratorMacros.h
index 0c11a6014fc6447147574857fcceb3a47cc1cb65..162028971bee80e5c5dc3e1408926154050883f7 100644
--- a/src/field/iterators/IteratorMacros.h
+++ b/src/field/iterators/IteratorMacros.h
@@ -486,7 +486,7 @@
             CODE \
             ++it0; ++it1; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
       } \
    } \
    else \
@@ -503,7 +503,7 @@
             CODE \
             ++it0; ++it1; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
       } \
    } }
    
@@ -532,8 +532,8 @@
             CODE \
             ++it0; ++it1; ++it2; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
       } \
    } \
    else \
@@ -551,11 +551,11 @@
             CODE \
             ++it0; ++it1; ++it2; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -584,9 +584,9 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
       } \
    } \
    else \
@@ -605,9 +605,9 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
       } \
    } }
 
@@ -642,10 +642,10 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
       } \
    } \
    else \
@@ -665,10 +665,10 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
       } \
    } }
 
@@ -706,11 +706,11 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
       } \
    } \
    else \
@@ -731,11 +731,11 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
       } \
    } }
 
@@ -776,12 +776,12 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
       } \
    } \
    else \
@@ -803,12 +803,12 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
       } \
    } }
 
@@ -852,13 +852,13 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
-         WALBERLA_ASSERT( it7 == (f7)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \
       } \
    } \
    else \
@@ -881,16 +881,16 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
-         WALBERLA_ASSERT( it7 == (f7)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \
       } \
    } }
-   
+
 #else // == not WALBERLA_CXX_COMPILER_IS_MSVC
 
 #define WALBERLA_FOR_ALL_CELLS_XYZ_OMP( field, omp, CODE ) \
@@ -956,7 +956,7 @@
          } \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_XYZ_OMP_4( field, gl, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
@@ -1041,7 +1041,7 @@
          } \
       } \
    } }
-   
+
 #define WALBERLA_FOR_ALL_CELLS_YZ_OMP( field, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
    const ::walberla::cell_idx_t ySize__ = ::walberla::cell_idx_c( (field)->ySize() ); \
@@ -1096,7 +1096,7 @@
          } \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP_4( field, gl, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
@@ -1168,7 +1168,7 @@
          } \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_4( it0, f0, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1228,7 +1228,7 @@
             CODE \
             ++it0; ++it1; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
       } \
    } \
    else \
@@ -1245,10 +1245,10 @@
             CODE \
             ++it0; ++it1; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_8( it0, f0, it1, f1, it2, f2, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1274,8 +1274,8 @@
             CODE \
             ++it0; ++it1; ++it2; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
       } \
    } \
    else \
@@ -1293,11 +1293,11 @@
             CODE \
             ++it0; ++it1; ++it2; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1326,9 +1326,9 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
       } \
    } \
    else \
@@ -1347,9 +1347,9 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
       } \
    } }
 
@@ -1384,10 +1384,10 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
       } \
    } \
    else \
@@ -1407,10 +1407,10 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
       } \
    } }
 
@@ -1448,11 +1448,11 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
       } \
    } \
    else \
@@ -1473,11 +1473,11 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
       } \
    } }
 
@@ -1518,12 +1518,12 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
       } \
    } \
    else \
@@ -1545,12 +1545,12 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
       } \
    } }
 
@@ -1594,13 +1594,13 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
-         WALBERLA_ASSERT( it7 == (f7)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \
       } \
    } \
    else \
@@ -1623,13 +1623,13 @@
             CODE \
             ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7; \
          } \
-         WALBERLA_ASSERT( it1 == (f1)->end() ); \
-         WALBERLA_ASSERT( it2 == (f2)->end() ); \
-         WALBERLA_ASSERT( it3 == (f3)->end() ); \
-         WALBERLA_ASSERT( it4 == (f4)->end() ); \
-         WALBERLA_ASSERT( it5 == (f5)->end() ); \
-         WALBERLA_ASSERT( it6 == (f6)->end() ); \
-         WALBERLA_ASSERT( it7 == (f7)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
+         WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); \
       } \
    } }
 
@@ -1650,7 +1650,7 @@
          } \
       } \
    } }
-   
+
 #define WALBERLA_FOR_ALL_CELLS_IN_INTERVAL_XYZ_OMP( interval, omp, CODE ) \
    { for( ::walberla::cell_idx_t z = interval.zMin(); z <= interval.zMax(); ++z ) { \
       for( ::walberla::cell_idx_t y = interval.yMin(); y <= interval.yMax(); ++y ) { \
@@ -1688,7 +1688,7 @@
          CODE \
       } \
    } }
-   
+
 #define WALBERLA_FOR_ALL_CELLS_IN_INTERVAL_YZ_OMP( interval, omp, CODE ) \
    { for( ::walberla::cell_idx_t z = interval.zMin(); z <= interval.zMax(); ++z ) { \
       for( ::walberla::cell_idx_t y = interval.yMin(); y <= interval.yMax(); ++y ) \
@@ -1697,7 +1697,7 @@
       } \
    } }
 
-// Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead   
+// Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_INCLUDING_GHOST_LAYER_YZ_OMP_4( field, gl, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (field) ); \
    WALBERLA_ASSERT_GREATER_EQUAL_2( (field)->nrOfGhostLayers(), gl ); \
@@ -1710,7 +1710,7 @@
          CODE \
       } \
    } }
-   
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_4( it0, f0, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1733,8 +1733,8 @@
       CODE \
       ++it0; ++it1; \
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); }
-   
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); }
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_8( it0, f0, it1, f1, it2, f2, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1750,9 +1750,9 @@
       CODE \
       ++it0; ++it1; ++it2; \
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); }
-   
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); }
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_10( it0, f0, it1, f1, it2, f2, it3, f3, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1771,10 +1771,10 @@
       CODE \
       ++it0; ++it1; ++it2; ++it3; \
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); \
-   WALBERLA_ASSERT( it3 == (f3)->end() ); }
- 
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); }
+
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_12( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, omp, CODE ) \
    { WALBERLA_ASSERT_NOT_NULLPTR_1( (f0) ); \
@@ -1796,10 +1796,10 @@
       CODE \
       ++it0; ++it1; ++it2; ++it3; ++it4;\
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); \
-   WALBERLA_ASSERT( it3 == (f3)->end() ); \
-   WALBERLA_ASSERT( it4 == (f4)->end() ); }
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); }
 
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_14( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, omp, CODE ) \
@@ -1825,11 +1825,11 @@
       CODE \
       ++it0; ++it1; ++it2; ++it3; ++it4; ++it5;\
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); \
-   WALBERLA_ASSERT( it3 == (f3)->end() ); \
-   WALBERLA_ASSERT( it4 == (f4)->end() ); \
-   WALBERLA_ASSERT( it5 == (f5)->end() ); }
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); }
 
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_16( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, it6, f6, omp, CODE ) \
@@ -1858,12 +1858,12 @@
       CODE \
       ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6;\
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); \
-   WALBERLA_ASSERT( it3 == (f3)->end() ); \
-   WALBERLA_ASSERT( it4 == (f4)->end() ); \
-   WALBERLA_ASSERT( it5 == (f5)->end() ); \
-   WALBERLA_ASSERT( it6 == (f6)->end() ); }
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); }
 
 // Do not call this macro, call 'WALBERLA_FOR_ALL_CELLS_OMP' (using the same signature) instead
 #define WALBERLA_FOR_ALL_CELLS_OMP_18( it0, f0, it1, f1, it2, f2, it3, f3, it4, f4, it5, f5, it6, f6, it7, f7, omp, CODE ) \
@@ -1895,13 +1895,13 @@
       CODE \
       ++it0; ++it1; ++it2; ++it3; ++it4; ++it5; ++it6; ++it7;\
    } \
-   WALBERLA_ASSERT( it1 == (f1)->end() ); \
-   WALBERLA_ASSERT( it2 == (f2)->end() ); \
-   WALBERLA_ASSERT( it3 == (f3)->end() ); \
-   WALBERLA_ASSERT( it4 == (f4)->end() ); \
-   WALBERLA_ASSERT( it5 == (f5)->end() ); \
-   WALBERLA_ASSERT( it6 == (f6)->end() ); \
-   WALBERLA_ASSERT( it7 == (f7)->end() ); }
+   WALBERLA_ASSERT_EQUAL_2( it1, (f1)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it2, (f2)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it3, (f3)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it4, (f4)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it5, (f5)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it6, (f6)->end() ); \
+   WALBERLA_ASSERT_EQUAL_2( it7, (f7)->end() ); }
 
 #endif // OpenMP
 
diff --git a/src/field/python/FieldExport.impl.h b/src/field/python/FieldExport.impl.h
index ecbbbae8ca9d72cd0b9c1db0352159297853a5c7..4dc9d0c3b0444561945dcfca2f1ed64fa5566bbd 100644
--- a/src/field/python/FieldExport.impl.h
+++ b/src/field/python/FieldExport.impl.h
@@ -1006,7 +1006,7 @@ namespace internal {
 
       auto result = make_shared<boost::python::object>();
       AddToStorageExporter exporter( blocks, name, fs, gl, layout, type, initValue );
-      python_coupling::for_each_noncopyable_type< FieldTypes >  ( boost::ref(exporter) );
+      python_coupling::for_each_noncopyable_type< FieldTypes >  ( std::ref(exporter) );
 
       if ( ! exporter.successful() ) {
          PyErr_SetString( PyExc_ValueError, "Adding Field failed.");
@@ -1079,7 +1079,7 @@ namespace internal {
       auto fieldID = python_coupling::blockDataIDFromString( *blocks, name );
 
       CreateVTKWriterExporter exporter(blocks, fieldID, vtkName);
-      python_coupling::for_each_noncopyable_type< FieldTypes >  ( boost::ref(exporter) );
+      python_coupling::for_each_noncopyable_type< FieldTypes >  ( std::ref(exporter) );
       if ( ! exporter.getCreatedWriter() ) {
          PyErr_SetString( PyExc_ValueError, "Failed to create writer");
          throw boost::python::error_already_set();
@@ -1154,7 +1154,7 @@ namespace internal {
       auto fieldID = python_coupling::blockDataIDFromString( *blocks, name );
 
       CreateFlagFieldVTKWriterExporter exporter(blocks, fieldID, vtkName, flagMapping);
-      python_coupling::for_each_noncopyable_type< FieldTypes >  ( boost::ref(exporter) );
+      python_coupling::for_each_noncopyable_type< FieldTypes >  ( std::ref(exporter) );
       if ( ! exporter.getCreatedWriter() ) {
          PyErr_SetString( PyExc_ValueError, "Failed to create writer");
          throw boost::python::error_already_set();
@@ -1221,7 +1221,7 @@ namespace internal {
       auto fieldID = python_coupling::blockDataIDFromString( *blocks, name );
 
       CreateBinarizationVTKWriterExporter exporter(blocks, fieldID, vtkName, mask);
-      python_coupling::for_each_noncopyable_type< FieldTypes >  ( boost::ref(exporter) );
+      python_coupling::for_each_noncopyable_type< FieldTypes >  ( std::ref(exporter) );
       if ( ! exporter.getCreatedWriter() ) {
          PyErr_SetString( PyExc_ValueError, "Failed to create writer");
          throw boost::python::error_already_set();
diff --git a/src/gather/DataProcessor.h b/src/gather/DataProcessor.h
index a2efd154aef4d02a762f15f7feaa903a17c30fe5..b337becc9a3aae5bb2c3782df4e9d37e09354d05 100644
--- a/src/gather/DataProcessor.h
+++ b/src/gather/DataProcessor.h
@@ -43,6 +43,8 @@ class DataProcessor
 {
    public:
 
+      virtual ~DataProcessor() = default;
+
       /*
        * Process "graph like" data
        * every entry in the outer vector is a data-point.
diff --git a/src/geometry/bodies/DynamicBody.h b/src/geometry/bodies/DynamicBody.h
index dd666f106720f9a45aa01c55710323e1437106d7..a3c6ccca5a61981a381644bfd9e8e4b908b63097 100644
--- a/src/geometry/bodies/DynamicBody.h
+++ b/src/geometry/bodies/DynamicBody.h
@@ -30,6 +30,7 @@ namespace geometry {
 
 class AbstractBody {
 public:
+   virtual ~AbstractBody() = default;
    virtual bool contains (const Vector3<real_t> & point ) const = 0;
    virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, real_t dx ) const = 0;
    virtual FastOverlapResult fastOverlapCheck ( const AABB & box ) const = 0;
diff --git a/src/geometry/initializer/BoundaryFromDomainBorder.impl.h b/src/geometry/initializer/BoundaryFromDomainBorder.impl.h
index 9984fcaca34a6a4da0ca99d5e385d7b7469275da..dca93f84d01ce55b345fe585b1b34263856249f8 100644
--- a/src/geometry/initializer/BoundaryFromDomainBorder.impl.h
+++ b/src/geometry/initializer/BoundaryFromDomainBorder.impl.h
@@ -106,7 +106,7 @@ void BoundaryFromDomainBorder<Handling>::init( stencil::Direction direction,
 
       const cell_idx_t wd = wallDistance;
 
-      CellInterval dBB = blocks_.getDomainCellBB();
+      CellInterval dBB = blocks_.getDomainCellBB( blocks_.getLevel(*blockIt) );
 
       for( uint_t dim = 0; dim< 3; ++dim )
          switch ( stencil::c[dim][direction] )
diff --git a/src/geometry/initializer/BoundarySetter.h b/src/geometry/initializer/BoundarySetter.h
index 256ec58444530bcce20502a4541cab8b3a1b951c..b9fe341228dca130ada4f2f8647d98cfcc1f9b3d 100644
--- a/src/geometry/initializer/BoundarySetter.h
+++ b/src/geometry/initializer/BoundarySetter.h
@@ -194,7 +194,10 @@ namespace initializer {
          }
 
          if ( boundaryConfigBlock_ )
+         {
             bcConfig_ = boundaryHandling_->createBoundaryConfiguration( boundaryUID_, boundaryConfigBlock_ );
+            boundaryConfigBlock_ = Config::BlockHandle(); // discard the config block so we don't unnecessarily run createBoundaryConfiguration more than once with the same arguments
+         }
 
          flag_ = boundaryHandling_->getBoundaryMask( boundaryUID_ );
          if ( ! field::isFlag( flag_ ) )
diff --git a/src/lbm/BlockForestEvaluation.h b/src/lbm/BlockForestEvaluation.h
index 5a8ed59d7a9772dba7fbcf3a5ff65553ff50357c..f9b823696a8aa942545c73648de02bd03faa0d30 100644
--- a/src/lbm/BlockForestEvaluation.h
+++ b/src/lbm/BlockForestEvaluation.h
@@ -38,8 +38,8 @@
 #include "field/CellCounter.h"
 #include "field/FlagUID.h"
 
-#include <boost/bind.hpp>
 
+#include <functional>
 #include <map>
 #include <string>
 #include <sstream>
diff --git a/src/lbm/boundary/DynamicUBB.h b/src/lbm/boundary/DynamicUBB.h
index 03f4af7c8fc980b210eff4576bf64f0a7d893010..67425aa05cc721a13cfe746e000520bbf6052fdd 100644
--- a/src/lbm/boundary/DynamicUBB.h
+++ b/src/lbm/boundary/DynamicUBB.h
@@ -78,13 +78,29 @@ public:
       origin_[0] = aabb.xMin() + real_c(0.5) * dx_[0];
       origin_[1] = aabb.yMin() + real_c(0.5) * dx_[1];
       origin_[2] = aabb.zMin() + real_c(0.5) * dx_[2];
+
+      if( !timeTracker_ )
+      {
+         velocity_( time_ );
+      }
    }
+   DynamicUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
+               const uint_t level, const VelocityFunctor_T & velocity, const AABB & aabb ) :
+      DynamicUBB( boundaryUID, uid, pdfField, nullptr, level, velocity, aabb )
+   {}
 
    shared_ptr< TimeTracker > getTimeTracker() { return timeTracker_; }
 
    void pushFlags( std::vector< FlagUID > & uids ) const { uids.push_back( uid_ ); }
 
-   void beforeBoundaryTreatment() { time_ = timeTracker_->getTime( level_ ); velocity_( time_ ); }
+   void beforeBoundaryTreatment()
+   {
+     if( timeTracker_ )
+     {
+        time_ = timeTracker_->getTime( level_ );
+        velocity_( time_ );
+     }
+   }
    void  afterBoundaryTreatment() const {}
 
    template< typename Buffer_T >
@@ -113,7 +129,7 @@ public:
       WALBERLA_ASSERT_EQUAL( nz, z + cell_idx_c( stencil::cz[ dir ] ) );
       WALBERLA_ASSERT_UNEQUAL( mask & this->mask_, numeric_cast<flag_t>(0) );
       WALBERLA_ASSERT_EQUAL( mask & this->mask_, this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the
-                                                                // current implementation of this boundary condition (SimpleUBB)
+                                                                // current implementation of this boundary condition (DynamicUBB)
 
       const Vector3< real_t > pos( origin_[0] + real_c(nx) * dx_[0],
                                    origin_[1] + real_c(ny) * dx_[1],
diff --git a/src/lbm/boundary/ParserUBB.h b/src/lbm/boundary/ParserUBB.h
new file mode 100644
index 0000000000000000000000000000000000000000..82bfff5e2ba37d7366f1bf1318a1992e664a7602
--- /dev/null
+++ b/src/lbm/boundary/ParserUBB.h
@@ -0,0 +1,546 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//  
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file ParserUBB.h
+//! \ingroup lbm
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include "lbm/field/DensityAndVelocity.h"
+#include "lbm/field/PdfField.h"
+#include "lbm/refinement/TimeTracker.h"
+
+#include "boundary/Boundary.h"
+
+#include "core/DataTypes.h"
+#include "core/cell/CellInterval.h"
+#include "core/config/Config.h"
+#include "core/debug/Debug.h"
+#include "core/math/Vector3.h"
+#include "core/math/ParserOMP.h"
+
+#include "field/FlagUID.h"
+
+#include "stencil/Directions.h"
+
+#include <vector>
+
+
+
+namespace walberla {
+namespace lbm {
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce = false >
+class ParserUBB : public Boundary<flag_t>
+{
+   typedef lbm::PdfField< LatticeModel_T >   PDFField;
+   typedef typename LatticeModel_T::Stencil  Stencil;
+
+public:
+
+   static const bool threadsafe = true;
+
+   class Parser : public BoundaryConfiguration
+   {
+   public:
+      inline Parser( const Config::BlockHandle & config );
+      inline Parser( std::array< std::string, 3 > & equations );
+      Vector3< real_t > operator()( const Vector3< real_t > & x, const real_t t ) const;
+      Vector3< real_t > operator()( const Vector3< real_t > & x ) const;
+      bool isTimeDependent() const { return timeDependent_; }
+      const std::array< std::string, 3 > & equations() const { return equations_; }
+
+   private:
+      std::array< math::FunctionParserOMP, 3 > parsers_;
+      std::array< std::string, 3 > equations_;
+      bool timeDependent_;
+   }; // class Parser
+
+   // constant velocity class is for API compatibility with UBB
+   class Velocity : public BoundaryConfiguration {
+   public:
+             Velocity( const Vector3< real_t > & _velocity ) : velocity_( _velocity ) {}
+             Velocity( const real_t _x, const real_t _y, const real_t _z ) : velocity_(_x,_y,_z) {}
+      inline Velocity( const Config::BlockHandle & config );
+
+      const Vector3< real_t > & velocity() const { return velocity_; }
+
+      const real_t & x() const { return velocity_[0]; }
+      const real_t & y() const { return velocity_[1]; }
+      const real_t & z() const { return velocity_[2]; }
+
+      Vector3< real_t > & velocity() { return velocity_; }
+
+      real_t & x() { return velocity_[0]; }
+      real_t & y() { return velocity_[1]; }
+      real_t & z() { return velocity_[2]; }
+
+   private:
+      Vector3< real_t > velocity_;
+   }; // class Velocity
+
+   typedef GhostLayerField< shared_ptr<Parser>, 1 > ParserField;
+   typedef GhostLayerField< Vector3<real_t>, 1 >    VelocityField;
+
+   static shared_ptr<Parser> createConfiguration( const Config::BlockHandle & config )
+      { return make_shared<Parser>( config ); }
+
+
+
+   ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
+              FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
+              const uint_t level, const AABB & aabb );
+   ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
+              FlagField<flag_t> * const flagField,  const uint_t level, const AABB & aabb );
+
+   shared_ptr< TimeTracker > getTimeTracker() { return timeTracker_; }
+
+   void pushFlags( std::vector< FlagUID > & uids ) const { uids.push_back( uid_ ); }
+
+   void beforeBoundaryTreatment()
+   {
+      if( timeTracker_ )
+         time_ = timeTracker_->getTime( level_ );
+   }
+   void  afterBoundaryTreatment() const {}
+
+   template< typename Buffer_T >
+   inline void packCell( Buffer_T &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const;
+
+   template< typename Buffer_T >
+   inline void registerCell( Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t );
+
+   inline void registerCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const BoundaryConfiguration & parser );
+   inline void registerCells( const flag_t, const CellInterval & cells, const BoundaryConfiguration & parser );
+   template< typename CellIterator >
+   inline void registerCells( const flag_t, const CellIterator & begin, const CellIterator & end, const BoundaryConfiguration & parser );
+
+   inline void unregisterCell( const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const;
+
+#ifndef NDEBUG
+   inline void treatDirection( const cell_idx_t  x, const cell_idx_t  y, const cell_idx_t  z, const stencil::Direction dir,
+                               const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t mask );
+#else
+   inline void treatDirection( const cell_idx_t  x, const cell_idx_t  y, const cell_idx_t  z, const stencil::Direction dir,
+                               const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t /*mask*/ );
+#endif
+
+   inline Vector3<real_t> getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z ) const;
+   inline Vector3<real_t> getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z, real_t t ) const;
+
+private:
+
+   const FlagUID uid_;
+
+   PDFField * const pdfField_;
+
+   Vector3< real_t > origin_;
+   Vector3< real_t > dx_;
+
+   // required to keep track of the simulation time
+   shared_ptr< TimeTracker > timeTracker_; // -> addPostBoundaryHandlingVoidFunction (when used with refinement time step)
+   real_t time_;
+   uint_t level_;
+
+   shared_ptr<ParserField> parserField_;
+   shared_ptr<VelocityField> velocityField_;
+
+}; // class ParserUBB
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::Parser( const Config::BlockHandle & config )
+: parsers_(), equations_(), timeDependent_( false )
+{
+   if( !config )
+      return;
+
+   if( config.isDefined( "x" ) )
+   {
+      equations_[0] = config.getParameter<std::string>( "x" );
+      parsers_[0].parse( equations_[0] );
+      if( parsers_[0].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+   if( config.isDefined( "y" ) )
+   {
+      equations_[1] = config.getParameter<std::string>( "y" );
+      parsers_[1].parse( equations_[1] );
+      if( parsers_[1].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+   if( config.isDefined( "z" ) )
+   {
+      equations_[2] = config.getParameter<std::string>( "z" );
+      parsers_[2].parse( equations_[2] );
+      if( parsers_[2].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+}
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::Parser( std::array< std::string, 3 > & equations )
+: parsers_(), equations_( equations ), timeDependent_( false )
+{
+   if( equations_[0].length() > 0 )
+   {
+      parsers_[0].parse( equations_[0] );
+      if( parsers_[0].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+   if( equations_[1].length() > 0 )
+   {
+      parsers_[1].parse( equations_[1] );
+      if( parsers_[1].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+   if( equations_[2].length() > 0 )
+   {
+      parsers_[2].parse( equations_[2] );
+      if( parsers_[2].symbolExists( "t" ) )
+         timeDependent_ = true;
+   }
+}
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::Velocity::Velocity( const Config::BlockHandle & config  )
+{
+   velocity_[0] = ( config && config.isDefined( "x" ) ) ? config.getParameter<real_t>( "x" ) : real_c(0.0);
+   velocity_[1] = ( config && config.isDefined( "y" ) ) ? config.getParameter<real_t>( "y" ) : real_c(0.0);
+   velocity_[2] = ( config && config.isDefined( "z" ) ) ? config.getParameter<real_t>( "z" ) : real_c(0.0);
+}
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+Vector3< real_t > ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::operator()( const Vector3< real_t > & x, const real_t t ) const
+{
+   std::map< std::string, double > symbols;
+   symbols["x"] = x[0];
+   symbols["y"] = x[1];
+   symbols["z"] = x[2];
+   symbols["t"] = t;
+
+   Vector3< real_t > v;
+   v[0] = parsers_[0].evaluate( symbols );
+   v[1] = parsers_[1].evaluate( symbols );
+   v[2] = parsers_[2].evaluate( symbols );
+   return v;
+}
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+Vector3< real_t > ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::Parser::operator()( const Vector3< real_t > & x ) const
+{
+   WALBERLA_ASSERT( !timeDependent_ );
+
+   std::map< std::string, double > symbols;
+   symbols["x"] = x[0];
+   symbols["y"] = x[1];
+   symbols["z"] = x[2];
+
+   Vector3< real_t > v;
+   v[0] = parsers_[0].evaluate( symbols );
+   v[1] = parsers_[1].evaluate( symbols );
+   v[2] = parsers_[2].evaluate( symbols );
+   return v;
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
+                                                                                   FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
+                                                                                   const uint_t level, const AABB & aabb )
+   : Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField ), timeTracker_( timeTracker ), time_( real_t(0) ), level_( level )
+{
+   WALBERLA_ASSERT_NOT_NULLPTR( pdfField_ );
+   dx_[0] = aabb.xSize() / real_c( pdfField_->xSize() );
+   dx_[1] = aabb.ySize() / real_c( pdfField_->ySize() );
+   dx_[2] = aabb.zSize() / real_c( pdfField_->zSize() );
+   origin_[0] = aabb.xMin() + real_c(0.5) * dx_[0];
+   origin_[1] = aabb.yMin() + real_c(0.5) * dx_[1];
+   origin_[2] = aabb.zMin() + real_c(0.5) * dx_[2];
+
+   if(flagField != NULL)
+   {
+      parserField_   = make_shared<ParserField>  ( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), flagField->nrOfGhostLayers(), field::zyxf );
+      velocityField_ = make_shared<VelocityField>( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), flagField->nrOfGhostLayers(), field::zyxf );
+   }
+   else
+   {
+      parserField_   = make_shared<ParserField>  ( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), pdfField->nrOfGhostLayers(),  field::zyxf );
+      velocityField_ = make_shared<VelocityField>( pdfField->xSize(), pdfField->ySize(), pdfField->zSize(), pdfField->nrOfGhostLayers(),  field::zyxf );
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+template< typename Buffer_T >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::packCell( Buffer_T & buffer, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
+{
+   if( parserField_->get( x, y, z ) )
+   {
+      auto & eqs = parserField_->get( x, y, z )->equations();
+      buffer << true << eqs[0] << eqs[1] << eqs[2];
+   }
+   else
+   {
+      buffer << false << velocityField_->get( x, y, z );
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+template< typename Buffer_T >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCell( Buffer_T & buffer, const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
+{
+   bool isparser;
+   buffer >> isparser;
+   if( isparser )
+   {
+      std::array< std::string, 3> eqs;
+      buffer >> eqs[0] >> eqs[1] >> eqs[2];
+
+      auto p = make_shared<Parser>(eqs);
+      parserField_->get( x, y, z ) = p;
+   }
+   else
+   {
+      buffer >> velocityField_->get( x, y, z );
+      parserField_->get( x, y, z ) = nullptr;
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
+                                                                                   FlagField<flag_t> * const flagField, const uint_t level, const AABB & aabb )
+   : ParserUBB( boundaryUID, uid, pdfField, flagField, nullptr, level, aabb )
+{}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
+                                                                                             const BoundaryConfiguration & parser )
+{
+   WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser );
+   WALBERLA_ASSERT_NOT_NULLPTR( parserField_ );
+
+   if( auto v = dynamic_cast< const Velocity * >( &parser ) )
+   {
+      velocityField_->get( x, y, z ) = v->velocity();
+      parserField_->get( x, y, z ) = nullptr;
+      return;
+   }
+
+   auto & p = dynamic_cast< const Parser & >( parser );
+
+   if( p.isTimeDependent() )
+   {
+      parserField_->get( x, y, z ) = make_shared<Parser>(p);
+   }
+   else
+   {
+      const Vector3< real_t > pos( origin_[0] + real_c(x) * dx_[0],
+                                   origin_[1] + real_c(y) * dx_[1],
+                                   origin_[2] + real_c(z) * dx_[2] );
+      velocityField_->get( x, y, z ) = p(pos);
+      parserField_->get( x, y, z ) = nullptr;
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCells( const flag_t, const CellInterval & cells, const BoundaryConfiguration & parser )
+{
+   WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser );
+   WALBERLA_ASSERT_NOT_NULLPTR( parserField_ );
+
+   if( auto v = dynamic_cast< const Velocity * >( &parser ) )
+   {
+      for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell )
+      {
+         velocityField_->get( cell.x(), cell.y(), cell.z() ) = v->velocity();
+         *cell = nullptr;
+      }
+      return;
+   }
+
+   auto & p = dynamic_cast< const Parser & >( parser );
+
+   if( p.isTimeDependent() )
+   {
+      auto shared_p = make_shared<Parser>(p);
+      for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell )
+         *cell = shared_p;
+   }
+   else
+   {
+      for( auto cell = parserField_->beginSliceXYZ( cells ); cell != parserField_->end(); ++cell )
+      {
+         const Vector3< real_t > pos( origin_[0] + real_c(cell.x()) * dx_[0],
+                                      origin_[1] + real_c(cell.y()) * dx_[1],
+                                      origin_[2] + real_c(cell.z()) * dx_[2] );
+         velocityField_->get( cell.x(), cell.y(), cell.z() ) = p(pos);
+         *cell = nullptr;
+      }
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+template< typename CellIterator >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::registerCells( const flag_t, const CellIterator & begin, const CellIterator & end,
+                                                                                              const BoundaryConfiguration & parser )
+{
+   WALBERLA_ASSERT_EQUAL( dynamic_cast< const Parser * >( &parser ), &parser );
+   WALBERLA_ASSERT_NOT_NULLPTR( parserField_ );
+
+   if( auto v = dynamic_cast< const Velocity * >( &parser ) )
+   {
+      for( auto cell = begin; cell != end; ++cell )
+      {
+         velocityField_->get( cell.x(), cell.y(), cell.z() ) = v->velocity();
+         parserField_->get( cell->x(), cell->y(), cell->z() ) = nullptr;
+      }
+      return;
+   }
+
+   auto & p = dynamic_cast< const Parser & >( parser );
+
+   if( p.isTimeDependent() )
+   {
+      auto shared_p = make_shared<Parser>(p);
+      for( auto cell = begin; cell != end; ++cell )
+      {
+         parserField_->get( cell->x(), cell->y(), cell->z() ) = shared_p;
+      }
+   }
+   else
+   {
+      for( auto cell = begin; cell != end; ++cell )
+      {
+         const Vector3< real_t > pos( origin_[0] + real_c(cell->x()) * dx_[0],
+                                      origin_[1] + real_c(cell->y()) * dx_[1],
+                                      origin_[2] + real_c(cell->z()) * dx_[2] );
+         velocityField_->get( cell->x(), cell->y(), cell->z() ) = p(pos);
+         parserField_->get( cell->x(), cell->y(), cell->z() ) = nullptr;
+      }
+   }
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline void ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::unregisterCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
+{
+   parserField_->get(x,y,z) = nullptr;
+}
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce>
+#ifndef NDEBUG
+inline void ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB::treatDirection( const cell_idx_t  x, const cell_idx_t  y, const cell_idx_t  z, const stencil::Direction dir,
+                                                                                                        const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t mask )
+#else
+inline void ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce>::ParserUBB::treatDirection( const cell_idx_t  x, const cell_idx_t  y, const cell_idx_t  z, const stencil::Direction dir,
+                                                                                                        const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz, const flag_t /*mask*/ )
+#endif
+   {
+      WALBERLA_ASSERT_EQUAL( nx, x + cell_idx_c( stencil::cx[ dir ] ) );
+      WALBERLA_ASSERT_EQUAL( ny, y + cell_idx_c( stencil::cy[ dir ] ) );
+      WALBERLA_ASSERT_EQUAL( nz, z + cell_idx_c( stencil::cz[ dir ] ) );
+      WALBERLA_ASSERT_UNEQUAL( mask & this->mask_, numeric_cast<flag_t>(0) );
+      WALBERLA_ASSERT_EQUAL( mask & this->mask_, this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the
+                                                                // current implementation of this boundary condition (ParserUBB)
+
+      Vector3<real_t> velocity;
+      if( parserField_->get(nx,ny,nz) )
+      {
+         WALBERLA_ASSERT_NOT_NULLPTR( getTimeTracker(), "A TimeTracker is needed for time-dependent equations" );
+         const Vector3< real_t > pos( origin_[0] + real_c(nx) * dx_[0],
+                                      origin_[1] + real_c(ny) * dx_[1],
+                                      origin_[2] + real_c(nz) * dx_[2] );
+         velocity = (*parserField_->get(nx,ny,nz))( pos, time_ );
+      }
+      else
+      {
+         velocity = velocityField_->get(nx,ny,nz);
+      }
+
+      if( LatticeModel_T::compressible )
+      {
+         const auto density  = pdfField_->getDensity(x,y,z);
+         const auto vel = AdaptVelocityToExternalForce ? lbm::internal::AdaptVelocityToForce<LatticeModel_T>::get( x, y, z, pdfField_->latticeModel(), velocity, density ) :
+                                                         velocity;
+
+         pdfField_->get( nx, ny, nz, Stencil::invDirIdx(dir) ) = pdfField_->get( x, y, z, Stencil::idx[dir] ) -
+                                                                 ( real_c(6) * density * real_c(LatticeModel_T::w[ Stencil::idx[dir] ]) *
+                                                                    ( real_c(stencil::cx[ dir ]) * vel[0] +
+                                                                      real_c(stencil::cy[ dir ]) * vel[1] +
+                                                                      real_c(stencil::cz[ dir ]) * vel[2] ) );
+      }
+      else
+      {
+         const auto vel = AdaptVelocityToExternalForce ? lbm::internal::AdaptVelocityToForce<LatticeModel_T>::get( x, y, z, pdfField_->latticeModel(), velocity, real_t(1) ) :
+                                                         velocity;
+
+         pdfField_->get( nx, ny, nz, Stencil::invDirIdx(dir) ) = pdfField_->get( x, y, z, Stencil::idx[dir] ) -
+                                                                 ( real_c(6) * real_c(LatticeModel_T::w[ Stencil::idx[dir] ]) *
+                                                                    ( real_c(stencil::cx[ dir ]) * vel[0] +
+                                                                      real_c(stencil::cy[ dir ]) * vel[1] +
+                                                                      real_c(stencil::cz[ dir ]) * vel[2] ) );
+      }
+   }
+
+
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline Vector3<real_t> ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z ) const
+{
+   return getValue( x, y, z, time_ );
+}
+
+template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce >
+inline Vector3<real_t> ParserUBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce >::getValue( const cell_idx_t x, cell_idx_t y, cell_idx_t z, real_t t ) const
+{
+   Vector3<real_t> velocity;
+   if( parserField_->get(x,y,z) )
+   {
+      WALBERLA_ASSERT_NOT_NULLPTR( getTimeTracker(), "A TimeTracker is needed for time-dependent equations" );
+      const Vector3< real_t > pos( origin_[0] + real_c(x) * dx_[0],
+                                   origin_[1] + real_c(y) * dx_[1],
+                                   origin_[2] + real_c(z) * dx_[2] );
+      velocity = (*parserField_->get(x,y,z))( pos, t );
+   }
+   else
+   {
+      velocity = velocityField_->get(x,y,z);
+   }
+   return velocity;
+}
+
+
+} // namespace lbm
+} // namespace walberla
diff --git a/src/lbm/boundary/Pressure.h b/src/lbm/boundary/Pressure.h
index a637b14d17133c33369a546163961a75e8f465a6..ae8afb05372001a7062c72df7e53a645e566e1b5 100644
--- a/src/lbm/boundary/Pressure.h
+++ b/src/lbm/boundary/Pressure.h
@@ -211,7 +211,7 @@ inline void Pressure< LatticeModel_T, flag_t >::treatDirection( const cell_idx_t
 
    WALBERLA_ASSERT_UNEQUAL( ( mask & this->mask_ ), numeric_cast<flag_t>(0) );
    WALBERLA_ASSERT_EQUAL( ( mask & this->mask_ ), this->mask_ ); // only true if "this->mask_" only contains one single flag, which is the case for the
-                                                                 // current implementation of this boundary condition (SimplePressure)
+                                                                 // current implementation of this boundary condition (Pressure)
    Vector3<real_t> u = pdfField_->getVelocity(x,y,z);
 
    // result will be streamed to (x,y,z, stencil::inverseDir[d]) during sweep
diff --git a/src/lbm/boundary/all.h b/src/lbm/boundary/all.h
index 158a9f887948684e90d55437748ff481b52e22a7..31709c60e0e538dddaaf537fe0d661fb2b4833c1 100644
--- a/src/lbm/boundary/all.h
+++ b/src/lbm/boundary/all.h
@@ -31,6 +31,7 @@
 #include "NoDiffusion.h"
 #include "NoSlip.h"
 #include "Outlet.h"
+#include "ParserUBB.h"
 #include "Pressure.h"
 #include "SimpleDiffusionDirichlet.h"
 #include "SimplePAB.h"
diff --git a/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h b/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h
index e54c74bcabbc3f53b17579fa73142860243d0037..4bee0c6c165d99ce6c57d746ddef667106e8056f 100644
--- a/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h
+++ b/src/lbm/boundary/factories/DefaultBoundaryHandlingCollection.h
@@ -26,6 +26,8 @@
 #include "lbm/boundary/factories/DefaultBoundaryHandling.h"
 #include "lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h"
 
+#include <functional>
+
 namespace walberla {
 namespace lbm{
 
@@ -67,7 +69,7 @@ public:
    static BlockDataID addDefaultBoundaryHandlingCollectionToStorage(
       const shared_ptr< StructuredBlockStorage >& bs, const std::string & identifier, const BlockDataID& flagFieldID, const BlockDataID& handlingID, const BlockDataID& diffusionHandlingID )
    {
-      auto func = boost::bind( createDefaultBoundaryHandlingCollectionFactory, _1, _2, flagFieldID, handlingID, diffusionHandlingID );
+      auto func = std::bind( createDefaultBoundaryHandlingCollectionFactory, std::placeholders::_1, std::placeholders::_2, flagFieldID, handlingID, diffusionHandlingID );
       return bs->addStructuredBlockData< BoundaryHandlingCollection_T >( func, identifier );
    }
 
diff --git a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
index 3104c3f7efda83d4cc2410729b6b0ea3b37a624a..42e3c7536baaf15361049affebc016eb46f7664d 100644
--- a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
+++ b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
@@ -36,6 +36,8 @@
 
 #include <boost/tuple/tuple.hpp>
 
+#include <functional>
+
 
 namespace walberla {
 namespace lbm{
@@ -136,7 +138,7 @@ public:
    static BlockDataID addDefaultDiffusionBoundaryHandlingToStorage(
       const shared_ptr< StructuredBlockStorage >& bs, const std::string & identifier, const BlockDataID& flagFieldID, const Set<FlagUID>& domainFlagUIDs, const BlockDataID& pdfFieldID, const Set<FlagUID>& initFlagUIDs )
    {
-      auto func = boost::bind( createDefaultDiffusionBoundaryHandlingFactory, _1, _2, flagFieldID, domainFlagUIDs, pdfFieldID, initFlagUIDs );
+      auto func = std::bind( createDefaultDiffusionBoundaryHandlingFactory, std::placeholders::_1, std::placeholders::_2, flagFieldID, domainFlagUIDs, pdfFieldID, initFlagUIDs );
       return bs->addStructuredBlockData< BoundaryHandling_T >( func, identifier );
    }
 
diff --git a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
index b12fdc4bb5ed9046d01ca2733e7e9ba66503d1c6..11ae8af9d3ca08da723e218d37b90796a6e35e85 100644
--- a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
+++ b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
@@ -24,7 +24,7 @@
 #include "lbm/boundary/FreeSlip.h"
 #include "lbm/boundary/NoSlip.h"
 #include "lbm/boundary/Pressure.h"
-#include "lbm/boundary/UBB.h"
+#include "lbm/boundary/ParserUBB.h"
 #include "lbm/boundary/Outlet.h"
 #include "lbm/boundary/Curved.h"
 
@@ -82,7 +82,7 @@ public:
    typedef NoSlip< LatticeModel, flag_t >         BcNoSlip;
    typedef FreeSlip< LatticeModel, FlagFieldT >   BcFreeSlip;
    typedef Pressure< LatticeModel, flag_t >       BcPressure;
-   typedef UBB<LatticeModel, flag_t>              BcUBB;
+   typedef ParserUBB<LatticeModel, flag_t>        BcUBB;
    typedef Outlet<LatticeModel, FlagFieldT >      BcOutlet;
    typedef Curved<LatticeModel, FlagFieldT >      BcCurved;
 
@@ -144,7 +144,7 @@ ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::ExtendedBoundaryHandl
 template <typename LatticeModel, typename FlagFieldT >
 typename ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::BoundaryHandling *
 ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( IBlock * const block,
-                                                                      const walberla::StructuredBlockStorage * const /*storage*/ ) const
+                                                                      const walberla::StructuredBlockStorage * const storage ) const
 {
    PdfFieldLM * const pdfField  = block->getData< PdfFieldLM >( pdfField_  );
    FlagFieldT * const flagField = block->getData< FlagFieldT >( flagField_ );
@@ -160,7 +160,7 @@ ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( IBlock *
         BcNoSlip    ( getNoSlipBoundaryUID(),   getNoSlip(),   pdfField ),
         BcFreeSlip  ( getFreeSlipBoundaryUID(), getFreeSlip(), pdfField, flagField, mask ),
         BcPressure  ( getPressureBoundaryUID(), getPressure(), pdfField ),
-        BcUBB       ( getUBBBoundaryUID(),      getUBB(),      pdfField ),
+        BcUBB       ( getUBBBoundaryUID(),      getUBB(),      pdfField, flagField, storage->getLevel(*block), block->getAABB() ),
         BcOutlet    ( getOutletBoundaryUID(),   getOutlet(),   pdfField, flagField, mask ),
         BcCurved    ( getCurvedBoundaryUID(),   getCurved(),   pdfField, flagField, mask )
       )
diff --git a/src/lbm/python/ExportBasic.impl.h b/src/lbm/python/ExportBasic.impl.h
index afae7a5a105fc0e4067d694eaa74e19b5817bb51..c0097f54eccce9d73217935797c41a37e9d3763e 100644
--- a/src/lbm/python/ExportBasic.impl.h
+++ b/src/lbm/python/ExportBasic.impl.h
@@ -165,7 +165,7 @@ namespace internal
       using namespace boost::python;
 
       LatticeModelCreator creator( compressible, equilibriumAccuracyOrder, stencil, collisionModel, forceModel );
-      python_coupling::for_each_noncopyable_type<LatticeModels>( boost::ref(creator) );
+      python_coupling::for_each_noncopyable_type<LatticeModels>( std::ref(creator) );
 
       if ( creator.getResult() == object() )
       {
@@ -346,7 +346,7 @@ namespace internal
 
       internal::AddPdfFieldToStorageExporter exporter( blocks, identifier, latticeModel, initialVelocity,
                                                        initialDensity, gl, layout, densityAdaptor, velocityAdaptor, shearRateAdaptor );
-      python_coupling::for_each_noncopyable_type< LatticeModels >  ( boost::ref(exporter) );
+      python_coupling::for_each_noncopyable_type< LatticeModels >  ( std::ref(exporter) );
       if ( ! exporter.successful() ) {
          PyErr_SetString( PyExc_ValueError, "Adding Pdf Field failed.");
          throw error_already_set();
diff --git a/src/lbm/python/ExportBoundary.impl.h b/src/lbm/python/ExportBoundary.impl.h
index 009bda5324524ea24c7c42ea8397b78b3f2ccd40..06845e35a29f9b4d9b5635944145766ea6e5e9f2 100644
--- a/src/lbm/python/ExportBoundary.impl.h
+++ b/src/lbm/python/ExportBoundary.impl.h
@@ -227,7 +227,7 @@ namespace internal
       }
 
       ExtendedBoundaryHandlingCreator creator( bs, name, pdfFieldID, flagFieldID );
-      python_coupling::for_each_noncopyable_type<LatticeModels>( boost::ref( creator ) );
+      python_coupling::for_each_noncopyable_type<LatticeModels>( std::ref( creator ) );
 
       if ( ! creator.successful() )
       {
diff --git a/src/lbm/python/ExportSweeps.impl.h b/src/lbm/python/ExportSweeps.impl.h
index fa01bf969cc7d9acce88e5eac7bd042da93d8c33..5f9440114375038cd2c75a17e82ef13dcb45ae83 100644
--- a/src/lbm/python/ExportSweeps.impl.h
+++ b/src/lbm/python/ExportSweeps.impl.h
@@ -221,7 +221,7 @@ namespace internal
       auto flagUidSet = python_coupling::uidSetFromStringContainer< FlagUID >( flagList );
 
       CellwiseSweepCreator creator( bs, pdfFieldID, flagFieldStringID, velocityFieldStringID, flagUidSet );
-      python_coupling::for_each_noncopyable_type<LatticeModel_FlagField_Pairs>( boost::ref( creator ) );
+      python_coupling::for_each_noncopyable_type<LatticeModel_FlagField_Pairs>( std::ref( creator ) );
 
       if ( creator.getResult() == object() )
       {
diff --git a/src/mesh/blockforest/BlockForestInitialization.h b/src/mesh/blockforest/BlockForestInitialization.h
index 6f9018beb5617cbb98718e8c285a529eac9ede9e..1c39d1c2ec8c340e53647e36a20577c131fdbcd4 100644
--- a/src/mesh/blockforest/BlockForestInitialization.h
+++ b/src/mesh/blockforest/BlockForestInitialization.h
@@ -21,6 +21,10 @@
 
 #pragma once
 
+#include "BlockExclusion.h"
+#include "mesh/MeshOperations.h"
+#include "mesh/distance_octree/DistanceOctree.h"
+
 #include "blockforest/StructuredBlockForest.h"
 #include "blockforest/SetupBlockForest.h"
 #include "blockforest/loadbalancing/StaticCurve.h"
@@ -110,5 +114,37 @@ private:
 };
 
 
+template< typename MeshType >
+shared_ptr<StructuredBlockForest> createStructuredBlockStorageInsideMesh( const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const Vector3<uint_t> & blockSize )
+{
+   ComplexGeometryStructuredBlockforestCreator creator( distanceOctree->getAABB(), Vector3<real_t>(dx), makeExcludeMeshExterior( distanceOctree, dx ) );
+   return creator.createStructuredBlockForest( blockSize );
+}
+
+
+template< typename MeshType >
+shared_ptr<StructuredBlockForest> createStructuredBlockStorageOutsideMesh( const AABB & aabb, const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const Vector3<uint_t> & blockSize )
+{
+   ComplexGeometryStructuredBlockforestCreator creator( aabb, Vector3<real_t>(dx), makeExcludeMeshInterior( distanceOctree, dx ) );
+   return creator.createStructuredBlockForest( blockSize );
+}
+
+
+template< typename MeshType >
+shared_ptr<StructuredBlockForest> createStructuredBlockStorageInsideMesh( const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const uint_t targetNumRootBlocks )
+{
+   ComplexGeometryStructuredBlockforestCreator creator( distanceOctree->getAABB(), Vector3<real_t>(dx), makeExcludeMeshExterior( distanceOctree, dx ) );
+   return creator.createStructuredBlockForest( targetNumRootBlocks );
+}
+
+
+template< typename MeshType >
+shared_ptr<StructuredBlockForest> createStructuredBlockStorageOutsideMesh( const AABB & aabb, const shared_ptr< mesh::DistanceOctree< MeshType > > & distanceOctree, const real_t dx, const uint_t targetNumRootBlocks )
+{
+   ComplexGeometryStructuredBlockforestCreator creator( aabb, Vector3<real_t>(dx), makeExcludeMeshInterior( distanceOctree, dx ) );
+   return creator.createStructuredBlockForest( targetNumRootBlocks );
+}
+
+
 } // namespace mesh
 } // namespace walberla
\ No newline at end of file
diff --git a/src/mesh/boundary/BoundarySetup.cpp b/src/mesh/boundary/BoundarySetup.cpp
index b8390b6b71ecf287821ab4f2694f5b6fcc628aea..c0edcc1ed81ce102e05eefb1556825730d39b582 100644
--- a/src/mesh/boundary/BoundarySetup.cpp
+++ b/src/mesh/boundary/BoundarySetup.cpp
@@ -27,6 +27,21 @@
 namespace walberla {
 namespace mesh {
 
+
+BoundarySetup::BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers )
+   : structuredBlockStorage_( structuredBlockStorage ), distanceFunction_( distanceFunction ), numGhostLayers_( numGhostLayers ), cellVectorChunkSize_( size_t(1000) )
+{
+   voxelize();
+
+   try {
+      auto & blockForest = dynamic_cast< StructuredBlockForest & >( *structuredBlockStorage_ );
+      if( !blockForest.storesUniformBlockGrid() )
+         refinementCorrection( blockForest );
+   }
+   catch( const std::bad_cast &  ) {} // If it's not a BlockForest no refinement correction is done
+}
+
+
 void BoundarySetup::divideAndPushCellInterval( const CellInterval & ci, std::queue< CellInterval > & outputQueue )
 {
    WALBERLA_ASSERT( !ci.empty() );
@@ -66,15 +81,15 @@ void BoundarySetup::allocateOrResetVoxelizationField()
 {
    if( voxelizationFieldId_ )
    {
-      for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt )
+      for( auto & block : *structuredBlockStorage_ )
       {
-         VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ );
+         VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
          voxelizationField->setWithGhostLayer( uint8_t(0) );
       }
    }
    else
    {
-      voxelizationFieldId_ = make_shared< BlockDataID >( field::addToStorage< VoxelizationField >( structuredBlockStorage_, "flag field", uint8_t(0), field::zyxf, numGhostLayers_ ) );
+      voxelizationFieldId_ = make_shared< BlockDataID >( field::addToStorage< VoxelizationField >( structuredBlockStorage_, "voxelization field", uint8_t(0), field::zyxf, numGhostLayers_ ) );
    }
 
    WALBERLA_ASSERT_NOT_NULLPTR( voxelizationFieldId_ );
@@ -93,15 +108,15 @@ void BoundarySetup::voxelize()
 {
    allocateOrResetVoxelizationField();
 
-   for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt )
+   for( auto & block : *structuredBlockStorage_ )
    {
-      VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ );
+      VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
 
       WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField );
       WALBERLA_ASSERT_EQUAL( numGhostLayers_, voxelizationField->nrOfGhostLayers() );
 
       CellInterval blockCi = voxelizationField->xyzSizeWithGhostLayer();
-      structuredBlockStorage_->transformBlockLocalToGlobalCellInterval( blockCi, *blockIt );
+      structuredBlockStorage_->transformBlockLocalToGlobalCellInterval( blockCi, block );
 
       std::queue< CellInterval > ciQueue;
       ciQueue.push( blockCi );
@@ -112,7 +127,7 @@ void BoundarySetup::voxelize()
 
          WALBERLA_ASSERT( !curCi.empty(), "Cell Interval: " << curCi );
 
-         AABB curAABB = structuredBlockStorage_->getAABBFromCellBB( curCi, structuredBlockStorage_->getLevel( *blockIt ) );
+         AABB curAABB = structuredBlockStorage_->getAABBFromCellBB( curCi, structuredBlockStorage_->getLevel( block ) );
 
          WALBERLA_ASSERT( !curAABB.empty(), "AABB: " << curAABB );
 
@@ -125,7 +140,7 @@ void BoundarySetup::voxelize()
             if( ( sqSignedDistance < real_t(0) ) )
             {
                Cell localCell;
-               structuredBlockStorage_->transformGlobalToBlockLocalCell( localCell, *blockIt, curCi.min() );
+               structuredBlockStorage_->transformGlobalToBlockLocalCell( localCell, block, curCi.min() );
                voxelizationField->get( localCell ) = uint8_t(1);
             }
 
@@ -140,7 +155,7 @@ void BoundarySetup::voxelize()
          {
             // clearly the cell interval is fully covered by the mesh
             CellInterval localCi;
-            structuredBlockStorage_->transformGlobalToBlockLocalCellInterval( localCi, *blockIt, curCi );
+            structuredBlockStorage_->transformGlobalToBlockLocalCellInterval( localCi, block, curCi );
             std::fill( voxelizationField->beginSliceXYZ( localCi ), voxelizationField->end(), uint8_t(1) );
 
             ciQueue.pop();
@@ -163,6 +178,78 @@ void BoundarySetup::voxelize()
    }
 }
 
+void BoundarySetup::refinementCorrection( StructuredBlockForest & blockForest )
+{
+   if(    blockForest.getNumberOfXCellsPerBlock() < uint_t( 16 )
+       || blockForest.getNumberOfYCellsPerBlock() < uint_t( 16 )
+       || blockForest.getNumberOfZCellsPerBlock() < uint_t( 16 ) )
+   {
+      WALBERLA_ABORT( "The mesh boundary setup requires a block size of at least 16 in each dimension, when refinement is used!" );
+   }
+
+   for( auto & iBlock : blockForest )
+   {
+      auto & block = dynamic_cast< blockforest::Block & >( iBlock );
+
+      const uint_t level = block.getLevel();
+
+      VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
+      const CellInterval cells = voxelizationField->xyzSize();
+
+      std::vector< CellInterval > coarseRegions;
+      for( auto dir = stencil::D3Q27::beginNoCenter(); dir != stencil::D3Q27::end(); ++dir )
+      {
+         const auto index = blockforest::getBlockNeighborhoodSectionIndex( dir.cx(), dir.cy(), dir.cz() );
+         if( block.neighborhoodSectionHasLargerBlock( index ) )
+         {
+            CellInterval coarseRegion( cells );
+            for( uint_t i = 0; i != 3; ++i )
+            {
+               const auto c = stencil::c[i][*dir];
+
+               if( c == -1 ) 
+               {
+                  coarseRegion.min()[i] -= cell_idx_c( numGhostLayers_ );
+                  coarseRegion.max()[i] = cells.min()[i] + cell_idx_c( 2 * numGhostLayers_ - 1 );
+               }
+               else if( c == 1 )
+               {
+                  coarseRegion.min()[i] = cells.max()[i] - cell_idx_c( 2 * numGhostLayers_ - 1 );
+                  coarseRegion.max()[i] += cell_idx_c( numGhostLayers_ );
+               }
+            }
+            coarseRegions.push_back( coarseRegion );
+         }
+      }
+
+      for( const CellInterval & coarseRegion : coarseRegions)
+         for( const Cell & cell : coarseRegion )
+         {
+            Cell globalCell( cell );
+            structuredBlockStorage_->transformBlockLocalToGlobalCell( globalCell, block );
+
+            Cell coarseCell( globalCell );
+            for( uint_t i = 0; i < 3; ++i )
+            {
+               if( coarseCell[i] < cell_idx_t(0) )
+               {
+                  coarseCell[i] = -( ( cell_idx_t(1) - coarseCell[i] ) >> 1 );
+               }
+               else
+               {
+                  coarseCell[i] >>= 1;
+               }
+            }
+
+            Vector3< real_t > coarseCenter;
+            structuredBlockStorage_->getCellCenter( coarseCenter, coarseCell, level - uint_t(1) );
+            structuredBlockStorage_->mapToPeriodicDomain( coarseCenter );
+
+            voxelizationField->get( cell ) =  distanceFunction_( coarseCenter ) < real_t(0) ? uint8_t(1) : uint8_t(0);
+         }
+   }
+}
+
 
 void BoundarySetup::writeVTKVoxelfile( const std::string & identifier, bool writeGhostLayers, const std::string & baseFolder, const std::string & executionFolder )
 {
diff --git a/src/mesh/boundary/BoundarySetup.h b/src/mesh/boundary/BoundarySetup.h
index 08840ed0ae24502e7248d9831351b955d15f0d30..1512fe618a89281707dae40e6c6465b01fb0258d 100644
--- a/src/mesh/boundary/BoundarySetup.h
+++ b/src/mesh/boundary/BoundarySetup.h
@@ -23,6 +23,8 @@
 
 #include "BoundaryInfo.h"
 
+#include "blockforest/StructuredBlockForest.h"
+
 #include "core/DataTypes.h"
 #include "core/cell/CellInterval.h"
 
@@ -50,11 +52,7 @@ public:
 
    enum Location { INSIDE, OUTSIDE };
 
-   BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers )
-      : structuredBlockStorage_( structuredBlockStorage ), distanceFunction_( distanceFunction ), numGhostLayers_( numGhostLayers ), cellVectorChunkSize_( size_t(1000) )
-   {
-      voxelize();
-   }
+   BoundarySetup( const shared_ptr< StructuredBlockStorage > & structuredBlockStorage, const DistanceFunction & distanceFunction, const uint_t numGhostLayers );
 
    ~BoundarySetup() { deallocateVoxelizationField(); }
 
@@ -79,12 +77,13 @@ private:
    void deallocateVoxelizationField();
 
    void voxelize();
+   void refinementCorrection( StructuredBlockForest & blockForest );
 
    shared_ptr< StructuredBlockStorage >       structuredBlockStorage_;
    shared_ptr< BlockDataID >                  voxelizationFieldId_;
-   DistanceFunction                           distanceFunction_;  // function providing the squared signed distance to an object
+   DistanceFunction                           distanceFunction_;  /// function providing the squared signed distance to an object
    uint_t                                     numGhostLayers_;
-   size_t                                     cellVectorChunkSize_;
+   size_t                                     cellVectorChunkSize_; /// Number of boundary cells which are setup simultaneously 
 };
 
 
@@ -92,12 +91,12 @@ private:
 template< typename BoundaryHandlingType >
 void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const Location domainLocation )
 {
-   for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt )
+   for( auto & block : *structuredBlockStorage_ )
    {
-      BoundaryHandlingType * boundaryHandling  = blockIt->getData< BoundaryHandlingType >( boundaryHandlingId  );
+      BoundaryHandlingType * boundaryHandling  = block.getData< BoundaryHandlingType >( boundaryHandlingId  );
       WALBERLA_CHECK_NOT_NULLPTR( boundaryHandling, "boundaryHandlingId invalid!" );
 
-      const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ );
+      const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
       WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField );
       WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, boundaryHandling->getFlagField()->nrOfGhostLayers(), "You want to use mesh boundary setup with " \
                                  << numGhostLayers_ << " but your flag field has only " << boundaryHandling->getFlagField()->nrOfGhostLayers() << " ghost layers!" );
@@ -111,7 +110,7 @@ void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const
             for( cell_idx_t x = -cell_idx_c( numGhostLayers_ ); x < cell_idx_c( voxelizationField->xSize() + numGhostLayers_ ); ++x )
             {
                if( voxelizationField->get( x, y, z ) == domainValue )
-                  domainCells.push_back( Cell(x,y,z) );
+                  domainCells.emplace_back( x, y, z );
 
                if( domainCells.size() > cellVectorChunkSize_ )
                {
@@ -128,13 +127,13 @@ void BoundarySetup::setDomainCells( const BlockDataID boundaryHandlingId, const
 template<typename FlagField_T>
 void BoundarySetup::setFlag( const BlockDataID flagFieldID, field::FlagUID flagUID, Location boundaryLocation )
 {
-   for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt )
+   for( auto & block : *structuredBlockStorage_ )
    {
-      FlagField_T * flagField  = blockIt->getData< FlagField_T >( flagFieldID );
+      FlagField_T * flagField  = block.getData< FlagField_T >( flagFieldID );
       WALBERLA_CHECK_NOT_NULLPTR( flagField, "flagFieldID invalid!" );
       auto flag = flagField->getFlag(flagUID);
 
-      const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField >( *voxelizationFieldId_ );
+      const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
       WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField );
       WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, flagField->nrOfGhostLayers(), "You want to use mesh boundary setup with " \
                                  << numGhostLayers_ << " but your flag field has only " << flagField->nrOfGhostLayers() << " ghost layers!" );
@@ -155,12 +154,12 @@ void BoundarySetup::setFlag( const BlockDataID flagFieldID, field::FlagUID flagU
 template< typename BoundaryHandlingType, typename BoundaryFunction, typename Stencil >
 void BoundarySetup::setBoundaries( const BlockDataID boundaryHandlingID, const BoundaryFunction & boundaryFunction, Location boundaryLocation )
 {
-   for( auto blockIt = structuredBlockStorage_->begin(); blockIt != structuredBlockStorage_->end(); ++blockIt )
+   for( auto & block : *structuredBlockStorage_ )
    {
-      BoundaryHandlingType * boundaryHandling  = blockIt->getData< BoundaryHandlingType >( boundaryHandlingID  );
+      BoundaryHandlingType * boundaryHandling  = block.getData< BoundaryHandlingType >( boundaryHandlingID  );
       WALBERLA_CHECK_NOT_NULLPTR( boundaryHandling, "boundaryHandlingId invalid!" );
 
-      const VoxelizationField * voxelizationField = blockIt->getData< VoxelizationField    >( *voxelizationFieldId_ );
+      const VoxelizationField * voxelizationField = block.getData< VoxelizationField >( *voxelizationFieldId_ );
       WALBERLA_ASSERT_NOT_NULLPTR( voxelizationField );
       WALBERLA_CHECK_LESS_EQUAL( numGhostLayers_, boundaryHandling->getFlagField()->nrOfGhostLayers(), "You want to use mesh boundary setup with " \
                                  << numGhostLayers_ << " but your flag field has only " << boundaryHandling->getFlagField()->nrOfGhostLayers() << " ghost layers!" );
@@ -182,7 +181,7 @@ void BoundarySetup::setBoundaries( const BlockDataID boundaryHandlingID, const B
                   const Cell neighborCell = cell + *dirIt;
                   if( blockCi.contains( neighborCell ) && voxelizationField->get( neighborCell ) == domainValue )
                   {
-                     const Vector3< real_t > cellCenter = structuredBlockStorage_->getBlockLocalCellCenter( *blockIt, cell );
+                     const Vector3< real_t > cellCenter = structuredBlockStorage_->getBlockLocalCellCenter( block, cell );
                      const BoundaryInfo & bi = boundaryFunction( cellCenter );
                      const auto boundaryMask = boundaryHandling->getBoundaryMask( bi.getUid() );
 
diff --git a/src/mesh/pe/Types.h b/src/mesh/pe/Types.h
index 842ba1132befa7e72d0d09f7c50a4889406d693b..6d94fad9c463f5ee0ff1bd645bf8d7e16ec18834 100644
--- a/src/mesh/pe/Types.h
+++ b/src/mesh/pe/Types.h
@@ -19,6 +19,8 @@
 //
 //======================================================================================================================
 
+#include <memory>
+
 namespace walberla {
 namespace mesh {
 namespace pe {
@@ -28,6 +30,7 @@ class ConvexPolyhedron;
 typedef ConvexPolyhedron        ConvexPolyhedronType;    //!< Type of the convex polyhedron geometric primitive.
 typedef ConvexPolyhedron*       ConvexPolyhedronID;      //!< Handle for a convexpolyhedron primitive.
 typedef const ConvexPolyhedron* ConstConvexPolyhedronID; //!< Handle for a constant convex polyhedron primitive.
+using   ConvexPolyhedronPtr   = std::unique_ptr<ConvexPolyhedron>;
 
 } // namespace pe
 } // namespace mesh
diff --git a/src/mesh/pe/communication/ConvexPolyhedron.h b/src/mesh/pe/communication/ConvexPolyhedron.h
index ef9bbb21cf1b6f4f8883a867395dbee0b8f5080f..df14bb1762f9755225f004d2730a76be617ed236 100644
--- a/src/mesh/pe/communication/ConvexPolyhedron.h
+++ b/src/mesh/pe/communication/ConvexPolyhedron.h
@@ -69,16 +69,17 @@ namespace pe {
 namespace communication {
 
 template<>
-inline mesh::pe::ConvexPolyhedronID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, mesh::pe::ConvexPolyhedronID& newBody )
+inline mesh::pe::ConvexPolyhedronPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, mesh::pe::ConvexPolyhedronID& newBody )
 {
    mesh::pe::ConvexPolyhedronParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new mesh::pe::ConvexPolyhedron( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto cp = std::make_unique<mesh::pe::ConvexPolyhedron>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.mesh_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   cp->setLinearVel( subobjparam.v_ );
+   cp->setAngularVel( subobjparam.w_ );
+   cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = static_cast<mesh::pe::ConvexPolyhedronID>(cp.get());
+   return cp;
 }
 
 }  // namespace communication
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
index 959215e94d18a34d34741e2a99f3b590e4a66d38..63c268ae6031a333d50e2720d8dacf8adeb97b93 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
@@ -65,7 +65,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
 {
    WALBERLA_ASSERT_UNEQUAL( ConvexPolyhedron::getStaticTypeID(), std::numeric_limits<id_t>::max(), "ConvexPolyhedron TypeID not initalized!");
 
-   ConvexPolyhedronID poly = NULL;
+   ConvexPolyhedronID poly = nullptr;
 
    Vec3 centroid = toWalberla( computeCentroid( mesh ) );
    translate( mesh, -centroid );
@@ -78,33 +78,30 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
       WALBERLA_CHECK_EQUAL(communicating, false, "Global bodies can not be communicating!" );
       WALBERLA_CHECK_EQUAL(infiniteMass, true, "Global bodies must have infinite mass!" );
 
-      poly = new ConvexPolyhedron(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, false, true);
-      globalStorage.add(poly);
+      auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, false, true);
+      poly = static_cast<ConvexPolyhedronID>(&globalStorage.add(std::move(cp)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            poly = new ConvexPolyhedron(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, communicating, infiniteMass);
-            poly->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(poly);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            auto cp = std::make_unique<ConvexPolyhedron>(sid, uid, gpos, Vec3(0,0,0), Quat(), mesh, material, global, communicating, infiniteMass);
+            cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            poly = static_cast<ConvexPolyhedronID>(&bs.add( std::move(cp) ) );
          }
       }
    }
 
-   if (poly != NULL)
+   if (poly != nullptr)
    {
       // Logging the successful creation of the box
       WALBERLA_LOG_DETAIL(
                 "Created ConvexPolyhedron " << poly->getSystemID() << "\n"
              << "   User-ID         = " << uid << "\n"
              << "   Global position = " << gpos << "\n"
-             << "   side length     = " << lengths << "\n"
-             << "   LinVel          = " << box->getLinearVel() << "\n"
              << "   Material        = " << Material::getName( material )
                );
    }
diff --git a/src/mesh/pe/vtk/CommonDataSources.h b/src/mesh/pe/vtk/CommonDataSources.h
index d2454c15cd6a59e836e6f97dba550b0d6696281e..bf86f2cddcde9b3283cf454cab882896212f0c42 100644
--- a/src/mesh/pe/vtk/CommonDataSources.h
+++ b/src/mesh/pe/vtk/CommonDataSources.h
@@ -189,6 +189,8 @@ public:
    LinearVelocityFaceDataSource( const std::string & _name = "linearVelocity" )
       : Base( _name ) { }
 
+   virtual ~LinearVelocityFaceDataSource() = default;
+
    virtual uint_t numComponents() { return uint_t(3); }
 
    virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer )
@@ -249,6 +251,8 @@ public:
    AngularVelocityFaceDataSource( const std::string & _name = "angularVelocity" )
       : Base( _name ) { }
 
+   virtual ~AngularVelocityFaceDataSource() = default;
+
    virtual uint_t numComponents() { return uint_t(3); }
 
    virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer )
@@ -279,6 +283,8 @@ public:
    SurfaceVelocityVertexDataSource( const std::string & _name = "surfaceVelocity" )
       : Base( _name ) { }
 
+   virtual ~SurfaceVelocityVertexDataSource() = default;
+
    virtual uint_t numComponents() { return uint_t(3); }
 
    virtual void getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data, const BodyPointerVPropManager & bodyPointer )
diff --git a/src/mesh/pe/vtk/PeVTKMeshWriter.h b/src/mesh/pe/vtk/PeVTKMeshWriter.h
index 55721ae20d67cdad08ed468ab8fe7378a4818e47..72685c362bbd486418b9edd1002db50347f1c712 100644
--- a/src/mesh/pe/vtk/PeVTKMeshWriter.h
+++ b/src/mesh/pe/vtk/PeVTKMeshWriter.h
@@ -186,16 +186,16 @@ protected:
          const walberla::pe::BodyStorage & bodyStorage = (*storage)[0];
          for(auto bodyIt = bodyStorage.begin(); bodyIt != bodyStorage.end(); ++bodyIt)
          {
-            if (!bodyFilter_(**bodyIt)) continue;
+            if (!bodyFilter_(*bodyIt)) continue;
             newVertices.clear();
             newFaces.clear();
-            tesselation_( **bodyIt, *mesh_, newVertices, newFaces );
+            tesselation_( *bodyIt, *mesh_, newVertices, newFaces );
 
             for( const auto & fh: newFaces )
-               faceBodyPointer_[fh] = *bodyIt;
+               faceBodyPointer_[fh] = bodyIt.getBodyID();
 
             for( const auto & vh: newVertices )
-               vertexBodyPointer_[vh] = *bodyIt;
+               vertexBodyPointer_[vh] = bodyIt.getBodyID();
 
          }
       }
diff --git a/src/mesh/vtk/VTKMeshWriter.h b/src/mesh/vtk/VTKMeshWriter.h
index cf01acf7e4c5451faa2459703a845228f9a9a8e0..129c456a1696a408484a67fb6b26a6933bfa6c6a 100644
--- a/src/mesh/vtk/VTKMeshWriter.h
+++ b/src/mesh/vtk/VTKMeshWriter.h
@@ -52,6 +52,7 @@ public:
    {
    public:
       DataSource( const std::string & _name ) : name_( _name ) { }
+      virtual ~DataSource() = default;
       typedef T value_type;
       virtual uint_t      numComponents() = 0;
       const std::string & name() { return name_; }
@@ -67,6 +68,7 @@ public:
       typedef typename VTKMeshWriter::Vertices Vertices;
 
       VertexDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
+      virtual ~VertexDataSource() = default;
       virtual void getData( const MeshType &, const Vertices & vertices, std::vector<T> & ) = 0;
    };
 
@@ -78,6 +80,7 @@ public:
       typedef typename VTKMeshWriter::Faces Faces;
 
       FaceDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
+      virtual ~FaceDataSource() = default;
       virtual void getData( const MeshType &, const Faces & faces, std::vector<T> & ) = 0;
    };
 
diff --git a/src/pde/iterations/VCycles.h b/src/pde/iterations/VCycles.h
index eca2b908fc5420cb24b1889e0bba71c2c2cbe86d..1d6f12fa61b1d5225cbd053584d9830139a819a2 100644
--- a/src/pde/iterations/VCycles.h
+++ b/src/pde/iterations/VCycles.h
@@ -32,6 +32,7 @@
 
 #include "pde/sweeps/RBGSFixedStencil.h"
 #include "pde/sweeps/RBGS.h"
+#include "pde/sweeps/Multigrid.h"
 
 #include <functional>
 
@@ -41,7 +42,21 @@
 namespace walberla {
 namespace pde {
 
-template< typename Stencil_T >
+//**********************************************************************************************************************
+/*!
+ *   \brief Class for multigrid V-cycle
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ *   \tparam OperatorCoarsening_T The coarsening operator to use, defaults to direct coarsening
+ *   \tparam Restrict_T The restriction operator to use
+ *   \tparam ProlongateAndCorrect_T The prolongation and correction operator to use
+ */
+//**********************************************************************************************************************
+template< typename Stencil_T,
+          typename OperatorCoarsening_T = CoarsenStencilFieldsDCA<Stencil_T>,
+          typename Restrict_T = Restrict<Stencil_T>,
+          typename ProlongateAndCorrect_T = ProlongateAndCorrect<Stencil_T>
+        >
 class VCycles
 {
 public:
@@ -50,6 +65,21 @@ public:
    typedef std::vector< real_t  > Weight_T;
    typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
 
+   //*******************************************************************************************************************
+   /*! Creates a multigrid V-cycle with a fixed stencil
+    * \param blocks the block storage where the fields are stored
+    * \param uFieldId the block data id of the solution field on the finest level
+    * \param fFieldId the block data id of the right-hand side field on the finest level
+    * \param weights vector of stencil weights for the discrete operator
+    * \param iterations maximum number of V-cycles to perform
+    * \param numLvl number of grid levels to use (including the finest level)
+    * \param preSmoothingIters number of Gauss-Seidel iterations before restriction
+    * \param postSmoothingIters number of Gauss-Seidel iterations after prolongation
+    * \param coarseIters number of Conjugate Gradient iterations on coarsest grid
+    * \param residualNorm function that returns the norm of the current residuum
+    * \param residualNormThreshold norm threshold below which the iteration is terminated
+    * \param residualCheckFrequency how often to check whether the threshold has been reached
+    *******************************************************************************************************************/
    VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
             const Weight_T weights,
             const uint_t iterations, const uint_t numLvl,
@@ -59,8 +89,25 @@ public:
             const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
             const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() );
 
+   //*******************************************************************************************************************
+   /*! Creates a multigrid V-cycle with a stencil field
+    * \param blocks the block storage where the fields are stored
+    * \param uFieldId the block data id of the solution field on the finest level
+    * \param fFieldId the block data id of the right-hand side field on the finest level
+    * \param stencilFieldId the block data id of the stencil field for the finest level.
+    *                       The values stored in the field must not change after this class has been constructed.
+    * \param operatorCoarsening function that performs the stencil coarsening
+    * \param iterations maximum number of V-cycles to perform
+    * \param numLvl number of grid levels to use (including the finest level)
+    * \param preSmoothingIters number of Gauss-Seidel iterations before restriction
+    * \param postSmoothingIters number of Gauss-Seidel iterations after prolongation
+    * \param coarseIters number of Conjugate Gradient iterations on coarsest grid
+    * \param residualNorm function that returns the norm of the current residuum
+    * \param residualNormThreshold norm threshold below which the iteration is terminated
+    * \param residualCheckFrequency how often to check whether the threshold has been reached
+    *******************************************************************************************************************/
    VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
-            const BlockDataID & stencilFieldId,
+            const BlockDataID & stencilFieldId, const OperatorCoarsening_T & operatorCoarsening,
             const uint_t iterations, const uint_t numLvl,
             const uint_t preSmoothingIters, const uint_t postSmoothingIters,
             const uint_t coarseIters, const std::function< real_t () > & residualNorm,
@@ -76,9 +123,7 @@ public:
    const std::vector<real_t> & convergenceRate() { return convergenceRate_; }
    static Vector3<uint_t> getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block );
 
-protected:
-
-   void coarsenStencilFields();
+private:
 
    StructuredBlockForest & blocks_;
    std::vector< Weight_T  > weights_;
diff --git a/src/pde/iterations/VCycles.impl.h b/src/pde/iterations/VCycles.impl.h
index a35cf35779f8dd3396a6792a4fedeaad7e7957e3..f202d89e20b45e8c3cd26fb9398b0acbff6fb1cc 100644
--- a/src/pde/iterations/VCycles.impl.h
+++ b/src/pde/iterations/VCycles.impl.h
@@ -39,10 +39,10 @@
 namespace walberla {
 namespace pde {
 
-template< typename Stencil_T >
-VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
-        const Weight_T weights,
-        const uint_t iterations, const uint_t numLvl,
+template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T >
+VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycles(
+		shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
+        const Weight_T weights, const uint_t iterations, const uint_t numLvl,
         const uint_t preSmoothingIters, const uint_t postSmoothingIters,
         const uint_t coarseIters, const std::function< real_t () > & residualNorm,
         const real_t residualNormThreshold, const uint_t residualCheckFrequency,
@@ -54,6 +54,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    iterationsPerformed_( uint_t(0) ), thresholdReached_( false ), residualNorm_( residualNorm ), convergenceRate_(), stencilId_(),
    requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
 {
+
+   static_assert(std::is_same<OperatorCoarsening_T, CoarsenStencilFieldsDCA<Stencil_T>>::value, "Use of weight requires DCA, use constructor with stencil field if you want to employ GCA");
+
    // Set up fields for finest level
    uId_.push_back( uFieldId );
    fId_.push_back( fFieldId );
@@ -87,7 +90,7 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    // Set up fields for coarser levels
    for ( uint_t lvl = 1; lvl < numLvl; ++lvl )
    {
-      auto getSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
+      auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
       uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
       fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
       rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
@@ -100,7 +103,7 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    }
 
    // Set up fields for CG on coarsest level
-   auto getFineSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
+   auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
    dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::zyxf, uint_t(1) );
    zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::zyxf, uint_t(1) );
 
@@ -132,9 +135,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    for (uint_t lvl = 0; lvl < numLvl-1; ++lvl)
    {
       computeResidual_.push_back( ComputeResidualFixedStencil< Stencil_T >( blocks, uId_[lvl], fId_[lvl], weights_[lvl], rId_[lvl] ) );
-      restrict_.push_back( Restrict< Stencil_T >(blocks, rId_[lvl], fId_[lvl+1] ) );
+      restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) );
       zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) );
-      prolongateAndCorrect_.push_back( ProlongateAndCorrect< Stencil_T >(blocks, uId_[lvl+1], uId_[lvl]) );
+      prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) );
    }
 
    // Set up CG coarse-grid iteration
@@ -145,9 +148,10 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
 
 
 
-template< typename Stencil_T >
-VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
-        const BlockDataID & stencilFieldId,
+template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T >
+VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycles(
+		shared_ptr< StructuredBlockForest > blocks, const BlockDataID & uFieldId, const BlockDataID & fFieldId,
+        const BlockDataID & stencilFieldId, const OperatorCoarsening_T & operatorCoarsening,
         const uint_t iterations, const uint_t numLvl,
         const uint_t preSmoothingIters, const uint_t postSmoothingIters,
         const uint_t coarseIters, const std::function< real_t () > & residualNorm,
@@ -192,17 +196,19 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    // Set up fields for coarser levels
    for ( uint_t lvl = 1; lvl < numLvl; ++lvl )
    {
-      auto getSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
+      auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
       uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
       fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
       rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
       stencilId_.push_back( field::addToStorage< StencilField_T >( blocks, "w_"+boost::lexical_cast<std::string>(lvl), getSize, real_t(0), field::zyxf, uint_t(1) ) );
    }
 
-   coarsenStencilFields(); // scaling by ( 1/h^2 )^lvl
+   // CoarsenStencilFieldsDCA<Stencil_T>( blocks, stencilId_, numLvl, uint_t(2)) ();  // scaling by ( 1/h^2 )^lvl
+   // CoarsenStencilFieldsGCA<Stencil_T>( blocks, stencilId_, numLvl, real_t(2)) ();
+   operatorCoarsening(stencilId_);
 
    // Set up fields for CG on coarsest level
-   auto getFineSize = std::bind(VCycles<Stencil_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
+   auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
    dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::zyxf, uint_t(1) );
    zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::zyxf, uint_t(1) );
 
@@ -234,9 +240,9 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
    for (uint_t lvl = 0; lvl < numLvl-1; ++lvl)
    {
       computeResidual_.push_back( ComputeResidual< Stencil_T >( blocks, uId_[lvl], fId_[lvl], stencilId_[lvl], rId_[lvl] ) );
-      restrict_.push_back( Restrict< Stencil_T >(blocks, rId_[lvl], fId_[lvl+1] ) );
+      restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) );
       zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) );
-      prolongateAndCorrect_.push_back( ProlongateAndCorrect< Stencil_T >(blocks, uId_[lvl+1], uId_[lvl]) );
+      prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) );
    }
 
    // Set up CG coarse-grid iteration
@@ -247,8 +253,8 @@ VCycles< Stencil_T >::VCycles( shared_ptr< StructuredBlockForest > blocks, const
 
 
 
-template< typename Stencil_T >
-void VCycles< Stencil_T >::operator()()
+template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T >
+void VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::operator()()
 {
    WALBERLA_LOG_PROGRESS_ON_ROOT( "Starting VCycle iteration with a maximum number of " << iterations_ << " cycles and " << numLvl_ << " levels" );
    thresholdReached_ = false;
@@ -300,32 +306,8 @@ void VCycles< Stencil_T >::operator()()
 
 
 
-template< typename Stencil_T >
-void VCycles< Stencil_T >::coarsenStencilFields()
-{
-   const real_t scalingFactor = real_t(0.25); // scaling by ( 1/h^2 )^lvl
-
-   WALBERLA_ASSERT_EQUAL(numLvl_, stencilId_.size(), "This function can only be called when operating with stencil fields!");
-
-   for ( uint_t lvl = 1; lvl < numLvl_; ++lvl )
-   {
-      for( auto block = blocks_.begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_.end(); ++block )
-      {
-         StencilField_T * fine   = block->template getData< StencilField_T >( stencilId_[lvl-1] );
-         StencilField_T * coarse = block->template getData< StencilField_T >( stencilId_[lvl] );
-         
-         WALBERLA_FOR_ALL_CELLS_XYZ(coarse,
-            for( auto dir = Stencil_T::begin(); dir != Stencil_T::end(); ++dir )
-               coarse->get(x,y,z, dir.toIdx()) = scalingFactor * fine->get(x,y,z, dir.toIdx());
-         )
-      }
-   }
-}
-
-
-
-template< typename Stencil_T >
-void VCycles< Stencil_T >::VCycle()
+template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T >
+void VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::VCycle()
 {
    // pre-smoothen -- go from fine to coarse
    for (uint_t l = 0; l < numLvl_-1; ++l)
@@ -376,8 +358,8 @@ void VCycles< Stencil_T >::VCycle()
 
 
 
-template< typename Stencil_T >
-Vector3<uint_t> VCycles< Stencil_T >::getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block )
+template< typename Stencil_T, typename OperatorCoarsening_T, typename Restrict_T, typename ProlongateAndCorrect_T >
+Vector3<uint_t> VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::getSizeForLevel( const uint_t level, const shared_ptr< StructuredBlockStorage > & blocks, IBlock * const block )
 {
    Vector3<uint_t> cells( blocks->getNumberOfXCells( *block ), blocks->getNumberOfYCells( *block ), blocks->getNumberOfZCells( *block ) );
 
diff --git a/src/pde/sweeps/Multigrid.h b/src/pde/sweeps/Multigrid.h
index 2398790832454c2f90eb91a7098c2ce8f678afaa..58d4d8f031afa649526cc3814b1115e9b8d6992b 100644
--- a/src/pde/sweeps/Multigrid.h
+++ b/src/pde/sweeps/Multigrid.h
@@ -31,6 +31,13 @@ namespace pde {
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Restriction sweep for multigrid
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
 template< typename Stencil_T >
 class Restrict
 {
@@ -38,6 +45,11 @@ public:
 
    typedef GhostLayerField< real_t, 1 > Field_T;
 
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param fineFieldId the block data id of the fine field
+    * \param coarseFieldId the block data id of the coarse field
+    *******************************************************************************************************************/
    Restrict( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                 const BlockDataID & fineFieldId, const BlockDataID & coarseFieldId ) :
       blocks_( blocks ), fineFieldId_( fineFieldId ), coarseFieldId_( coarseFieldId ) {}
@@ -53,6 +65,13 @@ private:
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Prolongation and correction sweep for multigrid
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
 template< typename Stencil_T >
 class ProlongateAndCorrect
 {
@@ -60,6 +79,11 @@ public:
 
    typedef GhostLayerField< real_t, 1 > Field_T;
 
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param coarseFieldId the block data id of the coarse field
+    * \param fineFieldId the block data id of the fine field
+    *******************************************************************************************************************/
    ProlongateAndCorrect( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                  const BlockDataID & coarseFieldId, const BlockDataID & fineFieldId ) :
    blocks_( blocks ), fineFieldId_( fineFieldId ), coarseFieldId_( coarseFieldId ) {}
@@ -75,6 +99,13 @@ private:
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Residual calculation sweep for multigrid with stencil field
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
 template< typename Stencil_T >
 class ComputeResidual
 {
@@ -83,6 +114,13 @@ public:
    typedef GhostLayerField< real_t, 1 >                Field_T;
    typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
 
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param uId the block data id of the solution field
+    * \param fId the block data id of the right-hand side field
+    * \param stencilId the block data id of the stencil field
+    * \param rId the block data id of the residual field
+    *******************************************************************************************************************/
    ComputeResidual( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & uId,
                     const BlockDataID & fId, const BlockDataID & stencilId, const BlockDataID & rId )
             : blocks_( blocks ), uId_( uId ), fId_( fId ), stencilId_( stencilId ), rId_( rId )
@@ -101,6 +139,13 @@ private:
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Residual calculation sweep for multigrid with fixed stencil weights
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
 template< typename Stencil_T >
 class ComputeResidualFixedStencil
 {
@@ -109,6 +154,13 @@ public:
    typedef GhostLayerField< real_t, 1 > Field_T;
    typedef std::vector< real_t  > Weight_T;
 
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param uId the block data id of the solution field
+    * \param fId the block data id of the right-hand side field
+    * \param weights vector of stencil weights for the discrete operator
+    * \param rId the block data id of the residual field
+    *******************************************************************************************************************/
    ComputeResidualFixedStencil( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & uId,
                                 const BlockDataID & fId, const std::vector <real_t> & weights, const BlockDataID & rId )
             : blocks_( blocks ), uId_( uId ), fId_( fId ), weights_( weights ), rId_( rId )
@@ -127,12 +179,21 @@ private:
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Sweep that sets all values in a field to zero
+ */
+//**********************************************************************************************************************
 class Zeroize
 {
 public:
 
    typedef GhostLayerField< real_t, 1 > Field_T;
 
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the field is stored
+    * \param fieldId the block data id of the field
+    *******************************************************************************************************************/
    Zeroize( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks, const BlockDataID & fieldId )
             : blocks_( blocks ), fieldId_( fieldId )
    { }
@@ -150,6 +211,97 @@ private:
 
 
 
+//**********************************************************************************************************************
+/*!
+ *   \brief Direct Coarsening Approach for the stencil field
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
+template< typename Stencil_T >
+class CoarsenStencilFieldsDCA
+{
+public:
+
+   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param numLvl number of grid levels to use (including the finest level)
+    * \param operatorOrder the order of the (continuum) differential operator, e.g. 2 for Laplace
+    *******************************************************************************************************************/
+   CoarsenStencilFieldsDCA( shared_ptr< StructuredBlockForest > blocks,
+                      const uint_t numLvl, const uint_t operatorOrder,
+                      const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
+                      const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() )
+         : blocks_( blocks ), numLvl_(numLvl), operatorOrder_(operatorOrder),
+           requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
+   { }
+
+   //*******************************************************************************************************************
+   /* \param stencilFieldId a vector of the block data ids of the stencil field for all levels (finest first)
+    *******************************************************************************************************************/
+   void operator()(const std::vector<BlockDataID> & stencilFieldId) const;
+
+private:
+
+   shared_ptr< domain_decomposition::StructuredBlockStorage > blocks_;
+
+   uint_t numLvl_;
+   uint_t operatorOrder_;
+
+   Set< SUID > requiredSelectors_;
+   Set< SUID > incompatibleSelectors_;
+
+};
+
+
+
+//**********************************************************************************************************************
+/*!
+ *   \brief Galerkin Coarsening Approach for the stencil field
+ *
+ *   \tparam Stencil_T The stencil used for the discrete operator
+ */
+//**********************************************************************************************************************
+template< typename Stencil_T >
+class CoarsenStencilFieldsGCA
+{
+public:
+
+   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+
+   //*******************************************************************************************************************
+   /* \param blocks the block storage where the fields are stored
+    * \param numLvl number of grid levels to use (including the finest level)
+    * \param overrelaxFact overrelaxation factor, e.g. 2 for the Poisson equation
+    *******************************************************************************************************************/
+   CoarsenStencilFieldsGCA( shared_ptr< StructuredBlockForest > blocks,
+                      const uint_t numLvl, const real_t overrelaxFact = real_t(1),
+                      const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
+                      const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() )
+         : blocks_( blocks ), numLvl_(numLvl), overrelaxFact_(overrelaxFact),
+           requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
+   { }
+
+   //*******************************************************************************************************************
+   /* \param stencilFieldId a vector of the block data ids of the stencil field for all levels (finest first)
+    *******************************************************************************************************************/
+   void operator()(const std::vector<BlockDataID> & stencilFieldId) const;
+
+private:
+
+   shared_ptr< domain_decomposition::StructuredBlockStorage > blocks_;
+
+   uint_t numLvl_;
+   real_t overrelaxFact_;
+
+   Set< SUID > requiredSelectors_;
+   Set< SUID > incompatibleSelectors_;
+
+};
+
+
 } // namespace pde
 } // namespace walberla
 
diff --git a/src/pde/sweeps/Multigrid.impl.h b/src/pde/sweeps/Multigrid.impl.h
index e83cf18b7f1ff496cefcf0496c62a42896f221a6..e4b5decf62bcd597fc7ef11eea707d1b3f85f42a 100644
--- a/src/pde/sweeps/Multigrid.impl.h
+++ b/src/pde/sweeps/Multigrid.impl.h
@@ -24,6 +24,19 @@
 
 #include "Multigrid.h"
 
+#include "stencil/D3Q7.h"
+
+#ifdef _MSC_VER
+#  pragma warning(push)
+// disable warning for multi_array: "declaration of 'extents' hides global declaration"
+#  pragma warning( disable : 4459 )
+#endif //_MSC_VER
+
+#include <boost/multi_array.hpp>
+
+#ifdef _MSC_VER
+#  pragma warning(pop)
+#endif //_MSC_VER
 
 
 namespace walberla {
@@ -53,6 +66,7 @@ void Restrict< Stencil_T >::operator()( IBlock * const block ) const
       else
       {
          WALBERLA_ASSERT_EQUAL(z, 0);
+         coarse->get(x,y,z) = real_t(0);
       }
 
       coarse->get(x,y,z) +=   fine->get(fx  , fy  , fz  ) + fine->get(fx+1, fy  , fz  )
@@ -140,5 +154,120 @@ void ComputeResidualFixedStencil< Stencil_T >::operator()( IBlock * const block
 
 
 
+template< typename Stencil_T >
+void CoarsenStencilFieldsDCA<Stencil_T >::operator()( const std::vector<BlockDataID> & stencilFieldId ) const
+{
+   const real_t scalingFactor = real_t(1)/real_c(2<< (operatorOrder_-1) ); // scaling by ( 1/h^operatorOrder )^lvl
+
+   WALBERLA_ASSERT_EQUAL(numLvl_, stencilFieldId.size(), "This function can only be called when operating with stencil fields!");
+
+   for ( uint_t lvl = 1; lvl < numLvl_; ++lvl )
+   {
+      for( auto block = blocks_->begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_->end(); ++block )
+      {
+         StencilField_T * fine   = block->template getData< StencilField_T >( stencilFieldId[lvl-1] );
+         StencilField_T * coarse = block->template getData< StencilField_T >( stencilFieldId[lvl] );
+
+         WALBERLA_FOR_ALL_CELLS_XYZ(coarse,
+            for( auto dir = Stencil_T::begin(); dir != Stencil_T::end(); ++dir )
+               coarse->get(x,y,z, dir.toIdx()) = scalingFactor * fine->get(x,y,z, dir.toIdx());
+         )
+      }
+   }
+}
+
+
+
+template< >
+void CoarsenStencilFieldsGCA< stencil::D3Q7 >::operator()( const std::vector<BlockDataID> & stencilFieldId ) const
+{
+
+   WALBERLA_ASSERT_EQUAL(numLvl_, stencilFieldId.size(), "This function can only be called when operating with stencil fields!");
+
+   // Apply Galerkin coarsening to each level //
+   // currently only implemented for CCMG with constant restriction and prolongation
+
+   for ( uint_t lvl = 1; lvl < numLvl_; ++lvl )
+   {
+      for( auto block = blocks_->begin( requiredSelectors_, incompatibleSelectors_ ); block != blocks_->end(); ++block )
+      {
+         StencilField_T * fine   = block->getData< StencilField_T >( stencilFieldId[lvl-1] );
+         StencilField_T * coarse = block->getData< StencilField_T >( stencilFieldId[lvl] );
+
+
+         typedef boost::multi_array<real_t, 3> Array3D;
+         Array3D p(boost::extents[7][7][7]);
+         Array3D r(boost::extents[2][2][2]);
+
+         // Set to restriction weights from constant restrict operator
+          for(Array3D::index z=0; z<2; ++z) {
+            for(Array3D::index y=0; y<2; ++y) {
+               for(Array3D::index x=0; x<2; ++x) {
+                  r[x][y][z] = real_t(1);
+               }
+            }
+         }
+
+         // Init to 0 //
+         for(Array3D::index k=0; k<7; ++k) {
+            for(Array3D::index j=0; j<7; ++j) {
+               for(Array3D::index i=0; i<7; ++i) {
+                  p[i][j][k] = real_t(0);
+               }
+            }
+         }
+
+         // Set center to prolongation weights, including overrelaxation factor (latter therefore no longer needed in ProlongateAndCorrect)
+         for(Array3D::index k=0; k<2; ++k) {
+            for(Array3D::index j=0; j<2; ++j) {
+               for(Array3D::index i=0; i<2; ++i) {
+                  p[i+2][j+2][k+2] = real_t(0.125)/overrelaxFact_;   // Factor 0.125 such that same prolongation operator for DCA and GCA
+               }
+            }
+         }
+
+
+         WALBERLA_FOR_ALL_CELLS_XYZ(coarse,
+
+            Array3D ap(boost::extents[7][7][7]);
+
+            const cell_idx_t fx = 2*x;
+            const cell_idx_t fy = 2*y;
+            const cell_idx_t fz = 2*z;
+
+            for(Array3D::index k=0; k<7; ++k)
+               for(Array3D::index j=0; j<7; ++j)
+                  for(Array3D::index i=0; i<7; ++i)
+                     ap[i][j][k] = real_t(0);
+
+
+            // Tested for spatially varying stencils! //
+            for(Array3D::index k=1; k<5; ++k)
+               for(Array3D::index j=1; j<5; ++j)
+                  for(Array3D::index i=1; i<5; ++i) {
+                     ap[i][j][k] = real_t(0);
+                     for(auto d = stencil::D3Q7::begin(); d != stencil::D3Q7::end(); ++d ){
+                        ap[i][j][k] += p[ i+d.cx() ] [ j+d.cy() ] [k+d.cz() ] * fine->get( fx+cell_idx_c(i%2), fy+cell_idx_c(j%2), fz+cell_idx_c(k%2), d.toIdx() ); // contains elements of one row of coarse grid matrix
+                     }
+                  }
+
+            // Checked, correct! //
+            for(auto d = stencil::D3Q7::begin(); d != stencil::D3Q7::end(); ++d ){
+               real_t sum = 0;
+               for(Array3D::index k=0; k<2; ++k)
+                  for(Array3D::index j=0; j<2; ++j)
+                     for(Array3D::index i=0; i<2; ++i) {
+                        sum += ap[i+2-2*d.cx()] [j+2-2*d.cy()] [k+2-2*d.cz()] * r[i][j][k];
+                        // either i+0 or i+4    // either j+0 or j+4    // either k+0 or k+4       // always 1 here
+                     }
+
+               coarse->get(x,y,z,*d) = sum;
+            }
+         )
+      }
+   }
+}
+
+
 } // namespace pde
 } // namespace walberla
diff --git a/src/pde/sweeps/RBGS.h b/src/pde/sweeps/RBGS.h
index 1f3404341379aea84ab26e4d514a8a5f9cc9ff58..69f7245fac91a5e77ec5bdddb2b25fa92d45d253 100644
--- a/src/pde/sweeps/RBGS.h
+++ b/src/pde/sweeps/RBGS.h
@@ -26,7 +26,7 @@
 #include "stencil/Directions.h"
 
 #include <map>
-
+#include <functional>
 
 
 namespace walberla {
@@ -53,12 +53,12 @@ public:
    
    std::function< void ( IBlock * const ) > getRedSweep()
    {
-      return boost::bind( &RBGS::update, this, _1, true );
+      return std::bind( &RBGS::update, this, std::placeholders::_1, true );
    }
 
    std::function< void ( IBlock * const ) > getBlackSweep()
    {
-      return boost::bind( &RBGS::update, this, _1, false );
+      return std::bind( &RBGS::update, this, std::placeholders::_1, false );
    }
 
 private:
diff --git a/src/pde/sweeps/RBGSFixedStencil.h b/src/pde/sweeps/RBGSFixedStencil.h
index 76df0005548e9df4126d30e017ce10bb1d75f750..75196987f18a941a716661f95873c8c960276904 100644
--- a/src/pde/sweeps/RBGSFixedStencil.h
+++ b/src/pde/sweeps/RBGSFixedStencil.h
@@ -26,7 +26,7 @@
 #include "stencil/Directions.h"
 
 #include <map>
-
+#include <functional>
 
 
 namespace walberla {
@@ -52,12 +52,12 @@ public:
    
    std::function< void ( IBlock * const ) > getRedSweep()
    {
-      return boost::bind( &RBGSFixedStencil::update, this, _1, true );
+      return std::bind( &RBGSFixedStencil::update, this, std::placeholders::_1, true );
    }
 
    std::function< void ( IBlock * const ) > getBlackSweep()
    {
-      return boost::bind( &RBGSFixedStencil::update, this, _1, false );
+      return std::bind( &RBGSFixedStencil::update, this, std::placeholders::_1, false );
    }
 
 private:
diff --git a/src/pde/sweeps/SOR.h b/src/pde/sweeps/SOR.h
index 90be98268340223cd6e22d750c7db6bee9d5105b..4997b40d6af610f7e995ae7229339dbb08e97b93 100644
--- a/src/pde/sweeps/SOR.h
+++ b/src/pde/sweeps/SOR.h
@@ -26,7 +26,7 @@
 #include "stencil/Directions.h"
 
 #include <map>
-
+#include <functional>
 
 
 namespace walberla {
@@ -53,12 +53,12 @@ public:
 
    std::function< void ( IBlock * const ) > getRedSweep()
    {
-      return boost::bind( &SOR::update, this, _1, true );
+      return std::bind( &SOR::update, this, std::placeholders::_1, true );
    }
 
    std::function< void ( IBlock * const ) > getBlackSweep()
    {
-      return boost::bind( &SOR::update, this, _1, false );
+      return std::bind( &SOR::update, this, std::placeholders::_1, false );
    }
 
 private:
diff --git a/src/pde/sweeps/SORFixedStencil.h b/src/pde/sweeps/SORFixedStencil.h
index 51535e0378b9ccaa5bcf1181442ed5ff7bdba5ec..d3983ab1861c856c388d7c2feb3601c654f0e58f 100644
--- a/src/pde/sweeps/SORFixedStencil.h
+++ b/src/pde/sweeps/SORFixedStencil.h
@@ -26,7 +26,7 @@
 #include "stencil/Directions.h"
 
 #include <map>
-
+#include <functional>
 
 
 namespace walberla {
@@ -52,12 +52,12 @@ public:
 
    std::function< void ( IBlock * const ) > getRedSweep()
    {
-      return boost::bind( &SORFixedStencil::update, this, _1, true );
+      return std::bind( &SORFixedStencil::update, this, std::placeholders::_1, true );
    }
 
    std::function< void ( IBlock * const ) > getBlackSweep()
    {
-      return boost::bind( &SORFixedStencil::update, this, _1, false );
+      return std::bind( &SORFixedStencil::update, this, std::placeholders::_1, false );
    }
 
 private:
diff --git a/src/pe/CMakeLists.txt b/src/pe/CMakeLists.txt
index 1dd7edd80c06535b2df4798075355d75fa46cd90..dadbb9186bda2e10b45607705aa606da413a0ce0 100644
--- a/src/pe/CMakeLists.txt
+++ b/src/pe/CMakeLists.txt
@@ -5,27 +5,4 @@
 #
 ###################################################################################################
 
-if(WALBERLA_DOUBLE_ACCURACY)
-    set(CCD_DOUBLE ON)
-    set(CCD_SINGLE OFF)
-else()
-    set(CCD_DOUBLE OFF)
-    set(CCD_SINGLE ON)
-endif()
-
-configure_file(extern/libccd/ccd/config.h.cmake.in extern/libccd/ccd/config.h)
-
-include_directories(extern/libccd)
-include_directories("${CMAKE_CURRENT_BINARY_DIR}/extern/libccd")
-
 waLBerla_add_module( DEPENDS core blockforest domain_decomposition geometry stencil vtk  )
-
-if( WALBERLA_CXX_COMPILER_IS_MSVC )
-   SET_SOURCE_FILES_PROPERTIES( extern/libccd/ccd.c
-                                extern/libccd/mpr.c
-                                extern/libccd/polytope.c
-                                extern/libccd/support.c
-                                extern/libccd/vec3.c
-                                PROPERTIES LANGUAGE CXX )
-endif()
-
diff --git a/src/pe/Types.h b/src/pe/Types.h
index 764bf4bb70610b43ec54215b60c85a95219ae25f..c71ee80907fa5506206c58de904e21d2bebc4550 100644
--- a/src/pe/Types.h
+++ b/src/pe/Types.h
@@ -27,6 +27,7 @@
 
 #include <boost/array.hpp>
 
+#include <memory>
 #include <vector>
 
 namespace walberla{
@@ -57,8 +58,6 @@ using math::AABB;
 //
 //=================================================================================================
 
-class Attachable;
-class BallJoint;
 class BodyManager;
 class BodyStorage;
 class Box;
@@ -67,21 +66,11 @@ class Contact;
 class Cylinder;
 class Ellipsoid;
 class CylindricalBoundary;
-class FixedJoint;
-class ForceGenerator;
 class GeomPrimitive;
-class Gravity;
-class HingeJoint;
-class Joint;
-class Link;
 class Material;
 class MPISystem;
-class Node;
 class Plane;
-class Process;
 class RigidBody;
-class Section;
-class SliderJoint;
 class Sphere;
 class Spring;
 class Squirmer;
@@ -92,6 +81,7 @@ class Union;
 typedef RigidBody             BodyType;            //!< Type of the rigid bodies.
 typedef RigidBody*            BodyID;              //!< Handle for a rigid body.
 typedef const RigidBody*      ConstBodyID;         //!< Handle for a constant rigid body.
+using   BodyPtr             = std::unique_ptr<RigidBody>;
 
 typedef GeomPrimitive*  GeomID;
 typedef const GeomPrimitive*  ConstGeomID;
@@ -99,80 +89,52 @@ typedef const GeomPrimitive*  ConstGeomID;
 typedef Box                   BoxType;             //!< Type of the box geometric primitive.
 typedef Box*                  BoxID;               //!< Handle for a box primitive.
 typedef const Box*            ConstBoxID;          //!< Handle for a constant box primitive.
+using   BoxPtr              = std::unique_ptr<Box>;
 
 typedef Capsule               CapsuleType;         //!< Type of the capsule geometric primitive.
 typedef Capsule*              CapsuleID;           //!< Handle for a capsule primitive.
 typedef const Capsule*        ConstCapsuleID;      //!< Handle for a constant capsule primitive.
+using   CapsulePtr          = std::unique_ptr<Capsule>;
 
 typedef Cylinder              CylinderType;        //!< Type of the cylinder geometric primitive.
 typedef Cylinder*             CylinderID;          //!< Handle for a cylinder primitive.
 typedef const Cylinder*       ConstCylinderID;     //!< Handle for a constant cylinder primitive.
+using   CylinderPtr         = std::unique_ptr<Cylinder>;
 
 typedef CylindricalBoundary        CylindricalBoundaryType;        //!< Type of the cylindrical boundary geometric primitive.
 typedef CylindricalBoundary*       CylindricalBoundaryID;          //!< Handle for a cylindrical boundary primitive.
 typedef const CylindricalBoundary* ConstCylindricalBoundaryID;     //!< Handle for a constant cylindrical boundary primitive.
+using   CylindricalBoundaryPtr   = std::unique_ptr<CylindricalBoundary>;
 
 typedef Ellipsoid             EllipsoidType;       //!< Type of the ellipsoid geometric primitive.
 typedef Ellipsoid*            EllipsoidID;         //!< Handle for a ellipsoid primitive.
 typedef const Ellipsoid*      ConstEllipsoidID;    //!< Handle for a constant ellipsoid primitive.
+using   EllipsoidPtr        = std::unique_ptr<Ellipsoid>;
 
 typedef Plane                 PlaneType;           //!< Type of the plane geometric primitive.
 typedef Plane*                PlaneID;             //!< Handle for a plane primitive.
 typedef const Plane*          ConstPlaneID;        //!< Handle for a constant plane primitive.
+using   PlanePtr            = std::unique_ptr<Plane>;
 
 typedef Sphere                SphereType;          //!< Type of the sphere geometric primitive.
 typedef Sphere*               SphereID;            //!< Handle for a sphere primitive.
 typedef const Sphere*         ConstSphereID;       //!< Handle for a constant sphere primitive.
+using   SpherePtr           = std::unique_ptr<Sphere>;
 
 typedef Squirmer              SquirmerType;        //!< Type of the squirmer geometric primitive.
 typedef Squirmer*             SquirmerID;          //!< Handle for a squirmer primitive.
 typedef const Squirmer*       ConstSquirmerID;     //!< Handle for a constant squirmer primitive.
+using   SquirmerPtr         = std::unique_ptr<Squirmer>;
 
 typedef TriangleMesh          MeshType;             //!< Type of the triangle mesh geometric primitive.
 typedef TriangleMesh*         MeshID;               //!< Handle for a triangle mesh primitive.
 typedef const TriangleMesh*   ConstMeshID;          //!< Handle for a constant triangle mesh primitive.
-
-typedef Attachable            AttachableType;      //!< Type of the attachables.
-typedef Attachable*           AttachableID;        //!< Handle for an attachable.
-typedef const Attachable*     ConstAttachableID;   //!< Handle for a constant attachable.
-
-typedef Gravity               GravityType;         //!< Type of the gravity force generators.
-typedef Gravity*              GravityID;           //!< Handle for a gravity force generator.
-typedef const Gravity*        ConstGravityID;      //!< Handle for a constant gravity force generator.
-
-typedef Spring                SpringType;          //!< Type of the spring force generators.
-typedef Spring*               SpringID;            //!< Handle for a spring force generator.
-typedef const Spring*         ConstSpringID;       //!< Handle for a constant spring force generator.
+using   TriangleMeshPtr     = std::unique_ptr<TriangleMesh>;
 
 typedef Contact               ContactType;         //!< Type of the contacts.
 typedef Contact*              ContactID;           //!< Handle for a contact.
 typedef const Contact*        ConstContactID;      //!< Handle for a constant contact.
 
-typedef Joint                 JointType;           //!< Type of the joints.
-typedef Joint*                JointID;             //!< Handle for a joint.
-typedef const Joint*          ConstJointID;        //!< Handle for a constant joint.
-
-typedef SliderJoint           SliderJointType;     //!< Type of the slider joint.
-typedef SliderJoint*          SldierJointID;       //!< Handle for a slider joint.
-typedef const SliderJoint*    ConstSliderJointID;  //!< Handle for a constant slider joint.
-
-typedef HingeJoint            HingeJointType;      //!< Type of the hinge joint.
-typedef HingeJoint*           HingeJointID;        //!< Handle for a hinge joint.
-typedef const HingeJoint*     ConstHingeJointID;   //!< Handle for a constant hinge joint.
-
-typedef BallJoint             BallJointType;       //!< Type of the ball joint.
-typedef BallJoint*            BallJointID;         //!< Handle for a ball joint.
-typedef const BallJoint*      ConstBallJointID;    //!< Handle for a constant ball joint.
-
-typedef Node                  NodeType;
-typedef Node*                 NodeID;       //!< Handle to a BodyTrait instance.
-typedef const Node*           ConstNodeID;  //!< Handle to a constant BodyTrait instance.
-
-typedef Process               ProcessType;         //!< Type of the remote processes.
-typedef Process*              ProcessID;           //!< Handle for a remote process.
-typedef const Process*        ConstProcessID;      //!< Handle for a constant remote process.
-
-
 typedef BodyManager*          ManagerID;           //!< Handle for a BodyManager.
 typedef const BodyManager*    ConstManagerID;      //!< Handle for a constant BodyManager.
 
diff --git a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
index 720c80a2e363302f6b60a582c7628000cada10ea..dd1fdac59c24ae7d751fc9014236109ccaedfca3 100644
--- a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
@@ -23,6 +23,7 @@
 #include "pe/amr/InfoCollection.h"
 
 #include "blockforest/loadbalancing/DynamicParMetis.h"
+#include "domain_decomposition/PeriodicIntersectionVolume.h"
 
 namespace walberla {
 namespace pe {
@@ -37,36 +38,50 @@ public:
 
    MetisAssignmentFunctor( shared_ptr<InfoCollection>& ic, const real_t baseWeight = real_t(10.0) ) : ic_(ic), baseWeight_(baseWeight) {}
 
-   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & forest )
    {
+      const std::array< bool, 3 > periodic {{forest.getBlockForest().isPeriodic(0),
+                  forest.getBlockForest().isPeriodic(1),
+                  forest.getBlockForest().isPeriodic(2)}};
+      const math::AABB domain     = forest.getBlockForest().getDomain();
+
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
-         const double weight     = double_c( ic_->find( it->first->getId() )->second.numberOfLocalBodies ) + baseWeight_;
-         //const double commWeight = double_c( edgeWeightFactor * (double_c(ic_->find( it->first->getId() )->second.numberOfShadowBodies) + baseWeight_)) + 1;
+         const PhantomBlock * block = it->first;
+         //only change of one level is supported!
+         WALBERLA_ASSERT_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 );
+
+         //all information is provided by info collection
+         auto infoIt         = ic_->find( block->getId() );
+         WALBERLA_CHECK_UNEQUAL( infoIt, ic_->end() );
+         const double weight = double_c( infoIt->second.numberOfLocalBodies ) + baseWeight_;
          blockforest::DynamicParMetisBlockInfo info( 0 );
          info.setVertexWeight( int64_c(weight) );
          info.setVertexSize( int64_c( weight ) );
          info.setVertexCoords( it->first->getAABB().center() );
          for( uint_t nb = uint_t(0); nb < it->first->getNeighborhoodSize(); ++nb )
          {
-            info.setEdgeWeight(it->first->getNeighborId(nb), int64_c(edgeWeight_) );
+            const double dx(1.0);
+            info.setEdgeWeight( it->first->getNeighborId(nb),
+                                static_cast<blockforest::DynamicParMetisBlockInfo::weight_t>(
+                                domain_decomposition::periodicIntersectionVolume( periodic,
+                                                                                  domain,
+                                                                                  it->first->getAABB(),
+                                                                                  it->first->getNeighborAABB(nb).getExtended(dx))) );
          }
          it->second = info;
+         continue;
       }
    }
 
    inline void   setBaseWeight( const double weight) { baseWeight_ = weight;}
    inline double getBaseWeight() const { return baseWeight_; }
 
-   inline void   setEdgeWeight( const double weight) { edgeWeight_ = weight;}
-   inline double getEdgeWeight() const { return edgeWeight_; }
-
 private:
    shared_ptr< InfoCollection > ic_;
 
    ///Base weight due to allocated data structures. A weight of zero for blocks is dangerous as empty blocks might accumulate on one process!
    double baseWeight_ = 10.0;
-   double edgeWeight_ = 1.0;
 };
 
 }
diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
index 1632bc596e1c3b01fc9d090e5fd29ca6c1f18ad0..7c7b381786967bd739b31f6c49ed673230ebd4fb 100644
--- a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
@@ -43,37 +43,11 @@ public:
       {
          const PhantomBlock * block = it->first;
          //only change of one level is supported!
-         WALBERLA_ASSERT_LESS( int_c(block->getLevel()) - int_c(block->getSourceLevel()), 2 );
+         WALBERLA_CHECK_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 );
 
-         if (block->sourceBlockIsLarger())
-         {
-            auto infoIt = ic_->find( block->getId()/*.getFatherId()*/ );
-            WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() );
-            it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ );
-            continue;
-         }
-
-         if (block->sourceBlockHasTheSameSize())
-         {
-            auto infoIt = ic_->find( block->getId() );
-            WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() );
-            it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ );
-            continue;
-         }
-
-         if (block->sourceBlockIsSmaller())
-         {
-            double weight = 0;
-            for (uint_t child = 0; child < 8; ++child)
-            {
-               blockforest::BlockID childId(block->getId(), child);
-               auto childIt = ic_->find( childId );
-               WALBERLA_ASSERT_UNEQUAL( childIt, ic_->end() );
-               weight += double_c(childIt->second.numberOfLocalBodies);
-            }
-            it->second = PhantomBlockWeight( weight + baseWeight_ );
-            continue;
-         }
+         auto infoIt = ic_->find( block->getId()/*.getFatherId()*/ );
+         WALBERLA_CHECK_UNEQUAL( infoIt, ic_->end() );
+         it->second = PhantomBlockWeight( double_c(infoIt->second.numberOfLocalBodies) + baseWeight_ );
       }
    }
 
diff --git a/src/pe/attachable/Attachable.cpp b/src/pe/attachable/Attachable.cpp
deleted file mode 100644
index 76056d6866479db8625431b72e49b7c87bcc06f8..0000000000000000000000000000000000000000
--- a/src/pe/attachable/Attachable.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file Attachable.cpp
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//! \brief Source file for the Attachable class
-//
-//======================================================================================================================
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <pe/attachable/Attachable.h>
-#include <pe/attachable/AttachableStorage.h>
-#include <core/DataTypes.h>
-
-namespace walberla {
-namespace pe {
-
-//=================================================================================================
-//
-//  CONSTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Constructor of the Attachable class.
- *
- * \param type The type of the rigid body.
- * \param sid The unique system-specific ID of the attachable.
- */
-Attachable::Attachable( AttachableType type, id_t sid )
-   : type_(type)
-   , sid_(sid)
-   , bodies_()
-{}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  DESTRUCTOR
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Destructor for the Attachable class.
- */
-Attachable::~Attachable()
-{
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  MPI FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\fn bool Attachable::isRemote() const
- * \brief Returns whether the attachable is remote or not.
- *
- * \return \a true in case the attachable is remote, \a false if not.
- *
- * This function returns whether the attachable is remote or not. In case the attachable is
- * attached to at least a single local rigid body the function returns \a false. Otherwise
- * it returns \a true.
- */
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ATTACHABLE SETUP FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Detaches the given attachable.
- *
- * \param attachable The detachable to be detached.
- */
-WALBERLA_PUBLIC void detach( AttachableID attachable )
-{
-   ///TDOD REVIEW
-//   typedef AttachableStorage AS;
-
-   // WARNING: Using friend relationship to get non-constant reference of attachable storage.
-//   AS& attachablestorage( theCollisionSystem()->attachablestorage_ );
-
-   // Removing the attachable from the attachable storage
-//   const AS::Iterator pos( attachablestorage.find( attachable ) );
-//   attachablestorage.remove( pos );
-
-   delete attachable;
-}
-//*************************************************************************************************
-
-//*************************************************************************************************
-/*!\brief Global output operator for AttachableType.
- *
- * \param os Reference to the output stream.
- * \param type The AttachableType to be put into the stream.
- * \return Reference to the output stream.
- */
-std::ostream& operator<<( std::ostream& os, Attachable::AttachableType type )
-{
-   switch( type )
-   {
-      case Attachable::gravityType: os << "gravity force generator"; break;
-      case Attachable::springType:  os << "spring force generator";  break;
-      default: WALBERLA_ASSERT( false, "Unknown attachable type" ); break;
-   }
-
-   return os;
-}
-//*************************************************************************************************
-
-} // namespace pe
-}  // namespace walberla
diff --git a/src/pe/attachable/Attachable.h b/src/pe/attachable/Attachable.h
deleted file mode 100644
index 9c7b2b368ad9d0377cd3284be39132122cfeb752..0000000000000000000000000000000000000000
--- a/src/pe/attachable/Attachable.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file Attachable.h
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//! \brief Header file for the Attachable class
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <core/NonCopyable.h>
-#include <pe/Types.h>
-#include <core/ptrvector/policies/NoDelete.h>
-#include <core/ptrvector/PtrVector.h>
-#include <pe/Types.h>
-
-#include "core/UniqueID.h"
-
-namespace walberla {
-namespace pe {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Attachable interface class.
- *
- * The Attachable class is the base class for the Attachable concept of the physics engine.
- * Classes deriving from this interface class (which are simply called Attachables) can be
- * attached to rigid bodies and are notified in case the rigid body is destroyed. This
- * concept is for example used for all force generators (see the ForceGenerator class
- * description).
- */
-class Attachable : private NonCopyable
-{
-public:
-   //*************************************************************************************************
-   //! Type codes of the attachables.
-   enum AttachableType {
-      gravityType  = 1,  //!< Code for the Gravity force generator.
-      springType   = 2   //!< Code for the Spring force generator.
-   };
-   //*************************************************************************************************
-protected:
-   //**Type definitions****************************************************************************
-   typedef PtrVector<RigidBody,NoDelete>  Bodies;  //!< Vector for attached rigid bodies.
-   //**********************************************************************************************
-
-   //**Constructor*********************************************************************************
-   /*!\name Constructor */
-   //@{
-   explicit Attachable( AttachableType type, id_t sid );
-   //@}
-   //**********************************************************************************************
-
-   //**Destructor**********************************************************************************
-   /*!\name Destructor */
-   //@{
-   virtual ~Attachable();
-   //@}
-   //**********************************************************************************************
-
-public:
-
-   //**Type definitions****************************************************************************
-   typedef Bodies::Iterator       Iterator;       //!< Iterator over the currently attached bodies.
-   typedef Bodies::ConstIterator  ConstIterator;  //!< ConstIterator over the currently attached bodies.
-   //**********************************************************************************************
-
-   //**MPI functions*******************************************************************************
-   /*!\name MPI functions */
-   //@{
-   virtual bool isRemote() const = 0;
-   //@}
-   //**********************************************************************************************
-
-   //**Get functions*******************************************************************************
-   /*!\name Get functions */
-   //@{
-   inline AttachableType getType()     const;
-   inline id_t           getSystemID() const;
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline Iterator      begin();
-   inline ConstIterator begin() const;
-   inline Iterator      end  ();
-   inline ConstIterator end  () const;
-   inline size_t        size () const;
-   //@}
-   //**********************************************************************************************
-
-protected:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   const AttachableType type_;  //!< The type code of the attachable.
-   id_t sid_;                   //!< The unique system-specific attachable ID.
-   Bodies bodies_;              //!< Vector of attached rigid bodies.
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Attachable setup functions******************************************************************
-   /*! \cond internal */
-   friend void detach( AttachableID attachable );
-   /*! \endcond */
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ATTACHABLE SETUP FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name Attachable setup functions */
-//@{
-void detach( AttachableID attachable );
-//@}
-//*************************************************************************************************
-
-//=================================================================================================
-//
-//  GET FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns the type of the attachable.
- *
- * \return The type of the attachable.
- */
-inline Attachable::AttachableType Attachable::getType() const
-{
-   return type_;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the unique system-specific ID of the attachable.
- *
- * \return The system-specific ID.
- */
-inline id_t Attachable::getSystemID() const
-{
-   return sid_;
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached rigid body.
- *
- * \return Iterator to the first attached rigid body.
- */
-inline Attachable::Iterator Attachable::begin()
-{
-   return bodies_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached rigid body.
- *
- * \return Iterator to the first attached rigid body.
- */
-inline Attachable::ConstIterator Attachable::begin() const
-{
-   return bodies_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached rigid body.
- *
- * \return Iterator just past the last attached rigid body.
- */
-inline Attachable::Iterator Attachable::end()
-{
-   return bodies_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached rigid body.
- *
- * \return Iterator just past the last attached rigid body.
- */
-inline Attachable::ConstIterator Attachable::end() const
-{
-   return bodies_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the number of attached rigid bodies.
- *
- * \return The number of attached rigid bodies
- */
-inline size_t Attachable::size() const
-{
-   return bodies_.size();
-}
-//*************************************************************************************************
-
-//=================================================================================================
-//
-//  ATTACHABLE TYPE UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name Attachable type utility functions */
-//@{
-std::ostream& operator<<( std::ostream& os, Attachable::AttachableType type );
-//@}
-//*************************************************************************************************
-
-} // namespace pe
-}  // namespace walberla
diff --git a/src/pe/attachable/AttachableCast.h b/src/pe/attachable/AttachableCast.h
deleted file mode 100644
index bace6db7f1aa632f16c9d70de8f8ede1f8ffcd49..0000000000000000000000000000000000000000
--- a/src/pe/attachable/AttachableCast.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file AttachableCast.h
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-#include <boost/type_traits/is_base_of.hpp>
-
-namespace walberla {
-namespace pe {
-
-//=================================================================================================
-//
-//  ATTACHABLE CAST OPERATORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\name Attachable cast operators */
-//@{
-template< typename To, typename From > inline To* static_attachable_cast( From* attachable );
-template< typename To, typename From > inline To* dynamic_attachable_cast( From* attachable );
-//@}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Static cast for attachables.
- *
- * \param attachable The attachable to be cast.
- * \return The casted attachable.
- *
- * The static_attachable_cast function is used exactly as the built-in static_cast operator
- * but for attachables.
-
-   \code
-   SphereID     sphere     = createSphere ( 1, 0.0, 0.0, 0.0, 1.0, iron );
-   AttachableID attachable = attachGravity( sphere, 0.0, 0.0, -9.81 );
-   GravityID    gravity    = static_attachable_cast<Gravity>( attachable );
-   \endcode
- */
-template< typename To, typename From >
-inline To* static_attachable_cast( From* attachable )
-{
-   static_assert(boost::is_base_of<Attachable, From>::value, "From has to be derived from Attachable!");
-   static_assert(boost::is_base_of<Attachable, To>::value, "To has to be derived from Attachable!");
-   return static_cast<To*>( attachable );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Dynamic cast for attachables.
- *
- * \param attachable The attachable to be cast.
- * \return The casted attachable.
- *
- * The dynamic_attachable_cast function is used exactly as the built-in dynamic_cast operator
- * but for attachables.
-
-   \code
-   AttachableID attachable;
-   GravityID gravity = dynamic_attachable_cast<Gravity>( attachable );
-   \endcode
- */
-template< typename To, typename From >
-inline To* dynamic_attachable_cast( From* attachable )
-{
-   static_assert(boost::is_base_of<Attachable, From>::value, "From has to be derived from Attachable!");
-   static_assert(boost::is_base_of<Attachable, To>::value, "To has to be derived from Attachable!");
-   return dynamic_cast<To*>( attachable );
-}
-//*************************************************************************************************
-
-} // namespace pe
-}
diff --git a/src/pe/attachable/AttachableStorage.h b/src/pe/attachable/AttachableStorage.h
deleted file mode 100644
index 009c3b087bef8d6556e071306846d210b548dd90..0000000000000000000000000000000000000000
--- a/src/pe/attachable/AttachableStorage.h
+++ /dev/null
@@ -1,356 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file AttachableStorage.h
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <algorithm>
-#include <functional>
-#include <pe/attachable/Attachable.h>
-#include <pe/Types.h>
-#include <core/ptrvector/policies/NoDelete.h>
-#include <core/ptrvector/PtrVector.h>
-#include <core/DataTypes.h>
-#include <core/debug/Debug.h>
-
-namespace walberla {
-namespace pe {
-
-//=================================================================================================
-//
-//  CLASS DEFINITION
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Attachable storage of the rigid body simulation world.
- *
- * The AttachableStorage class stores all currently existing attachables in the simulation world
- * (see class World).
- */
-class AttachableStorage
-{
-private:
-   //**Type definitions****************************************************************************
-   //! Container for the attachables contained in the simulation world.
-   typedef PtrVector<Attachable,NoDelete>  Attachables;
-   //**********************************************************************************************
-
-public:
-   //**Type definitions****************************************************************************
-   typedef Attachables::SizeType       SizeType;       //!< Size type of the attachable storage.
-   typedef Attachables::Iterator       Iterator;       //!< Iterator over non-const attachables.
-   typedef Attachables::ConstIterator  ConstIterator;  //!< Iterator over constant attachables.
-   //**********************************************************************************************
-
-   //**Constructors********************************************************************************
-   /*!\name Constructors */
-   //@{
-   explicit inline AttachableStorage( SizeType initCapacity = 100 );
-   //@}
-   //**********************************************************************************************
-
-   //**Utility functions***************************************************************************
-   /*!\name Utility functions */
-   //@{
-   inline bool          isEmpty() const;
-   inline SizeType      size   () const;
-   inline Iterator      begin  ();
-   inline ConstIterator begin  () const;
-   inline Iterator      end    ();
-   inline ConstIterator end    () const;
-   inline Iterator      find   ( id_t sid );
-   inline ConstIterator find   ( id_t sid ) const;
-   inline Iterator      find   ( ConstAttachableID attachable );
-   inline ConstIterator find   ( ConstAttachableID attachable ) const;
-   //@}
-   //**********************************************************************************************
-
-   //**Add/Remove functions************************************************************************
-   /*!\name Add/Remove functions */
-   //@{
-   inline void     add   ( AttachableID attachable );
-   inline Iterator remove( Iterator pos );
-   //@}
-   //**********************************************************************************************
-
-private:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   Attachables attachables_;  //!< The currently existing attachables.
-   //@}
-   //**********************************************************************************************
-
-   //**Private struct Compare**********************************************************************
-   /*! \cond internal */
-   /*!\brief Helper class for the find() function. */
-   struct Compare : public std::binary_function<AttachableID,id_t,bool>
-   {
-      //**Binary function call operator************************************************************
-      /*!\name Binary function call operator */
-      //@{
-      inline bool operator()( ConstAttachableID attachable, id_t sid ) const {
-         return attachable->getSystemID() < sid;
-      }
-      inline bool operator()( id_t sid, ConstAttachableID attachable ) const {
-         return sid < attachable->getSystemID();
-      }
-      inline bool operator()( ConstAttachableID attachable1, ConstAttachableID attachable2 ) const {
-         return attachable1->getSystemID() < attachable2->getSystemID();
-      }
-      //@}
-      //*******************************************************************************************
-   };
-   /*! \endcond */
-   //**********************************************************************************************
-
-   //**Friend declarations*************************************************************************
-   /*! \cond internal */
-   friend class Attachable;
-   /*! \endcond */
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  CONSTRUCTORS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Standard constructor for the AttachableStorage.
- *
- * \param initCapacity The initial capacity of the attachable storage.
- */
-inline AttachableStorage::AttachableStorage( SizeType initCapacity )
-   : attachables_( initCapacity )
-{}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  UTILITY FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns \a true if the attachable storage contains no attachables.
- *
- * \return \a true if the attachable storage is empty, \a false if it is not.
- */
-inline bool AttachableStorage::isEmpty() const
-{
-   return attachables_.isEmpty();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the number of attachables contained in the attachable storage.
- *
- * \return The number of attachables.
- */
-inline AttachableStorage::SizeType AttachableStorage::size() const
-{
-   return attachables_.size();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first contained attachable.
- *
- * \return Iterator to the first contained attachable.
- */
-inline AttachableStorage::Iterator AttachableStorage::begin()
-{
-   return attachables_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a constant iterator to the first contained attachable.
- *
- * \return Constant iterator to the first contained attachable.
- */
-inline AttachableStorage::ConstIterator AttachableStorage::begin() const
-{
-   return attachables_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last contained attachable.
- *
- * \return Iterator just past the last contained attachable.
- */
-inline AttachableStorage::Iterator AttachableStorage::end()
-{
-   return attachables_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a constant iterator just past the last contained attachable.
- *
- * \return Constant iterator just past the last contained attachable.
- */
-inline AttachableStorage::ConstIterator AttachableStorage::end() const
-{
-   return attachables_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Finding an attachable with a certain unique system-specific ID.
- *
- * \param sid The unique system-specific ID for the search.
- * \return Iterator to the attachable with system-specific ID \a sid or an iterator just past the end.
- *
- * This function finds the attachable with the system-specific ID \a sid. In case the attachable
- * is found, the function returns an iterator to the attachable. Otherwise, the function returns
- * an iterator just past the end of last attachable contained in the attachable storage.
- */
-inline AttachableStorage::Iterator AttachableStorage::find( id_t sid )
-{
-   Iterator pos = std::lower_bound( begin(), end(), sid, Compare() );
-   if( pos != end() && pos->getSystemID() == sid )
-      return pos;
-   else
-      return end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Finding an attachable with a certain unique system-specific ID.
- *
- * \param sid The unique system-specific ID for the search.
- * \return Constant iterator to the attachable with system-specific ID \a sid or a constant iterator just past the end.
- *
- * This function finds the attachable with the system-specific ID \a sid. In case the attachable
- * is found, the function returns a constant iterator to the attachable. Otherwise, the function
- * returns a constant iterator just past the end of last attachable contained in the attachable
- * storage.
- */
-inline AttachableStorage::ConstIterator AttachableStorage::find( id_t sid ) const
-{
-   ConstIterator pos = std::lower_bound( begin(), end(), sid, Compare() );
-   if( pos != end() && pos->getSystemID() == sid )
-      return pos;
-   else
-      return end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Finding a specific attachable in the attachable storage.
- *
- * \param attachable The given attachable for the search.
- * \return Iterator to the given attachable or an iterator just past the end.
- *
- * This function finds the attachable in the attachable storage. In case the attachable is found,
- * the function returns an iterator to the attachable. Otherwise, the function returns an iterator
- * just past the end of last attachable contained in the attachable storage.
- */
-inline AttachableStorage::Iterator AttachableStorage::find( ConstAttachableID attachable )
-{
-   return find( attachable->getSystemID() );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Finding a specific attachable in the attachable storage.
- *
- * \param attachable The given attachable for the search.
- * \return Iterator to the given attachable or an iterator just past the end.
- *
- * This function finds the attachable in the attachable storage. In case the attachable is found,
- * the function returns an iterator to the attachable. Otherwise, the function returns an iterator
- * just past the end of last attachable contained in the attachable storage.
- */
-inline AttachableStorage::ConstIterator AttachableStorage::find( ConstAttachableID attachable ) const
-{
-   return find( attachable->getSystemID() );
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ADD/REMOVE FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Adding an attachable to the attachable storage.
- *
- * \param attachable The new attachable to be added to the attachable storage.
- * \return void
- *
- * This function adds an attachable to the attachable storage.
- */
-inline void AttachableStorage::add( AttachableID attachable )
-{
-   Iterator pos = std::lower_bound( begin(), end(), attachable->getSystemID(), Compare() );
-   attachables_.insert( pos, attachable );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Removing an attachable from the attachable storage.
- *
- * \param pos The position of the attachable to be removed.
- * \return Iterator to the attachable after the erased attachable.
- *
- * This function removes an attachable from the attachable storage.
- */
-inline AttachableStorage::Iterator AttachableStorage::remove( Iterator pos )
-{
-   WALBERLA_ASSERT( pos != end(), "Attachable is not contained in the attachable storage" );
-
-   return attachables_.erase( pos );
-}
-//*************************************************************************************************
-
-} // namespace pe
-}  // namespace walberla
diff --git a/src/pe/ccd/HashGrids.cpp b/src/pe/ccd/HashGrids.cpp
index 8b7b001c7887d601ae6bab15cd00595bfc4a3cce..3eee9158b6fb6ce554e507fa3d2ce316295049eb 100644
--- a/src/pe/ccd/HashGrids.cpp
+++ b/src/pe/ccd/HashGrids.cpp
@@ -764,15 +764,15 @@ void HashGrids::reloadBodies()
 {
    clear();
 
-   for (auto bodyIt = bodystorage_.begin(); bodyIt != bodystorage_.end(); ++bodyIt)
+   for (auto& body : bodystorage_)
    {
-      add( *bodyIt );
+      add( &body );
    }
    if( &bodystorage_ != &bodystorageShadowCopies_ )
    {
-      for (auto bodyIt = bodystorageShadowCopies_.begin(); bodyIt != bodystorageShadowCopies_.end(); ++bodyIt)
+      for (auto& body : bodystorageShadowCopies_)
       {
-         add( *bodyIt );
+         add( &body );
       }
    }
 }
@@ -872,46 +872,42 @@ void HashGrids::update(WcTimingTree* tt)
       //                        suitably sized cells (=> "addGrid()").
 
       {
-         const auto end( bodystorage_.end() );
-         for( auto bIt = bodystorage_.begin(); bIt != end; ++bIt )
+         for( auto& body : bodystorage_ )
          {
-            BodyID body = *bIt;
-            HashGrid* grid = static_cast<HashGrid*>( body->getGrid() );
+            HashGrid* grid = static_cast<HashGrid*>( body.getGrid() );
 
             if( grid != NULL )
             {
-               real_t size     = body->getAABBSize();
+               real_t size     = body.getAABBSize();
                real_t cellSpan = grid->getCellSpan();
 
                if( size >= cellSpan || size < ( cellSpan / hierarchyFactor ) ) {
-                  grid->remove( body );
-                  addGrid( body );
+                  grid->remove( &body );
+                  addGrid( &body );
                }
                else {
-                  grid->update( body );
+                  grid->update( &body );
                }
             }
          }
       }
 
       if( &bodystorage_ != &bodystorageShadowCopies_ ) {
-         const auto end( bodystorageShadowCopies_.end() );
-         for( auto bIt = bodystorageShadowCopies_.begin(); bIt != end; ++bIt )
+         for( auto& body : bodystorageShadowCopies_ )
          {
-            BodyID body = *bIt;
-            HashGrid* grid = static_cast<HashGrid*>( body->getGrid() );
+            HashGrid* grid = static_cast<HashGrid*>( body.getGrid() );
 
             if( grid != NULL )
             {
-               real_t size     = body->getAABBSize();
+               real_t size     = body.getAABBSize();
                real_t cellSpan = grid->getCellSpan();
 
                if( size >= cellSpan || size < ( cellSpan / hierarchyFactor ) ) {
-                  grid->remove( body );
-                  addGrid( body );
+                  grid->remove( &body );
+                  addGrid( &body );
                }
                else {
-                  grid->update( body );
+                  grid->update( &body );
                }
             }
          }
@@ -966,7 +962,7 @@ PossibleContacts& HashGrids::generatePossibleContacts( WcTimingTree* tt )
             }
             // Test all bodies stored in 'grid' against all bodies stored in 'globalStorage_'.
             for( auto bIt = globalStorage_.begin(); bIt < globalStorage_.end(); ++bIt ) {
-               collide( *a, *bIt, contacts_ );
+               collide( *a, &(*bIt), contacts_ );
             }
          }
       }
@@ -982,7 +978,7 @@ PossibleContacts& HashGrids::generatePossibleContacts( WcTimingTree* tt )
 
       // Pairwise test (=> contact generation) for all bodies that are stored in 'nonGridBodies_' with global bodies.
       for( auto bIt = globalStorage_.begin(); bIt < globalStorage_.end(); ++bIt ) {
-         collide( *aIt, *bIt, contacts_ );
+         collide( *aIt, &(*bIt), contacts_ );
       }
    }
    if (tt != NULL) tt->stop("Detection");
diff --git a/src/pe/ccd/SimpleCCD.cpp b/src/pe/ccd/SimpleCCD.cpp
index dee87d16b92bd0b26120cee2c63d61d7eac93636..2fcb2b9e6506767a21ae77c7d0903e10ac0c0b0e 100644
--- a/src/pe/ccd/SimpleCCD.cpp
+++ b/src/pe/ccd/SimpleCCD.cpp
@@ -70,12 +70,12 @@ PossibleContacts& SimpleCCD::generatePossibleContacts( WcTimingTree* tt ){
 
       for (auto it2 = globalStorage_.begin(); it2 != globalStorage_.end(); ++it2)
       {
-         if (!((*it1)->hasInfiniteMass() && (*it2)->hasInfiniteMass()))
+         if (!((*it1)->hasInfiniteMass() && it2->hasInfiniteMass()))
          {
-            if ( (*it1)->getSystemID() > (*it2)->getSystemID() )
-               contacts_.push_back(std::make_pair(*it2, *it1));
+            if ( (*it1)->getSystemID() > it2->getSystemID() )
+               contacts_.push_back(std::make_pair(it2.getBodyID(), *it1));
             else
-               contacts_.push_back(std::make_pair(*it1, *it2));
+               contacts_.push_back(std::make_pair(*it1, it2.getBodyID()));
          }
       }
    }
diff --git a/src/pe/collision/EPA.cpp b/src/pe/collision/EPA.cpp
index 2e0d0e889c2911827f298a7a76ca578513c22997..415ef46d5f9b51f42f9d5c5b5e9480bf1401c72a 100644
--- a/src/pe/collision/EPA.cpp
+++ b/src/pe/collision/EPA.cpp
@@ -119,7 +119,7 @@ inline bool EPA::EPA_Triangle::link( size_t edge0, EPA_Triangle* tria, size_t ed
    tria->adjEdges_[edge1] = edge0;
 
    bool b = indices_[edge0]       == tria->indices_[(edge1+1)%3] &&
-         indices_[(edge0+1)%3] == tria->indices_[edge1];
+            indices_[(edge0+1)%3] == tria->indices_[edge1];
    return b;
 }
 //*************************************************************************************************
@@ -145,7 +145,7 @@ inline void EPA::EPA_Triangle::silhouette( const Vec3& w, EPA_EdgeBuffer& edgeBu
 /*! \brief Recursive silhuette finding method.
  */
 void EPA::EPA_Triangle::silhouette( size_t index, const Vec3& w,
-                                           EPA_EdgeBuffer& edgeBuffer )
+                                    EPA_EdgeBuffer& edgeBuffer )
 {
    if (!obsolete_) {
       real_t test = (closest_ * w);
@@ -184,7 +184,7 @@ const long double EpsilonRelEPA< long double >::value = static_cast< long double
 /*! \brief Does an EPA computation with contactthreshold added. Use Default relative Error.
  */
 bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal,
-                                        Vec3& contactPoint, real_t& penetrationDepth){
+                                 Vec3& contactPoint, real_t& penetrationDepth){
 
    //Default relative epsilon
    return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, contactThreshold, EpsilonRelEPA<real_t>::value);
@@ -196,7 +196,7 @@ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, con
 /*! \brief Does an EPA computation with contactThreshold added. Relative Error can be specified.
  */
 bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal,
-                                        Vec3& contactPoint, real_t& penetrationDepth, real_t eps_rel){
+                                 Vec3& contactPoint, real_t& penetrationDepth, real_t eps_rel){
 
    return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, contactThreshold, eps_rel);
 }
@@ -207,7 +207,7 @@ bool EPA::doEPAcontactThreshold( GeomPrimitive &geom1, GeomPrimitive &geom2, con
 /*! \brief Does an EPA computation with margin added. Use Default relative Error.
  */
 bool EPA::doEPAmargin( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal,
-                              Vec3& contactPoint, real_t& penetrationDepth, real_t margin){
+                       Vec3& contactPoint, real_t& penetrationDepth, real_t margin){
    //Default relative epsilon
    return doEPA(geom1, geom2, gjk, retNormal, contactPoint, penetrationDepth, margin, EpsilonRelEPA<real_t>::value);
 }
@@ -218,7 +218,7 @@ bool EPA::doEPAmargin( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gj
 /*! \brief Does an epa computation with contact margin added and specified realtive error.
  */
 bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& retNormal,
-                        Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel )
+                 Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel )
 {
    //have in mind that we use a support mapping which blows up the objects a wee bit so
    //zero penetraion aka toching contact means that the original bodies have a distance of 2*margin between them
@@ -271,8 +271,10 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec
    std::make_heap(entryHeap.begin(), entryHeap.end(), EPA::EPA_TriangleComp());
    EPA_Triangle* current = NULL;
 
+   numIterations_ = 0;
    //EPA Main-Loop
    do {
+      ++numIterations_;
       std::pop_heap(entryHeap.begin(), entryHeap.end(), EPA::EPA_TriangleComp());
       current = entryHeap.back();
       entryHeap.pop_back();
@@ -310,38 +312,49 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec
          //std::cerr << "New upper bound: " <<  farDist*farDist << std::endl;
          upperBoundSqr = std::min(upperBoundSqr, farDist*farDist);
 
+
+
          //Try to approximate the new surface with a sphere
-         Vec3 ctr;
-         real_t radius2 = calculateCircle(support, epaVolume[(*current)[0]],
-               epaVolume[(*current)[1]], epaVolume[(*current)[2]], ctr);
-         if(radius2 > real_t(0.0)){ //if a Sphere exists
-            //std::cerr << "Circle created with center at " << ctr << ". r2=" << radius2 << std::endl;
-            real_t center_len = ctr.length();
-            real_t circle_dist = (std::sqrt(radius2) - center_len); //Distance from center to the spheres surface
-            //Check if the circle matches the bounds given by EPA and limit max error to ca. 5%
-            if(circle_dist*circle_dist <= upperBoundSqr && circle_dist*circle_dist >= lowerBoundSqr &&
-                  (circle_dist*circle_dist)/lowerBoundSqr < real_t(1.10) && !floatIsEqual(center_len, real_t(0.0))) {
-
-               ctr = -1*ctr.getNormalized();
-               //std::cerr << "New support direction: " <<  ctr << std::endl;
-               pushSupportMargin(geom1, geom2, ctr, margin, epaVolume, supportA, supportB);
-               support = epaVolume.back();
-               // Check if support is in expected direction
-
-               if(floatIsEqual((support % ctr).sqrLength()/support.sqrLength(), real_t(0.0))){ //Accept sphere
-
-                  contactPoint = real_t(0.5) * (supportA.back() + supportB.back());
-                  penetrationDepth = -support.length()+ real_t(2.0) * margin;
-                  retNormal = -ctr;
-                  //std::cerr << "Found penetration depth " << penetrationDepth << " with CurvedEPA!" << std::endl;
-                  if(penetrationDepth < contactThreshold){
-                     return true;
-                  }else{
-                     return false;
-                  }
-               } else { //Reject sphere
-                  removeSupportMargin(epaVolume, supportA, supportB);
+         if (bUseSphereOptimization_)
+         {
+            Vec3 ctr;
+            real_t radius2 = calculateCircle(support,
+                                             epaVolume[(*current)[0]],
+                  epaVolume[(*current)[1]],
+                  epaVolume[(*current)[2]],
+                  ctr);
+            if(radius2 > real_t(0.0)){ //if a Sphere exists
+               //std::cerr << "Circle created with center at " << ctr << ". r2=" << radius2 << std::endl;
+               real_t center_len = ctr.length();
+               real_t circle_dist = (std::sqrt(radius2) - center_len); //Distance from center to the spheres surface
+               //Check if the circle matches the bounds given by EPA and limit max error to ca. 5%
+               if (circle_dist*circle_dist <= upperBoundSqr &&
+                   circle_dist*circle_dist >= lowerBoundSqr &&
+                   (circle_dist*circle_dist) < real_t(1.10) * lowerBoundSqr &&
+                   !floatIsEqual(center_len, real_t(0.0)))
+               {
+                  const auto ilen = real_t(1.0) / center_len;
+                  ctr *= -ilen;
+                  //std::cerr << "New support direction: " <<  ctr << std::endl;
+                  pushSupportMargin(geom1, geom2, ctr, margin, epaVolume, supportA, supportB);
                   support = epaVolume.back();
+                  // Check if support is in expected direction
+
+                  if(floatIsEqual((support % ctr).sqrLength()/support.sqrLength(), real_t(0.0)))
+                  { //Accept sphere
+                     contactPoint = real_t(0.5) * (supportA.back() + supportB.back());
+                     penetrationDepth = -support.length() + real_t(2.0) * margin;
+                     retNormal = -ctr;
+                     //std::cerr << "Found penetration depth " << penetrationDepth << " with CurvedEPA!" << std::endl;
+                     if(penetrationDepth < contactThreshold){
+                        return true;
+                     }else{
+                        return false;
+                     }
+                  } else { //Reject sphere
+                     removeSupportMargin(epaVolume, supportA, supportB);
+                     support = epaVolume.back();
+                  }
                }
             }
          }
@@ -853,26 +866,20 @@ inline bool EPA::searchTetrahedron(GeomPrimitive &geom1, GeomPrimitive &geom2, s
  */
 inline real_t EPA::calculateCircle(const Vec3& A, const Vec3& B, const Vec3& C,
                                    const Vec3& D, Vec3& center ){
-   real_t l1, l2, l3, d1, d2, d3;
-   l1 = (A-B).length(); /* These three sqrt evaluations are necessary */
-   l2 = (A-C).length();
-   l3 = (A-D).length();
-
-   Vec3 n1, n2, n3;
-   n1 = (real_t(1.0)/l1)*(A-B);
-   n2 = (real_t(1.0)/l2)*(A-C);
-   n3 = (real_t(1.0)/l3)*(A-D);
+   const Vec3 n1(A-B);
+   const Vec3 n2(A-C);
+   const Vec3 n3(A-D);
 
    // Here we already see if such circle exists.
-   real_t det = n1 * (n2 % n3);
+   const real_t det = n1 * (n2 % n3);
    if(std::fabs(det) < math::Limits<real_t>::fpuAccuracy()){
       //no circle exists. Leave center untouched, and return -1.0
       return real_t(-1.0);
    }
-   real_t Alen = A.sqrLength();
-   d1 = (Alen - B.sqrLength())/(real_t(2.0)*l1);
-   d2 = (Alen - C.sqrLength())/(real_t(2.0)*l2);
-   d3 = (Alen - D.sqrLength())/(real_t(2.0)*l3);
+   const real_t Alen = A.sqrLength();
+   const real_t d1 = (Alen - B.sqrLength())*real_t(0.5);
+   const real_t d2 = (Alen - C.sqrLength())*real_t(0.5);
+   const real_t d3 = (Alen - D.sqrLength())*real_t(0.5);
 
    //Apply solution formula
    center = (real_t(1.0)/det)*(d1 * (n2 % n3) + d2 * (n3 % n1) + d3 * (n1 % n2));
diff --git a/src/pe/collision/EPA.h b/src/pe/collision/EPA.h
index da611ecaec9e01165899874d5769ea32511befd1..a318e7e578323e4237e51492b3ef250d7838427c 100644
--- a/src/pe/collision/EPA.h
+++ b/src/pe/collision/EPA.h
@@ -86,6 +86,8 @@ public:
    bool doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec3& normal,
                       Vec3& contactPoint, real_t& penetrationDepth, real_t margin, real_t eps_rel );
 
+
+
    //@}
    //**********************************************************************************************
 
@@ -100,6 +102,11 @@ public:
 
    inline size_t getMaxTriangles() {return maxTriangles_;}
 
+   inline int getNumIterations() const {return numIterations_; }
+
+   inline bool useSphereOptimization() const {return bUseSphereOptimization_; }
+   inline void useSphereOptimization(const bool useIt) {bUseSphereOptimization_ = useIt;}
+
    //@}
    //**********************************************************************************************
 
@@ -143,6 +150,9 @@ private:
    //EPA constants
    size_t maxSupportPoints_ = 100;
    size_t maxTriangles_     = 200;
+
+   int numIterations_ = 0;
+   bool bUseSphereOptimization_ = false;
 };
 //*************************************************************************************************
 
diff --git a/src/pe/collision/GJKEPAHelper.cpp b/src/pe/collision/GJKEPAHelper.cpp
deleted file mode 100644
index d8316cd6db099983dc7b0772f6d506e9ac23cd3a..0000000000000000000000000000000000000000
--- a/src/pe/collision/GJKEPAHelper.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file GJKHelper.cpp
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include "GJKEPAHelper.h"
-
-#include "pe/rigidbody/GeomPrimitive.h"
-
-extern "C" {
-   #include "pe/extern/libccd/ccd/ccd.h"
-   #include "pe/extern/libccd/ccd/quat.h"
-}
-
-#include "core/logging/Logging.h"
-
-namespace walberla {
-namespace pe {
-
-Vec3       convertVec3(const ccd_vec3_t& vec) { return Vec3(real_c(vec.v[0]), real_c(vec.v[1]), real_c(vec.v[2])); }
-ccd_vec3_t convertVec3(const Vec3& vec)       { ccd_vec3_t ret; ret.v[0] = vec[0]; ret.v[1] = vec[1]; ret.v[2] = vec[2]; return ret; }
-
-void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec)
-{
-    ConstGeomID bd = reinterpret_cast<ConstGeomID> (obj);
-    Vec3 d = convertVec3(*dir);
-    Vec3 sup = bd->support( d );
-    *vec = convertVec3(sup);
-}
-
-bool collideGJK( ConstGeomID bd1,
-                 ConstGeomID bd2,
-                 Vec3& contactPoint,
-                 Vec3& contactNormal,
-                 real_t& penetrationDepth,
-                 const unsigned long numIterations,
-                 const real_t epaTol )
-{
-    ccd_t ccd;
-    CCD_INIT(&ccd); // initialize ccd_t struct
-
-    // set up ccd_t struct
-    ccd.support1       = support;       // support function for first object
-    ccd.support2       = support;       // support function for second object
-    ccd.max_iterations = numIterations; // maximal number of iterations
-    ccd.epa_tolerance  = epaTol;
-
-    ccd_vec3_t dir, pos;
-    ccd_real_t penetrationDepthCCD;
-    int intersect = ccdGJKPenetration(reinterpret_cast<const void*> (bd1), reinterpret_cast<const void*> (bd2), &ccd, &penetrationDepthCCD, &dir, &pos);
-    penetrationDepth = real_c(penetrationDepthCCD);
-    contactPoint  = convertVec3(pos);
-    contactNormal = -convertVec3(dir);
-    penetrationDepth *= -1;
-
-    return (intersect == 0);
-}
-
-} // namespace pe
-} // namespace walberla
diff --git a/src/pe/collision/GJKEPAHelper.h b/src/pe/collision/GJKEPAHelper.h
deleted file mode 100644
index b1d73b1a19584a53449034529163c9247a5f230c..0000000000000000000000000000000000000000
--- a/src/pe/collision/GJKEPAHelper.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file GJKHelper.h
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include "pe/contact/Contact.h"
-#include "pe/Types.h"
-
-#include "core/math/Vector3.h"
-
-namespace walberla {
-namespace pe {
-
-static unsigned long maxGJKIterations = 100ul;
-static real_t epaTolerance = real_t(0.000001);
-
-inline
-void setMaxGJKIterations(const unsigned long& iter)
-{
-   maxGJKIterations = iter;
-}
-inline
-unsigned long getMaxGJKIterations()
-{
-   return maxGJKIterations;
-}
-
-inline
-void setEPATolerance(const real_t& tol)
-{
-   epaTolerance = tol;
-}
-inline
-real_t getEPATolerance()
-{
-   return epaTolerance;
-}
-
-bool collideGJK( ConstGeomID bd1,
-                 ConstGeomID bd2,
-                 Vec3& contactPoint,
-                 Vec3& contactNormal,
-                 real_t& penetrationDepth,
-                 const unsigned long numIterations = maxGJKIterations,
-                 const real_t epaTol = epaTolerance );
-
-template <typename Container>
-bool collideGJK( GeomID bd1,
-                 GeomID bd2,
-                 Container& container,
-                 const unsigned long numIterations = maxGJKIterations,
-                 const real_t epaTol = epaTolerance )
-{
-   real_t penetrationDepth;
-   Vec3   contactPoint;
-   Vec3   contactNormal;
-   bool retVal = collideGJK(bd1, bd2, contactPoint, contactNormal, penetrationDepth, numIterations, epaTol);
-   if (retVal)
-   {
-      container.push_back( Contact(bd1, bd2, contactPoint, contactNormal, penetrationDepth) );
-   }
-   return retVal;
-}
-
-} // namespace pe
-} // namespace walberla
diff --git a/src/pe/communication/DynamicMarshalling.h b/src/pe/communication/DynamicMarshalling.h
index e2d2c4a6ceb2b4e35d1aad180c9b4700514bc03f..032708bff7ac44d5ece117697ea337097f6a1a66 100644
--- a/src/pe/communication/DynamicMarshalling.h
+++ b/src/pe/communication/DynamicMarshalling.h
@@ -91,7 +91,7 @@ private:
          , block_(block) {}
 
       template< typename BodyType >
-      BodyID operator()( BodyType* bd) { return instantiate( buffer_, domain_, block_, bd ); }
+      BodyPtr operator()( BodyType* bd) { return instantiate( buffer_, domain_, block_, bd ); }
    };
 
 public:
@@ -105,10 +105,10 @@ public:
     * The rigid body is casted dynamically to its original type and then marshalled. For recognition
     * an identifying tag is prepended.
     */
-   static BodyID execute(mpi::RecvBuffer& buffer, const id_t typeID, const math::AABB& domain, const math::AABB& block)
+   static BodyPtr execute(mpi::RecvBuffer& buffer, const id_t typeID, const math::AABB& domain, const math::AABB& block)
    {
       UnmarshalFunctor func(buffer, domain, block);
-      return SingleCast<BodyTypeTuple, UnmarshalFunctor, BodyID>::execute (typeID, func);
+      return SingleCast<BodyTypeTuple, UnmarshalFunctor, BodyPtr>::execute (typeID, func);
    }
 };
 
diff --git a/src/pe/communication/Instantiate.h b/src/pe/communication/Instantiate.h
index 6096c6552d3e21e63ec29a99efbefcfc0cfb20c3..f10a27dddab2efb0a4a6b9ae375110fce368dd29 100644
--- a/src/pe/communication/Instantiate.h
+++ b/src/pe/communication/Instantiate.h
@@ -55,7 +55,7 @@ void correctBodyPosition(const math::AABB& domain, const Vec3& center, Vec3& pos
 }
 
 template < class BodyT >
-BodyT* instantiate( mpi::RecvBuffer& /*buffer*/, const math::AABB& /*domain*/, const math::AABB& /*block*/, BodyT*& /*newBody*/ )
+std::unique_ptr<BodyT> instantiate( mpi::RecvBuffer& /*buffer*/, const math::AABB& /*domain*/, const math::AABB& /*block*/, BodyT*& /*newBody*/ )
 {
    WALBERLA_ABORT( "Body instantiation not implemented! (" << demangle(typeid(BodyT).name()) << ")" );
 }
diff --git a/src/pe/communication/ParseMessage.h b/src/pe/communication/ParseMessage.h
index 5735beb152fb332ae5d007ad56115d339b6f5194..deea7db9689387c9adcd3f8dc4edccca02a8488a 100644
--- a/src/pe/communication/ParseMessage.h
+++ b/src/pe/communication/ParseMessage.h
@@ -64,17 +64,18 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
 
             WALBERLA_LOG_DETAIL( "Received " << objparam.geomType_ << " copy notification from neighboring process with rank " << sender );
 
-            BodyID obj = UnmarshalDynamically<BodyTypeTuple>::execute(rb, objparam.geomType_, blockStorage.getDomain(), block.getAABB());
+            BodyPtr obj = UnmarshalDynamically<BodyTypeTuple>::execute(rb, objparam.geomType_, blockStorage.getDomain(), block.getAABB());
             obj->setRemote( true );
+            obj->MPITrait.setBlockState( sender.blockID_ );
+
             if (shadowStorage.find( obj->getSystemID() ) == shadowStorage.end())
             {
-               WALBERLA_LOG_DETAIL( "Adding new shadow copy with id " << obj->getSystemID() << " to domain " << block.getAABB() << ".\n" << obj);
-               shadowStorage.add( obj );
+               WALBERLA_LOG_DETAIL( "Adding new shadow copy with id " << obj->getSystemID() << " to domain " << block.getAABB() << ".\n" << *obj);
+               shadowStorage.add( std::move(obj) );
             } else
             {
                WALBERLA_LOG_DETAIL( "Shadow copy with id " << obj->getSystemID() << " already existend.");
             }
-            obj->MPITrait.setBlockState( sender.blockID_ );
 
             WALBERLA_LOG_DETAIL( "Processed " << objparam.geomType_ << " copy notification."  );
 
@@ -88,7 +89,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
 
             auto bodyIt = shadowStorage.find( objparam.sid_ );
             WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() );
-            BodyID b( *bodyIt );
+            BodyID b( bodyIt.getBodyID() );
 
             WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Update notifications must be sent by owner.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ );
             WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow copies." );
@@ -112,10 +113,9 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
 
             auto bodyIt = shadowStorage.find( objparam.sid_ );
             if ( bodyIt == shadowStorage.end() ) WALBERLA_ABORT( "Object with id: " << objparam.sid_ << " not found in shadowStorage! Cannot transfer ownership! \nlocal domain: " << block.getAABB() );
-            BodyID b( *bodyIt );
+            BodyID b( bodyIt.getBodyID() );
 
-            shadowStorage.release( b );
-            localStorage.add( b );
+            localStorage.add( shadowStorage.release( b ) );
 
             WALBERLA_ASSERT( sender.blockID_ == b->MPITrait.getOwner().blockID_, "Migration notifications must be sent by previous owner.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ );
             WALBERLA_ASSERT( b->isRemote(), "Bodies in migration notifications must be available as shadow copies in local process." );
@@ -143,7 +143,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
 
             auto bodyIt = shadowStorage.find( objparam.sid_ );
             WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() );
-            BodyID b( *bodyIt );
+            BodyID b( bodyIt.getBodyID() );
 
             WALBERLA_ASSERT( sender.blockID_ == b->MPITrait.getOwner().blockID_, "Remote migration notifications must be sent by previous owner.\n" << sender.blockID_ << " != " << b->MPITrait.getOwner().blockID_  );
             WALBERLA_ASSERT( b->isRemote(), "Bodies in remote migration notifications must be available as shadow copies in local process." );
@@ -164,7 +164,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
             // Remove shadow copy as prompted.
             auto bodyIt = shadowStorage.find( objparam.sid_ );
             WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() );
-            BodyID b( *bodyIt );
+            BodyID b( bodyIt.getBodyID() );
 
             // TODO assert that we indeed do not need the shadow copy anymore
             WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Only owner is allowed to send removal notifications.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ );
@@ -184,7 +184,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
          // Remove invalid shadow copy.
          auto bodyIt = shadowStorage.find( objparam.sid_ );
          WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() );
-         BodyID b( *bodyIt );
+         BodyID b( bodyIt.getBodyID() );
 
          WALBERLA_ASSERT( b->MPITrait.getOwner().blockID_ == sender.blockID_, "Only owner is allowed to send deletion notifications.\n" << b->MPITrait.getOwner().blockID_ << " != "<< sender.blockID_ );
 
@@ -203,7 +203,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
          // Remove invalid shadow copy.
          auto bodyIt = localStorage.find( objparam.sid_ );
          WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() );
-         BodyID b( *bodyIt );
+         BodyID b( bodyIt.getBodyID() );
 
          b->MPITrait.registerShadowOwner( objparam.newOwner_ );
 
@@ -221,7 +221,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
          {
             auto bodyIt = localStorage.find( objparam.sid_ );
             WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() );
-            BodyID b( *bodyIt );
+            BodyID b( bodyIt.getBodyID() );
             b->MPITrait.deregisterShadowOwner( sender );
             b->MPITrait.unsetBlockState( sender.blockID_ );
          } else
@@ -229,7 +229,7 @@ void parseMessage(Owner sender, mpi::RecvBuffer& rb, const domain_decomposition:
             auto bodyIt = shadowStorage.find( objparam.sid_ );
             if (bodyIt != shadowStorage.end() )
             {
-               BodyID b( *bodyIt );
+               BodyID b( bodyIt.getBodyID() );
                b->MPITrait.unsetBlockState( sender.blockID_ );
             }
          }
@@ -260,7 +260,7 @@ void parseForceReduceMessage(Owner sender, mpi::RecvBuffer& rb, const domain_dec
 
       auto bodyIt = localStorage.find( objparam.sid_ );
       WALBERLA_ASSERT_UNEQUAL( bodyIt, localStorage.end() );
-      BodyID b( *bodyIt );
+      BodyID b( bodyIt.getBodyID() );
 
       WALBERLA_ASSERT( !b->isRemote(), "Update notification must only concern local bodies." );
 
@@ -292,7 +292,7 @@ void parseForceDistributeMessage(Owner sender, mpi::RecvBuffer& rb, const domain
 
       auto bodyIt = shadowStorage.find( objparam.sid_ );
       WALBERLA_ASSERT_UNEQUAL( bodyIt, shadowStorage.end() );
-      BodyID b( *bodyIt );
+      BodyID b( bodyIt.getBodyID() );
 
       WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow bodies." );
 
diff --git a/src/pe/communication/rigidbody/Box.h b/src/pe/communication/rigidbody/Box.h
index 3a4c35a20e31b259cddd3fc0cfea4bf1d87d95d8..77f543cbc9183348f40a08d07fd95981b9800fdc 100644
--- a/src/pe/communication/rigidbody/Box.h
+++ b/src/pe/communication/rigidbody/Box.h
@@ -59,16 +59,17 @@ void marshal( mpi::SendBuffer& buffer, const Box& obj );
  */
 void unmarshal( mpi::RecvBuffer& buffer, BoxParameters& objparam );
 //*************************************************************************************************
-inline BoxID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, BoxID& newBody )
+inline BoxPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, BoxID& newBody )
 {
    BoxParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Box( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto bx = std::make_unique<Box>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.lengths_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   bx->setLinearVel( subobjparam.v_ );
+   bx->setAngularVel( subobjparam.w_ );
+   bx->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = bx.get();
+   return bx;
 }
 
 }  // namespace communication
diff --git a/src/pe/communication/rigidbody/Capsule.h b/src/pe/communication/rigidbody/Capsule.h
index 7f99b1d1d47d7fb4e96713213f3ecababd718915..3ef02f07d1d4b95fbb3010be10e61eb158772cca 100644
--- a/src/pe/communication/rigidbody/Capsule.h
+++ b/src/pe/communication/rigidbody/Capsule.h
@@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, CapsuleParameters& objparam );
 //*************************************************************************************************
 
 
-inline CapsuleID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, CapsuleID& newBody )
+inline CapsulePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, CapsuleID& newBody )
 {
    CapsuleParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Capsule( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto cp = std::make_unique<Capsule>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.length_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   cp->setLinearVel( subobjparam.v_ );
+   cp->setAngularVel( subobjparam.w_ );
+   cp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = cp.get();
+   return cp;
 }
 
 }  // namespace communication
diff --git a/src/pe/communication/rigidbody/Ellipsoid.h b/src/pe/communication/rigidbody/Ellipsoid.h
index 57916d268a30dbfea187071a18b4270ee63c83f3..a292c5b1dd1bc9bfbd2fb487260571fa26bc9756 100644
--- a/src/pe/communication/rigidbody/Ellipsoid.h
+++ b/src/pe/communication/rigidbody/Ellipsoid.h
@@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, EllipsoidParameters& objparam );
 //*************************************************************************************************
 
 
-inline EllipsoidID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, EllipsoidID& newBody )
+inline EllipsoidPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, EllipsoidID& newBody )
 {
    EllipsoidParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Ellipsoid( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto el = std::make_unique<Ellipsoid>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.semiAxes_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   el->setLinearVel( subobjparam.v_ );
+   el->setAngularVel( subobjparam.w_ );
+   el->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = el.get();
+   return el;
 }
 
 }  // namespace communication
diff --git a/src/pe/communication/rigidbody/Sphere.h b/src/pe/communication/rigidbody/Sphere.h
index 55881f65aa0e3c5e02cd0ea099093dd16ef45379..3e7da560142c29a93161b691975f403808f09fba 100644
--- a/src/pe/communication/rigidbody/Sphere.h
+++ b/src/pe/communication/rigidbody/Sphere.h
@@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, SphereParameters& objparam );
 //*************************************************************************************************
 
 
-inline SphereID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SphereID& newBody )
+inline SpherePtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SphereID& newBody )
 {
    SphereParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Sphere( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto sp = std::make_unique<Sphere>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   sp->setLinearVel( subobjparam.v_ );
+   sp->setAngularVel( subobjparam.w_ );
+   sp->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = sp.get();
+   return sp;
 }
 
 }  // namespace communication
diff --git a/src/pe/communication/rigidbody/Squirmer.h b/src/pe/communication/rigidbody/Squirmer.h
index 9029c93586fa36c5d3b4e29d2aaefe74a4d5a4d1..3c9b3fbe094c6cef756168c6bfd63078825f001c 100644
--- a/src/pe/communication/rigidbody/Squirmer.h
+++ b/src/pe/communication/rigidbody/Squirmer.h
@@ -61,16 +61,17 @@ void unmarshal( mpi::RecvBuffer& buffer, SquirmerParameters& objparam );
 //*************************************************************************************************
 
 
-inline SquirmerID instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SquirmerID& newBody )
+inline SquirmerPtr instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, SquirmerID& newBody )
 {
    SquirmerParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Squirmer( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
-   return newBody;
+   auto sq = std::make_unique<Squirmer>( subobjparam.sid_, subobjparam.uid_, subobjparam.gpos_, subobjparam.rpos_, subobjparam.q_, subobjparam.radius_, subobjparam.squirmerVelocity_, subobjparam.squirmerBeta_, subobjparam.material_, false, subobjparam.communicating_, subobjparam.infiniteMass_ );
+   sq->setLinearVel( subobjparam.v_ );
+   sq->setAngularVel( subobjparam.w_ );
+   sq->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   newBody = sq.get();
+   return sq;
 }
 
 }  // namespace communication
diff --git a/src/pe/communication/rigidbody/Union.h b/src/pe/communication/rigidbody/Union.h
index 69c2d6bb172ac8589b56f68e7ecc2946ac0b471f..544c131efff56184a82296a67c073784b0f585a4 100644
--- a/src/pe/communication/rigidbody/Union.h
+++ b/src/pe/communication/rigidbody/Union.h
@@ -72,12 +72,12 @@ void marshal( mpi::SendBuffer& buffer, const Union<BodyTypeTuple>& obj )
    buffer << static_cast<size_t> (obj.size());                  // Encoding the number of contained bodies
 
    // Encoding the contained primitives
-   const typename Union<BodyTypeTuple>::ConstIterator begin( obj.begin() );
-   const typename Union<BodyTypeTuple>::ConstIterator end  ( obj.end()   );
-   for(  typename Union<BodyTypeTuple>::ConstIterator body=begin; body!=end; ++body )
+   const typename Union<BodyTypeTuple>::const_iterator begin( obj.begin() );
+   const typename Union<BodyTypeTuple>::const_iterator end  ( obj.end()   );
+   for(  typename Union<BodyTypeTuple>::const_iterator body=begin; body!=end; ++body )
    {
       buffer << body->getTypeID();
-      MarshalDynamically<BodyTypeTuple>::execute( buffer, **body );
+      MarshalDynamically<BodyTypeTuple>::execute( buffer, *body );
    }
 }
 
@@ -110,34 +110,35 @@ void unmarshal( mpi::RecvBuffer& buffer, UnionParameters& objparam )
 
 
 template <typename BodyTypeTuple>
-inline Union<BodyTypeTuple>* instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, Union<BodyTypeTuple>*& newBody )
+inline std::unique_ptr<Union<BodyTypeTuple>> instantiate( mpi::RecvBuffer& buffer, const math::AABB& domain, const math::AABB& block, Union<BodyTypeTuple>*& newBody )
 {
    UnionParameters subobjparam;
    unmarshal( buffer, subobjparam );
    correctBodyPosition(domain, block.center(), subobjparam.gpos_);
-   newBody = new Union<BodyTypeTuple>( subobjparam.sid_,
-                                       subobjparam.uid_,
-                                       subobjparam.gpos_,
-                                       subobjparam.rpos_,
-                                       subobjparam.q_,
-                                       false,
-                                       subobjparam.communicating_,
-                                       subobjparam.infiniteMass_ );
-   newBody->setLinearVel( subobjparam.v_ );
-   newBody->setAngularVel( subobjparam.w_ );
-   newBody->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
+   auto un = std::make_unique<Union<BodyTypeTuple>>( subobjparam.sid_,
+                                                     subobjparam.uid_,
+                                                     subobjparam.gpos_,
+                                                     subobjparam.rpos_,
+                                                     subobjparam.q_,
+                                                     false,
+                                                     subobjparam.communicating_,
+                                                     subobjparam.infiniteMass_ );
+   un->setLinearVel( subobjparam.v_ );
+   un->setAngularVel( subobjparam.w_ );
+   un->MPITrait.setOwner( subobjparam.mpiTrait_.owner_ );
 
    // Decoding the contained primitives
    for( size_t i = 0; i < subobjparam.size_; ++i )
    {
       decltype ( static_cast<BodyID>(nullptr)->getTypeID() ) type;
       buffer >> type;
-      BodyID obj = UnmarshalDynamically<BodyTypeTuple>::execute(buffer, type, domain, block);
+      BodyPtr obj( UnmarshalDynamically<BodyTypeTuple>::execute(buffer, type, domain, block) );
       obj->setRemote( true );
-      newBody->add(obj);
+      un->add(std::move(obj));
    }
 
-   return newBody;
+   newBody = un.get();
+   return un;
 }
 
 }  // namespace communication
diff --git a/src/pe/contact/Contact.cpp b/src/pe/contact/Contact.cpp
index ed9e68e28cc7bff136a697d4b1716f3421f92a23..7bc7dc04127ff734e3153201f3037fb3663cf72e 100644
--- a/src/pe/contact/Contact.cpp
+++ b/src/pe/contact/Contact.cpp
@@ -62,17 +62,8 @@ Contact::Contact( GeomID g1, GeomID g2, const Vec3& gpos, const Vec3& normal, re
    WALBERLA_ASSERT_FLOAT_EQUAL( normal.sqrLength(), real_c(1), "Invalid contact normal\n" << g1 << "\n" << g2 );
    WALBERLA_ASSERT( !( b1_->hasInfiniteMass() && b2_->hasInfiniteMass() ), "Invalid contact between two rigid bodies with infinite masses" );
 
-   // Registering the contact with both attached rigid bodies
-//   if( !b1_->hasInfiniteMass() ) b1_->registerContact( this );
-//   if( !b2_->hasInfiniteMass() ) b2_->registerContact( this );
-
-   // Merging the contact graph
-//   if( !b1_->hasInfiniteMass() && !b2_->hasInfiniteMass() )
-//      mergeNodes( b1_, b2_ );
-
    // Debugging output
    WALBERLA_LOG_DETAIL( "         => contact-id = " << id_ );
-
 }
 //*************************************************************************************************
 
diff --git a/src/pe/cr/DEM.h b/src/pe/cr/DEM.h
index 9d0887e774253fcfbb7c76e4ded484a30abbd843..dcc19af292c646addf2f0eac477d3c87e5a4218f 100644
--- a/src/pe/cr/DEM.h
+++ b/src/pe/cr/DEM.h
@@ -79,7 +79,7 @@ private:
    size_t                            numberOfContactsTreated_;
 };
 
-class DEM : public DEMSolver<IntegrateImplictEuler, ResolveContactSpringDashpotHaffWerner>
+class DEM : public DEMSolver<IntegrateImplicitEuler, ResolveContactSpringDashpotHaffWerner>
 {
 public:
    DEM(  const shared_ptr<BodyStorage>&    globalBodyStorage
@@ -88,8 +88,8 @@ public:
        , domain_decomposition::BlockDataID ccdID
        , domain_decomposition::BlockDataID fcdID
        , WcTimingTree*                     tt = NULL)
-   : DEMSolver<IntegrateImplictEuler, ResolveContactSpringDashpotHaffWerner>(
-              IntegrateImplictEuler(), ResolveContactSpringDashpotHaffWerner(),
+   : DEMSolver<IntegrateImplicitEuler, ResolveContactSpringDashpotHaffWerner>(
+              IntegrateImplicitEuler(), ResolveContactSpringDashpotHaffWerner(),
               globalBodyStorage, blockStorage, storageID, ccdID, fcdID, tt )
    {
    }
diff --git a/src/pe/cr/DEM.impl.h b/src/pe/cr/DEM.impl.h
index c64669ba210b48ca9f8101d7c09883c10405cc73..a3560e50fd94ba9daf71b71032deaa4ad3a9ec58 100644
--- a/src/pe/cr/DEM.impl.h
+++ b/src/pe/cr/DEM.impl.h
@@ -120,25 +120,21 @@ void DEMSolver<Integrator,ContactResolver>::timestep( real_t dt )
       {
          WALBERLA_LOG_DETAIL( "Time integration of body with system id " << bodyIt->getSystemID());// << "\n" << *bodyIt );
 
-         // Resetting the contact node and removing all attached contacts
-      //      bodyIt->resetNode();
-         bodyIt->clearContacts();
-
          // Checking the state of the body
          WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid body state detected" );
          WALBERLA_ASSERT( !bodyIt->hasSuperBody(), "Invalid superordinate body detected" );
          
-         // Moving the capsule according to the acting forces (don't move a sleeping capsule)
+         // Moving the body according to the acting forces (don't move a sleeping body)
          if( bodyIt->isAwake() && !bodyIt->hasInfiniteMass() )
          {
-            integrate_( *bodyIt, dt, *this );
+            integrate_( bodyIt.getBodyID(), dt, *this );
          }
          
          // Resetting the acting forces
          bodyIt->resetForceAndTorque();
          
          // Checking the state of the rigid body
-         WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid capsule state detected" );
+         WALBERLA_ASSERT( bodyIt->checkInvariants(), "Invalid body state detected" );
 
          // Resetting the acting forces
          bodyIt->resetForceAndTorque();
@@ -147,9 +143,8 @@ void DEMSolver<Integrator,ContactResolver>::timestep( real_t dt )
       if (tt_ != NULL) tt_->stop("Integration");
 
       // Reset forces of shadow copies
-      for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt ) {
-         bodyIt->clearContacts();
-         bodyIt->resetForceAndTorque();
+      for( auto& body : shadowStorage ) {
+         body.resetForceAndTorque();
       }
 
    }
diff --git a/src/pe/cr/HCSITS.impl.h b/src/pe/cr/HCSITS.impl.h
index 457cd4c299c88731b6e35058e59706a34774ea59..314b3d1c1dae7313d706053d66011ebf62b7e540 100644
--- a/src/pe/cr/HCSITS.impl.h
+++ b/src/pe/cr/HCSITS.impl.h
@@ -154,6 +154,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
 
    numContacts_        = 0;
    numContactsTreated_ = 0;
+   maximumPenetration_ = 0;
 
    if (tt_ != NULL) tt_->start("Simulation Step");
 
@@ -210,7 +211,6 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
       contactCache.resize( numContactsMasked );
 
       {
-         maximumPenetration_ = 0;
 
          size_t j = 0;
          for( size_t i = 0; i < numContacts; ++i )
@@ -290,7 +290,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          body->index_ = j;
          WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" );
 
-         initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
+         initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
 
          bodyCache.v_[j] = body->getLinearVel();
          bodyCache.w_[j] = body->getAngularVel();
@@ -300,7 +300,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          body->wake(); // BUGFIX: Force awaking of all bodies!
          body->index_ = j;
 
-         initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
+         initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
 
          if( body->isAwake() && !body->hasInfiniteMass() ) {
             bodyCache.v_[j] = body->getLinearVel() + getGlobalLinearAcceleration() * dt;
@@ -317,7 +317,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          body->wake(); // BUGFIX: Force awaking of all bodies!
          body->index_ = j;
 
-         initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt );
+         initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt );
 
          // Velocities of shadow copies will be initialized by velocity synchronization.
 #ifndef NDEBUG
@@ -349,7 +349,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          body->index_ = j;
          WALBERLA_CHECK( body->hasInfiniteMass(), "Global bodies need to have infinite mass as they are not communicated!" );
 
-         initializeVelocityCorrections( *body, bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
+         initializeVelocityCorrections( body.getBodyID(), bodyCache.dv_[j], bodyCache.dw_[j], dt ); // use applied external forces to calculate starting velocity
 
          bodyCache.v_[j] = body->getLinearVel();
          bodyCache.w_[j] = body->getAngularVel();
@@ -457,10 +457,10 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          WALBERLA_LOG_DETAIL( "Integrating position of global body " << *body << " with velocity " << body->getLinearVel() << "" );
          if (body->hasInfiniteMass())
          {
-            integratePositions( *body, bodyCache.v_[j], bodyCache.w_[j], dt );
+            integratePositions( body.getBodyID(), bodyCache.v_[j], bodyCache.w_[j], dt );
          } else
          {
-            integratePositions( *body, bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt );
+            integratePositions( body.getBodyID(), bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt );
          }
          WALBERLA_LOG_DETAIL( "Result:\n" << *body << "");
       }
@@ -476,11 +476,11 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
       BodyStorage& localStorage = (*storage)[0];
       BodyStorage& shadowStorage = (*storage)[1];
 
-      for( auto body = ConcatIterator<BodyStorage::Iterator>
+      for( auto body = ConcatIterator<BodyStorage::iterator>
            (localStorage.begin(),
             localStorage.end(),
             shadowStorage.begin(),
-            shadowStorage.end()); body != ConcatIterator<BodyStorage::Iterator>(); ++body )
+            shadowStorage.end()); body != ConcatIterator<BodyStorage::iterator>(); ++body )
       {
          if (!body->isCommunicating())
          {
@@ -492,10 +492,10 @@ inline void HardContactSemiImplicitTimesteppingSolvers::timestep( const real_t d
          WALBERLA_LOG_DETAIL( "Integrating position of body with infinite mass " << *body << " with velocity " << bodyCache.v_[j] << "" );
          if( body->hasInfiniteMass() )
          {
-            integratePositions( *body, bodyCache.v_[j], bodyCache.w_[j], dt );
+            integratePositions( &(*body), bodyCache.v_[j], bodyCache.w_[j], dt );
          } else
          {
-            integratePositions( *body, bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt );
+            integratePositions( &(*body), bodyCache.v_[j] + bodyCache.dv_[j], bodyCache.w_[j] + bodyCache.dw_[j], dt );
          }
          WALBERLA_LOG_DETAIL( "Result:\n" << *body << "" );
       }
@@ -1433,7 +1433,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::parseVelocityCorrection(
 
       auto bodyIt = bodyStorage.find( objparam.sid_ );
       WALBERLA_ASSERT(bodyIt != bodyStorage.end(), "Body not found!");
-      BodyID b( *bodyIt );
+      BodyID b( bodyIt.getBodyID() );
       bodyCache.v_[b->index_] += relaxationParam_*objparam.dv_;
       bodyCache.w_[b->index_] += relaxationParam_*objparam.dw_;
 
@@ -1462,7 +1462,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::parseVelocityCorrectionS
 
       auto bodyIt = bodyStorage.find( objparam.sid_ );
       WALBERLA_ASSERT(bodyIt != bodyStorage.end(), "Body not found!");
-      BodyID b( *bodyIt );
+      BodyID b( bodyIt.getBodyID() );
       WALBERLA_ASSERT( b->isRemote(), "Update notification must only concern shadow copies." );
 
       bodyCache.v_[b->index_] = objparam.dv_;
@@ -1531,12 +1531,12 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( )
 
          WALBERLA_LOG_DETAIL( "Sending velocity correction " << bodyCache.dv_[i] << ", " << bodyCache.dw_[i] << " of body " << body->getSystemID() << " to owner process " << body->MPITrait.getOwner() << ".");
 
-         packNotificationWithoutSender(body->MPITrait.getOwner(), sb, RigidBodyVelocityCorrectionNotification( *(*body), bodyCache.dv_[i], bodyCache.dw_[i] ));
+         packNotificationWithoutSender(body->MPITrait.getOwner(), sb, RigidBodyVelocityCorrectionNotification( *body, bodyCache.dv_[i], bodyCache.dw_[i] ));
       }
 
       for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt )
       {
-         BodyID b(*bodyIt);
+         BodyID b(bodyIt.getBodyID());
          for (auto shadows = b->MPITrait.beginShadowOwners(); shadows != b->MPITrait.endShadowOwners(); ++shadows )
          {
             recvRanks.insert(shadows->rank_);
@@ -1630,7 +1630,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( )
 
             mpi::SendBuffer& sb = syncVelBS.sendBuffer( shadow->rank_ );
             if (sb.isEmpty()) sb << walberla::uint8_c(0);
-            packNotificationWithoutSender(*shadow, sb, RigidBodyVelocityCorrectionNotification( *(*body), bodyCache.v_[i], bodyCache.w_[i] ));
+            packNotificationWithoutSender(*shadow, sb, RigidBodyVelocityCorrectionNotification( *body, bodyCache.v_[i], bodyCache.w_[i] ));
 
             WALBERLA_LOG_DETAIL( "Sending velocity update " << bodyCache.v_[i] << ", " << bodyCache.w_[i] << " of body " << body->getSystemID() << " to process " << *shadow << " having a shadow copy.");
          }
@@ -1638,7 +1638,7 @@ inline void HardContactSemiImplicitTimesteppingSolvers::synchronizeVelocities( )
 
       for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt )
       {
-         BodyID b(*bodyIt);
+         BodyID b(bodyIt.getBodyID());
          recvRanks.insert(b->MPITrait.getOwner().rank_);
       }
    }
@@ -1795,10 +1795,6 @@ inline void HardContactSemiImplicitTimesteppingSolvers::integratePositions( Body
    if ( body->isFixed() )
       return;
 
-   // Resetting the contact node and removing all attached contacts
-   body->resetNode();
-   body->clearContacts();
-
    if( body->isAwake() )
    {
       if ( isSpeedLimiterActive() )
diff --git a/src/pe/cr/Integrators.h b/src/pe/cr/Integrators.h
index 30b56e50a9e308917872d03156447d9e3b520157..1ea365f6661f542c73fde4ad31255cb5b18c2097 100644
--- a/src/pe/cr/Integrators.h
+++ b/src/pe/cr/Integrators.h
@@ -30,7 +30,7 @@ namespace pe {
 namespace cr {
 
 //*************************************************************************************************
-/*!\brief Integrate the trajectory of one body using implict Euler.
+/*!\brief Integrate the trajectory of one body using implicit Euler.
 *
 * \param id Body ID.
 * \param dt Time step size.
@@ -40,7 +40,7 @@ namespace cr {
 * The implicit Euler algorithm, also known as backward Euler, is used. It is a first-order
 * integrator that does conserves energy (i.e. it is symplectic.)
 */
-class IntegrateImplictEuler {
+class IntegrateImplicitEuler {
 public:
    void operator()( BodyID id, real_t dt, ICR & solver ) const
    {
@@ -72,7 +72,7 @@ public:
       // Setting the axis-aligned bounding box
       id->calcBoundingBox();
 
-      // Calculating the current motion of the capsule
+      // Calculating the current motion of the body
       id->calcMotion();
    }
 };
@@ -88,7 +88,7 @@ public:
 * The explicit Euler algorithm, also known as forward Euler, is used. It is a first-order
 * integrator that does not conserve energy (i.e. it is not symplectic.)
 */
-class IntegrateExplictEuler {
+class IntegrateExplicitEuler {
 public:
    void operator()( BodyID id, real_t dt, ICR & solver ) const
    {
@@ -120,7 +120,7 @@ public:
       // Setting the axis-aligned bounding box
       id->calcBoundingBox();
 
-      // Calculating the current motion of the capsule
+      // Calculating the current motion of the body
       id->calcMotion();
    }
 };
diff --git a/src/pe/cr/PlainIntegrator.h b/src/pe/cr/PlainIntegrator.h
index 271847f5d3d9b601452553d08d4a85bae8a4eb71..92abbbfb3746b59f08927fb9222b4b72bd00045f 100644
--- a/src/pe/cr/PlainIntegrator.h
+++ b/src/pe/cr/PlainIntegrator.h
@@ -61,14 +61,14 @@ private:
    WcTimingTree*                     tt_;
 };
    
-class PlainIntegrator : public PlainIntegratorSolver<IntegrateImplictEuler>
+class PlainIntegrator : public PlainIntegratorSolver<IntegrateImplicitEuler>
 {
 public:
    PlainIntegrator(  const shared_ptr<BodyStorage>&    globalBodyStorage
                    , const shared_ptr<BlockStorage>&   blockStorage
                    , domain_decomposition::BlockDataID storageID
                    , WcTimingTree*                     tt = NULL)
-   : PlainIntegratorSolver<IntegrateImplictEuler>( IntegrateImplictEuler(), globalBodyStorage, blockStorage,
+   : PlainIntegratorSolver<IntegrateImplicitEuler>( IntegrateImplicitEuler(), globalBodyStorage, blockStorage,
                                                    storageID, tt )
    {
    }
diff --git a/src/pe/cr/PlainIntegrator.impl.h b/src/pe/cr/PlainIntegrator.impl.h
index 7b9c4ce45101e774ed936da68e81caab088f1f95..e2a45b2f8eda5405f858db551101d17f545e6537 100644
--- a/src/pe/cr/PlainIntegrator.impl.h
+++ b/src/pe/cr/PlainIntegrator.impl.h
@@ -65,23 +65,19 @@ void PlainIntegratorSolver<Integrator>::timestep( const real_t dt )
       BodyStorage& localStorage = (*storage)[0];
       for (auto bd = localStorage.begin(); bd != localStorage.end(); ++bd){
          // Checking the state of the body
-         WALBERLA_ASSERT( bd->checkInvariants(), "Invalid capsule state detected" );
+         WALBERLA_ASSERT( bd->checkInvariants(), "Invalid body state detected" );
          WALBERLA_ASSERT( !bd->hasSuperBody(), "Invalid superordinate body detected" );
 
-         // Resetting the contact node and removing all attached contacts
-      //      bd->resetNode();
-         bd->clearContacts();
-
-         // Moving the capsule according to the acting forces (don't move a sleeping capsule)
+         // Moving the body according to the acting forces (don't move a sleeping body)
          if( bd->isAwake() && !bd->hasInfiniteMass() ) {
-            integrate_( *bd, dt, *this );
+            integrate_( bd.getBodyID(), dt, *this );
          }
 
          // Resetting the acting forces
          bd->resetForceAndTorque();
 
-         // Checking the state of the capsule
-         WALBERLA_ASSERT( bd->checkInvariants(), "Invalid capsule state detected" );
+         // Checking the state of the body
+         WALBERLA_ASSERT( bd->checkInvariants(), "Invalid body state detected" );
       }
    }
    if (tt_!=NULL) tt_->stop("Integrate Bodies");
diff --git a/src/pe/extern/libccd/.gitignore b/src/pe/extern/libccd/.gitignore
deleted file mode 100644
index e3fa61345b7e1907936cb6042b7afbdb57c1ae68..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-*.o
-*.a
-ccd/config.h
-ccd/config.h.in
-
diff --git a/src/pe/extern/libccd/BSD-LICENSE b/src/pe/extern/libccd/BSD-LICENSE
deleted file mode 100644
index 1cb2dc53db0a2e70017314ee88fd59eb375920c5..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/BSD-LICENSE
+++ /dev/null
@@ -1,44 +0,0 @@
-libccd
--------
-
-Copyright (c)2010-2012 Daniel Fiser <danfis@danfis.cz>,
-Intelligent and Mobile Robotics Group, Department of Cybernetics,
-Faculty of Electrical Engineering, Czech Technical University in Prague.
-All rights reserved.
-
-
-This work was supported by SYMBRION and REPLICATOR projects.
-The SYMBRION project is funded by European Commission within the work
-"Future and Emergent Technologies Proactive" under grant agreement no.
-216342.
-The REPLICATOR project is funded within the work programme "Cognitive
-Systems, Interaction, Robotics" under grant agreement no. 216240.
-http://www.symbrion.eu/
-http://www.replicators.eu/
-
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- - Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
- - Neither the name of the University nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/pe/extern/libccd/alloc.h b/src/pe/extern/libccd/alloc.h
deleted file mode 100644
index 7cba3a4d71e81c399282cb2a0298a39acf407d51..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/alloc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_ALLOC_H__
-#define __CCD_ALLOC_H__
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * Functions and macros required for memory allocation.
- */
-
-/* Memory allocation: */
-#define __CCD_ALLOC_MEMORY(type, ptr_old, size) \
-    (type *)realloc((void *)ptr_old, (size))
-
-/** Allocate memory for one element of type.  */
-#define CCD_ALLOC(type) \
-    __CCD_ALLOC_MEMORY(type, NULL, sizeof(type))
-
-/** Allocate memory for array of elements of type type.  */
-#define CCD_ALLOC_ARR(type, num_elements) \
-    __CCD_ALLOC_MEMORY(type, NULL, sizeof(type) * (num_elements))
-
-#define CCD_REALLOC_ARR(ptr, type, num_elements) \
-    __CCD_ALLOC_MEMORY(type, ptr, sizeof(type) * (num_elements))
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_ALLOC_H__ */
diff --git a/src/pe/extern/libccd/ccd.c b/src/pe/extern/libccd/ccd.c
deleted file mode 100644
index 79b2f42c91287df03239384228afe79aee6d6935..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd.c
+++ /dev/null
@@ -1,1001 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2012 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#include <stdio.h>
-#include <float.h>
-#include <ccd/ccd.h>
-#include <ccd/vec3.h>
-#include "simplex.h"
-#include "polytope.h"
-#include "alloc.h"
-#include "dbg.h"
-
-
-/** Performs GJK algorithm. Returns 0 if intersection was found and simplex
- *  is filled with resulting polytope. */
-static int __ccdGJK(const void *obj1, const void *obj2,
-                    const ccd_t *ccd, ccd_simplex_t *simplex);
-
-/** Performs GJK+EPA algorithm. Returns 0 if intersection was found and
- *  pt is filled with resulting polytope and nearest with pointer to
- *  nearest element (vertex, edge, face) of polytope to origin. */
-static int __ccdGJKEPA(const void *obj1, const void *obj2,
-                       const ccd_t *ccd,
-                       ccd_pt_t *pt, ccd_pt_el_t **nearest);
-
-
-/** Returns true if simplex contains origin.
- *  This function also alteres simplex and dir according to further
- *  processing of GJK algorithm. */
-static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir);
-static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir);
-static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir);
-static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir);
-
-/** d = a x b x c */
-_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b,
-                             const ccd_vec3_t *c, ccd_vec3_t *d);
-
-
-/** Transforms simplex to polytope. It is assumed that simplex has 4
- *  vertices. */
-static int simplexToPolytope4(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest);
-
-/** Transforms simplex to polytope, three vertices required */
-static int simplexToPolytope3(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              const ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest);
-
-/** Transforms simplex to polytope, two vertices required */
-static int simplexToPolytope2(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              const ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest);
-
-/** Expands polytope using new vertex v.
- *  Return 0 on success, -2 on memory allocation failure.*/
-static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el,
-                          const ccd_support_t *newv);
-
-/** Finds next support point (at stores it in out argument).
- *  Returns 0 on success, -1 otherwise */
-static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd,
-                       const ccd_pt_el_t *el,
-                       ccd_support_t *out);
-
-
-
-void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir)
-{
-    (void)(o1);
-    (void)(o2);
-
-    ccdVec3Set(dir, CCD_ONE, CCD_ZERO, CCD_ZERO);
-}
-
-int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd)
-{
-    ccd_simplex_t simplex;
-    return __ccdGJK(obj1, obj2, ccd, &simplex) == 0;
-}
-
-int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd,
-                   ccd_vec3_t *sep)
-{
-    ccd_pt_t polytope;
-    ccd_pt_el_t *nearest;
-    int ret;
-
-    ccdPtInit(&polytope);
-
-    ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest);
-
-    // set separation vector
-    if (nearest)
-        ccdVec3Copy(sep, &nearest->witness);
-
-    ccdPtDestroy(&polytope);
-
-    return ret;
-}
-
-
-static int penEPAPosCmp(const void *a, const void *b)
-{
-    ccd_pt_vertex_t *v1, *v2;
-    v1 = *(ccd_pt_vertex_t **)a;
-    v2 = *(ccd_pt_vertex_t **)b;
-
-    if (ccdEq(v1->dist, v2->dist)){
-        return 0;
-    }else if (v1->dist < v2->dist){
-        return -1;
-    }else{
-        return 1;
-    }
-}
-
-static int penEPAPos(const ccd_pt_t *pt, const ccd_pt_el_t * nearest,
-                     ccd_vec3_t *pos)
-{
-    (void)(nearest);
-
-    ccd_pt_vertex_t *v;
-    ccd_pt_vertex_t **vs;
-    size_t i, len;
-    ccd_real_t scale;
-
-    // compute median
-    len = 0;
-    ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
-        len++;
-    }
-
-    vs = CCD_ALLOC_ARR(ccd_pt_vertex_t *, len);
-    if (vs == NULL)
-        return -1;
-
-    i = 0;
-    ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
-        vs[i++] = v;
-    }
-
-    qsort(vs, len, sizeof(ccd_pt_vertex_t *), penEPAPosCmp);
-
-    ccdVec3Set(pos, CCD_ZERO, CCD_ZERO, CCD_ZERO);
-    scale = CCD_ZERO;
-    if (len % 2 == 1)
-        len++;
-
-    for (i = 0; i < len / 2; i++){
-        ccdVec3Add(pos, &vs[i]->v.v1);
-        ccdVec3Add(pos, &vs[i]->v.v2);
-        scale += CCD_REAL(2.);
-    }
-    ccdVec3Scale(pos, CCD_ONE / scale);
-
-    free(vs);
-
-    return 0;
-}
-
-int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
-                      ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos)
-{
-    ccd_pt_t polytope;
-    ccd_pt_el_t *nearest;
-    int ret;
-
-    ccdPtInit(&polytope);
-
-    ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest);
-
-    // set separation vector
-    if (ret == 0 && nearest){
-        // compute depth of penetration
-        *depth = CCD_SQRT(nearest->dist);
-
-        // store normalized direction vector
-        ccdVec3Copy(dir, &nearest->witness);
-        ccdVec3Normalize(dir);
-
-        // compute position
-        if (penEPAPos(&polytope, nearest, pos) != 0){
-            ccdPtDestroy(&polytope);
-            return -2;
-        }
-    }
-
-    ccdPtDestroy(&polytope);
-
-    return ret;
-}
-
-
-static int __ccdGJK(const void *obj1, const void *obj2,
-                    const ccd_t *ccd, ccd_simplex_t *simplex)
-{
-    unsigned long iterations;
-    ccd_vec3_t dir; // direction vector
-    ccd_support_t last; // last support point
-    int do_simplex_res;
-
-    // initialize simplex struct
-    ccdSimplexInit(simplex);
-
-    // get first direction
-    ccd->first_dir(obj1, obj2, &dir);
-    // get first support point
-    __ccdSupport(obj1, obj2, &dir, ccd, &last);
-    // and add this point to simplex as last one
-    ccdSimplexAdd(simplex, &last);
-
-    // set up direction vector to as (O - last) which is exactly -last
-    ccdVec3Copy(&dir, &last.v);
-    ccdVec3Scale(&dir, -CCD_ONE);
-
-    // start iterations
-    for (iterations = 0UL; iterations < ccd->max_iterations; ++iterations) {
-        // obtain support point
-        __ccdSupport(obj1, obj2, &dir, ccd, &last);
-
-        // check if farthest point in Minkowski difference in direction dir
-        // isn't somewhere before origin (the test on negative dot product)
-        // - because if it is, objects are not intersecting at all.
-        if (ccdVec3Dot(&last.v, &dir) < CCD_ZERO){
-            return -1; // intersection not found
-        }
-
-        // add last support vector to simplex
-        ccdSimplexAdd(simplex, &last);
-
-        // if doSimplex returns 1 if objects intersect, -1 if objects don't
-        // intersect and 0 if algorithm should continue
-        do_simplex_res = doSimplex(simplex, &dir);
-        if (do_simplex_res == 1){
-            return 0; // intersection found
-        }else if (do_simplex_res == -1){
-            return -1; // intersection not found
-        }
-
-        if (ccdIsZero(ccdVec3Len2(&dir))){
-            return -1; // intersection not found
-        }
-    }
-
-    // intersection wasn't found
-    return -1;
-}
-
-static int __ccdGJKEPA(const void *obj1, const void *obj2,
-                       const ccd_t *ccd,
-                       ccd_pt_t *polytope, ccd_pt_el_t **nearest)
-{
-    ccd_simplex_t simplex;
-    ccd_support_t supp; // support point
-    int ret, size;
-
-    *nearest = NULL;
-
-    // run GJK and obtain terminal simplex
-    ret = __ccdGJK(obj1, obj2, ccd, &simplex);
-    if (ret != 0)
-        return -1;
-
-    // transform simplex to polytope - simplex won't be used anymore
-    size = ccdSimplexSize(&simplex);
-    if (size == 4){
-        ret = simplexToPolytope4(obj1, obj2, ccd, &simplex, polytope, nearest);
-    }else if (size == 3){
-        ret = simplexToPolytope3(obj1, obj2, ccd, &simplex, polytope, nearest);
-    }else{ // size == 2
-        ret = simplexToPolytope2(obj1, obj2, ccd, &simplex, polytope, nearest);
-    }
-
-    if (ret == -1){
-        // touching contact
-        return 0;
-    }else if (ret == -2){
-        // failed memory allocation
-        return -2;
-    }
-
-
-    while (1){
-        // get triangle nearest to origin
-        *nearest = ccdPtNearest(polytope);
-
-        // get next support point
-        if (nextSupport(obj1, obj2, ccd, *nearest, &supp) != 0)
-            break;
-
-        // expand nearest triangle using new point - supp
-        if (expandPolytope(polytope, *nearest, &supp) != 0)
-            return -2;
-    }
-
-    return 0;
-}
-
-
-
-static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir)
-{
-    const ccd_support_t *A, *B;
-    ccd_vec3_t AB, AO, tmp;
-    ccd_real_t dot;
-
-    // get last added as A
-    A = ccdSimplexLast(simplex);
-    // get the other point
-    B = ccdSimplexPoint(simplex, 0);
-    // compute AB oriented segment
-    ccdVec3Sub2(&AB, &B->v, &A->v);
-    // compute AO vector
-    ccdVec3Copy(&AO, &A->v);
-    ccdVec3Scale(&AO, -CCD_ONE);
-
-    // dot product AB . AO
-    dot = ccdVec3Dot(&AB, &AO);
-
-    // check if origin doesn't lie on AB segment
-    ccdVec3Cross(&tmp, &AB, &AO);
-    if (ccdIsZero(ccdVec3Len2(&tmp)) && dot > CCD_ZERO){
-        return 1;
-    }
-
-    // check if origin is in area where AB segment is
-    if (ccdIsZero(dot) || dot < CCD_ZERO){
-        // origin is in outside are of A
-        ccdSimplexSet(simplex, 0, A);
-        ccdSimplexSetSize(simplex, 1);
-        ccdVec3Copy(dir, &AO);
-    }else{
-        // origin is in area where AB segment is
-
-        // keep simplex untouched and set direction to
-        // AB x AO x AB
-        tripleCross(&AB, &AO, &AB, dir);
-    }
-
-    return 0;
-}
-
-static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir)
-{
-    const ccd_support_t *A, *B, *C;
-    ccd_vec3_t AO, AB, AC, ABC, tmp;
-    ccd_real_t dot, dist;
-
-    // get last added as A
-    A = ccdSimplexLast(simplex);
-    // get the other points
-    B = ccdSimplexPoint(simplex, 1);
-    C = ccdSimplexPoint(simplex, 0);
-
-    // check touching contact
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL);
-    if (ccdIsZero(dist)){
-        return 1;
-    }
-
-    // check if triangle is really triangle (has area > 0)
-    // if not simplex can't be expanded and thus no itersection is found
-    if (ccdVec3Eq(&A->v, &B->v) || ccdVec3Eq(&A->v, &C->v)){
-        return -1;
-    }
-
-    // compute AO vector
-    ccdVec3Copy(&AO, &A->v);
-    ccdVec3Scale(&AO, -CCD_ONE);
-
-    // compute AB and AC segments and ABC vector (perpendircular to triangle)
-    ccdVec3Sub2(&AB, &B->v, &A->v);
-    ccdVec3Sub2(&AC, &C->v, &A->v);
-    ccdVec3Cross(&ABC, &AB, &AC);
-
-    ccdVec3Cross(&tmp, &ABC, &AC);
-    dot = ccdVec3Dot(&tmp, &AO);
-    if (ccdIsZero(dot) || dot > CCD_ZERO){
-        dot = ccdVec3Dot(&AC, &AO);
-        if (ccdIsZero(dot) || dot > CCD_ZERO){
-            // C is already in place
-            ccdSimplexSet(simplex, 1, A);
-            ccdSimplexSetSize(simplex, 2);
-            tripleCross(&AC, &AO, &AC, dir);
-        }else{
-ccd_do_simplex3_45:
-            dot = ccdVec3Dot(&AB, &AO);
-            if (ccdIsZero(dot) || dot > CCD_ZERO){
-                ccdSimplexSet(simplex, 0, B);
-                ccdSimplexSet(simplex, 1, A);
-                ccdSimplexSetSize(simplex, 2);
-                tripleCross(&AB, &AO, &AB, dir);
-            }else{
-                ccdSimplexSet(simplex, 0, A);
-                ccdSimplexSetSize(simplex, 1);
-                ccdVec3Copy(dir, &AO);
-            }
-        }
-    }else{
-        ccdVec3Cross(&tmp, &AB, &ABC);
-        dot = ccdVec3Dot(&tmp, &AO);
-        if (ccdIsZero(dot) || dot > CCD_ZERO){
-            goto ccd_do_simplex3_45;
-        }else{
-            dot = ccdVec3Dot(&ABC, &AO);
-            if (ccdIsZero(dot) || dot > CCD_ZERO){
-                ccdVec3Copy(dir, &ABC);
-            }else{
-                ccd_support_t Ctmp;
-                ccdSupportCopy(&Ctmp, C);
-                ccdSimplexSet(simplex, 0, B);
-                ccdSimplexSet(simplex, 1, &Ctmp);
-
-                ccdVec3Copy(dir, &ABC);
-                ccdVec3Scale(dir, -CCD_ONE);
-            }
-        }
-    }
-
-    return 0;
-}
-
-static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir)
-{
-    const ccd_support_t *A, *B, *C, *D;
-    ccd_vec3_t AO, AB, AC, AD, ABC, ACD, ADB;
-    int B_on_ACD, C_on_ADB, D_on_ABC;
-    int AB_O, AC_O, AD_O;
-    ccd_real_t dist;
-
-    // get last added as A
-    A = ccdSimplexLast(simplex);
-    // get the other points
-    B = ccdSimplexPoint(simplex, 2);
-    C = ccdSimplexPoint(simplex, 1);
-    D = ccdSimplexPoint(simplex, 0);
-
-    // check if tetrahedron is really tetrahedron (has volume > 0)
-    // if it is not simplex can't be expanded and thus no intersection is
-    // found
-    dist = ccdVec3PointTriDist2(&A->v, &B->v, &C->v, &D->v, NULL);
-    if (ccdIsZero(dist)){
-        return -1;
-    }
-
-    // check if origin lies on some of tetrahedron's face - if so objects
-    // intersect
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL);
-    if (ccdIsZero(dist))
-        return 1;
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &C->v, &D->v, NULL);
-    if (ccdIsZero(dist))
-        return 1;
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &D->v, NULL);
-    if (ccdIsZero(dist))
-        return 1;
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &B->v, &C->v, &D->v, NULL);
-    if (ccdIsZero(dist))
-        return 1;
-
-    // compute AO, AB, AC, AD segments and ABC, ACD, ADB normal vectors
-    ccdVec3Copy(&AO, &A->v);
-    ccdVec3Scale(&AO, -CCD_ONE);
-    ccdVec3Sub2(&AB, &B->v, &A->v);
-    ccdVec3Sub2(&AC, &C->v, &A->v);
-    ccdVec3Sub2(&AD, &D->v, &A->v);
-    ccdVec3Cross(&ABC, &AB, &AC);
-    ccdVec3Cross(&ACD, &AC, &AD);
-    ccdVec3Cross(&ADB, &AD, &AB);
-
-    // side (positive or negative) of B, C, D relative to planes ACD, ADB
-    // and ABC respectively
-    B_on_ACD = ccdSign(ccdVec3Dot(&ACD, &AB));
-    C_on_ADB = ccdSign(ccdVec3Dot(&ADB, &AC));
-    D_on_ABC = ccdSign(ccdVec3Dot(&ABC, &AD));
-
-    // whether origin is on same side of ACD, ADB, ABC as B, C, D
-    // respectively
-    AB_O = ccdSign(ccdVec3Dot(&ACD, &AO)) == B_on_ACD;
-    AC_O = ccdSign(ccdVec3Dot(&ADB, &AO)) == C_on_ADB;
-    AD_O = ccdSign(ccdVec3Dot(&ABC, &AO)) == D_on_ABC;
-
-    if (AB_O && AC_O && AD_O){
-        // origin is in tetrahedron
-        return 1;
-
-    // rearrange simplex to triangle and call doSimplex3()
-    }else if (!AB_O){
-        // B is farthest from the origin among all of the tetrahedron's
-        // points, so remove it from the list and go on with the triangle
-        // case
-
-        // D and C are in place
-        ccdSimplexSet(simplex, 2, A);
-        ccdSimplexSetSize(simplex, 3);
-    }else if (!AC_O){
-        // C is farthest
-        ccdSimplexSet(simplex, 1, D);
-        ccdSimplexSet(simplex, 0, B);
-        ccdSimplexSet(simplex, 2, A);
-        ccdSimplexSetSize(simplex, 3);
-    }else{ // (!AD_O)
-        ccdSimplexSet(simplex, 0, C);
-        ccdSimplexSet(simplex, 1, B);
-        ccdSimplexSet(simplex, 2, A);
-        ccdSimplexSetSize(simplex, 3);
-    }
-
-    return doSimplex3(simplex, dir);
-}
-
-static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir)
-{
-    if (ccdSimplexSize(simplex) == 2){
-        // simplex contains segment only one segment
-        return doSimplex2(simplex, dir);
-    }else if (ccdSimplexSize(simplex) == 3){
-        // simplex contains triangle
-        return doSimplex3(simplex, dir);
-    }else{ // ccdSimplexSize(simplex) == 4
-        // tetrahedron - this is the only shape which can encapsule origin
-        // so doSimplex4() also contains test on it
-        return doSimplex4(simplex, dir);
-    }
-}
-
-
-_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b,
-                             const ccd_vec3_t *c, ccd_vec3_t *d)
-{
-    ccd_vec3_t e;
-    ccdVec3Cross(&e, a, b);
-    ccdVec3Cross(d, &e, c);
-}
-
-
-
-/** Transforms simplex to polytope. It is assumed that simplex has 4
- *  vertices! */
-static int simplexToPolytope4(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest)
-{
-    const ccd_support_t *a, *b, *c, *d;
-    int use_polytope3;
-    ccd_real_t dist;
-    ccd_pt_vertex_t *v[4];
-    ccd_pt_edge_t *e[6];
-    size_t i;
-
-    a = ccdSimplexPoint(simplex, 0);
-    b = ccdSimplexPoint(simplex, 1);
-    c = ccdSimplexPoint(simplex, 2);
-    d = ccdSimplexPoint(simplex, 3);
-
-    // check if origin lies on some of tetrahedron's face - if so use
-    // simplexToPolytope3()
-    use_polytope3 = 0;
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &c->v, NULL);
-    if (ccdIsZero(dist)){
-        use_polytope3 = 1;
-    }
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &c->v, &d->v, NULL);
-    if (ccdIsZero(dist)){
-        use_polytope3 = 1;
-        ccdSimplexSet(simplex, 1, c);
-        ccdSimplexSet(simplex, 2, d);
-    }
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &d->v, NULL);
-    if (ccdIsZero(dist)){
-        use_polytope3 = 1;
-        ccdSimplexSet(simplex, 2, d);
-    }
-    dist = ccdVec3PointTriDist2(ccd_vec3_origin, &b->v, &c->v, &d->v, NULL);
-    if (ccdIsZero(dist)){
-        use_polytope3 = 1;
-        ccdSimplexSet(simplex, 0, b);
-        ccdSimplexSet(simplex, 1, c);
-        ccdSimplexSet(simplex, 2, d);
-    }
-
-    if (use_polytope3){
-        ccdSimplexSetSize(simplex, 3);
-        return simplexToPolytope3(obj1, obj2, ccd, simplex, pt, nearest);
-    }
-
-    // no touching contact - simply create tetrahedron
-    for (i = 0; i < 4; i++){
-        v[i] = ccdPtAddVertex(pt, ccdSimplexPoint(simplex, (int)i));
-    }
-    
-    e[0] = ccdPtAddEdge(pt, v[0], v[1]);
-    e[1] = ccdPtAddEdge(pt, v[1], v[2]);
-    e[2] = ccdPtAddEdge(pt, v[2], v[0]);
-    e[3] = ccdPtAddEdge(pt, v[3], v[0]);
-    e[4] = ccdPtAddEdge(pt, v[3], v[1]);
-    e[5] = ccdPtAddEdge(pt, v[3], v[2]);
-
-    // ccdPtAdd*() functions return NULL either if the memory allocation
-    // failed of if any of the input pointers are NULL, so the bad
-    // allocation can be checked by the last calls of ccdPtAddFace()
-    // because the rest of the bad allocations eventually "bubble up" here
-    if (ccdPtAddFace(pt, e[0], e[1], e[2]) == NULL
-            || ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL
-            || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL
-            || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){
-        return -2;
-    }
-
-    return 0;
-}
-
-/** Transforms simplex to polytope, three vertices required */
-static int simplexToPolytope3(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              const ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest)
-{
-    const ccd_support_t *a, *b, *c;
-    ccd_support_t d, d2;
-    ccd_vec3_t ab, ac, dir;
-    ccd_pt_vertex_t *v[5];
-    ccd_pt_edge_t *e[9];
-    ccd_real_t dist, dist2;
-
-    *nearest = NULL;
-
-    a = ccdSimplexPoint(simplex, 0);
-    b = ccdSimplexPoint(simplex, 1);
-    c = ccdSimplexPoint(simplex, 2);
-
-    // If only one triangle left from previous GJK run origin lies on this
-    // triangle. So it is necessary to expand triangle into two
-    // tetrahedrons connected with base (which is exactly abc triangle).
-
-    // get next support point in direction of normal of triangle
-    ccdVec3Sub2(&ab, &b->v, &a->v);
-    ccdVec3Sub2(&ac, &c->v, &a->v);
-    ccdVec3Cross(&dir, &ab, &ac);
-    __ccdSupport(obj1, obj2, &dir, ccd, &d);
-    dist = ccdVec3PointTriDist2(&d.v, &a->v, &b->v, &c->v, NULL);
-
-    // and second one take in opposite direction
-    ccdVec3Scale(&dir, -CCD_ONE);
-    __ccdSupport(obj1, obj2, &dir, ccd, &d2);
-    dist2 = ccdVec3PointTriDist2(&d2.v, &a->v, &b->v, &c->v, NULL);
-
-    // check if face isn't already on edge of minkowski sum and thus we
-    // have touching contact
-    if (ccdIsZero(dist) || ccdIsZero(dist2)){
-        v[0] = ccdPtAddVertex(pt, a);
-        v[1] = ccdPtAddVertex(pt, b);
-        v[2] = ccdPtAddVertex(pt, c);
-        e[0] = ccdPtAddEdge(pt, v[0], v[1]);
-        e[1] = ccdPtAddEdge(pt, v[1], v[2]);
-        e[2] = ccdPtAddEdge(pt, v[2], v[0]);
-        *nearest = (ccd_pt_el_t *)ccdPtAddFace(pt, e[0], e[1], e[2]);
-        if (*nearest == NULL)
-            return -2;
-
-        return -1;
-    }
-
-    // form polyhedron
-    v[0] = ccdPtAddVertex(pt, a);
-    v[1] = ccdPtAddVertex(pt, b);
-    v[2] = ccdPtAddVertex(pt, c);
-    v[3] = ccdPtAddVertex(pt, &d);
-    v[4] = ccdPtAddVertex(pt, &d2);
-
-    e[0] = ccdPtAddEdge(pt, v[0], v[1]);
-    e[1] = ccdPtAddEdge(pt, v[1], v[2]);
-    e[2] = ccdPtAddEdge(pt, v[2], v[0]);
-
-    e[3] = ccdPtAddEdge(pt, v[3], v[0]);
-    e[4] = ccdPtAddEdge(pt, v[3], v[1]);
-    e[5] = ccdPtAddEdge(pt, v[3], v[2]);
-
-    e[6] = ccdPtAddEdge(pt, v[4], v[0]);
-    e[7] = ccdPtAddEdge(pt, v[4], v[1]);
-    e[8] = ccdPtAddEdge(pt, v[4], v[2]);
-
-    if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL
-            || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL
-            || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL
-
-            || ccdPtAddFace(pt, e[6], e[7], e[0]) == NULL
-            || ccdPtAddFace(pt, e[7], e[8], e[1]) == NULL
-            || ccdPtAddFace(pt, e[8], e[6], e[2]) == NULL){
-        return -2;
-    }
-
-    return 0;
-}
-
-/** Transforms simplex to polytope, two vertices required */
-static int simplexToPolytope2(const void *obj1, const void *obj2,
-                              const ccd_t *ccd,
-                              const ccd_simplex_t *simplex,
-                              ccd_pt_t *pt, ccd_pt_el_t **nearest)
-{
-    const ccd_support_t *a, *b;
-    ccd_vec3_t ab, ac, dir;
-    ccd_support_t supp[4];
-    ccd_pt_vertex_t *v[6];
-    ccd_pt_edge_t *e[12];
-    size_t i;
-    int found;
-
-    a = ccdSimplexPoint(simplex, 0);
-    b = ccdSimplexPoint(simplex, 1);
-
-    // This situation is a bit tricky. If only one segment comes from
-    // previous run of GJK - it means that either this segment is on
-    // minkowski edge (and thus we have touch contact) or it it isn't and
-    // therefore segment is somewhere *inside* minkowski sum and it *must*
-    // be possible to fully enclose this segment with polyhedron formed by
-    // at least 8 triangle faces.
-
-    // get first support point (any)
-    found = 0;
-    for (i = 0; i < ccd_points_on_sphere_len; i++){
-        __ccdSupport(obj1, obj2, &ccd_points_on_sphere[i], ccd, &supp[0]);
-        if (!ccdVec3Eq(&a->v, &supp[0].v) && !ccdVec3Eq(&b->v, &supp[0].v)){
-            found = 1;
-            break;
-        }
-    }
-    if (!found)
-        goto simplexToPolytope2_touching_contact;
-
-    // get second support point in opposite direction than supp[0]
-    ccdVec3Copy(&dir, &supp[0].v);
-    ccdVec3Scale(&dir, -CCD_ONE);
-    __ccdSupport(obj1, obj2, &dir, ccd, &supp[1]);
-    if (ccdVec3Eq(&a->v, &supp[1].v) || ccdVec3Eq(&b->v, &supp[1].v))
-        goto simplexToPolytope2_touching_contact;
-
-    // next will be in direction of normal of triangle a,supp[0],supp[1]
-    ccdVec3Sub2(&ab, &supp[0].v, &a->v);
-    ccdVec3Sub2(&ac, &supp[1].v, &a->v);
-    ccdVec3Cross(&dir, &ab, &ac);
-    __ccdSupport(obj1, obj2, &dir, ccd, &supp[2]);
-    if (ccdVec3Eq(&a->v, &supp[2].v) || ccdVec3Eq(&b->v, &supp[2].v))
-        goto simplexToPolytope2_touching_contact;
-
-    // and last one will be in opposite direction
-    ccdVec3Scale(&dir, -CCD_ONE);
-    __ccdSupport(obj1, obj2, &dir, ccd, &supp[3]);
-    if (ccdVec3Eq(&a->v, &supp[3].v) || ccdVec3Eq(&b->v, &supp[3].v))
-        goto simplexToPolytope2_touching_contact;
-
-    goto simplexToPolytope2_not_touching_contact;
-simplexToPolytope2_touching_contact:
-    v[0] = ccdPtAddVertex(pt, a);
-    v[1] = ccdPtAddVertex(pt, b);
-    *nearest = (ccd_pt_el_t *)ccdPtAddEdge(pt, v[0], v[1]);
-    if (*nearest == NULL)
-        return -2;
-
-    return -1;
-
-simplexToPolytope2_not_touching_contact:
-    // form polyhedron
-    v[0] = ccdPtAddVertex(pt, a);
-    v[1] = ccdPtAddVertex(pt, &supp[0]);
-    v[2] = ccdPtAddVertex(pt, b);
-    v[3] = ccdPtAddVertex(pt, &supp[1]);
-    v[4] = ccdPtAddVertex(pt, &supp[2]);
-    v[5] = ccdPtAddVertex(pt, &supp[3]);
-
-    e[0] = ccdPtAddEdge(pt, v[0], v[1]);
-    e[1] = ccdPtAddEdge(pt, v[1], v[2]);
-    e[2] = ccdPtAddEdge(pt, v[2], v[3]);
-    e[3] = ccdPtAddEdge(pt, v[3], v[0]);
-
-    e[4] = ccdPtAddEdge(pt, v[4], v[0]);
-    e[5] = ccdPtAddEdge(pt, v[4], v[1]);
-    e[6] = ccdPtAddEdge(pt, v[4], v[2]);
-    e[7] = ccdPtAddEdge(pt, v[4], v[3]);
-
-    e[8]  = ccdPtAddEdge(pt, v[5], v[0]);
-    e[9]  = ccdPtAddEdge(pt, v[5], v[1]);
-    e[10] = ccdPtAddEdge(pt, v[5], v[2]);
-    e[11] = ccdPtAddEdge(pt, v[5], v[3]);
-
-    if (ccdPtAddFace(pt, e[4], e[5], e[0]) == NULL
-            || ccdPtAddFace(pt, e[5], e[6], e[1]) == NULL
-            || ccdPtAddFace(pt, e[6], e[7], e[2]) == NULL
-            || ccdPtAddFace(pt, e[7], e[4], e[3]) == NULL
-
-            || ccdPtAddFace(pt, e[8],  e[9],  e[0]) == NULL
-            || ccdPtAddFace(pt, e[9],  e[10], e[1]) == NULL
-            || ccdPtAddFace(pt, e[10], e[11], e[2]) == NULL
-            || ccdPtAddFace(pt, e[11], e[8],  e[3]) == NULL){
-        return -2;
-    }
-
-    return 0;
-}
-
-/** Expands polytope's tri by new vertex v. Triangle tri is replaced by
- *  three triangles each with one vertex in v. */
-static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el,
-                          const ccd_support_t *newv)
-{
-    ccd_pt_vertex_t *v[5];
-    ccd_pt_edge_t *e[8];
-    ccd_pt_face_t *f[2];
-
-
-    // element can be either segment or triangle
-    if (el->type == CCD_PT_EDGE){
-        // In this case, segment should be replaced by new point.
-        // Simpliest case is when segment stands alone and in this case
-        // this segment is replaced by two other segments both connected to
-        // newv.
-        // Segment can be also connected to max two faces and in that case
-        // each face must be replaced by two other faces. To do this
-        // correctly it is necessary to have correctly ordered edges and
-        // vertices which is exactly what is done in following code.
-        //
-
-        ccdPtEdgeVertices((const ccd_pt_edge_t *)el, &v[0], &v[2]);
-
-        ccdPtEdgeFaces((ccd_pt_edge_t *)el, &f[0], &f[1]);
-
-        if (f[0]){
-            ccdPtFaceEdges(f[0], &e[0], &e[1], &e[2]);
-            if (e[0] == (ccd_pt_edge_t *)el){
-                e[0] = e[2];
-            }else if (e[1] == (ccd_pt_edge_t *)el){
-                e[1] = e[2];
-            }
-            ccdPtEdgeVertices(e[0], &v[1], &v[3]);
-            if (v[1] != v[0] && v[3] != v[0]){
-                e[2] = e[0];
-                e[0] = e[1];
-                e[1] = e[2];
-                if (v[1] == v[2])
-                    v[1] = v[3];
-            }else{
-                if (v[1] == v[0])
-                    v[1] = v[3];
-            }
-
-            if (f[1]){
-                ccdPtFaceEdges(f[1], &e[2], &e[3], &e[4]);
-                if (e[2] == (ccd_pt_edge_t *)el){
-                    e[2] = e[4];
-                }else if (e[3] == (ccd_pt_edge_t *)el){
-                    e[3] = e[4];
-                }
-                ccdPtEdgeVertices(e[2], &v[3], &v[4]);
-                if (v[3] != v[2] && v[4] != v[2]){
-                    e[4] = e[2];
-                    e[2] = e[3];
-                    e[3] = e[4];
-                    if (v[3] == v[0])
-                        v[3] = v[4];
-                }else{
-                    if (v[3] == v[2])
-                        v[3] = v[4];
-                }
-            }
-
-
-            v[4] = ccdPtAddVertex(pt, newv);
-
-            ccdPtDelFace(pt, f[0]);
-            if (f[1]){
-                ccdPtDelFace(pt, f[1]);
-                ccdPtDelEdge(pt, (ccd_pt_edge_t *)el);
-            }
-
-            e[4] = ccdPtAddEdge(pt, v[4], v[2]);
-            e[5] = ccdPtAddEdge(pt, v[4], v[0]);
-            e[6] = ccdPtAddEdge(pt, v[4], v[1]);
-            if (f[1])
-                e[7] = ccdPtAddEdge(pt, v[4], v[3]);
-
-
-            if (ccdPtAddFace(pt, e[1], e[4], e[6]) == NULL
-                    || ccdPtAddFace(pt, e[0], e[6], e[5]) == NULL){
-                return -2;
-            }
-
-            if (f[1]){
-                if (ccdPtAddFace(pt, e[3], e[5], e[7]) == NULL
-                        || ccdPtAddFace(pt, e[4], e[7], e[2]) == NULL){
-                    return -2;
-                }
-            }else{
-                if (ccdPtAddFace(pt, e[4], e[5], (ccd_pt_edge_t *)el) == NULL)
-                    return -2;
-            }
-        }
-    }else{ // el->type == CCD_PT_FACE
-        // replace triangle by tetrahedron without base (base would be the
-        // triangle that will be removed)
-
-        // get triplet of surrounding edges and vertices of triangle face
-        ccdPtFaceEdges((const ccd_pt_face_t *)el, &e[0], &e[1], &e[2]);
-        ccdPtEdgeVertices(e[0], &v[0], &v[1]);
-        ccdPtEdgeVertices(e[1], &v[2], &v[3]);
-
-        // following code sorts edges to have e[0] between vertices 0-1,
-        // e[1] between 1-2 and e[2] between 2-0
-        if (v[2] != v[1] && v[3] != v[1]){
-            // swap e[1] and e[2] 
-            e[3] = e[1];
-            e[1] = e[2];
-            e[2] = e[3];
-        }
-        if (v[3] != v[0] && v[3] != v[1])
-            v[2] = v[3];
-
-        // remove triangle face
-        ccdPtDelFace(pt, (ccd_pt_face_t *)el);
-
-        // expand triangle to tetrahedron
-        v[3] = ccdPtAddVertex(pt, newv);
-        e[3] = ccdPtAddEdge(pt, v[3], v[0]);
-        e[4] = ccdPtAddEdge(pt, v[3], v[1]);
-        e[5] = ccdPtAddEdge(pt, v[3], v[2]);
-
-        if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL
-                || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL
-                || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){
-            return -2;
-        }
-    }
-
-    return 0;
-}
-
-/** Finds next support point (and stores it in out argument).
- *  Returns 0 on success, -1 otherwise */
-static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd,
-                       const ccd_pt_el_t *el,
-                       ccd_support_t *out)
-{
-    ccd_vec3_t *a, *b, *c;
-    ccd_real_t dist;
-
-    if (el->type == CCD_PT_VERTEX)
-        return -1;
-
-    // touch contact
-    if (ccdIsZero(el->dist))
-        return -1;
-
-    __ccdSupport(obj1, obj2, &el->witness, ccd, out);
-
-    // Compute dist of support point along element witness point direction
-    // so we can determine whether we expanded a polytope surrounding the
-    // origin a bit.
-    dist = ccdVec3Dot(&out->v, &el->witness);
-
-    if (dist - el->dist < ccd->epa_tolerance)
-        return -1;
-
-    if (el->type == CCD_PT_EDGE){
-        // fetch end points of edge
-        ccdPtEdgeVec3((ccd_pt_edge_t *)el, &a, &b);
-
-        // get distance from segment
-        dist = ccdVec3PointSegmentDist2(&out->v, a, b, NULL);
-    }else{ // el->type == CCD_PT_FACE
-        // fetch vertices of triangle face
-        ccdPtFaceVec3((ccd_pt_face_t *)el, &a, &b, &c);
-
-        // check if new point can significantly expand polytope
-        dist = ccdVec3PointTriDist2(&out->v, a, b, c, NULL);
-    }
-
-    if (dist < ccd->epa_tolerance)
-        return -1;
-
-    return 0;
-}
diff --git a/src/pe/extern/libccd/ccd/ccd.h b/src/pe/extern/libccd/ccd/ccd.h
deleted file mode 100644
index fb8df75a081c6484c7f9445adb82c2b4f30fe786..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/ccd.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_H__
-#define __CCD_H__
-
-#include <ccd/vec3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/**
- * Type of *support* function that takes pointer to 3D object and direction
- * and returns (via vec argument) furthest point from object in specified
- * direction.
- */
-typedef void (*ccd_support_fn)(const void *obj, const ccd_vec3_t *dir,
-                               ccd_vec3_t *vec);
-
-/**
- * Returns (via dir argument) first direction vector that will be used in
- * initialization of algorithm.
- */
-typedef void (*ccd_first_dir_fn)(const void *obj1, const void *obj2,
-                                 ccd_vec3_t *dir);
-
-
-/**
- * Returns (via center argument) geometric center (some point near center)
- * of given object.
- */
-typedef void (*ccd_center_fn)(const void *obj1, ccd_vec3_t *center);
-
-/**
- * Main structure of CCD algorithm.
- */
-struct _ccd_t {
-    ccd_first_dir_fn first_dir; //!< Returns initial direction where first
-                                //!< support point will be searched
-    ccd_support_fn support1; //!< Function that returns support point of
-                             //!< first object
-    ccd_support_fn support2; //!< Function that returns support point of
-                             //!< second object
-
-    ccd_center_fn center1; //!< Function that returns geometric center of
-                           //!< first object
-    ccd_center_fn center2; //!< Function that returns geometric center of
-                           //!< second object
-
-    unsigned long max_iterations; //!< Maximal number of iterations
-    ccd_real_t epa_tolerance;
-    ccd_real_t mpr_tolerance; //!< Boundary tolerance for MPR algorithm
-    ccd_real_t dist_tolerance;
-};
-typedef struct _ccd_t ccd_t;
-
-/**
- * Default first direction.
- */
-_ccd_export void ccdFirstDirDefault(const void *o1, const void *o2,
-                                    ccd_vec3_t *dir);
-
-#define CCD_INIT(ccd) \
-    do { \
-        (ccd)->first_dir = ccdFirstDirDefault; \
-        (ccd)->support1 = NULL; \
-        (ccd)->support2 = NULL; \
-        (ccd)->center1  = NULL; \
-        (ccd)->center2  = NULL; \
-        \
-        (ccd)->max_iterations = (unsigned long)-1; \
-        (ccd)->epa_tolerance = CCD_REAL(0.0001); \
-        (ccd)->mpr_tolerance = CCD_REAL(0.0001); \
-        (ccd)->dist_tolerance = CCD_REAL(1E-6); \
-    } while(0)
-
-
-/**
- * Returns true if two given objects interest.
- */
-_ccd_export int ccdGJKIntersect(const void *obj1, const void *obj2,
-                                const ccd_t *ccd);
-
-/**
- * This function computes separation vector of two objects. Separation
- * vector is minimal translation of obj2 to get obj1 and obj2 speparated
- * (without intersection).
- * Returns 0 if obj1 and obj2 intersect and sep is filled with translation
- * vector. If obj1 and obj2 don't intersect -1 is returned.
- * If memory allocation fails -2 is returned.
- */
-_ccd_export int ccdGJKSeparate(const void *obj1, const void *obj2,
-                               const ccd_t *ccd, ccd_vec3_t *sep);
-
-/**
- * Computes penetration of obj2 into obj1.
- * Depth of penetration, direction and position is returned. It means that
- * if obj2 is translated by distance depth in direction dir objects will
- * have touching contact, pos should be position in global coordinates
- * where force should take a place.
- *
- * CCD+EPA algorithm is used.
- *
- * Returns 0 if obj1 and obj2 intersect and depth, dir and pos are filled
- * if given non-NULL pointers.
- * If obj1 and obj2 don't intersect -1 is returned.
- * If memory allocation fails -2 is returned.
- */
-_ccd_export int ccdGJKPenetration(const void *obj1, const void *obj2,
-                                  const ccd_t *ccd, ccd_real_t *depth,
-                                  ccd_vec3_t *dir, ccd_vec3_t *pos);
-
-/**
- * Returns true if two given objects intersect - MPR algorithm is used.
- */
-_ccd_export int ccdMPRIntersect(const void *obj1, const void *obj2,
-                                const ccd_t *ccd);
-
-/**
- * Computes penetration of obj2 into obj1.
- * Depth of penetration, direction and position is returned, i.e. if obj2
- * is translated by computed depth in resulting direction obj1 and obj2
- * would have touching contact. Position is point in global coordinates
- * where force should be take a place.
- *
- * Minkowski Portal Refinement algorithm is used (MPR, a.k.a. XenoCollide,
- * see Game Programming Gem 7).
- *
- * Returns 0 if obj1 and obj2 intersect, otherwise -1 is returned.
- */
-_ccd_export int ccdMPRPenetration(const void *obj1, const void *obj2,
-                                  const ccd_t *ccd, ccd_real_t *depth,
-                                  ccd_vec3_t *dir, ccd_vec3_t *pos);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_H__ */
diff --git a/src/pe/extern/libccd/ccd/compiler.h b/src/pe/extern/libccd/ccd/compiler.h
deleted file mode 100644
index b022e26e47875e9f2392b82adfadbd430d5b69b6..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/compiler.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_COMPILER_H__
-#define __CCD_COMPILER_H__
-
-#include <stddef.h>
-
-#define ccd_offsetof(TYPE, MEMBER) offsetof(TYPE, MEMBER)
-
-#define ccd_container_of(ptr, type, member) \
-    (type *)( (char *)ptr - ccd_offsetof(type, member))
-
-
-/**
- * Marks exported function.
- */
-//#ifdef _WIN32
-//# ifdef libccd_EXPORTS
-//#   define _ccd_export __declspec(dllexport)
-//# else /* libccd_EXPORTS */
-//#   define _ccd_export __declspec(dllimport)
-//# endif /* libccd_EXPORTS */
-//#else /* _WIN32 */
-//# define _ccd_export
-//#endif /* _WIN32 */
-
-#define _ccd_export
-
-
-/**
- * Marks inline function.
- */
-#ifdef __GNUC__
-# define _ccd_inline static inline __attribute__((always_inline))
-#else /* __GNUC__ */
-# define _ccd_inline static __inline
-#endif /* __GNUC__ */
-
-
-/**
- * __prefetch(x)  - prefetches the cacheline at "x" for read
- * __prefetchw(x) - prefetches the cacheline at "x" for write
- */
-#ifdef __GNUC__
-# define _ccd_prefetch(x) __builtin_prefetch(x)
-# define _ccd_prefetchw(x) __builtin_prefetch(x,1)
-#else /* __GNUC__ */
-# define _ccd_prefetch(x) ((void)0)
-# define _ccd_prefetchw(x) ((void)0)
-#endif /* __GNUC__ */
-
-
-#ifdef __ICC
-// disable unused parameter warning
-# pragma warning(disable:869)
-// disable annoying "operands are evaluated in unspecified order" warning
-# pragma warning(disable:981)
-#endif /* __ICC */
-
-#ifdef _MSC_VER
-// disable unsafe function warning
-# ifndef _CRT_SECURE_NO_WARNINGS
-#  define _CRT_SECURE_NO_WARNINGS
-# endif
-#endif /* _MSC_VER */
-
-#endif /* __CCD_COMPILER_H__ */
-
diff --git a/src/pe/extern/libccd/ccd/config.h.cmake.in b/src/pe/extern/libccd/ccd/config.h.cmake.in
deleted file mode 100644
index 0515009164d1c01f11f1728cb4913338bbe808e8..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/config.h.cmake.in
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __CCD_CONFIG_H__
-#define __CCD_CONFIG_H__
-
-#cmakedefine CCD_SINGLE
-#cmakedefine CCD_DOUBLE
-
-#endif /* __CCD_CONFIG_H__ */
diff --git a/src/pe/extern/libccd/ccd/config.h.m4 b/src/pe/extern/libccd/ccd/config.h.m4
deleted file mode 100644
index 4c11fbab0c11d9e9fd63ddd177fb262514732ee9..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/config.h.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __CCD_CONFIG_H__
-#define __CCD_CONFIG_H__
-
-ifdef(`USE_SINGLE', `#define CCD_SINGLE')
-ifdef(`USE_DOUBLE', `#define CCD_DOUBLE')
-
-#endif /* __CCD_CONFIG_H__ */
diff --git a/src/pe/extern/libccd/ccd/quat.h b/src/pe/extern/libccd/ccd/quat.h
deleted file mode 100644
index fc67532109560e904d7b90f02554c15b0f0a0ccf..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/quat.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_QUAT_H__
-#define __CCD_QUAT_H__
-
-#include <ccd/compiler.h>
-#include <ccd/vec3.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct _ccd_quat_t {
-    ccd_real_t q[4]; //!< x, y, z, w
-};
-typedef struct _ccd_quat_t ccd_quat_t;
-
-#define CCD_QUAT(name, x, y, z, w) \
-    ccd_quat_t name = { {x, y, z, w} }
-
-_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q);
-_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q);
-
-_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w);
-_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src);
-
-_ccd_inline int ccdQuatNormalize(ccd_quat_t *q);
-
-_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q,
-                                     ccd_real_t angle, const ccd_vec3_t *axis);
-
-_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k);
-
-/**
- * q = q * q2
- */
-_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2);
-
-/**
- * q = a * b
- */
-_ccd_inline void ccdQuatMul2(ccd_quat_t *q,
-                             const ccd_quat_t *a, const ccd_quat_t *b);
-
-/**
- * Inverts quaternion.
- * Returns 0 on success.
- */
-_ccd_inline int ccdQuatInvert(ccd_quat_t *q);
-_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src);
-
-
-/**
- * Rotate vector v by quaternion q.
- */
-_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q);
-
-
-/**** INLINES ****/
-_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q)
-{
-    ccd_real_t len;
-
-    len  = q->q[0] * q->q[0];
-    len += q->q[1] * q->q[1];
-    len += q->q[2] * q->q[2];
-    len += q->q[3] * q->q[3];
-
-    return len;
-}
-
-_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q)
-{
-    return CCD_SQRT(ccdQuatLen2(q));
-}
-
-_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w)
-{
-    q->q[0] = x;
-    q->q[1] = y;
-    q->q[2] = z;
-    q->q[3] = w;
-}
-
-_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src)
-{
-    *dest = *src;
-}
-
-
-_ccd_inline int ccdQuatNormalize(ccd_quat_t *q)
-{
-    ccd_real_t len = ccdQuatLen(q);
-    if (len < CCD_EPS)
-        return 0;
-
-    ccdQuatScale(q, CCD_ONE / len);
-    return 1;
-}
-
-_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q,
-                                     ccd_real_t angle, const ccd_vec3_t *axis)
-{
-    ccd_real_t a, x, y, z, n, s;
-
-    a = angle/2;
-    x = ccdVec3X(axis);
-    y = ccdVec3Y(axis);
-    z = ccdVec3Z(axis);
-    n = CCD_SQRT(x*x + y*y + z*z);
-
-    // axis==0? (treat this the same as angle==0 with an arbitrary axis)
-    if (n < CCD_EPS){
-        q->q[0] = q->q[1] = q->q[2] = CCD_ZERO;
-        q->q[3] = CCD_ONE;
-    }else{
-#ifdef CCD_DOUBLE
-        s = sin(a)/n;
-#else
-        s = sinf(a)/n;
-#endif
-
-#ifdef CCD_DOUBLE
-        q->q[3] = cos(a);
-#else
-        q->q[3] = cosf(a);
-#endif
-        q->q[0] = x*s;
-        q->q[1] = y*s;
-        q->q[2] = z*s;
-
-        ccdQuatNormalize(q);
-    }
-}
-
-
-_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k)
-{
-    size_t i;
-    for (i = 0; i < 4; i++)
-        q->q[i] *= k;
-}
-
-_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2)
-{
-    ccd_quat_t a;
-    ccdQuatCopy(&a, q);
-    ccdQuatMul2(q, &a, q2);
-}
-
-_ccd_inline void ccdQuatMul2(ccd_quat_t *q,
-                             const ccd_quat_t *a, const ccd_quat_t *b)
-{
-    q->q[0] = a->q[3] * b->q[0]
-                + a->q[0] * b->q[3]
-                + a->q[1] * b->q[2]
-                - a->q[2] * b->q[1];
-    q->q[1] = a->q[3] * b->q[1]
-                + a->q[1] * b->q[3]
-                - a->q[0] * b->q[2]
-                + a->q[2] * b->q[0];
-    q->q[2] = a->q[3] * b->q[2]
-                + a->q[2] * b->q[3]
-                + a->q[0] * b->q[1]
-                - a->q[1] * b->q[0];
-    q->q[3] = a->q[3] * b->q[3]
-                - a->q[0] * b->q[0]
-                - a->q[1] * b->q[1]
-                - a->q[2] * b->q[2];
-}
-
-_ccd_inline int ccdQuatInvert(ccd_quat_t *q)
-{
-    ccd_real_t len2 = ccdQuatLen2(q);
-    if (len2 < CCD_EPS)
-        return -1;
-
-    len2 = CCD_ONE / len2;
-
-    q->q[0] = -q->q[0] * len2;
-    q->q[1] = -q->q[1] * len2;
-    q->q[2] = -q->q[2] * len2;
-    q->q[3] = q->q[3] * len2;
-
-    return 0;
-}
-_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src)
-{
-    ccdQuatCopy(dest, src);
-    return ccdQuatInvert(dest);
-}
-
-_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q)
-{
-    // original version: 31 mul + 21 add
-    // optimized version: 18 mul + 12 add
-    // formula: v = v + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * v)
-    ccd_real_t cross1_x, cross1_y, cross1_z, cross2_x, cross2_y, cross2_z;
-    ccd_real_t x, y, z, w;
-    ccd_real_t vx, vy, vz;
-
-    vx = ccdVec3X(v);
-    vy = ccdVec3Y(v);
-    vz = ccdVec3Z(v);
-
-    w = q->q[3];
-    x = q->q[0];
-    y = q->q[1];
-    z = q->q[2];
-
-    cross1_x = y * vz - z * vy + w * vx;
-    cross1_y = z * vx - x * vz + w * vy;
-    cross1_z = x * vy - y * vx + w * vz;
-    cross2_x = y * cross1_z - z * cross1_y;
-    cross2_y = z * cross1_x - x * cross1_z;
-    cross2_z = x * cross1_y - y * cross1_x;
-    ccdVec3Set(v, vx + 2 * cross2_x, vy + 2 * cross2_y, vz + 2 * cross2_z);
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_QUAT_H__ */
diff --git a/src/pe/extern/libccd/ccd/vec3.h b/src/pe/extern/libccd/ccd/vec3.h
deleted file mode 100644
index b0c1b338f59cfc8e5c55903c1dae9d14463bb4dc..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/ccd/vec3.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010-2013 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_VEC3_H__
-#define __CCD_VEC3_H__
-
-#include <math.h>
-#include <float.h>
-#include <stdlib.h>
-#include <ccd/compiler.h>
-#include <ccd/config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#ifndef CCD_SINGLE
-# ifndef CCD_DOUBLE
-#  error You must define CCD_SINGLE or CCD_DOUBLE
-# endif /* CCD_DOUBLE */
-#endif /* CCD_SINGLE */
-
-#ifdef WIN32
-# define CCD_FMIN(x, y) ((x) < (y) ? (x) : (y))
-#endif /* WIN32 */
-
-#ifdef CCD_SINGLE
-# ifdef CCD_DOUBLE
-#  error You can define either CCD_SINGLE or CCD_DOUBLE, not both!
-# endif /* CCD_DOUBLE */
-
-typedef float ccd_real_t;
-
-//# define CCD_EPS 1E-6
-# define CCD_EPS FLT_EPSILON
-
-# define CCD_REAL_MAX FLT_MAX
-
-# define CCD_REAL(x) (x ## f)   /*!< form a constant */
-# define CCD_SQRT(x) (sqrtf(x)) /*!< square root */
-# define CCD_FABS(x) (fabsf(x)) /*!< absolute value */
-# define CCD_FMAX(x, y) (fmaxf((x), (y))) /*!< maximum of two floats */
-
-# ifndef CCD_FMIN
-#  define CCD_FMIN(x, y) (fminf((x), (y))) /*!< minimum of two floats */
-# endif /* CCD_FMIN */
-
-#endif /* CCD_SINGLE */
-
-#ifdef CCD_DOUBLE
-typedef double ccd_real_t;
-
-//# define CCD_EPS 1E-10
-# define CCD_EPS DBL_EPSILON
-
-# define CCD_REAL_MAX DBL_MAX
-
-# define CCD_REAL(x) (x)       /*!< form a constant */
-# define CCD_SQRT(x) (sqrt(x)) /*!< square root */
-# define CCD_FABS(x) (fabs(x)) /*!< absolute value */
-# define CCD_FMAX(x, y) (fmax((x), (y))) /*!< maximum of two floats */
-
-# ifndef CCD_FMIN
-#  define CCD_FMIN(x, y) (fmin((x), (y))) /*!< minimum of two floats */
-# endif /* CCD_FMIN */
-
-#endif /* CCD_DOUBLE */
-
-#define CCD_ONE CCD_REAL(1.)
-#define CCD_ZERO CCD_REAL(0.)
-
-struct _ccd_vec3_t {
-    ccd_real_t v[3];
-};
-typedef struct _ccd_vec3_t ccd_vec3_t;
-
-
-/**
- * Holds origin (0,0,0) - this variable is meant to be read-only!
- */
-extern ccd_vec3_t *ccd_vec3_origin;
-
-/**
- * Array of points uniformly distributed on unit sphere.
- */
-extern ccd_vec3_t *ccd_points_on_sphere;
-extern size_t ccd_points_on_sphere_len;
-
-/** Returns sign of value. */
-_ccd_inline int ccdSign(ccd_real_t val);
-/** Returns true if val is zero. **/
-_ccd_inline int ccdIsZero(ccd_real_t val);
-/** Returns true if a and b equal. **/
-_ccd_inline int ccdEq(ccd_real_t a, ccd_real_t b);
-
-
-#define CCD_VEC3_STATIC(x, y, z) \
-    { { (x), (y), (z) } }
-
-#define CCD_VEC3(name, x, y, z) \
-    ccd_vec3_t name = CCD_VEC3_STATIC((x), (y), (z))
-
-_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v);
-_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v);
-_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v);
-
-/**
- * Returns true if a and b equal.
- */
-_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b);
-
-/**
- * Returns squared length of vector.
- */
-_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v);
-
-/**
- * Returns distance between a and b.
- */
-_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b);
-
-
-_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z);
-
-/**
- * v = w
- */
-_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w);
-
-/**
- * Substracts coordinates of vector w from vector v. v = v - w
- */
-_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w);
-
-/**
- * Adds coordinates of vector w to vector v. v = v + w
- */
-_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w);
-
-/**
- * d = v - w
- */
-_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w);
-
-/**
- * d = d * k;
- */
-_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k);
-
-/**
- * Normalizes given vector to unit length.
- */
-_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d);
-
-
-/**
- * Dot product of two vectors.
- */
-_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b);
-
-/**
- * Cross product: d = a x b.
- */
-_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b);
-
-
-/**
- * Returns distance^2 of point P to segment ab.
- * If witness is non-NULL it is filled with coordinates of point from which
- * was computed distance to point P.
- */
-_ccd_export ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P,
-                                                const ccd_vec3_t *a,
-                                                const ccd_vec3_t *b,
-                                                ccd_vec3_t *witness);
-
-/**
- * Returns distance^2 of point P from triangle formed by triplet a, b, c.
- * If witness vector is provided it is filled with coordinates of point
- * from which was computed distance to point P.
- */
-_ccd_export ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P,
-                                            const ccd_vec3_t *a,
-                                            const ccd_vec3_t *b,
-                                            const ccd_vec3_t *c,
-                                            ccd_vec3_t *witness);
-
-
-/**** INLINES ****/
-_ccd_inline int ccdSign(ccd_real_t val)
-{
-    if (ccdIsZero(val)){
-        return 0;
-    }else if (val < CCD_ZERO){
-        return -1;
-    }
-    return 1;
-}
-
-_ccd_inline int ccdIsZero(ccd_real_t val)
-{
-    return CCD_FABS(val) < CCD_EPS;
-}
-
-_ccd_inline int ccdEq(ccd_real_t _a, ccd_real_t _b)
-{
-    ccd_real_t ab;
-    ccd_real_t a, b;
-
-    ab = CCD_FABS(_a - _b);
-    if (CCD_FABS(ab) < CCD_EPS)
-        return 1;
-
-    a = CCD_FABS(_a);
-    b = CCD_FABS(_b);
-    if (b > a){
-        return ab < CCD_EPS * b;
-    }else{
-        return ab < CCD_EPS * a;
-    }
-}
-
-
-_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v)
-{
-    return v->v[0];
-}
-
-_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v)
-{
-    return v->v[1];
-}
-
-_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v)
-{
-    return v->v[2];
-}
-
-_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b)
-{
-    return ccdEq(ccdVec3X(a), ccdVec3X(b))
-            && ccdEq(ccdVec3Y(a), ccdVec3Y(b))
-            && ccdEq(ccdVec3Z(a), ccdVec3Z(b));
-}
-
-_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v)
-{
-    return ccdVec3Dot(v, v);
-}
-
-_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b)
-{
-    ccd_vec3_t ab;
-    ccdVec3Sub2(&ab, a, b);
-    return ccdVec3Len2(&ab);
-}
-
-_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z)
-{
-    v->v[0] = x;
-    v->v[1] = y;
-    v->v[2] = z;
-}
-
-_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w)
-{
-    *v = *w;
-}
-
-_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w)
-{
-    v->v[0] -= w->v[0];
-    v->v[1] -= w->v[1];
-    v->v[2] -= w->v[2];
-}
-_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w)
-{
-    d->v[0] = v->v[0] - w->v[0];
-    d->v[1] = v->v[1] - w->v[1];
-    d->v[2] = v->v[2] - w->v[2];
-}
-
-_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w)
-{
-    v->v[0] += w->v[0];
-    v->v[1] += w->v[1];
-    v->v[2] += w->v[2];
-}
-
-_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k)
-{
-    d->v[0] *= k;
-    d->v[1] *= k;
-    d->v[2] *= k;
-}
-
-_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d)
-{
-    ccd_real_t k = CCD_ONE / CCD_SQRT(ccdVec3Len2(d));
-    ccdVec3Scale(d, k);
-}
-
-_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b)
-{
-    ccd_real_t dot;
-
-    dot  = a->v[0] * b->v[0];
-    dot += a->v[1] * b->v[1];
-    dot += a->v[2] * b->v[2];
-    return dot;
-}
-
-_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b)
-{
-    d->v[0] = (a->v[1] * b->v[2]) - (a->v[2] * b->v[1]);
-    d->v[1] = (a->v[2] * b->v[0]) - (a->v[0] * b->v[2]);
-    d->v[2] = (a->v[0] * b->v[1]) - (a->v[1] * b->v[0]);
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_VEC3_H__ */
diff --git a/src/pe/extern/libccd/dbg.h b/src/pe/extern/libccd/dbg.h
deleted file mode 100644
index f4852c1a06a5b852fc80fadf3fa56e5dfd00a973..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/dbg.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_DBG_H__
-#define __CCD_DBG_H__
-
-/**
- * Some macros which can be used for printing debug info to stderr if macro
- * NDEBUG not defined.
- *
- * DBG_PROLOGUE can be specified as string and this string will be
- * prepended to output text
- */
-#ifndef NDEBUG
-
-#include <stdio.h>
-
-#ifndef DBG_PROLOGUE
-# define DBG_PROLOGUE
-#endif
-
-# define DBG(format, ...) do { \
-    fprintf(stderr, DBG_PROLOGUE "%s :: " format "\n", __func__, ## __VA_ARGS__); \
-    fflush(stderr); \
-    } while (0)
-
-# define DBG2(str) do { \
-    fprintf(stderr, DBG_PROLOGUE "%s :: " str "\n", __func__); \
-    fflush(stderr); \
-    } while (0)
-
-# define DBG_VEC3(vec, prefix) do {\
-    fprintf(stderr, DBG_PROLOGUE "%s :: %s[%lf %lf %lf]\n", \
-            __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \
-    fflush(stderr); \
-    } while (0)
-/*
-# define DBG_VEC3(vec, prefix) do {\
-    fprintf(stderr, DBG_PROLOGUE "%s :: %s[%.20lf %.20lf %.20lf]\n", \
-            __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \
-    fflush(stderr); \
-    } while (0)
-*/
-
-#else
-# define DBG(format, ...)
-# define DBG2(str)
-# define DBG_VEC3(v, prefix)
-#endif
-
-#endif /* __CCD_DBG_H__ */
diff --git a/src/pe/extern/libccd/list.h b/src/pe/extern/libccd/list.h
deleted file mode 100644
index 40ea6328fa2633f430623662322ddd5cb65613a3..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/list.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_LIST_H__
-#define __CCD_LIST_H__
-
-#include <string.h>
-#include <ccd/compiler.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct _ccd_list_t {
-    struct _ccd_list_t *next, *prev;
-};
-typedef struct _ccd_list_t ccd_list_t;
-
-
-
-/**
- * Get the struct for this entry.
- * @ptr:	the &ccd_list_t pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- */
-#define ccdListEntry(ptr, type, member) \
-    ccd_container_of(ptr, type, member)
-
-/**
- * Iterates over list.
- */
-#define ccdListForEach(list, item) \
-        for (item = (list)->next; \
-             _ccd_prefetch((item)->next), item != (list); \
-             item = (item)->next)
-
-/**
- * Iterates over list safe against remove of list entry
- */
-#define ccdListForEachSafe(list, item, tmp) \
-	    for (item = (list)->next, tmp = (item)->next; \
-             item != (list); \
-		     item = tmp, tmp = (item)->next)
-
-/**
- * Iterates over list of given type.
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define ccdListForEachEntry(head, pos, postype, member)                 \
-	for (pos = ccdListEntry((head)->next, postype, member);	\
-	     _ccd_prefetch(pos->member.next), &pos->member != (head); 	\
-	     pos = ccdListEntry(pos->member.next, postype, member))
-
-/**
- * Iterates over list of given type safe against removal of list entry
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define ccdListForEachEntrySafe(head, pos, postype, n, ntype, member)         \
-    for (pos = ccdListEntry((head)->next, postype, member),             \
-		 n = ccdListEntry(pos->member.next, postype, member);	\
-	     &pos->member != (head); 					\
-	     pos = n, n = ccdListEntry(n->member.next, ntype, member))
-
-
-/**
- * Initialize list.
- */
-_ccd_inline void ccdListInit(ccd_list_t *l);
-
-_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l);
-_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l);
-
-/**
- * Returns true if list is empty.
- */
-_ccd_inline int ccdListEmpty(const ccd_list_t *head);
-
-/**
- * Appends item to end of the list l.
- */
-_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *item);
-
-/**
- * Removes item from list.
- */
-_ccd_inline void ccdListDel(ccd_list_t *item);
-
-
-
-///
-/// INLINES:
-///
-
-_ccd_inline void ccdListInit(ccd_list_t *l)
-{
-    l->next = l;
-    l->prev = l;
-}
-
-_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l)
-{
-    return l->next;
-}
-
-_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l)
-{
-    return l->prev;
-}
-
-_ccd_inline int ccdListEmpty(const ccd_list_t *head)
-{
-    return head->next == head;
-}
-
-_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *new_element)
-{
-    new_element->prev = l->prev;
-    new_element->next = l;
-    l->prev->next = new_element;
-    l->prev = new_element;
-}
-
-_ccd_inline void ccdListDel(ccd_list_t *item)
-{
-    item->next->prev = item->prev;
-    item->prev->next = item->next;
-    item->next = item;
-    item->prev = item;
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_LIST_H__ */
diff --git a/src/pe/extern/libccd/mpr.c b/src/pe/extern/libccd/mpr.c
deleted file mode 100644
index 5f5533a5bad9ba5a78be456f88e0ea0162af7b72..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/mpr.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#include <stdlib.h>
-#include <ccd/ccd.h>
-#include "simplex.h"
-#include "dbg.h"
-
-/** Finds origin (center) of Minkowski difference (actually it can be any
- *  interior point of Minkowski difference. */
-_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd,
-                            ccd_support_t *center);
-
-/** Discovers initial portal - that is tetrahedron that intersects with
- *  origin ray (ray from center of Minkowski diff to (0,0,0).
- *
- *  Returns -1 if already recognized that origin is outside Minkowski
- *  portal.
- *  Returns 1 if origin lies on v1 of simplex (only v0 and v1 are present
- *  in simplex).
- *  Returns 2 if origin lies on v0-v1 segment.
- *  Returns 0 if portal was built.
- */
-static int discoverPortal(const void *obj1, const void *obj2,
-                          const ccd_t *ccd, ccd_simplex_t *portal);
-
-
-/** Expands portal towards origin and determine if objects intersect.
- *  Already established portal must be given as argument.
- *  If intersection is found 0 is returned, -1 otherwise */
-static int refinePortal(const void *obj1, const void *obj2,
-                        const ccd_t *ccd, ccd_simplex_t *portal);
-
-/** Finds penetration info by expanding provided portal. */
-static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd,
-                       ccd_simplex_t *portal,
-                       ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
-
-/** Finds penetration info if origin lies on portal's v1 */
-static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd,
-                            ccd_simplex_t *portal,
-                            ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
-
-/** Find penetration info if origin lies on portal's segment v0-v1 */
-static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd,
-                              ccd_simplex_t *portal,
-                              ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
-
-/** Finds position vector from fully established portal */
-static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd,
-                    const ccd_simplex_t *portal, ccd_vec3_t *pos);
-
-/** Extends portal with new support point.
- *  Portal must have face v1-v2-v3 arranged to face outside portal. */
-_ccd_inline void expandPortal(ccd_simplex_t *portal,
-                              const ccd_support_t *v4);
-
-/** Fill dir with direction outside portal. Portal's v1-v2-v3 face must be
- *  arranged in correct order! */
-_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir);
-
-/** Returns true if portal encapsules origin (0,0,0), dir is direction of
- *  v1-v2-v3 face. */
-_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal,
-                                       const ccd_vec3_t *dir);
-
-/** Returns true if portal with new point v4 would reach specified
- *  tolerance (i.e. returns true if portal can _not_ significantly expand
- *  within Minkowski difference).
- *
- *  v4 is candidate for new point in portal, dir is direction in which v4
- *  was obtained. */
-_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal,
-                                     const ccd_support_t *v4,
-                                     const ccd_vec3_t *dir,
-                                     const ccd_t *ccd);
-
-/** Returns true if portal expanded by new point v4 could possibly contain
- *  origin, dir is direction in which v4 was obtained. */
-_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal,   
-                                         const ccd_support_t *v4,
-                                         const ccd_vec3_t *dir);
-
-
-int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd)
-{
-    ccd_simplex_t portal;
-    int res;
-
-    // Phase 1: Portal discovery - find portal that intersects with origin
-    // ray (ray from center of Minkowski diff to origin of coordinates)
-    res = discoverPortal(obj1, obj2, ccd, &portal);
-    if (res < 0)
-        return 0;
-    if (res > 0)
-        return 1;
-
-    // Phase 2: Portal refinement
-    res = refinePortal(obj1, obj2, ccd, &portal);
-    return (res == 0 ? 1 : 0);
-}
-
-int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
-                      ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos)
-{
-    ccd_simplex_t portal;
-    int res;
-
-    // Phase 1: Portal discovery
-    res = discoverPortal(obj1, obj2, ccd, &portal);
-    if (res < 0){
-        // Origin isn't inside portal - no collision.
-        return -1;
-
-    }else if (res == 1){
-        // Touching contact on portal's v1.
-        findPenetrTouch(obj1, obj2, ccd, &portal, depth, dir, pos);
-
-    }else if (res == 2){
-        // Origin lies on v0-v1 segment.
-        findPenetrSegment(obj1, obj2, ccd, &portal, depth, dir, pos);
-
-    }else if (res == 0){
-        // Phase 2: Portal refinement
-        res = refinePortal(obj1, obj2, ccd, &portal);
-        if (res < 0)
-            return -1;
-
-        // Phase 3. Penetration info
-        findPenetr(obj1, obj2, ccd, &portal, depth, dir, pos);
-    }
-
-    return 0;
-}
-
-
-
-_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd,
-                            ccd_support_t *center)
-{
-    ccd->center1(obj1, &center->v1);
-    ccd->center2(obj2, &center->v2);
-    ccdVec3Sub2(&center->v, &center->v1, &center->v2);
-}
-
-static int discoverPortal(const void *obj1, const void *obj2,
-                          const ccd_t *ccd, ccd_simplex_t *portal)
-{
-    ccd_vec3_t dir, va, vb;
-    ccd_real_t dot;
-    int cont;
-
-    // vertex 0 is center of portal
-    findOrigin(obj1, obj2, ccd, ccdSimplexPointW(portal, 0));
-    ccdSimplexSetSize(portal, 1);
-
-    if (ccdVec3Eq(&ccdSimplexPoint(portal, 0)->v, ccd_vec3_origin)){
-        // Portal's center lies on origin (0,0,0) => we know that objects
-        // intersect but we would need to know penetration info.
-        // So move center little bit...
-        ccdVec3Set(&va, CCD_EPS * CCD_REAL(10.), CCD_ZERO, CCD_ZERO);
-        ccdVec3Add(&ccdSimplexPointW(portal, 0)->v, &va);
-    }
-
-
-    // vertex 1 = support in direction of origin
-    ccdVec3Copy(&dir, &ccdSimplexPoint(portal, 0)->v);
-    ccdVec3Scale(&dir, CCD_REAL(-1.));
-    ccdVec3Normalize(&dir);
-    __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 1));
-    ccdSimplexSetSize(portal, 2);
-
-    // test if origin isn't outside of v1
-    dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &dir);
-    if (ccdIsZero(dot) || dot < CCD_ZERO)
-        return -1;
-
-
-    // vertex 2
-    ccdVec3Cross(&dir, &ccdSimplexPoint(portal, 0)->v,
-                       &ccdSimplexPoint(portal, 1)->v);
-    if (ccdIsZero(ccdVec3Len2(&dir))){
-        if (ccdVec3Eq(&ccdSimplexPoint(portal, 1)->v, ccd_vec3_origin)){
-            // origin lies on v1
-            return 1;
-        }else{
-            // origin lies on v0-v1 segment
-            return 2;
-        }
-    }
-
-    ccdVec3Normalize(&dir);
-    __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 2));
-    dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &dir);
-    if (ccdIsZero(dot) || dot < CCD_ZERO)
-        return -1;
-
-    ccdSimplexSetSize(portal, 3);
-
-    // vertex 3 direction
-    ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v,
-                     &ccdSimplexPoint(portal, 0)->v);
-    ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v,
-                     &ccdSimplexPoint(portal, 0)->v);
-    ccdVec3Cross(&dir, &va, &vb);
-    ccdVec3Normalize(&dir);
-
-    // it is better to form portal faces to be oriented "outside" origin
-    dot = ccdVec3Dot(&dir, &ccdSimplexPoint(portal, 0)->v);
-    if (dot > CCD_ZERO){
-        ccdSimplexSwap(portal, 1, 2);
-        ccdVec3Scale(&dir, CCD_REAL(-1.));
-    }
-
-    while (ccdSimplexSize(portal) < 4){
-        __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 3));
-        dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &dir);
-        if (ccdIsZero(dot) || dot < CCD_ZERO)
-            return -1;
-
-        cont = 0;
-
-        // test if origin is outside (v1, v0, v3) - set v2 as v3 and
-        // continue
-        ccdVec3Cross(&va, &ccdSimplexPoint(portal, 1)->v,
-                          &ccdSimplexPoint(portal, 3)->v);
-        dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v);
-        if (dot < CCD_ZERO && !ccdIsZero(dot)){
-            ccdSimplexSet(portal, 2, ccdSimplexPoint(portal, 3));
-            cont = 1;
-        }
-
-        if (!cont){
-            // test if origin is outside (v3, v0, v2) - set v1 as v3 and
-            // continue
-            ccdVec3Cross(&va, &ccdSimplexPoint(portal, 3)->v,
-                              &ccdSimplexPoint(portal, 2)->v);
-            dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v);
-            if (dot < CCD_ZERO && !ccdIsZero(dot)){
-                ccdSimplexSet(portal, 1, ccdSimplexPoint(portal, 3));
-                cont = 1;
-            }
-        }
-
-        if (cont){
-            ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v,
-                             &ccdSimplexPoint(portal, 0)->v);
-            ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v,
-                             &ccdSimplexPoint(portal, 0)->v);
-            ccdVec3Cross(&dir, &va, &vb);
-            ccdVec3Normalize(&dir);
-        }else{
-            ccdSimplexSetSize(portal, 4);
-        }
-    }
-
-    return 0;
-}
-
-static int refinePortal(const void *obj1, const void *obj2,
-                        const ccd_t *ccd, ccd_simplex_t *portal)
-{
-    ccd_vec3_t dir;
-    ccd_support_t v4;
-
-    while (1){
-        // compute direction outside the portal (from v0 throught v1,v2,v3
-        // face)
-        portalDir(portal, &dir);
-
-        // test if origin is inside the portal
-        if (portalEncapsulesOrigin(portal, &dir))
-            return 0;
-
-        // get next support point
-        __ccdSupport(obj1, obj2, &dir, ccd, &v4);
-
-        // test if v4 can expand portal to contain origin and if portal
-        // expanding doesn't reach given tolerance
-        if (!portalCanEncapsuleOrigin(portal, &v4, &dir)
-                || portalReachTolerance(portal, &v4, &dir, ccd)){
-            return -1;
-        }
-
-        // v1-v2-v3 triangle must be rearranged to face outside Minkowski
-        // difference (direction from v0).
-        expandPortal(portal, &v4);
-    }
-
-    return -1;
-}
-
-
-static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd,
-                       ccd_simplex_t *portal,
-                       ccd_real_t *depth, ccd_vec3_t *pdir, ccd_vec3_t *pos)
-{
-    ccd_vec3_t dir;
-    ccd_support_t v4;
-    unsigned long iterations;
-
-    iterations = 0UL;
-    while (1){
-        // compute portal direction and obtain next support point
-        portalDir(portal, &dir);
-        __ccdSupport(obj1, obj2, &dir, ccd, &v4);
-
-        // reached tolerance -> find penetration info
-        if (portalReachTolerance(portal, &v4, &dir, ccd)
-                || iterations > ccd->max_iterations){
-            *depth = ccdVec3PointTriDist2(ccd_vec3_origin,
-                                          &ccdSimplexPoint(portal, 1)->v,
-                                          &ccdSimplexPoint(portal, 2)->v,
-                                          &ccdSimplexPoint(portal, 3)->v,
-                                          pdir);
-            *depth = CCD_SQRT(*depth);
-            ccdVec3Normalize(pdir);
-
-            // barycentric coordinates:
-            findPos(obj1, obj2, ccd, portal, pos);
-
-            return;
-        }
-
-        expandPortal(portal, &v4);
-
-        iterations++;
-    }
-}
-
-static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd,
-                            ccd_simplex_t *portal,
-                            ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos)
-{
-   (void)(obj1);
-   (void)(obj2);
-   (void)(ccd);
-    // Touching contact on portal's v1 - so depth is zero and direction
-    // is unimportant and pos can be guessed
-    *depth = CCD_REAL(0.);
-    ccdVec3Copy(dir, ccd_vec3_origin);
-
-    ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1);
-    ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2);
-    ccdVec3Scale(pos, 0.5);
-}
-
-static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd,
-                              ccd_simplex_t *portal,
-                              ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos)
-{
-    (void)(obj1);
-    (void)(obj2);
-    (void)(ccd);
-
-    /*
-    ccd_vec3_t vec;
-    ccd_real_t k;
-    */
-
-    // Origin lies on v0-v1 segment.
-    // Depth is distance to v1, direction also and position must be
-    // computed
-
-    ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1);
-    ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2);
-    ccdVec3Scale(pos, CCD_REAL(0.5));
-
-    /*
-    ccdVec3Sub2(&vec, &ccdSimplexPoint(portal, 1)->v,
-                      &ccdSimplexPoint(portal, 0)->v);
-    k  = CCD_SQRT(ccdVec3Len2(&ccdSimplexPoint(portal, 0)->v));
-    k /= CCD_SQRT(ccdVec3Len2(&vec));
-    ccdVec3Scale(&vec, -k);
-    ccdVec3Add(pos, &vec);
-    */
-
-    ccdVec3Copy(dir, &ccdSimplexPoint(portal, 1)->v);
-    *depth = CCD_SQRT(ccdVec3Len2(dir));
-    ccdVec3Normalize(dir);
-}
-
-
-static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd,
-                    const ccd_simplex_t *portal, ccd_vec3_t *pos)
-{
-    (void)(obj1);
-    (void)(obj2);
-    (void)(ccd);
-
-    ccd_vec3_t dir;
-    size_t i;
-    ccd_real_t b[4], sum, inv;
-    ccd_vec3_t vec, p1, p2;
-
-    portalDir(portal, &dir);
-
-    // use barycentric coordinates of tetrahedron to find origin
-    ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v,
-                       &ccdSimplexPoint(portal, 2)->v);
-    b[0] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v);
-
-    ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v,
-                       &ccdSimplexPoint(portal, 2)->v);
-    b[1] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v);
-
-    ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 0)->v,
-                       &ccdSimplexPoint(portal, 1)->v);
-    b[2] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v);
-
-    ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v,
-                       &ccdSimplexPoint(portal, 1)->v);
-    b[3] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v);
-
-	sum = b[0] + b[1] + b[2] + b[3];
-
-    if (ccdIsZero(sum) || sum < CCD_ZERO){
-		b[0] = CCD_REAL(0.);
-
-        ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v,
-                           &ccdSimplexPoint(portal, 3)->v);
-        b[1] = ccdVec3Dot(&vec, &dir);
-        ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v,
-                           &ccdSimplexPoint(portal, 1)->v);
-        b[2] = ccdVec3Dot(&vec, &dir);
-        ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v,
-                           &ccdSimplexPoint(portal, 2)->v);
-        b[3] = ccdVec3Dot(&vec, &dir);
-
-		sum = b[1] + b[2] + b[3];
-	}
-
-	inv = CCD_REAL(1.) / sum;
-
-    ccdVec3Copy(&p1, ccd_vec3_origin);
-    ccdVec3Copy(&p2, ccd_vec3_origin);
-    for (i = 0; i < 4; i++){
-        ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v1);
-        ccdVec3Scale(&vec, b[i]);
-        ccdVec3Add(&p1, &vec);
-
-        ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v2);
-        ccdVec3Scale(&vec, b[i]);
-        ccdVec3Add(&p2, &vec);
-    }
-    ccdVec3Scale(&p1, inv);
-    ccdVec3Scale(&p2, inv);
-
-    ccdVec3Copy(pos, &p1);
-    ccdVec3Add(pos, &p2);
-    ccdVec3Scale(pos, 0.5);
-}
-
-_ccd_inline void expandPortal(ccd_simplex_t *portal,
-                              const ccd_support_t *v4)
-{
-    ccd_real_t dot;
-    ccd_vec3_t v4v0;
-
-    ccdVec3Cross(&v4v0, &v4->v, &ccdSimplexPoint(portal, 0)->v);
-    dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &v4v0);
-    if (dot > CCD_ZERO){
-        dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &v4v0);
-        if (dot > CCD_ZERO){
-            ccdSimplexSet(portal, 1, v4);
-        }else{
-            ccdSimplexSet(portal, 3, v4);
-        }
-    }else{
-        dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &v4v0);
-        if (dot > CCD_ZERO){
-            ccdSimplexSet(portal, 2, v4);
-        }else{
-            ccdSimplexSet(portal, 1, v4);
-        }
-    }
-}
-
-_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir)
-{
-    ccd_vec3_t v2v1, v3v1;
-
-    ccdVec3Sub2(&v2v1, &ccdSimplexPoint(portal, 2)->v,
-                       &ccdSimplexPoint(portal, 1)->v);
-    ccdVec3Sub2(&v3v1, &ccdSimplexPoint(portal, 3)->v,
-                       &ccdSimplexPoint(portal, 1)->v);
-    ccdVec3Cross(dir, &v2v1, &v3v1);
-    ccdVec3Normalize(dir);
-}
-
-_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal,
-                                       const ccd_vec3_t *dir)
-{
-    ccd_real_t dot;
-    dot = ccdVec3Dot(dir, &ccdSimplexPoint(portal, 1)->v);
-    return ccdIsZero(dot) || dot > CCD_ZERO;
-}
-
-_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal,
-                                     const ccd_support_t *v4,
-                                     const ccd_vec3_t *dir,
-                                     const ccd_t *ccd)
-{
-    ccd_real_t dv1, dv2, dv3, dv4;
-    ccd_real_t dot1, dot2, dot3;
-
-    // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4}
-
-    dv1 = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, dir);
-    dv2 = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, dir);
-    dv3 = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, dir);
-    dv4 = ccdVec3Dot(&v4->v, dir);
-
-    dot1 = dv4 - dv1;
-    dot2 = dv4 - dv2;
-    dot3 = dv4 - dv3;
-
-    dot1 = CCD_FMIN(dot1, dot2);
-    dot1 = CCD_FMIN(dot1, dot3);
-
-    return ccdEq(dot1, ccd->mpr_tolerance) || dot1 < ccd->mpr_tolerance;
-}
-
-_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal,   
-                                         const ccd_support_t *v4,
-                                         const ccd_vec3_t *dir)
-{
-    (void)(portal);
-
-    ccd_real_t dot;
-    dot = ccdVec3Dot(&v4->v, dir);
-    return ccdIsZero(dot) || dot > CCD_ZERO;
-}
diff --git a/src/pe/extern/libccd/polytope.c b/src/pe/extern/libccd/polytope.c
deleted file mode 100644
index 527016cdee360a5eba62e8063720b63c3b010a81..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/polytope.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#include <stdio.h>
-#include <float.h>
-#include "polytope.h"
-#include "alloc.h"
-
-_ccd_inline void _ccdPtNearestUpdate(ccd_pt_t *pt, ccd_pt_el_t *el)
-{
-    if (ccdEq(pt->nearest_dist, el->dist)){
-        if (el->type < pt->nearest_type){
-            pt->nearest = el;
-            pt->nearest_dist = el->dist;
-            pt->nearest_type = el->type;
-        }
-    }else if (el->dist < pt->nearest_dist){
-        pt->nearest = el;
-        pt->nearest_dist = el->dist;
-        pt->nearest_type = el->type;
-    }
-}
-
-static void _ccdPtNearestRenew(ccd_pt_t *pt)
-{
-    ccd_pt_vertex_t *v;
-    ccd_pt_edge_t *e;
-    ccd_pt_face_t *f;
-
-    pt->nearest_dist = CCD_REAL_MAX;
-    pt->nearest_type = 3;
-    pt->nearest = NULL;
-
-    ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
-        _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)v);
-    }
-
-    ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
-        _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)e);
-    }
-
-    ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
-        _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)f);
-    }
-}
-
-
-
-void ccdPtInit(ccd_pt_t *pt)
-{
-    ccdListInit(&pt->vertices);
-    ccdListInit(&pt->edges);
-    ccdListInit(&pt->faces);
-
-    pt->nearest = NULL;
-    pt->nearest_dist = CCD_REAL_MAX;
-    pt->nearest_type = 3;
-}
-
-void ccdPtDestroy(ccd_pt_t *pt)
-{
-    ccd_pt_face_t *f, *f2;
-    ccd_pt_edge_t *e, *e2;
-    ccd_pt_vertex_t *v, *v2;
-
-    // first delete all faces
-    ccdListForEachEntrySafe(&pt->faces, f, ccd_pt_face_t, f2, ccd_pt_face_t, list){
-        ccdPtDelFace(pt, f);
-    }
-
-    // delete all edges
-    ccdListForEachEntrySafe(&pt->edges, e, ccd_pt_edge_t, e2, ccd_pt_edge_t, list){
-        ccdPtDelEdge(pt, e);
-    }
-
-    // delete all vertices
-    ccdListForEachEntrySafe(&pt->vertices, v, ccd_pt_vertex_t, v2, ccd_pt_vertex_t, list){
-        ccdPtDelVertex(pt, v);
-    }
-}
-
-
-ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v)
-{
-    ccd_pt_vertex_t *vert;
-
-    vert = CCD_ALLOC(ccd_pt_vertex_t);
-    if (vert == NULL)
-        return NULL;
-
-    vert->type = CCD_PT_VERTEX;
-    ccdSupportCopy(&vert->v, v);
-
-    vert->dist = ccdVec3Len2(&vert->v.v);
-    ccdVec3Copy(&vert->witness, &vert->v.v);
-
-    ccdListInit(&vert->edges);
-
-    // add vertex to list
-    ccdListAppend(&pt->vertices, &vert->list);
-
-    // update position in .nearest array
-    _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)vert);
-
-    return vert;
-}
-
-ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1,
-                                          ccd_pt_vertex_t *v2)
-{
-    const ccd_vec3_t *a, *b;
-    ccd_pt_edge_t *edge;
-
-    if (v1 == NULL || v2 == NULL)
-        return NULL;
-
-    edge = CCD_ALLOC(ccd_pt_edge_t);
-    if (edge == NULL)
-        return NULL;
-
-    edge->type = CCD_PT_EDGE;
-    edge->vertex[0] = v1;
-    edge->vertex[1] = v2;
-    edge->faces[0] = edge->faces[1] = NULL;
-
-    a = &edge->vertex[0]->v.v;
-    b = &edge->vertex[1]->v.v;
-    edge->dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &edge->witness);
-
-    ccdListAppend(&edge->vertex[0]->edges, &edge->vertex_list[0]);
-    ccdListAppend(&edge->vertex[1]->edges, &edge->vertex_list[1]);
-
-    ccdListAppend(&pt->edges, &edge->list);
-
-    // update position in .nearest array
-    _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)edge);
-
-    return edge;
-}
-
-ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1,
-                                          ccd_pt_edge_t *e2,
-                                          ccd_pt_edge_t *e3)
-{
-    const ccd_vec3_t *a, *b, *c;
-    ccd_pt_face_t *face;
-    ccd_pt_edge_t *e;
-    size_t i;
-
-    if (e1 == NULL || e2 == NULL || e3 == NULL)
-        return NULL;
-
-    face = CCD_ALLOC(ccd_pt_face_t);
-    if (face == NULL)
-        return NULL;
-
-    face->type = CCD_PT_FACE;
-    face->edge[0] = e1;
-    face->edge[1] = e2;
-    face->edge[2] = e3;
-
-    // obtain triplet of vertices
-    a = &face->edge[0]->vertex[0]->v.v;
-    b = &face->edge[0]->vertex[1]->v.v;
-    e = face->edge[1];
-    if (e->vertex[0] != face->edge[0]->vertex[0]
-            && e->vertex[0] != face->edge[0]->vertex[1]){
-        c = &e->vertex[0]->v.v;
-    }else{
-        c = &e->vertex[1]->v.v;
-    }
-    face->dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &face->witness);
-
-
-    for (i = 0; i < 3; i++){
-        if (face->edge[i]->faces[0] == NULL){
-            face->edge[i]->faces[0] = face;
-        }else{
-            face->edge[i]->faces[1] = face;
-        }
-    }
-
-    ccdListAppend(&pt->faces, &face->list);
-
-    // update position in .nearest array
-    _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)face);
-
-    return face;
-}
-
-
-void ccdPtRecomputeDistances(ccd_pt_t *pt)
-{
-    ccd_pt_vertex_t *v;
-    ccd_pt_edge_t *e;
-    ccd_pt_face_t *f;
-    const ccd_vec3_t *a, *b, *c;
-    ccd_real_t dist;
-
-    ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
-        dist = ccdVec3Len2(&v->v.v);
-        v->dist = dist;
-        ccdVec3Copy(&v->witness, &v->v.v);
-    }
-
-    ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
-        a = &e->vertex[0]->v.v;
-        b = &e->vertex[1]->v.v;
-        dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &e->witness);
-        e->dist = dist;
-    }
-
-    ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
-        // obtain triplet of vertices
-        a = &f->edge[0]->vertex[0]->v.v;
-        b = &f->edge[0]->vertex[1]->v.v;
-        e = f->edge[1];
-        if (e->vertex[0] != f->edge[0]->vertex[0]
-                && e->vertex[0] != f->edge[0]->vertex[1]){
-            c = &e->vertex[0]->v.v;
-        }else{
-            c = &e->vertex[1]->v.v;
-        }
-
-        dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &f->witness);
-        f->dist = dist;
-    }
-}
-
-ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt)
-{
-    if (!pt->nearest){
-        _ccdPtNearestRenew(pt);
-    }
-    return pt->nearest;
-}
-
-
-void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn)
-{
-    FILE *fout;
-
-    fout = fopen(fn, "a");
-    if (fout == NULL)
-        return;
-
-    ccdPtDumpSVT2(pt, fout);
-
-    fclose(fout);
-}
-
-void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *fout)
-{
-    ccd_pt_vertex_t *v, *a, *b, *c;
-    ccd_pt_edge_t *e;
-    ccd_pt_face_t *f;
-    size_t i;
-
-    fprintf(fout, "-----\n");
-
-    fprintf(fout, "Points:\n");
-    i = 0;
-    ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
-        v->id = (int)(i++);
-        fprintf(fout, "%lf %lf %lf\n",
-                ccdVec3X(&v->v.v), ccdVec3Y(&v->v.v), ccdVec3Z(&v->v.v));
-    }
-
-    fprintf(fout, "Edges:\n");
-    ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
-        fprintf(fout, "%d %d\n", e->vertex[0]->id, e->vertex[1]->id);
-    }
-
-    fprintf(fout, "Faces:\n");
-    ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
-        a = f->edge[0]->vertex[0];
-        b = f->edge[0]->vertex[1];
-        c = f->edge[1]->vertex[0];
-        if (c == a || c == b){
-            c = f->edge[1]->vertex[1];
-        }
-        fprintf(fout, "%d %d %d\n", a->id, b->id, c->id);
-    }
-}
diff --git a/src/pe/extern/libccd/polytope.h b/src/pe/extern/libccd/polytope.h
deleted file mode 100644
index b671224ebf904208fe7b9b3aee7267fcf7aec696..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/polytope.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_POLYTOPE_H__
-#define __CCD_POLYTOPE_H__
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "support.h"
-#include "list.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define CCD_PT_VERTEX 1
-#define CCD_PT_EDGE   2
-#define CCD_PT_FACE   3
-
-
-#define __CCD_PT_EL \
-    int type;           /*! type of element */ \
-    ccd_real_t dist;        /*! distance from origin */ \
-    ccd_vec3_t witness; /*! witness point of projection of origin */ \
-    ccd_list_t list;    /*! list of elements of same type */
-
-/**
- * General polytope element.
- * Could be vertex, edge or triangle.
- */
-struct _ccd_pt_el_t {
-    __CCD_PT_EL
-};
-typedef struct _ccd_pt_el_t ccd_pt_el_t;
-
-struct _ccd_pt_edge_t;
-struct _ccd_pt_face_t;
-
-/**
- * Polytope's vertex.
- */
-struct _ccd_pt_vertex_t {
-    __CCD_PT_EL
-
-    int id;
-    ccd_support_t v;
-    ccd_list_t edges; //!< List of edges
-};
-typedef struct _ccd_pt_vertex_t ccd_pt_vertex_t;
-
-/**
- * Polytope's edge.
- */
-struct _ccd_pt_edge_t {
-    __CCD_PT_EL
-
-    ccd_pt_vertex_t *vertex[2]; //!< Reference to vertices
-    struct _ccd_pt_face_t *faces[2]; //!< Reference to faces
-
-    ccd_list_t vertex_list[2]; //!< List items in vertices' lists
-};
-typedef struct _ccd_pt_edge_t ccd_pt_edge_t;
-
-/**
- * Polytope's triangle faces.
- */
-struct _ccd_pt_face_t {
-    __CCD_PT_EL
-
-    ccd_pt_edge_t *edge[3]; //!< Reference to surrounding edges
-};
-typedef struct _ccd_pt_face_t ccd_pt_face_t;
-
-
-/**
- * Struct containing polytope.
- */
-struct _ccd_pt_t {
-    ccd_list_t vertices; //!< List of vertices
-    ccd_list_t edges; //!< List of edges
-    ccd_list_t faces; //!< List of faces
-
-    ccd_pt_el_t *nearest;
-    ccd_real_t nearest_dist;
-    int nearest_type;
-};
-typedef struct _ccd_pt_t ccd_pt_t;
-
-
-void ccdPtInit(ccd_pt_t *pt);
-void ccdPtDestroy(ccd_pt_t *pt);
-
-/**
- * Returns vertices surrounding given triangle face.
- */
-_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face,
-                               ccd_vec3_t **a,
-                               ccd_vec3_t **b,
-                               ccd_vec3_t **c);
-_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face,
-                                   ccd_pt_vertex_t **a,
-                                   ccd_pt_vertex_t **b,
-                                   ccd_pt_vertex_t **c);
-_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f,
-                                ccd_pt_edge_t **a,
-                                ccd_pt_edge_t **b,
-                                ccd_pt_edge_t **c);
-
-_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e,
-                               ccd_vec3_t **a,
-                               ccd_vec3_t **b);
-_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e,
-                                   ccd_pt_vertex_t **a,
-                                   ccd_pt_vertex_t **b);
-_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e,
-                                ccd_pt_face_t **f1,
-                                ccd_pt_face_t **f2);
-
-
-/**
- * Adds vertex to polytope and returns pointer to newly created vertex.
- */
-ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v);
-_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt,
-                                                  ccd_real_t x, ccd_real_t y, ccd_real_t z);
-
-/**
- * Adds edge to polytope.
- */
-ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1,
-                                          ccd_pt_vertex_t *v2);
-
-/**
- * Adds face to polytope.
- */
-ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1,
-                                          ccd_pt_edge_t *e2,
-                                          ccd_pt_edge_t *e3);
-
-/**
- * Deletes vertex from polytope.
- * Returns 0 on success, -1 otherwise.
- */
-_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *);
-_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *);
-_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *);
-
-
-/**
- * Recompute distances from origin for all elements in pt.
- */
-void ccdPtRecomputeDistances(ccd_pt_t *pt);
-
-/**
- * Returns nearest element to origin.
- */
-ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt);
-
-
-void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn);
-void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *);
-
-
-/**** INLINES ****/
-_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt,
-                                                  ccd_real_t x, ccd_real_t y, ccd_real_t z)
-{
-    ccd_support_t s;
-    ccdVec3Set(&s.v, x, y, z);
-    return ccdPtAddVertex(pt, &s);
-}
-
-_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *v)
-{
-    // test if any edge is connected to this vertex
-    if (!ccdListEmpty(&v->edges))
-        return -1;
-
-    // delete vertex from main list
-    ccdListDel(&v->list);
-
-    if ((void *)pt->nearest == (void *)v){
-        pt->nearest = NULL;
-    }
-
-    free(v);
-    return 0;
-}
-
-_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *e)
-{
-    // text if any face is connected to this edge (faces[] is always
-    // aligned to lower indices)
-    if (e->faces[0] != NULL)
-        return -1;
-
-    // disconnect edge from lists of edges in vertex struct
-    ccdListDel(&e->vertex_list[0]);
-    ccdListDel(&e->vertex_list[1]);
-
-    // disconnect edge from main list
-    ccdListDel(&e->list);
-
-    if ((void *)pt->nearest == (void *)e){
-        pt->nearest = NULL;
-    }
-
-    free(e);
-    return 0;
-}
-
-_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *f)
-{
-    ccd_pt_edge_t *e;
-    size_t i;
-
-    // remove face from edges' recerence lists
-    for (i = 0; i < 3; i++){
-        e = f->edge[i];
-        if (e->faces[0] == f){
-            e->faces[0] = e->faces[1];
-        }
-        e->faces[1] = NULL;
-    }
-
-    // remove face from list of all faces
-    ccdListDel(&f->list);
-
-    if ((void *)pt->nearest == (void *)f){
-        pt->nearest = NULL;
-    }
-
-    free(f);
-    return 0;
-}
-
-_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face,
-                               ccd_vec3_t **a,
-                               ccd_vec3_t **b,
-                               ccd_vec3_t **c)
-{
-    *a = &face->edge[0]->vertex[0]->v.v;
-    *b = &face->edge[0]->vertex[1]->v.v;
-
-    if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0]
-            && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){
-        *c = &face->edge[1]->vertex[0]->v.v;
-    }else{
-        *c = &face->edge[1]->vertex[1]->v.v;
-    }
-}
-
-_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face,
-                                   ccd_pt_vertex_t **a,
-                                   ccd_pt_vertex_t **b,
-                                   ccd_pt_vertex_t **c)
-{
-    *a = face->edge[0]->vertex[0];
-    *b = face->edge[0]->vertex[1];
-
-    if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0]
-            && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){
-        *c = face->edge[1]->vertex[0];
-    }else{
-        *c = face->edge[1]->vertex[1];
-    }
-}
-
-_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f,
-                                ccd_pt_edge_t **a,
-                                ccd_pt_edge_t **b,
-                                ccd_pt_edge_t **c)
-{
-    *a = f->edge[0];
-    *b = f->edge[1];
-    *c = f->edge[2];
-}
-
-_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e,
-                               ccd_vec3_t **a,
-                               ccd_vec3_t **b)
-{
-    *a = &e->vertex[0]->v.v;
-    *b = &e->vertex[1]->v.v;
-}
-
-_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e,
-                                   ccd_pt_vertex_t **a,
-                                   ccd_pt_vertex_t **b)
-{
-    *a = e->vertex[0];
-    *b = e->vertex[1];
-}
-
-_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e,
-                                ccd_pt_face_t **f1,
-                                ccd_pt_face_t **f2)
-{
-    *f1 = e->faces[0];
-    *f2 = e->faces[1];
-}
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_POLYTOPE_H__ */
diff --git a/src/pe/extern/libccd/simplex.h b/src/pe/extern/libccd/simplex.h
deleted file mode 100644
index 8ae09c7123b32d709baace7f8eb0ad7872f9d7c0..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/simplex.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_SIMPLEX_H__
-#define __CCD_SIMPLEX_H__
-
-#include <ccd/compiler.h>
-#include "support.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct _ccd_simplex_t {
-    ccd_support_t ps[4];
-    int last; //!< index of last added point
-};
-typedef struct _ccd_simplex_t ccd_simplex_t;
-
-
-_ccd_inline void ccdSimplexInit(ccd_simplex_t *s);
-_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s);
-_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s);
-_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx);
-_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx);
-
-_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v);
-_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a);
-_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size);
-_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2);
-
-
-/**** INLINES ****/
-
-_ccd_inline void ccdSimplexInit(ccd_simplex_t *s)
-{
-    s->last = -1;
-}
-
-_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s)
-{
-    return s->last + 1;
-}
-
-_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s)
-{
-    return ccdSimplexPoint(s, s->last);
-}
-
-_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx)
-{
-    // here is no check on boundaries
-    return &s->ps[idx];
-}
-_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx)
-{
-    return &s->ps[idx];
-}
-
-_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v)
-{
-    // here is no check on boundaries in sake of speed
-    ++s->last;
-    ccdSupportCopy(s->ps + s->last, v);
-}
-
-_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a)
-{
-    ccdSupportCopy(s->ps + pos, a);
-}
-
-_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size)
-{
-    s->last = size - 1;
-}
-
-_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2)
-{
-    ccd_support_t supp;
-
-    ccdSupportCopy(&supp, &s->ps[pos1]);
-    ccdSupportCopy(&s->ps[pos1], &s->ps[pos2]);
-    ccdSupportCopy(&s->ps[pos2], &supp);
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_SIMPLEX_H__ */
diff --git a/src/pe/extern/libccd/support.c b/src/pe/extern/libccd/support.c
deleted file mode 100644
index 6c7f1cc65863be3c974aed1a37df2c9bd3623c50..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/support.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#include "support.h"
-
-void __ccdSupport(const void *obj1, const void *obj2,
-                  const ccd_vec3_t *_dir, const ccd_t *ccd,
-                  ccd_support_t *supp)
-{
-    ccd_vec3_t dir;
-
-    ccdVec3Copy(&dir, _dir);
-
-    ccd->support1(obj1, &dir, &supp->v1);
-
-    ccdVec3Scale(&dir, -CCD_ONE);
-    ccd->support2(obj2, &dir, &supp->v2);
-
-    ccdVec3Sub2(&supp->v, &supp->v1, &supp->v2);
-}
diff --git a/src/pe/extern/libccd/support.h b/src/pe/extern/libccd/support.h
deleted file mode 100644
index 3372f5ef216e6d2c2e834e3dd45b2ec368a88913..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/support.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#ifndef __CCD_SUPPORT_H__
-#define __CCD_SUPPORT_H__
-
-#include <ccd/ccd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct _ccd_support_t {
-    ccd_vec3_t v;  //!< Support point in minkowski sum
-    ccd_vec3_t v1; //!< Support point in obj1
-    ccd_vec3_t v2; //!< Support point in obj2
-};
-typedef struct _ccd_support_t ccd_support_t;
-
-_ccd_inline void ccdSupportCopy(ccd_support_t *, const ccd_support_t *s);
-
-/**
- * Computes support point of obj1 and obj2 in direction dir.
- * Support point is returned via supp.
- */
-void __ccdSupport(const void *obj1, const void *obj2,
-                  const ccd_vec3_t *dir, const ccd_t *ccd,
-                  ccd_support_t *supp);
-
-
-/**** INLINES ****/
-_ccd_inline void ccdSupportCopy(ccd_support_t *d, const ccd_support_t *s)
-{
-    *d = *s;
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* __CCD_SUPPORT_H__ */
diff --git a/src/pe/extern/libccd/vec3.c b/src/pe/extern/libccd/vec3.c
deleted file mode 100644
index f0a331f4fd486a8919dcc23902568cfa3b903540..0000000000000000000000000000000000000000
--- a/src/pe/extern/libccd/vec3.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/***
- * libccd
- * ---------------------------------
- * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
- *
- *
- *  This file is part of libccd.
- *
- *  Distributed under the OSI-approved BSD License (the "License");
- *  see accompanying file BDS-LICENSE for details or see
- *  <http://www.opensource.org/licenses/bsd-license.php>.
- *
- *  This software is distributed WITHOUT ANY WARRANTY; without even the
- *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *  See the License for more information.
- */
-
-#include <stdio.h>
-#include <ccd/vec3.h>
-#include "dbg.h"
-
-static CCD_VEC3(__ccd_vec3_origin, CCD_ZERO, CCD_ZERO, CCD_ZERO);
-ccd_vec3_t *ccd_vec3_origin = &__ccd_vec3_origin;
-
-static ccd_vec3_t points_on_sphere[] = {
-	CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-0.000000), CCD_REAL(-1.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL(-0.525725), CCD_REAL(-0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL(-0.850649), CCD_REAL(-0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.894426), CCD_REAL(-0.000000), CCD_REAL(-0.447216)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL( 0.850649), CCD_REAL(-0.447220)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL( 0.525725), CCD_REAL(-0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL(-0.850649), CCD_REAL( 0.447220)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL(-0.525725), CCD_REAL( 0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL( 0.525725), CCD_REAL( 0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL( 0.850649), CCD_REAL( 0.447219)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.894426), CCD_REAL( 0.000000), CCD_REAL( 0.447216)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 0.000000), CCD_REAL( 1.000000)), 
-	CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL(-0.309011), CCD_REAL(-0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL(-0.499995), CCD_REAL(-0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL(-0.809012), CCD_REAL(-0.525738)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL( 0.309011), CCD_REAL(-0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.850648), CCD_REAL(-0.000000), CCD_REAL(-0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.525730), CCD_REAL(-0.000000), CCD_REAL(-0.850652)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL(-0.499997), CCD_REAL(-0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL( 0.499995), CCD_REAL(-0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL( 0.499997), CCD_REAL(-0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL( 0.809012), CCD_REAL(-0.525738)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL( 0.309013), CCD_REAL( 0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL(-0.309013), CCD_REAL( 0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-1.000000), CCD_REAL( 0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL(-0.309013), CCD_REAL(-0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL( 0.309013), CCD_REAL(-0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 1.000000), CCD_REAL(-0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL(-0.499997), CCD_REAL( 0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL(-0.809012), CCD_REAL( 0.525738)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.850648), CCD_REAL( 0.000000), CCD_REAL( 0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL( 0.809012), CCD_REAL( 0.525738)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL( 0.499997), CCD_REAL( 0.525736)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.525730), CCD_REAL( 0.000000), CCD_REAL( 0.850652)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL(-0.499995), CCD_REAL( 0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL(-0.309011), CCD_REAL( 0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL( 0.309011), CCD_REAL( 0.850654)),
-	CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL( 0.499995), CCD_REAL( 0.850654))
-};
-ccd_vec3_t *ccd_points_on_sphere = points_on_sphere;
-size_t ccd_points_on_sphere_len = sizeof(points_on_sphere) / sizeof(ccd_vec3_t);
-
-
-_ccd_inline ccd_real_t __ccdVec3PointSegmentDist2(const ccd_vec3_t *P,
-                                                  const ccd_vec3_t *x0,
-                                                  const ccd_vec3_t *b,
-                                                  ccd_vec3_t *witness)
-{
-    // The computation comes from solving equation of segment:
-    //      S(t) = x0 + t.d
-    //          where - x0 is initial point of segment
-    //                - d is direction of segment from x0 (|d| > 0)
-    //                - t belongs to <0, 1> interval
-    // 
-    // Than, distance from a segment to some point P can be expressed:
-    //      D(t) = |x0 + t.d - P|^2
-    //          which is distance from any point on segment. Minimization
-    //          of this function brings distance from P to segment.
-    // Minimization of D(t) leads to simple quadratic equation that's
-    // solving is straightforward.
-    //
-    // Bonus of this method is witness point for free.
-
-    ccd_real_t dist, t;
-    ccd_vec3_t d, a;
-
-    // direction of segment
-    ccdVec3Sub2(&d, b, x0);
-
-    // precompute vector from P to x0
-    ccdVec3Sub2(&a, x0, P);
-
-    t  = -CCD_REAL(1.) * ccdVec3Dot(&a, &d);
-    t /= ccdVec3Len2(&d);
-
-    if (t < CCD_ZERO || ccdIsZero(t)){
-        dist = ccdVec3Dist2(x0, P);
-        if (witness)
-            ccdVec3Copy(witness, x0);
-    }else if (t > CCD_ONE || ccdEq(t, CCD_ONE)){
-        dist = ccdVec3Dist2(b, P);
-        if (witness)
-            ccdVec3Copy(witness, b);
-    }else{
-        if (witness){
-            ccdVec3Copy(witness, &d);
-            ccdVec3Scale(witness, t);
-            ccdVec3Add(witness, x0);
-            dist = ccdVec3Dist2(witness, P);
-        }else{
-            // recycling variables
-            ccdVec3Scale(&d, t);
-            ccdVec3Add(&d, &a);
-            dist = ccdVec3Len2(&d);
-        }
-    }
-
-    return dist;
-}
-
-ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P,
-                                    const ccd_vec3_t *x0, const ccd_vec3_t *b,
-                                    ccd_vec3_t *witness)
-{
-    return __ccdVec3PointSegmentDist2(P, x0, b, witness);
-}
-
-ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P,
-                                const ccd_vec3_t *x0, const ccd_vec3_t *B,
-                                const ccd_vec3_t *C,
-                                ccd_vec3_t *witness)
-{
-    // Computation comes from analytic expression for triangle (x0, B, C)
-    //      T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and
-    // Then equation for distance is:
-    //      D(s, t) = | T(s, t) - P |^2
-    // This leads to minimization of quadratic function of two variables.
-    // The solution from is taken only if s is between 0 and 1, t is
-    // between 0 and 1 and t + s < 1, otherwise distance from segment is
-    // computed.
-
-    ccd_vec3_t d1, d2, a;
-    ccd_real_t u, v, w, p, q, r;
-    ccd_real_t s, t, dist, dist2;
-    ccd_vec3_t witness2;
-
-    ccdVec3Sub2(&d1, B, x0);
-    ccdVec3Sub2(&d2, C, x0);
-    ccdVec3Sub2(&a, x0, P);
-
-    u = ccdVec3Dot(&a, &a);
-    v = ccdVec3Dot(&d1, &d1);
-    w = ccdVec3Dot(&d2, &d2);
-    p = ccdVec3Dot(&a, &d1);
-    q = ccdVec3Dot(&a, &d2);
-    r = ccdVec3Dot(&d1, &d2);
-
-    s = (q * r - w * p) / (w * v - r * r);
-    t = (-s * r - q) / w;
-
-    if ((ccdIsZero(s) || s > CCD_ZERO)
-            && (ccdEq(s, CCD_ONE) || s < CCD_ONE)
-            && (ccdIsZero(t) || t > CCD_ZERO)
-            && (ccdEq(t, CCD_ONE) || t < CCD_ONE)
-            && (ccdEq(t + s, CCD_ONE) || t + s < CCD_ONE)){
-
-        if (witness){
-            ccdVec3Scale(&d1, s);
-            ccdVec3Scale(&d2, t);
-            ccdVec3Copy(witness, x0);
-            ccdVec3Add(witness, &d1);
-            ccdVec3Add(witness, &d2);
-
-            dist = ccdVec3Dist2(witness, P);
-        }else{
-            dist  = s * s * v;
-            dist += t * t * w;
-            dist += CCD_REAL(2.) * s * t * r;
-            dist += CCD_REAL(2.) * s * p;
-            dist += CCD_REAL(2.) * t * q;
-            dist += u;
-        }
-    }else{
-        dist = __ccdVec3PointSegmentDist2(P, x0, B, witness);
-
-        dist2 = __ccdVec3PointSegmentDist2(P, x0, C, &witness2);
-        if (dist2 < dist){
-            dist = dist2;
-            if (witness)
-                ccdVec3Copy(witness, &witness2);
-        }
-
-        dist2 = __ccdVec3PointSegmentDist2(P, B, C, &witness2);
-        if (dist2 < dist){
-            dist = dist2;
-            if (witness)
-                ccdVec3Copy(witness, &witness2);
-        }
-    }
-
-    return dist;
-}
diff --git a/src/pe/fcd/AnalyticCollisionDetection.h b/src/pe/fcd/AnalyticCollisionDetection.h
index 8b6fa28538b785034d8a1e94bf371f6940aeb403..5318eaae9176b0a826447a2b18de1e0a716b4269 100644
--- a/src/pe/fcd/AnalyticCollisionDetection.h
+++ b/src/pe/fcd/AnalyticCollisionDetection.h
@@ -2124,7 +2124,7 @@ bool collide( Union<BodyTypeTuple>* bd1, BodyB* bd2, Container& container )
    bool collision = false;
    for( auto it=bd1->begin(); it!=bd1->end(); ++it )
    {
-      collision |= SingleCast<BodyTypeTuple, AnalyticSingleCollideFunctor<BodyB, Container>, bool>::execute(*it, func);
+      collision |= SingleCast<BodyTypeTuple, AnalyticSingleCollideFunctor<BodyB, Container>, bool>::execute(it.getBodyID(), func);
    }
    return collision;
 }
@@ -2146,7 +2146,7 @@ bool collide( Union<BodyTypeTupleA>* bd1, Union<BodyTypeTupleB>* bd2, Container&
    {
       for( auto it2=bd2->begin(); it2!=bd2->end(); ++it2 )
       {
-         collision |= DoubleCast<BodyTypeTupleA, BodyTypeTupleB, AnalyticCollideFunctor<Container>, bool>::execute(*it1, *it2, func);
+         collision |= DoubleCast<BodyTypeTupleA, BodyTypeTupleB, AnalyticCollideFunctor<Container>, bool>::execute(it1.getBodyID(), it2.getBodyID(), func);
       }
    }
    return collision;
diff --git a/src/pe/fcd/GJKEPACollideFunctor.h b/src/pe/fcd/GJKEPACollideFunctor.h
index 84b6d62e4bf58386aae3e2f4b94484647511854c..051d5bcbcace3bb1b99aeb497b789ae4f7895c42 100644
--- a/src/pe/fcd/GJKEPACollideFunctor.h
+++ b/src/pe/fcd/GJKEPACollideFunctor.h
@@ -115,6 +115,7 @@ namespace gjkepa{
       if(gjk.doGJKmargin(*a, *b, margin)){
          //2. If collision is possible perform EPA.
          EPA epa;
+         epa.useSphereOptimization(true);
          if(epa.doEPAmargin(*a, *b, gjk, normal, contactPoint, penetrationDepth, margin)){
             contacts_.push_back( Contact(a, b, contactPoint, normal, penetrationDepth) );
             return true;
@@ -168,7 +169,7 @@ namespace gjkepa{
       bool collision = false;
       for( auto it=a->begin(); it!=a->end(); ++it )
       {
-         collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<BodyB, Container>, bool>::execute(*it, func);
+         collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<BodyB, Container>, bool>::execute(it.getBodyID(), func);
       }
       return collision;
    }
@@ -186,7 +187,7 @@ namespace gjkepa{
       {
          for( auto it2=b->begin(); it2!=b->end(); ++it2 )
          {
-            collision |= DoubleCast<BodyTupleA, BodyTupleB, GJKEPACollideFunctor<Container>, bool>::execute(*it1, *it2, func);
+            collision |= DoubleCast<BodyTupleA, BodyTupleB, GJKEPACollideFunctor<Container>, bool>::execute(it1.getBodyID(), it2.getBodyID(), func);
          }
       }
       return collision;
@@ -199,7 +200,7 @@ namespace gjkepa{
       bool collision = false;
       for( auto it=a->begin(); it!=a->end(); ++it )
       {
-         collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<Plane, Container>, bool>::execute(*it, func);
+         collision |= SingleCast<BodyTupleA, GJKEPASingleCollideFunctor<Plane, Container>, bool>::execute(it.getBodyID(), func);
       }
       return collision;
    }
diff --git a/src/pe/raytracing/Color.cpp b/src/pe/raytracing/Color.cpp
index 29c7e6d3491eb9c041470474ec6af3c43f784a64..4e9deab3f029827d88226d6ab353d144e33bc165 100644
--- a/src/pe/raytracing/Color.cpp
+++ b/src/pe/raytracing/Color.cpp
@@ -13,7 +13,7 @@
 //  You should have received a copy of the GNU General Public License along
 //  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
-//! \file Color.cpp
+//! \file   Color.cpp
 //! \author Lukas Werner
 //
 //======================================================================================================================
diff --git a/src/pe/raytracing/Color.h b/src/pe/raytracing/Color.h
index 159c0ef13772b5b01b2dbe18d4beb0f9c9dfd711..cf599930460172403014367436679d9304d194f3 100644
--- a/src/pe/raytracing/Color.h
+++ b/src/pe/raytracing/Color.h
@@ -13,6 +13,7 @@
 //  You should have received a copy of the GNU General Public License along
 //  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
+//! \file   Color.h
 //! \author Lukas Werner
 //
 //======================================================================================================================
@@ -25,6 +26,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 class Color: public Vector3<real_t> {
 public:
    /*!\name Constructors */
@@ -75,6 +77,7 @@ public:
    
    static Color colorFromHSV(real_t hue, real_t saturation, real_t value);
 };
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Intersects.h b/src/pe/raytracing/Intersects.h
index ee889724d55445c9beaadbcac1d675d2e080534d..836ee8dc6af313d2b3b25841900cf61d1a927abc 100644
--- a/src/pe/raytracing/Intersects.h
+++ b/src/pe/raytracing/Intersects.h
@@ -37,6 +37,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t, Vec3& n);
 inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t, Vec3& n);
 inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n);
@@ -461,6 +462,7 @@ inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t, real_t paddi
    t = t_;
    return true;
 }
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Lighting.h b/src/pe/raytracing/Lighting.h
index ce2778c343b6ad08feae7dc9afbf495ce9d528bc..451cfe3357ca80dad10613a79251ed75da366898 100644
--- a/src/pe/raytracing/Lighting.h
+++ b/src/pe/raytracing/Lighting.h
@@ -28,6 +28,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 /*!\brief The Lighting struct defines the properties of a point light in the scene.
  */
 struct Lighting {
@@ -71,6 +72,7 @@ struct Lighting {
       ambientColor = config.getParameter<Color>("ambientColor", Color(0.5,0.5,0.5));
    }
 };
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Ray.cpp b/src/pe/raytracing/Ray.cpp
index 3fbcd307067470b387a2e5511c2fab08605c3afc..c3f0a977684c1ffa0e2171503942572e49460949 100644
--- a/src/pe/raytracing/Ray.cpp
+++ b/src/pe/raytracing/Ray.cpp
@@ -23,6 +23,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 /*!\brief Global output operator for rays.
  *
  * \param os Reference to the output stream.
@@ -35,6 +36,6 @@ std::ostream& operator<<(std::ostream& os, const Ray& ray) {
    << ", c: (" << ray.getImageX() << "/" << ray.getImageY() << ")>";
 }
 
-}
-}
-}
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Ray.h b/src/pe/raytracing/Ray.h
index 6fed295fc8a05449b7f30f3c9273852066e847cf..052ee87bf4cd11398d9e3229808068600741eb24 100644
--- a/src/pe/raytracing/Ray.h
+++ b/src/pe/raytracing/Ray.h
@@ -219,6 +219,7 @@ public:
    }
    //@}
 };
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp
index b3793fae2f2c0f72d1f1794fdcf3cec646aeedbb..59320cc4abcb15f6217b53b0e4c1faa03b371dc4 100644
--- a/src/pe/raytracing/Raytracer.cpp
+++ b/src/pe/raytracing/Raytracer.cpp
@@ -421,6 +421,6 @@ void Raytracer::output(const std::vector<BodyIntersectionInfo>& intersectionsBuf
    if (tt != NULL) tt->stop("Output");
 }
 
-}
-}
-}
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h
index 1bf7b93b1e5e305408d1b94571107463e13ff118..366098150e5f5082439c39e93a157d908f13ecdf 100644
--- a/src/pe/raytracing/Raytracer.h
+++ b/src/pe/raytracing/Raytracer.h
@@ -37,9 +37,6 @@
 
 #include <stddef.h>
 
-using namespace walberla::pe;
-using namespace walberla::timing;
-
 namespace walberla {
 namespace pe {
 namespace raytracing {
@@ -420,30 +417,37 @@ inline void Raytracer::traceRayInGlobalBodyStorage(const Ray& ray, BodyID& body_
       
       IntersectsFunctor func(ray, t, n);
       
-      for(auto bodyIt: *globalBodyStorage_) {
-         if (!isBodyVisibleFunc_(bodyIt)) {
+      for(auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt)
+      {
+         if (!isBodyVisibleFunc_(bodyIt.getBodyID()))
+         {
             continue;
          }
          
          bool isPlane = (bodyIt->getTypeID() == Plane::getStaticTypeID());
-         if (isPlane) {
-            PlaneID plane = (PlaneID)bodyIt;
-            if (!isPlaneVisible(plane, ray)) {
+         if (isPlane)
+         {
+            PlaneID plane = (PlaneID)bodyIt.getBodyID();
+            if (!isPlaneVisible(plane, ray))
+            {
                continue;
             }
          }
          
-         bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt, func);
-         if (intersects && t < t_closest) {
-            if (isPlane && confinePlanesToDomain_) {
+         bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt.getBodyID(), func);
+         if (intersects && t < t_closest)
+         {
+            if (isPlane && confinePlanesToDomain_)
+            {
                Vec3 intersectionPoint = ray.getOrigin()+ray.getDirection()*t;
-               if (!forest_->getDomain().contains(intersectionPoint, real_t(1e-8))) {
+               if (!forest_->getDomain().contains(intersectionPoint, real_t(1e-8)))
+               {
                   continue;
                }
             }
             // body was shot by ray and is currently closest to camera
             t_closest = t;
-            body_closest = bodyIt;
+            body_closest = bodyIt.getBodyID();
             n_closest = n;
          }
       }
@@ -466,15 +470,15 @@ inline void Raytracer::traceRayNaively(const Ray& ray, BodyID& body_closest, rea
    
    for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) {
       for (auto bodyIt = LocalBodyIterator::begin(*blockIt, storageID_); bodyIt != LocalBodyIterator::end(); ++bodyIt) {
-         if (!isBodyVisibleFunc_(*bodyIt)) {
+         if (!isBodyVisibleFunc_(bodyIt.getBodyID())) {
             continue;
          }
          
-         bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(*bodyIt, func);
+         bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(bodyIt.getBodyID(), func);
          if (intersects && t < t_closest) {
             // body was shot by ray and is currently closest to camera
             t_closest = t;
-            body_closest = *bodyIt;
+            body_closest = bodyIt.getBodyID();
             n_closest = n;
          }
       }
@@ -699,6 +703,7 @@ inline Color Raytracer::getColor(const BodyID body, const Ray& ray, real_t t, co
 
    return color;
 }
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/ShadingFunctions.h b/src/pe/raytracing/ShadingFunctions.h
index 20f1f9f1fd6098a734784ed21e064f72055348c8..65675bb21aaee1f85688341e064457c5bdfb6954 100644
--- a/src/pe/raytracing/ShadingFunctions.h
+++ b/src/pe/raytracing/ShadingFunctions.h
@@ -30,6 +30,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 inline ShadingParameters defaultBodyTypeDependentShadingParams (const BodyID body);
 inline ShadingParameters processRankDependentShadingParams (const BodyID body);
 inline ShadingParameters defaultShadingParams (const BodyID body);
@@ -169,6 +170,7 @@ inline ShadingParameters violetShadingParams (const BodyID body) {
                        real_t(0));
    return s;
 }
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
diff --git a/src/pe/raytracing/ShadingParameters.h b/src/pe/raytracing/ShadingParameters.h
index 7d0930379729f0e9fd3a127a78bbcf7a4ac478d7..7e476527d1bd665c4017780f8858dbd39aff8876 100644
--- a/src/pe/raytracing/ShadingParameters.h
+++ b/src/pe/raytracing/ShadingParameters.h
@@ -27,6 +27,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
+
 struct ShadingParameters {
    Color diffuseColor;  //!< Primary color of the material.
    Color ambientColor;  //!< Color the material has even when its not directly lit.
@@ -80,7 +81,8 @@ struct ShadingParameters {
       return *this;
    }
 };
-}
-}
-}
+
+} //namespace raytracing
+} //namespace pe
+} //namespace walberla
 
diff --git a/src/pe/rigidbody/BodyIterators.h b/src/pe/rigidbody/BodyIterators.h
index aaf7d7daf55ea5698822197817db048bdebee7a4..5f4ef40fc5bc9be40788c60af43cff52dea9972e 100644
--- a/src/pe/rigidbody/BodyIterators.h
+++ b/src/pe/rigidbody/BodyIterators.h
@@ -33,104 +33,109 @@ class BodyIterator
 {
 public:
 
-    template< typename T >
-    class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
-    {
-        friend class BodyIterator;
-    public:
-        iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
-        iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
-
-        bool operator==( const iterator & rhs ) const
-        {
-            if (ended_ || rhs.ended_)
+   template< typename T >
+   class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
+   {
+      friend class BodyIterator;
+   public:
+      iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
+      iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
+
+      bool operator==( const iterator & rhs ) const
+      {
+         if (ended_ || rhs.ended_)
+         {
+            if (ended_ == rhs.ended_)
             {
-               if (ended_ == rhs.ended_)
-               {
-                  return true;
-               }
-               else
-               {
-                  return false;
-               }
+               return true;
             }
-
-            return it_ == rhs.it_;
-        }
-        bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
-
-        typename T::value_type operator*()  { return *it_; }
-        typename T::pointer    operator->() { return *it_; }
-
-    private:
-
-        iterator( const T& begin,
-                  const T& localEnd,
-                  const T& shadowBegin,
-                  const T& shadowEnd )
-            : it_(begin)
-            , itLocalEnd_(localEnd)
-            , itShadowBegin_(shadowBegin)
-            , itShadowEnd_(shadowEnd)
-            , local_(true)
-            , ended_(false)
-        {
-            checkStateAndAdapt();
-        }
-
-        iterator( )
-            : ended_( true )
-        {}
-
-        void checkStateAndAdapt()
-        {
-            if( local_ && it_ == itLocalEnd_ )
+            else
             {
-               it_ = itShadowBegin_;
-               local_ = false;
+               return false;
             }
+         }
 
-            if( it_ == itShadowEnd_ )
-            {
-                ended_ = true;
-            }
-        }
-
-        T it_;
-        T itLocalEnd_;
-        T itShadowBegin_;
-        T itShadowEnd_;
-
-        bool local_;
-
-        bool ended_;
-    };
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>         begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[0].begin(), (*storage)[0].end(), (*storage)[1].begin(), (*storage)[1].end() );
-    }
-
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>(), (*storage)[1].begin<C>(), (*storage)[1].end<C>() );
-    }
-
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>             end()
-    {
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( );
-    }
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> >     end()
-    {
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( );
-    }
+         //std::vector::iterator cannot be compared between different instances (assert!)
+         if (local_ == rhs.local_)
+            return it_ == rhs.it_;
+         else
+            return false;
+      }
+      bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
+
+      typename T::reference  operator*()  { return *it_; }
+      typename T::pointer    operator->() { return it_.operator->(); }
+      typename T::pointer    getBodyID()  { return it_.getBodyID(); }
+
+   private:
+
+      iterator( const T& begin,
+                const T& localEnd,
+                const T& shadowBegin,
+                const T& shadowEnd )
+         : it_(begin)
+         , itLocalEnd_(localEnd)
+         , itShadowBegin_(shadowBegin)
+         , itShadowEnd_(shadowEnd)
+         , local_(true)
+         , ended_(false)
+      {
+         checkStateAndAdapt();
+      }
+
+      iterator( )
+         : ended_( true )
+      {}
+
+      void checkStateAndAdapt()
+      {
+         if( local_ && it_ == itLocalEnd_ )
+         {
+            it_ = itShadowBegin_;
+            local_ = false;
+         }
+
+         if( !local_ && it_ == itShadowEnd_ )
+         {
+            ended_ = true;
+         }
+      }
+
+      T it_;
+      T itLocalEnd_;
+      T itShadowBegin_;
+      T itShadowEnd_;
+
+      bool local_; //!< still in local storage?
+
+      bool ended_;
+   };
+
+   static inline iterator<pe::BodyStorage::iterator>         begin(      IBlock & block,
+                                                                         const BlockDataID & bodyStorageId)
+   {
+      pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
+      return iterator<pe::BodyStorage::iterator> ( (*storage)[0].begin(), (*storage)[0].end(), (*storage)[1].begin(), (*storage)[1].end() );
+   }
+
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> > begin(      IBlock & block,
+                                                                          const BlockDataID & bodyStorageId)
+   {
+      pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>(), (*storage)[1].begin<C>(), (*storage)[1].end<C>() );
+   }
+
+
+   static inline iterator<pe::BodyStorage::iterator>             end()
+   {
+      return iterator<pe::BodyStorage::iterator> ( );
+   }
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> >     end()
+   {
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( );
+   }
 
 }; // class BodyIterator
 
@@ -140,87 +145,88 @@ class LocalBodyIterator
 {
 public:
 
-    template< typename T >
-    class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
-    {
-        friend class LocalBodyIterator;
-    public:
-        iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
-        iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
-
-        bool operator==( const iterator & rhs ) const
-        {
-            if (ended_ || rhs.ended_)
+   template< typename T >
+   class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
+   {
+      friend class LocalBodyIterator;
+   public:
+      iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
+      iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
+
+      bool operator==( const iterator & rhs ) const
+      {
+         if (ended_ || rhs.ended_)
+         {
+            if (ended_ == rhs.ended_)
             {
-               if (ended_ == rhs.ended_)
-               {
-                  return true;
-               }
-               else
-               {
-                  return false;
-               }
+               return true;
             }
-
-            return it_ == rhs.it_;
-        }
-        bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
-
-        typename T::value_type operator*()  { return *it_; }
-        typename T::pointer    operator->() { return *it_; }
-
-    private:
-
-        iterator( const T& begin,
-                  const T& end )
-            : it_(begin), itEnd_(end), ended_( false )
-        {
-            checkStateAndAdapt();
-        }
-
-        iterator( )
-            : ended_( true )
-        {}
-
-        void checkStateAndAdapt()
-        {
-            if( it_ == itEnd_ )
+            else
             {
-                ended_ = true;
+               return false;
             }
-        }
-
-        T it_;
-        T itEnd_;
-
-        bool ended_;
-    };
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>         begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[0].begin(), (*storage)[0].end() );
-    }
-
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>() );
-    }
-
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>             end()
-    {
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( );
-    }
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> >     end()
-    {
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( );
-    }
+         }
+
+         return it_ == rhs.it_;
+      }
+      bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
+
+      typename T::reference  operator*()  { return *it_; }
+      typename T::pointer    operator->() { return it_.operator->(); }
+      typename T::pointer    getBodyID()  { return it_.getBodyID(); }
+
+   private:
+
+      iterator( const T& begin,
+                const T& end )
+         : it_(begin), itEnd_(end), ended_( false )
+      {
+         checkStateAndAdapt();
+      }
+
+      iterator( )
+         : ended_( true )
+      {}
+
+      void checkStateAndAdapt()
+      {
+         if( it_ == itEnd_ )
+         {
+            ended_ = true;
+         }
+      }
+
+      T it_;
+      T itEnd_;
+
+      bool ended_;
+   };
+
+   static inline iterator<pe::BodyStorage::iterator>         begin(      IBlock & block,
+                                                                         const BlockDataID & bodyStorageId)
+   {
+      pe::BodyStorage& storage = (*block.getData< pe::Storage >( bodyStorageId ))[0];
+      return iterator<pe::BodyStorage::iterator> ( storage.begin(), storage.end() );
+   }
+
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> > begin(      IBlock & block,
+                                                                          const BlockDataID & bodyStorageId)
+   {
+      pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[0].begin<C>(), (*storage)[0].end<C>() );
+   }
+
+
+   static inline iterator<pe::BodyStorage::iterator>             end()
+   {
+      return iterator<pe::BodyStorage::iterator> ( );
+   }
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> >     end()
+   {
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( );
+   }
 
 }; // class LocalBodyIterator
 
@@ -229,87 +235,88 @@ class ShadowBodyIterator
 {
 public:
 
-    template< typename T >
-    class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
-    {
-        friend class ShadowBodyIterator;
-    public:
-        iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
-        iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
-
-        bool operator==( const iterator & rhs ) const
-        {
-            if (ended_ || rhs.ended_)
+   template< typename T >
+   class iterator : public std::iterator< std::input_iterator_tag, typename T::value_type, typename T::difference_type, typename T::pointer, typename T::reference >
+   {
+      friend class ShadowBodyIterator;
+   public:
+      iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
+      iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
+
+      bool operator==( const iterator & rhs ) const
+      {
+         if (ended_ || rhs.ended_)
+         {
+            if (ended_ == rhs.ended_)
             {
-               if (ended_ == rhs.ended_)
-               {
-                  return true;
-               }
-               else
-               {
-                  return false;
-               }
+               return true;
             }
-
-            return it_ == rhs.it_;
-        }
-        bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
-
-        typename T::value_type operator*()  { return *it_; }
-        typename T::pointer    operator->() { return *it_; }
-
-    private:
-
-        iterator( const T& begin,
-                  const T& end )
-            : it_(begin), itEnd_(end), ended_( false )
-        {
-            checkStateAndAdapt();
-        }
-
-        iterator( )
-            : ended_( true )
-        {}
-
-        void checkStateAndAdapt()
-        {
-            if( it_ == itEnd_ )
+            else
             {
-                ended_ = true;
+               return false;
             }
-        }
-
-        T it_;
-        T itEnd_;
-
-        bool ended_;
-    };
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>         begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( (*storage)[1].begin(), (*storage)[1].end() );
-    }
-
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> > begin(      IBlock & block,
-                                                                            const BlockDataID & bodyStorageId)
-    {
-        pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( (*storage)[1].begin<C>(), (*storage)[1].end<C>() );
-    }
-
-
-    static inline iterator<pe::BodyStorage::Bodies::Iterator>             end()
-    {
-        return iterator<pe::BodyStorage::Bodies::Iterator> ( );
-    }
-    template< typename C >
-    static inline iterator<pe::BodyStorage::Bodies::CastIterator<C> >     end()
-    {
-        return iterator<pe::BodyStorage::Bodies::CastIterator<C> > ( );
-    }
+         }
+
+         return it_ == rhs.it_;
+      }
+      bool operator!=( const iterator & rhs ) const { return !(*this == rhs); }
+
+      typename T::reference  operator*()  { return *it_; }
+      typename T::pointer    operator->() { return it_.operator->(); }
+      typename T::pointer    getBodyID()  { return it_.getBodyID(); }
+
+   private:
+
+      iterator( const T& begin,
+                const T& end )
+         : it_(begin), itEnd_(end), ended_( false )
+      {
+         checkStateAndAdapt();
+      }
+
+      iterator( )
+         : ended_( true )
+      {}
+
+      void checkStateAndAdapt()
+      {
+         if( it_ == itEnd_ )
+         {
+            ended_ = true;
+         }
+      }
+
+      T it_;
+      T itEnd_;
+
+      bool ended_;
+   };
+
+   static inline iterator<pe::BodyStorage::iterator>         begin(      IBlock & block,
+                                                                         const BlockDataID & bodyStorageId)
+   {
+      pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
+      return iterator<pe::BodyStorage::iterator> ( (*storage)[1].begin(), (*storage)[1].end() );
+   }
+
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> > begin(      IBlock & block,
+                                                                          const BlockDataID & bodyStorageId)
+   {
+      pe::Storage * storage = block.getData< pe::Storage >( bodyStorageId );
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( (*storage)[1].begin<C>(), (*storage)[1].end<C>() );
+   }
+
+
+   static inline iterator<pe::BodyStorage::iterator>             end()
+   {
+      return iterator<pe::BodyStorage::iterator> ( );
+   }
+   template< typename C >
+   static inline iterator<pe::BodyStorage::cast_iterator<C> >     end()
+   {
+      return iterator<pe::BodyStorage::cast_iterator<C> > ( );
+   }
 
 }; // class ShadowBodyIterator
 
diff --git a/src/pe/rigidbody/BodyStorage.h b/src/pe/rigidbody/BodyStorage.h
index 0ab0ef40b58ab71e2712d2de3132e2ad388baa66..7e4475e9a7ab8dfd8e19730ae27ee141391a15f3 100644
--- a/src/pe/rigidbody/BodyStorage.h
+++ b/src/pe/rigidbody/BodyStorage.h
@@ -26,25 +26,22 @@
 // Includes
 //*************************************************************************************************
 
-#include <algorithm>
-#include <functional>
-#include <map>
-#include <vector>
 #include <core/NonCopyable.h>
 #include <core/debug/Debug.h>
-#include <core/ptrvector/policies/PtrDelete.h>
-#include <core/ptrvector/PtrVector.h>
 #include <pe/rigidbody/RigidBody.h>
+#include <pe/rigidbody/RigidBodyCastIterator.h>
+#include <pe/rigidbody/RigidBodyIterator.h>
 #include <pe/Types.h>
 
+#include <algorithm>
 #include <functional>
+#include <map>
+#include <memory>
+#include <vector>
 
 namespace walberla {
 namespace pe {
 
-
-
-
 //=================================================================================================
 //
 //  CLASS DEFINITION
@@ -62,13 +59,18 @@ class BodyStorage : private NonCopyable
 public:
    //**Type definitions****************************************************************************
    //! Container for the bodies contained in the simulation world.
-   typedef PtrVector<BodyType, PtrDelete>  Bodies;
+   using VectorContainer = std::vector< std::unique_ptr<RigidBody> >;
+   using ConstVectorContainer = std::vector< std::unique_ptr<const RigidBody> >;
    //**********************************************************************************************
 
    //**Type definitions****************************************************************************
-   typedef Bodies::SizeType       SizeType;       //!< Size type of the body storage.
-   typedef Bodies::Iterator       Iterator;       //!< Iterator over non-const bodies.
-   typedef Bodies::ConstIterator  ConstIterator;  //!< Iterator over constant bodies.
+   using size_type             = VectorContainer::size_type;           //!< Size type of the body storage.
+   using iterator              = RigidBodyIterator;                    //!< Iterator over non-const bodies.
+   using const_iterator        = ConstRigidBodyIterator;               //!< Iterator over constant bodies.
+   template <typename C> //cast type
+   using cast_iterator         = RigidBodyCastIterator<C>;
+   template <typename C> //cast type
+   using const_cast_iterator   = ConstRigidBodyCastIterator<C>;
    //**********************************************************************************************
 
    //**Constructors********************************************************************************
@@ -88,45 +90,58 @@ public:
    //**Utility functions***************************************************************************
    /*!\name Utility functions */
    //@{
-   inline bool          isEmpty () const;
-   inline SizeType      size    () const;
-   template< typename T >
-   inline SizeType      size    () const;
-   inline Iterator      begin   ();
-   inline ConstIterator begin   () const;
-   template< typename T >
-   inline typename Bodies::template CastIterator<T> begin();
-   template< typename T >
-   inline typename Bodies::template ConstCastIterator<T> begin() const;
-   inline Iterator      end     ();
-   inline ConstIterator end     () const;
-   template< typename T >
-   inline typename Bodies::template CastIterator<T> end();
-   template< typename T >
-   inline typename Bodies::template ConstCastIterator<T> end() const;
-   inline BodyID        at      ( SizeType index );
-   inline ConstBodyID   at      ( SizeType index ) const;
-   inline Iterator      find    ( id_t sid );
-   inline ConstIterator find    ( id_t sid ) const;
-   inline Iterator      find    ( ConstBodyID body );
-   inline ConstIterator find    ( ConstBodyID body ) const;
-   inline void          validate();
+   inline bool           isEmpty () const;
+   inline size_type      size    () const;
+
+   inline iterator       begin   ();
+   inline const_iterator begin   () const;
+   inline const_iterator cbegin  () const;
+   inline iterator       end     ();
+   inline const_iterator end     () const;
+   inline const_iterator cend    () const;
+
+   template< typename C >
+   inline cast_iterator<C> begin();
+   template< typename C >
+   inline const_cast_iterator<C> begin() const;
+   template< typename C >
+   inline const_cast_iterator<C> cbegin() const;
+   template< typename C >
+   inline cast_iterator<C> end();
+   template< typename C >
+   inline const_cast_iterator<C> end() const;
+   template< typename C >
+   inline const_cast_iterator<C> cend() const;
+
+   inline RigidBody&         front();
+   inline const RigidBody&   front() const;
+   inline RigidBody&         back();
+   inline const RigidBody&   back() const;
+
+   inline BodyID         at      ( size_type index );
+   inline ConstBodyID    at      ( size_type index ) const;
+   inline iterator       find    ( id_t sid );
+   inline const_iterator find    ( id_t sid ) const;
+   inline iterator       find    ( ConstBodyID body );
+   inline const_iterator find    ( ConstBodyID body ) const;
+   inline void           validate();
    //@}
    //**********************************************************************************************
 
    //**Add/Remove functions************************************************************************
    /*!\name Add/Remove functions */
    //@{
-   inline void          add     ( BodyID body );
-   inline void          remove  ( const id_t sid );
-   inline void          remove  ( BodyID body );
-   inline ConstIterator remove  ( ConstIterator pos );
-   inline Iterator      remove  ( Iterator pos );
-   inline void          release ( const id_t sid );
-   inline void          release ( BodyID body );
-   inline ConstIterator release  ( ConstIterator pos );
-   inline Iterator      release  ( Iterator pos );
-   inline void          clear   ();
+   [[deprecated]] inline RigidBody&     add     ( BodyID body );
+   inline RigidBody&     add     ( std::unique_ptr<RigidBody>&& body );
+   inline iterator       remove  ( const id_t sid );
+   inline iterator       remove  ( BodyID body );
+   inline const_iterator remove  ( const_iterator pos );
+   inline iterator       remove  ( iterator pos );
+   inline std::unique_ptr<RigidBody> release ( const id_t sid );
+   inline std::unique_ptr<RigidBody> release ( BodyID body );
+   inline std::unique_ptr<RigidBody> release ( const_iterator& pos );
+   inline std::unique_ptr<RigidBody> release ( iterator& pos );
+   inline void           clear   ();
    //@}
    //**********************************************************************************************
 
@@ -147,8 +162,8 @@ private:
    //**Member variables****************************************************************************
    /*!\name Member variables */
    //@{
-   Bodies bodies_;  //!< The rigid bodies contained in the simulation world.
-   std::map<id_t, SizeType> bodyIDs_;   //!< The association of system IDs to rigid bodies.
+   VectorContainer           bodies_;    //!< The rigid bodies contained in the simulation world.
+   std::map<id_t, size_type> bodyIDs_;   //!< The association of system IDs to rigid bodies.
 
    std::map< std::string, std::function<void (BodyID)> > addCallbacks_;
    std::map< std::string, std::function<void (BodyID)> > removeCallbacks_;
@@ -170,9 +185,9 @@ private:
 /*!\brief The standard constructor.
  */
 inline BodyStorage::BodyStorage()
-	: bodies_( 1000 )
-	, bodyIDs_()
+   : bodyIDs_()
 {
+   bodies_.reserve(1000);
 }
 //*************************************************************************************************
 
@@ -195,7 +210,7 @@ inline BodyStorage::~BodyStorage()
 {
    WALBERLA_ASSERT_EQUAL(addCallbacks_.size(), 0, "Still add callbacks registered!");
    WALBERLA_ASSERT_EQUAL(removeCallbacks_.size(), 0, "Still remove callbacks registered!");
-	clear();
+   clear();
 }
 //*************************************************************************************************
 
@@ -216,7 +231,7 @@ inline BodyStorage::~BodyStorage()
 
 inline bool BodyStorage::isEmpty() const
 {
-   return bodies_.isEmpty();
+   return bodies_.empty();
 }
 //*************************************************************************************************
 
@@ -227,7 +242,7 @@ inline bool BodyStorage::isEmpty() const
  * \return The number of rigid bodies.
  */
 
-inline BodyStorage::SizeType BodyStorage::size() const
+inline BodyStorage::size_type BodyStorage::size() const
 {
    return bodies_.size();
 }
@@ -235,33 +250,27 @@ inline BodyStorage::SizeType BodyStorage::size() const
 
 
 //*************************************************************************************************
-/*!\brief Returns the number of rigid bodies of type \a T contained in the body storage.
- *
- * \return The number of rigid bodies of type \a T.
+/*!\brief Returns an iterator to the first contained rigid body.
  *
- * \b Note: The total number of objects of type \a T is not cached but recalculated each time the
- * function is called. Using the templated version of size() to calculate the total number objects
- * of type \a T is therefore more expensive than using the non-template version of size() to get
- * the total number of pointers in the vector!
+ * \return Iterator to the first contained rigid body.
  */
 
-template< typename T >  // Cast type
-inline BodyStorage::SizeType BodyStorage::size() const
+inline BodyStorage::iterator BodyStorage::begin()
 {
-   return bodies_.template size<T>();
+   return BodyStorage::iterator(bodies_.begin());
 }
 //*************************************************************************************************
 
 
 //*************************************************************************************************
-/*!\brief Returns an iterator to the first contained rigid body.
+/*!\brief Returns a constant iterator to the first contained rigid body.
  *
- * \return Iterator to the first contained rigid body.
+ * \return Constant iterator to the first contained rigid body.
  */
 
-inline BodyStorage::Iterator BodyStorage::begin()
+inline BodyStorage::const_iterator BodyStorage::begin() const
 {
-   return bodies_.begin();
+   return cbegin();
 }
 //*************************************************************************************************
 
@@ -272,9 +281,48 @@ inline BodyStorage::Iterator BodyStorage::begin()
  * \return Constant iterator to the first contained rigid body.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::begin() const
+inline BodyStorage::const_iterator BodyStorage::cbegin() const
+{
+   return BodyStorage::const_iterator(bodies_.cbegin());
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Returns an iterator just past the last contained rigid body.
+ *
+ * \return Iterator just past the last contained rigid body.
+ */
+
+inline BodyStorage::iterator BodyStorage::end()
+{
+   return BodyStorage::iterator(bodies_.end());
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Returns a constant iterator just past the last contained rigid body.
+ *
+ * \return Constant iterator just past the last contained rigid body.
+ */
+
+inline BodyStorage::const_iterator BodyStorage::end() const
+{
+   return cend();
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Returns a constant iterator just past the last contained rigid body.
+ *
+ * \return Constant iterator just past the last contained rigid body.
+ */
+
+inline BodyStorage::const_iterator BodyStorage::cend() const
 {
-   return bodies_.begin();
+   return BodyStorage::const_iterator(bodies_.cend());
 }
 //*************************************************************************************************
 
@@ -285,10 +333,10 @@ inline BodyStorage::ConstIterator BodyStorage::begin() const
  * \return Iterator to the first contained rigid body.
  */
 
-template< typename T >  // Cast Type
-inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::begin()
+template< typename C >  // Cast Type
+inline BodyStorage::cast_iterator<C> BodyStorage::begin()
 {
-   return bodies_.template begin<T>();
+   return BodyStorage::cast_iterator<C>(bodies_.begin(), bodies_.end());
 }
 //*************************************************************************************************
 
@@ -299,50 +347,52 @@ inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::begin()
  * \return Constant iterator to the first contained rigid body.
  */
 
-template< typename T >  // Cast Type
-inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::begin() const
+template< typename C >  // Cast Type
+inline BodyStorage::const_cast_iterator<C> BodyStorage::begin() const
 {
-   return bodies_.template begin<T>();
+   return cbegin();
 }
 //*************************************************************************************************
 
 
 //*************************************************************************************************
-/*!\brief Returns an iterator just past the last contained rigid body.
+/*!\brief Returns a constant iterator to the first contained rigid body.
  *
- * \return Iterator just past the last contained rigid body.
+ * \return Constant iterator to the first contained rigid body.
  */
 
-inline BodyStorage::Iterator BodyStorage::end()
+template< typename C >  // Cast Type
+inline BodyStorage::const_cast_iterator<C> BodyStorage::cbegin() const
 {
-   return bodies_.end();
+   return BodyStorage::const_cast_iterator<C>(bodies_.begin(), bodies_.end());
 }
 //*************************************************************************************************
 
 
 //*************************************************************************************************
-/*!\brief Returns a constant iterator just past the last contained rigid body.
+/*!\brief Returns an iterator just past the last contained rigid body.
  *
- * \return Constant iterator just past the last contained rigid body.
+ * \return Iterator just past the last contained rigid body.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::end() const
+template< typename C >  // Cast Type
+inline BodyStorage::cast_iterator<C> BodyStorage::end()
 {
-   return bodies_.end();
+   return BodyStorage::cast_iterator<C>(bodies_.end(), bodies_.end());
 }
 //*************************************************************************************************
 
 
 //*************************************************************************************************
-/*!\brief Returns an iterator just past the last contained rigid body.
+/*!\brief Returns a constant iterator just past the last contained rigid body.
  *
- * \return Iterator just past the last contained rigid body.
+ * \return Constant iterator just past the last contained rigid body.
  */
 
-template< typename T >  // Cast Type
-inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::end()
+template< typename C >  // Cast Type
+inline BodyStorage::const_cast_iterator<C> BodyStorage::end() const
 {
-   return bodies_.template end<T>();
+   return cend();
 }
 //*************************************************************************************************
 
@@ -353,13 +403,30 @@ inline BodyStorage::Bodies::template CastIterator<T> BodyStorage::end()
  * \return Constant iterator just past the last contained rigid body.
  */
 
-template< typename T >  // Cast Type
-inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::end() const
+template< typename C >  // Cast Type
+inline BodyStorage::const_cast_iterator<C> BodyStorage::cend() const
 {
-   return bodies_.template end<T>();
+   return BodyStorage::const_cast_iterator<C>(bodies_.end(), bodies_.end());
 }
 //*************************************************************************************************
 
+inline RigidBody&         BodyStorage::front()
+{
+   return *bodies_.front();
+}
+inline const RigidBody&   BodyStorage::front() const
+{
+   return *bodies_.front();
+}
+inline RigidBody&         BodyStorage::back()
+{
+   return *bodies_.back();
+}
+inline const RigidBody&   BodyStorage::back() const
+{
+   return *bodies_.back();
+}
+
 
 //*************************************************************************************************
 /*!\brief Returns a handle to the indexed rigid body.
@@ -370,10 +437,10 @@ inline BodyStorage::Bodies::template ConstCastIterator<T> BodyStorage::end() con
  * \b Note: No runtime check is performed to ensure the validity of the access index.
  */
 
-inline BodyID BodyStorage::at( SizeType index )
+inline BodyID BodyStorage::at( size_type index )
 {
    WALBERLA_ASSERT( index < size(), "Invalid body index" );
-   return bodies_[index];
+   return bodies_[index].get();
 }
 //*************************************************************************************************
 
@@ -387,10 +454,10 @@ inline BodyID BodyStorage::at( SizeType index )
  * \b Note: No runtime check is performed to ensure the validity of the access index.
  */
 
-inline ConstBodyID BodyStorage::at( SizeType index ) const
+inline ConstBodyID BodyStorage::at( size_type index ) const
 {
    WALBERLA_ASSERT( index < size(), "Invalid body index" );
-   return bodies_[index];
+   return bodies_[index].get();
 }
 //*************************************************************************************************
 
@@ -406,13 +473,13 @@ inline ConstBodyID BodyStorage::at( SizeType index ) const
  * iterator just past the end of the last body contained in the body storage.
  */
 
-inline BodyStorage::Iterator BodyStorage::find( id_t sid )
+inline BodyStorage::iterator BodyStorage::find( id_t sid )
 {
-   std::map<id_t, SizeType>::const_iterator pos = bodyIDs_.find( sid );
+   std::map<id_t, size_type>::const_iterator pos = bodyIDs_.find( sid );
    if( pos == bodyIDs_.end() )
-      return bodies_.end();
+      return BodyStorage::iterator(bodies_.end());
 
-   return bodies_.begin() + static_cast<Bodies::Iterator::difference_type>(pos->second);
+   return BodyStorage::iterator(bodies_.begin() + static_cast<VectorContainer::iterator::difference_type>(pos->second));
 }
 //*************************************************************************************************
 
@@ -428,13 +495,13 @@ inline BodyStorage::Iterator BodyStorage::find( id_t sid )
  * a constant iterator just past the end of the last body contained in the body storage.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::find( id_t sid ) const
+inline BodyStorage::const_iterator BodyStorage::find( id_t sid ) const
 {
-   std::map<id_t, SizeType>::const_iterator pos = bodyIDs_.find( sid );
+   std::map<id_t, size_type>::const_iterator pos = bodyIDs_.find( sid );
    if( pos == bodyIDs_.end() )
-      return bodies_.end();
+      return BodyStorage::const_iterator(bodies_.end());
 
-   return bodies_.begin() + static_cast<Bodies::Iterator::difference_type>(pos->second);
+   return BodyStorage::const_iterator(bodies_.begin() + static_cast<VectorContainer::iterator::difference_type>(pos->second));
 }
 //*************************************************************************************************
 
@@ -450,9 +517,9 @@ inline BodyStorage::ConstIterator BodyStorage::find( id_t sid ) const
  * just past the end of the last body contained in the body storage.
  */
 
-inline BodyStorage::Iterator BodyStorage::find( ConstBodyID body )
+inline BodyStorage::iterator BodyStorage::find( ConstBodyID body )
 {
-   return find( body->getSystemID() );
+   return BodyStorage::iterator(find( body->getSystemID() ));
 }
 //*************************************************************************************************
 
@@ -468,9 +535,9 @@ inline BodyStorage::Iterator BodyStorage::find( ConstBodyID body )
  * constant iterator just past the end of the last body contained in the body storage.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::find( ConstBodyID body ) const
+inline BodyStorage::const_iterator BodyStorage::find( ConstBodyID body ) const
 {
-   return find( body->getSystemID() );
+   return BodyStorage::const_iterator(find( body->getSystemID() ));
 }
 //*************************************************************************************************
 
@@ -494,16 +561,45 @@ inline BodyStorage::ConstIterator BodyStorage::find( ConstBodyID body ) const
  * logarithmic unless reallocation occurs.
  */
 
-inline void BodyStorage::add( BodyID body )
+inline RigidBody& BodyStorage::add( BodyID body )
 {
    WALBERLA_ASSERT( bodyIDs_.find( body->getSystemID() ) == bodyIDs_.end(), "Body with same system ID already added." );
    bodyIDs_[ body->getSystemID() ] = bodies_.size();
-   bodies_.pushBack( body );
+   bodies_.push_back( std::unique_ptr<RigidBody>(body) );
 
    for (auto it = addCallbacks_.begin(); it != addCallbacks_.end(); ++it)
    {
-      it->second(body);
+      it->second(bodies_.back().get());
    }
+
+   return *bodies_.back();
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Adding a rigid body to the body storage.
+ *
+ * \param body The new rigid body to be added to the body storage.
+ * \return void
+ *
+ * This function adds a rigid body to the body storage. Adding bodies with non-unique system ID or
+ * adding the same body multiple times results in undefined behaviour. The time complexity is
+ * logarithmic unless reallocation occurs.
+ */
+
+inline RigidBody& BodyStorage::add( std::unique_ptr<RigidBody>&& body )
+{
+   WALBERLA_ASSERT( bodyIDs_.find( body->getSystemID() ) == bodyIDs_.end(), "Body with same system ID already added." );
+   bodyIDs_[ body->getSystemID() ] = bodies_.size();
+   bodies_.push_back( std::move(body) );
+
+   for (auto it = addCallbacks_.begin(); it != addCallbacks_.end(); ++it)
+   {
+      it->second(bodies_.back().get());
+   }
+
+   return *bodies_.back();
 }
 //*************************************************************************************************
 
@@ -520,23 +616,25 @@ inline void BodyStorage::add( BodyID body )
  * The last element is swapped to the actual position and the length is reduced by one.
  */
 
-inline void BodyStorage::remove( const id_t sid )
+inline
+BodyStorage::iterator BodyStorage::remove( const id_t sid )
 {
-   std::map<id_t, SizeType>::iterator it = bodyIDs_.find( sid );
+   std::map<id_t, size_type>::iterator it = bodyIDs_.find( sid );
    WALBERLA_ASSERT( it != bodyIDs_.end(), "The body's system ID was not registered." );
 
    // Move last element to deleted place and update the system ID to index mapping.
-   SizeType i = it->second;
+   size_type i = it->second;
 
    for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb)
    {
-      cb->second( bodies_[i] );
+      cb->second( bodies_[i].get() );
    }
 
    bodyIDs_[ bodies_.back()->getSystemID() ] = i;
    std::swap( bodies_[i], bodies_.back() );
    bodyIDs_.erase( it );
-   bodies_.popBack();
+   bodies_.pop_back();
+   return iterator(bodies_.begin() + int_c(i));
 }
 //*************************************************************************************************
 
@@ -552,10 +650,9 @@ inline void BodyStorage::remove( const id_t sid )
  * the element to be removed. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::remove( ConstIterator pos )
+inline BodyStorage::const_iterator BodyStorage::remove( const_iterator pos )
 {
-   remove( (*pos)->getSystemID() );
-   return pos;
+   return remove( pos->getSystemID() );
 }
 //*************************************************************************************************
 
@@ -571,10 +668,9 @@ inline BodyStorage::ConstIterator BodyStorage::remove( ConstIterator pos )
  * the element to be removed. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline BodyStorage::Iterator BodyStorage::remove( Iterator pos )
+inline BodyStorage::iterator BodyStorage::remove( iterator pos )
 {
-   remove( (*pos)->getSystemID() );
-   return pos;
+   return remove( pos->getSystemID() );
 }
 //*************************************************************************************************
 
@@ -590,9 +686,10 @@ inline BodyStorage::Iterator BodyStorage::remove( Iterator pos )
  * the element to be removed. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline void BodyStorage::remove( BodyID body )
+inline
+BodyStorage::iterator BodyStorage::remove( BodyID body )
 {
-   remove( body->getSystemID() );
+   return remove( body->getSystemID() );
 }
 //*************************************************************************************************
 
@@ -609,23 +706,22 @@ inline void BodyStorage::remove( BodyID body )
  * Last element is swapped to the actual position and length is reduced by 1.
  */
 
-inline void BodyStorage::release( const id_t sid )
+inline std::unique_ptr<RigidBody> BodyStorage::release( const id_t sid )
 {
-   std::map<id_t, SizeType>::iterator it = bodyIDs_.find( sid );
+   std::map<id_t, size_type>::iterator it = bodyIDs_.find( sid );
    WALBERLA_ASSERT( it != bodyIDs_.end(), "The body's system ID was not registered." );
 
    // Move last element to deleted place and update the system ID to index mapping.
-   SizeType i = it->second;
+   size_type i = it->second;
 
-   for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb)
-   {
-      cb->second( bodies_[i] );
-   }
+   std::for_each(removeCallbacks_.begin(), removeCallbacks_.end(), [&](auto& cb){cb.second( bodies_[i].get() );});
 
    bodyIDs_[ bodies_.back()->getSystemID() ] = i;
    std::swap( bodies_[i], bodies_.back() );
    bodyIDs_.erase( it );
-   bodies_.releaseBack();
+   auto tmp = std::move(bodies_.back());
+   bodies_.pop_back();
+   return tmp;
 }
 //*************************************************************************************************
 
@@ -641,10 +737,12 @@ inline void BodyStorage::release( const id_t sid )
  * the element to be released. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline BodyStorage::ConstIterator BodyStorage::release( ConstIterator pos )
+inline std::unique_ptr<RigidBody> BodyStorage::release( const_iterator& pos )
 {
-   release( (*pos)->getSystemID() );
-   return pos;
+   auto diff = std::distance(bodies_.cbegin(), pos.get());
+   auto tmp = release( pos->getSystemID() );
+   pos = const_iterator(bodies_.begin() + diff);
+   return tmp;
 }
 //*************************************************************************************************
 
@@ -661,10 +759,12 @@ inline BodyStorage::ConstIterator BodyStorage::release( ConstIterator pos )
  * the element to be released. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline BodyStorage::Iterator BodyStorage::release( Iterator pos )
+inline std::unique_ptr<RigidBody> BodyStorage::release( iterator& pos )
 {
-   release( (*pos)->getSystemID() );
-   return pos;
+   auto diff = std::distance(bodies_.begin(), pos.get());
+   auto tmp = release( pos->getSystemID() );
+   pos = iterator(bodies_.begin() + diff);
+   return tmp;
 }
 //*************************************************************************************************
 
@@ -681,9 +781,9 @@ inline BodyStorage::Iterator BodyStorage::release( Iterator pos )
  * the element to be released. The time complexity is logarithmic unless reallocation occurs.
  */
 
-inline void BodyStorage::release( BodyID body )
+inline std::unique_ptr<RigidBody> BodyStorage::release( BodyID body )
 {
-   release( body->getSystemID() );
+   return release( body->getSystemID() );
 }
 //*************************************************************************************************
 
@@ -704,7 +804,7 @@ inline void BodyStorage::clear()
    {
       for (auto cb = removeCallbacks_.begin(); cb != removeCallbacks_.end(); ++cb)
       {
-         cb->second( *bodyIt );
+         cb->second( bodyIt->get() );
       }
    }
 
@@ -766,7 +866,7 @@ inline void          BodyStorage::clearRemoveCallbacks       ( )
 inline void BodyStorage::validate()
 {
    std::vector<bool> tmp(bodies_.size());
-   std::map<id_t, SizeType>::iterator it = bodyIDs_.begin();
+   std::map<id_t, size_type>::iterator it = bodyIDs_.begin();
    while( it != bodyIDs_.end() ) {
       WALBERLA_ASSERT(tmp[it->second] == false, "Two system IDs point to the same storage index.");
       tmp[it->second] = true;
diff --git a/src/pe/rigidbody/BoxFactory.cpp b/src/pe/rigidbody/BoxFactory.cpp
index 6473eaa18e60f971b71d31614cdd3cb13b82889e..6f471ba55ee6fbf1a9838eef6b2da5ec91255958 100644
--- a/src/pe/rigidbody/BoxFactory.cpp
+++ b/src/pe/rigidbody/BoxFactory.cpp
@@ -26,6 +26,9 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Box.h"
 
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
+
 namespace walberla {
 namespace pe {
 
@@ -40,32 +43,31 @@ BoxID createBox(       BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
    if( lengths[0] <= real_t(0) || lengths[1] <= real_t(0) || lengths[2] <= real_t(0) )
       throw std::invalid_argument( "Invalid side length" );
 
-   BoxID box = NULL;
+   BoxID box = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, false, true);
-      globalStorage.add(box);
+      BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, false, true);
+      box = static_cast<BoxID>(&globalStorage.add(std::move(bx)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
-            box->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(box);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            BoxPtr bx = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
+            bx->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            box = static_cast<BoxID>(&bs.add(std::move(bx)));
          }
       }
    }
 
-   if (box != NULL)
+   if (box != nullptr)
    {
       // Logging the successful creation of the box
       WALBERLA_LOG_DETAIL(
diff --git a/src/pe/rigidbody/CapsuleFactory.cpp b/src/pe/rigidbody/CapsuleFactory.cpp
index 44b7839d11d8587d6415f9d0d52d3c885a4e6b23..325af9701f1c78bcf1497f2717fa586372d3e80b 100644
--- a/src/pe/rigidbody/CapsuleFactory.cpp
+++ b/src/pe/rigidbody/CapsuleFactory.cpp
@@ -26,6 +26,9 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Capsule.h"
 
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
+
 namespace walberla {
 namespace pe {
 
@@ -40,32 +43,31 @@ CapsuleID createCapsule(   BodyStorage& globalStorage, BlockStorage& blocks, Blo
    WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid capsule radius" );
    WALBERLA_ASSERT_GREATER( length, real_t(0), "Invalid capsule length" );
 
-   CapsuleID capsule = NULL;
+   CapsuleID capsule = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, false, true);
-      globalStorage.add(capsule);
+      CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, false, true);
+      capsule = static_cast<CapsuleID>(&globalStorage.add(std::move(cp)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
-            capsule->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(capsule);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            CapsulePtr cp = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
+            cp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            capsule = static_cast<CapsuleID>(&bs.add( std::move(cp) ));
          }
       }
    }
 
-   if (capsule != NULL)
+   if (capsule != nullptr)
    {
       // Logging the successful creation of the box
       WALBERLA_LOG_DETAIL(
diff --git a/src/pe/rigidbody/CylindricalBoundary.cpp b/src/pe/rigidbody/CylindricalBoundary.cpp
index 6b99c946384f11f2ecc5cd9f3d88a4e65956622d..66f639e49015a66ab41caf851690e678149c507b 100644
--- a/src/pe/rigidbody/CylindricalBoundary.cpp
+++ b/src/pe/rigidbody/CylindricalBoundary.cpp
@@ -56,7 +56,7 @@ namespace pe {
 CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos, const real_t radius,
                                           MaterialID material )
    : GeomPrimitive( getStaticTypeID(), sid, uid, material )           // Initializing the base object
-   , radius_(radius)                                                  // Radius of the cylinder                                                // Length of the capsule
+   , radius_(radius)                                                  // Radius of the cylinder
 {
    //boundaries are always considered locally and have infinite mass
    setGlobal( true );
@@ -66,11 +66,11 @@ CylindricalBoundary::CylindricalBoundary( id_t sid, id_t uid, const Vec3& gpos,
 
    // Checking the radius
    // Since the constructor is never directly called but only used in a small number
-   // of functions that already check the capsule arguments, only asserts are used here to
+   // of functions that already check the cylinder arguments, only asserts are used here to
    // double check the arguments.
-   WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid capsule radius"  );
+   WALBERLA_ASSERT_GREATER( radius, real_t(0), "Invalid cylinder radius"  );
 
-   // Initializing the instantiated capsule
+   // Initializing the instantiated cylinder
    gpos_   = gpos;
    q_      = Quat();                 // Setting the orientation
    R_      = q_.toRotationMatrix();  // Setting the rotation matrix
diff --git a/src/pe/rigidbody/CylindricalBoundary.h b/src/pe/rigidbody/CylindricalBoundary.h
index 4c095c1a20bae85959c756a856500ec7b4332b93..5d9b4c9d5da23922f0858500e065b25ca884a6f0 100644
--- a/src/pe/rigidbody/CylindricalBoundary.h
+++ b/src/pe/rigidbody/CylindricalBoundary.h
@@ -175,7 +175,7 @@ inline id_t CylindricalBoundary::getStaticTypeID()
 //=================================================================================================
 
 //*************************************************************************************************
-/*!\name Capsule operators */
+/*!\name Cylinder operators */
 //@{
 std::ostream& operator<<( std::ostream& os, const CylindricalBoundary& cb );
 std::ostream& operator<<( std::ostream& os, CylindricalBoundaryID cb );
diff --git a/src/pe/rigidbody/CylindricalBoundaryFactory.cpp b/src/pe/rigidbody/CylindricalBoundaryFactory.cpp
index a82ea0c684ad7dbc7f60c2d02b99fb7eb6ded2f2..6cbf752cb9bb0c29f576e34c7ce336b2077ec4b1 100644
--- a/src/pe/rigidbody/CylindricalBoundaryFactory.cpp
+++ b/src/pe/rigidbody/CylindricalBoundaryFactory.cpp
@@ -24,7 +24,8 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/CylindricalBoundary.h"
 
-#include "core/logging/Logging.h"
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
 
 namespace walberla {
 namespace pe {
@@ -37,9 +38,9 @@ CylindricalBoundaryID createCylindricalBoundary( BodyStorage& globalStorage,
 
    const id_t sid( UniqueID<RigidBody>::createGlobal() );
 
-   CylindricalBoundaryID cb = new CylindricalBoundary( sid, uid, gpos, radius, material );
+   CylindricalBoundaryPtr cbPtr = std::make_unique<CylindricalBoundary>( sid, uid, gpos, radius, material );
 
-   globalStorage.add(cb);
+   CylindricalBoundaryID cb = static_cast<CylindricalBoundaryID>(&globalStorage.add(std::move(cbPtr)));
 
    // Logging the successful creation of the plane
    WALBERLA_LOG_DETAIL( "Created cylindrical boundary " << sid << "\n" << cb);
diff --git a/src/pe/rigidbody/EllipsoidFactory.cpp b/src/pe/rigidbody/EllipsoidFactory.cpp
index e848dd28527d9c763c55bab2b7e02467c82b05a3..8e8835b23d2507e053026d6cd081a95907436ddb 100644
--- a/src/pe/rigidbody/EllipsoidFactory.cpp
+++ b/src/pe/rigidbody/EllipsoidFactory.cpp
@@ -25,40 +25,42 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Ellipsoid.h"
 
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
+
 namespace walberla {
 namespace pe {
 
 EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID storageID,
-                       id_t uid, const Vec3& gpos, const Vec3& semiAxes,
-                       MaterialID material,
-                       bool global, bool communicating, bool infiniteMass )
+                             id_t uid, const Vec3& gpos, const Vec3& semiAxes,
+                             MaterialID material,
+                             bool global, bool communicating, bool infiniteMass )
 {
    WALBERLA_ASSERT_UNEQUAL( Ellipsoid::getStaticTypeID(), std::numeric_limits<id_t>::max(), "Ellipsoid TypeID not initalized!");
    // Checking the semiAxes
    if( semiAxes[0] <= real_c(0) || semiAxes[1] <= real_c(0) || semiAxes[2] <= real_c(0) )
       throw std::invalid_argument( "Invalid Ellipsoid semi-axes" );
 
-   EllipsoidID ellipsoid = NULL;
+   EllipsoidID ellipsoid = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      ellipsoid = new Ellipsoid(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, false, true);
-      globalStorage.add(ellipsoid);
+      EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, false, true);
+      ellipsoid = static_cast<EllipsoidID>(&globalStorage.add(std::move(el)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            ellipsoid = new Ellipsoid(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, communicating, infiniteMass);
-            ellipsoid->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(ellipsoid);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            EllipsoidPtr el = std::make_unique<Ellipsoid>(sid, uid, gpos, Vec3(0,0,0), Quat(), semiAxes, material, global, communicating, infiniteMass);
+            el->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            ellipsoid = static_cast<EllipsoidID>(&bs.add(std::move(el)));
          }
       }
    }
@@ -67,12 +69,12 @@ EllipsoidID createEllipsoid( BodyStorage& globalStorage, BlockStorage& blocks, B
    {
       // Logging the successful creation of the Ellipsoid
       WALBERLA_LOG_DETAIL(
-                "Created Ellipsoid " << ellipsoid->getSystemID() << "\n"
-             << "   User-ID         = " << uid << "\n"
-             << "   Global position = " << gpos << "\n"
-             << "   Semi-axes       = " << semiAxes << "\n"
-             << "   LinVel          = " << ellipsoid->getLinearVel() << "\n"
-             << "   Material        = " << Material::getName( material )
+               "Created Ellipsoid " << ellipsoid->getSystemID() << "\n"
+               << "   User-ID         = " << uid << "\n"
+               << "   Global position = " << gpos << "\n"
+               << "   Semi-axes       = " << semiAxes << "\n"
+               << "   LinVel          = " << ellipsoid->getLinearVel() << "\n"
+               << "   Material        = " << Material::getName( material )
                );
    }
 
diff --git a/src/pe/rigidbody/Node.h b/src/pe/rigidbody/Node.h
deleted file mode 100644
index 584d44e4f5bb66ce8c2d55d7891992178776160e..0000000000000000000000000000000000000000
--- a/src/pe/rigidbody/Node.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file Node.h
-//! \author Klaus Iglberger
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#pragma once
-
-
-//*************************************************************************************************
-// Includes
-//*************************************************************************************************
-
-#include <pe/Types.h>
-#include <core/DataTypes.h>
-
-namespace walberla {
-namespace pe {
-
-//=================================================================================================
-//
-//  SPECIALIZATION FOR THE UNION FIND ALGORITHM
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Node for the 'Union Find' algorithm.
- *
- * This specialization of the BodyTrait class template adapts rigid bodies to the 'Union Find'
- * batch generation algorithm. In this algorithm, rigid bodies act as nodes in a graph and
- * contacts between the rigid bodies act as edges.
- */
-class Node
-{
-public:
-
-   //**Constructor*********************************************************************************
-   /*!\name Constructor */
-   //@{
-   explicit inline Node();
-   //@}
-   //**********************************************************************************************
-
-   //**Node functions******************************************************************************
-   /*!\name Node functions */
-   //@{
-   inline ConstNodeID getRoot()   const;
-   inline void        resetNode() const;
-   //@}
-   //**********************************************************************************************
-
-public:
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   mutable ConstNodeID root_;  //!< The root of the contact graph containing the rigid body.
-   mutable size_t rank_;       //!< The current rank of the rigid body in the contact graph.
-   mutable size_t batch_;      //!< Index of the batch containing all contacts in the contact graph.
-   //@}
-   //**********************************************************************************************
-};
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Default constructor for the BodyTrait<UnionFind> specialization.
- */
-inline Node::Node()
-   : rank_ ( 0 )
-   , batch_( 0 )
-{
-   root_ = this ;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Calculating the current root of the contact graph.
- *
- * \return The current root of the contact graph.
- *
- * This function returns the current root of the contact graph and compresses the graph for
- * a fast access to the root node.
- */
-inline ConstNodeID Node::getRoot() const
-{
-   ConstNodeID root( this );
-
-   // Traverse the contact graph to find the root node
-   while( root->root_ != root ) {
-      root = root->root_;
-   }
-
-   // Retraverse the graph for graph compression
-   ConstNodeID tmp( this );
-   while( tmp->root_ != tmp ) {
-      ConstNodeID last = tmp;
-      tmp = tmp->root_;
-      last->root_ = root;
-   }
-
-   return root;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Resetting the data members of the node.
- *
- * \return void
- */
-inline void Node::resetNode() const
-{
-   root_  = this;
-   rank_  = 0;
-   batch_ = 0;
-}
-//*************************************************************************************************
-
-} // namespace pe
-
-} // namespace walberla
diff --git a/src/pe/rigidbody/PlaneFactory.cpp b/src/pe/rigidbody/PlaneFactory.cpp
index 2f780a12a1d1377fcf72b283d082e0e3a1320884..650054ee07b68655d53d5e959122d35ed66ea2ce 100644
--- a/src/pe/rigidbody/PlaneFactory.cpp
+++ b/src/pe/rigidbody/PlaneFactory.cpp
@@ -26,7 +26,8 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Plane.h"
 
-#include "core/logging/Logging.h"
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
 
 namespace walberla {
 namespace pe {
@@ -44,9 +45,8 @@ PlaneID createPlane( BodyStorage& globalStorage, id_t uid, Vec3 normal, const Ve
 
    const id_t sid( UniqueID<RigidBody>::createGlobal() );
 
-   PlaneID plane = new Plane( sid, uid, gpos, normal, normal*gpos, material );
-
-   globalStorage.add(plane);
+   PlanePtr pl = std::make_unique<Plane>( sid, uid, gpos, normal, normal*gpos, material );
+   PlaneID plane = static_cast<PlaneID>(&globalStorage.add(std::move(pl)));
 
    // Logging the successful creation of the plane
    WALBERLA_LOG_DETAIL( "Created plane " << sid << "\n"
diff --git a/src/pe/rigidbody/RigidBody.cpp b/src/pe/rigidbody/RigidBody.cpp
index 45d40109e31a29020a55517e8c28b1b5fecddf2f..f23bde4e08d0e5c320a89a356cfdb3cdc2988e18 100644
--- a/src/pe/rigidbody/RigidBody.cpp
+++ b/src/pe/rigidbody/RigidBody.cpp
@@ -33,8 +33,7 @@ namespace pe{
  * \param uid The user-specific ID of the rigid body.
  */
 RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid )
-   : Node()
-   , awake_( true )           // Sleep mode flag
+   : awake_( true )           // Sleep mode flag
    , mass_( 0 )               // Total mass of the rigid body
    , invMass_( 0 )            // Inverse total mass of the rigid body
    , motion_(sleepThreshold)  // The current motion of the rigid body
@@ -57,7 +56,6 @@ RigidBody::RigidBody( id_t const typeID, id_t sid, id_t uid )
    , toBeDeleted_(false)      // deletion flag
    , sid_    (sid)            // System-specific body index
    , uid_    (uid)            // User-specific body ID
-   , contacts_()              // Vector of the currently attached contacts
    , typeID_(typeID)          // geometry type
 {
    sb_ = this;           // The superordinate rigid body
diff --git a/src/pe/rigidbody/RigidBody.h b/src/pe/rigidbody/RigidBody.h
index 119616748a90f49f94333ad14cf0d5335b35650e..fdebc3ff61424cbbdcc213d45bb2d473b6d07014 100644
--- a/src/pe/rigidbody/RigidBody.h
+++ b/src/pe/rigidbody/RigidBody.h
@@ -28,16 +28,12 @@
 #include "core/math/Matrix3.h"
 #include "core/math/Quaternion.h"
 #include "core/math/Vector3.h"
-#include <pe/rigidbody/Node.h>
 
 #include "core/NonCopyable.h"
 #include "core/DataTypes.h"
-#include "core/ptrvector/PtrVector.h"
-#include "core/ptrvector/policies/NoDelete.h"
 #include "core/debug/Debug.h"
 #include "core/logging/Logging.h"
 #include "core/math/AABB.h"
-#include "pe/attachable/Attachable.h"
 #include "pe/rigidbody/MPIRigidBodyTrait.h"
 
 namespace walberla{
@@ -49,8 +45,7 @@ class Union;
 /**
  * \ingroup pe
  */
-class RigidBody : public Node
-                , public ccd::HashGridsBodyTrait
+class RigidBody : public ccd::HashGridsBodyTrait
                 , public cr::HCSITSBodyTrait
                 , private NonCopyable
 {
@@ -58,21 +53,6 @@ private:
    template <typename BodyTypeTuple>
    friend class Union;
 
-   //**Type definitions****************************************************************************
-   typedef PtrVector<RigidBody,NoDelete>   Bodies;       //!< Vector for superordinate bodies containing this rigid body.
-   typedef PtrVector<Contact,NoDelete>     Contacts;     //!< Vector for attached contacts.
-   typedef PtrVector<Attachable,NoDelete>  Attachables;  //!< Vector for attachables.
-   //**********************************************************************************************
-
-public:
-   //**Type definitions****************************************************************************
-   typedef Contacts::Iterator          ContactIterator;            //!< Iterator over the currently attached contacts.
-   typedef Contacts::ConstIterator     ConstContactIterator;       //!< ConstIterator over the currently attached contacts.
-   typedef Attachables::Iterator       AttachableIterator;         //!< Iterator over the currently attached attachables.
-   typedef Attachables::ConstIterator  ConstAttachableIterator;    //!< ConstIterator over the currently attached attachables.
-   typedef Bodies::Iterator            AttachedBodyIterator;       //!< Iterator over the currently attached rigid bodies.
-   typedef Bodies::ConstIterator       ConstAttachedBodyIterator;  //!< ConstIterator over the currently attached rigid bodies.
-   //**********************************************************************************************
 protected:
    //**Constructor*********************************************************************************
    /*!\name Constructor */
@@ -275,38 +255,6 @@ public:
    //@}
    //**********************************************************************************************
 
-   //**Contact functions***************************************************************************
-   /*!\name Contact functions */
-   //@{
-   inline void                 registerContact( ContactID contact );
-   inline bool                 hasContacts  () const;
-   inline void                 clearContacts();
-   inline size_t               countContacts() const;
-   inline ContactIterator      beginContacts();
-   inline ConstContactIterator beginContacts() const;
-   inline ContactIterator      endContacts  ();
-   inline ConstContactIterator endContacts  () const;
-   //@}
-   //**********************************************************************************************
-
-   //**Attachable functions************************************************************************
-   /*!\name Attachable functions */
-   //@{
-          void                      registerAttachable  ( AttachableID attachable );
-          void                      deregisterAttachable( AttachableID attachable );
-   inline bool                      isAttached          () const;
-   inline size_t                    countAttachables    () const;
-   inline AttachableIterator        beginAttachables    ();
-   inline ConstAttachableIterator   beginAttachables    () const;
-   inline AttachableIterator        endAttachables      ();
-   inline ConstAttachableIterator   endAttachables      () const;
-   inline AttachedBodyIterator      beginAttachedBodies ();
-   inline ConstAttachedBodyIterator beginAttachedBodies () const;
-   inline AttachedBodyIterator      endAttachedBodies   ();
-   inline ConstAttachedBodyIterator endAttachedBodies   () const;
-   //@}
-   //**********************************************************************************************
-
    //**MPI functions*******************************************************************************
    /*!\name MPI functions */
    //@{
@@ -460,9 +408,6 @@ protected:
    bool toBeDeleted_;         //!< This flag marks the body for deletion during the next synchronization (only works on local bodies)
    id_t sid_;                 //!< The unique system-specific body ID.
    id_t uid_;                 //!< The user-specific body ID.
-   Contacts contacts_;        //!< Vector for the currently attached contacts.
-   Attachables attachables_;  //!< Vector for the currently attached attachables.
-   Bodies attachedBodies_;    //!< Vector for the currently attached rigid bodies.
    //@}
    //**********************************************************************************************
 
@@ -1170,7 +1115,11 @@ const Vec3 RigidBody::accFromWF( real_t px, real_t py, real_t pz ) const
 }
 //*************************************************************************************************
 
-inline id_t     RigidBody::getTypeID() const{
+inline id_t RigidBody::getTypeID() const
+{
+   WALBERLA_ASSERT_LESS( typeID_, std::numeric_limits<id_t>::max(), "You are requesting the type " \
+                         " id of a body, but the static type id for the body has not yet been " \
+                         " initialized! Call SetBodyTypeIDs<BodyTypeTuple>::execute to initialize!" );
    return typeID_;
 }
 
@@ -1939,240 +1888,6 @@ inline void RigidBody::signalFixation()
 
 
 
-//=================================================================================================
-//
-//  CONTACT FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Registering a single attached contact with the rigid body.
- *
- * \param contact The contact to be registered with the rigid body.
- * \return void
- */
-inline void RigidBody::registerContact( ContactID contact )
-{
-   WALBERLA_ASSERT( !hasSuperBody(), "Invalid contact on subordinate body detected" );
-   contacts_.pushBack( contact );
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Clears all contacts registered with the rigid body.
- *
- * \return void
- */
-inline void RigidBody::clearContacts()
-{
-   contacts_.clear();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns whether any contacts are registered with the rigid body.
- *
- * \return \a true if at least one contact is registered with the rigid body, \a false if not.
- */
-inline bool RigidBody::hasContacts() const
-{
-   return !contacts_.isEmpty();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the number of currently registered contacts.
- *
- * \return The number of registered contacts.
- */
-inline size_t RigidBody::countContacts() const
-{
-   return contacts_.size();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached contact.
- *
- * \return Iterator to the first attached contact.
- */
-inline RigidBody::ContactIterator RigidBody::beginContacts()
-{
-   return contacts_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached contact.
- *
- * \return Iterator to the first attached contact.
- */
-inline RigidBody::ConstContactIterator RigidBody::beginContacts() const
-{
-   return contacts_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached contact.
- *
- * \return Iterator just past the last attached contact.
- */
-inline RigidBody::ContactIterator RigidBody::endContacts()
-{
-   return contacts_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached contact.
- *
- * \return Iterator just past the last attached contact.
- */
-inline RigidBody::ConstContactIterator RigidBody::endContacts() const
-{
-   return contacts_.end();
-}
-//*************************************************************************************************
-
-
-
-
-//=================================================================================================
-//
-//  ATTACHABLE FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Returns whether any attachable is registered with the rigid body.
- *
- * \return \a true in case at least one attachable is registered with the rigid body, \a false otherwise.
- */
-inline bool RigidBody::isAttached() const
-{
-   return !attachables_.isEmpty();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the number of currently registered attachables.
- *
- * \return The number of registered attachables.
- */
-inline size_t RigidBody::countAttachables() const
-{
-   return attachables_.size();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first registered attachable.
- *
- * \return Iterator to the first registered attachable.
- */
-inline RigidBody::AttachableIterator RigidBody::beginAttachables()
-{
-   return attachables_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first registered attachable.
- *
- * \return Iterator to the first registered attachable.
- */
-inline RigidBody::ConstAttachableIterator RigidBody::beginAttachables() const
-{
-   return attachables_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last registered attachable.
- *
- * \return Iterator just past the last registered attachable.
- */
-inline RigidBody::AttachableIterator RigidBody::endAttachables()
-{
-   return attachables_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last registered attachable.
- *
- * \return Iterator just past the last registered attachable.
- */
-inline RigidBody::ConstAttachableIterator RigidBody::endAttachables() const
-{
-   return attachables_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached rigid body.
- *
- * \return Iterator to the first attached rigid body.
- */
-inline RigidBody::AttachedBodyIterator RigidBody::beginAttachedBodies()
-{
-   return attachedBodies_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator to the first attached rigid body.
- *
- * \return Iterator to the first attached rigid body.
- */
-inline RigidBody::ConstAttachedBodyIterator RigidBody::beginAttachedBodies() const
-{
-   return attachedBodies_.begin();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached rigid body.
- *
- * \return Iterator just past the last attached rigid body.
- */
-inline RigidBody::AttachedBodyIterator RigidBody::endAttachedBodies()
-{
-   return attachedBodies_.end();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns an iterator just past the last attached rigid body.
- *
- * \return Iterator just past the last attached rigid body.
- */
-inline RigidBody::ConstAttachedBodyIterator RigidBody::endAttachedBodies() const
-{
-   return attachedBodies_.end();
-}
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  MPI FUNCTIONS
@@ -3343,73 +3058,6 @@ inline void RigidBody::update( const Quat& dq )
 
 
 
-//=================================================================================================
-//
-//  ATTACHABLE FUNCTIONS
-//
-//=================================================================================================
-
-//*************************************************************************************************
-/*!\brief Registering a single attachable with the rigid body.
- *
- * \param attachable The attachable to be registered with the rigid body.
- * \return void
- *
- * This function must NOT be called explicitly, but is reserved for internal use only!
- * Attachables are automatically registered during their construction process.
- */
-inline void RigidBody::registerAttachable( AttachableID attachable )
-{
-   // Registering the attachable
-   attachables_.pushBack( attachable );
-
-   // Registering all newly attached rigid bodies
-   const Attachable::Iterator end( attachable->end() );
-   for( Attachable::Iterator body=attachable->begin(); body!=end; ++body ) {
-      const AttachedBodyIterator bbegin( attachedBodies_.begin() );
-      const AttachedBodyIterator bend  ( attachedBodies_.end()   );
-      if( *body != this && std::find( bbegin, bend, *body ) == bend )
-         attachedBodies_.pushBack( *body );
-   }
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Deregistering a single attachable from the rigid body.
- *
- * \param attachable The attachable to be deregistered from the rigid body.
- * \return void
- *
- * This function must NOT be called explicitly, but is reserved for internal use only!
- * Attachables are automatically deregistered during their destruction process.
- */
-inline void RigidBody::deregisterAttachable( AttachableID attachable )
-{
-   // Deregistering the attachable
-   Attachables::Iterator pos( std::find( attachables_.begin(), attachables_.end(), attachable ) );
-   WALBERLA_ASSERT( pos != attachables_.end(), "Attachable is not registered" );
-   attachables_.erase( pos );
-
-   // Deregistering all attached rigid bodies
-   attachedBodies_.clear();
-
-   // Recreating the vector of attached rigid bodies
-   for( Attachables::Iterator it=attachables_.begin(); it!=attachables_.end(); ++it ) {
-      const Attachable::Iterator end( it->end() );
-      for( Attachable::Iterator body=it->begin(); body!=end; ++body ) {
-         const AttachedBodyIterator bbegin( attachedBodies_.begin() );
-         const AttachedBodyIterator bend  ( attachedBodies_.end()   );
-         if( *body != this && std::find( bbegin, bend, *body ) == bend )
-            attachedBodies_.pushBack( *body );
-      }
-   }
-}
-//*************************************************************************************************
-
-
-
-
 //=================================================================================================
 //
 //  SIMULATION FUNCTIONS
diff --git a/src/pe/rigidbody/RigidBodyCastIterator.h b/src/pe/rigidbody/RigidBodyCastIterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..7241baa63ce3b6eac5bafb20be5571016f992526
--- /dev/null
+++ b/src/pe/rigidbody/RigidBodyCastIterator.h
@@ -0,0 +1,315 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file RigidBodyCastIterator.h
+//! \author Klaus Iglberger
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include "RigidBody.h"
+
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+namespace walberla {
+namespace pe {
+
+//*************************************************************************************************
+/*!\brief Dynamic cast iterator for polymorphic pointer vectors.
+ *
+ * The RigidBodyCastIterator is a forward iterator which only selects elements of type C.
+ * Dereferencing this iterator will implicitly cast to C.
+ */
+template <typename C>
+class RigidBodyCastIterator
+{
+   static_assert(std::is_base_of<RigidBody, C>::value && !std::is_base_of<C, RigidBody>::value,
+                 "C has to be strictly derived from RigidBody");
+
+   template <typename C2>
+   friend inline bool operator==( const RigidBodyCastIterator<C2>& lhs, const RigidBodyCastIterator<C2>& rhs );
+   template <typename C2>
+   friend inline bool operator!=( const RigidBodyCastIterator<C2>& lhs, const RigidBodyCastIterator<C2>& rhs );
+public:
+   using ContainerType         = std::vector< std::unique_ptr<RigidBody> >;
+   //**Type definitions****************************************************************************
+   // STL iterator requirements
+   using iterator_category     = std::forward_iterator_tag;
+   using value_type            = C;
+   using pointer               = C*;
+   using reference             = C&;
+   using difference_type       = std::ptrdiff_t;
+   //**********************************************************************************************
+
+   //**Constructors********************************************************************************
+   /*!\name Constructors */
+   //@{
+   inline RigidBodyCastIterator() {}
+   explicit inline RigidBodyCastIterator( const typename ContainerType::iterator& begin, const typename ContainerType::iterator& end );
+
+   RigidBodyCastIterator( const RigidBodyCastIterator<C>& it) = default;
+   RigidBodyCastIterator( RigidBodyCastIterator<C>&& it) = default;
+
+   RigidBodyCastIterator& operator=(const RigidBodyCastIterator<C>& it) = default;
+   RigidBodyCastIterator& operator=(RigidBodyCastIterator<C>&& it) = default;
+
+   //**Operators***********************************************************************************
+   /*!\name Operators */
+   //@{
+   inline RigidBodyCastIterator<C>&   operator++();
+   inline RigidBodyCastIterator<C>    operator++( int ) {RigidBodyCastIterator<C> tmp(*this); ++(*this); return tmp;}
+   //@}
+   //**********************************************************************************************
+
+   //**Access operators****************************************************************************
+   /*!\name Access operators */
+   //@{
+   inline reference operator*()   {return static_cast<reference>( *(cur_->get()) );}
+   inline pointer   operator->()  {return static_cast<pointer>(     cur_->get()  );}
+   //@}
+   //**********************************************************************************************
+
+   //**Utility functions***************************************************************************
+   /*!\name Utility functions */
+   //@{
+   inline pointer getBodyID() {return static_cast<pointer>(cur_->get());}
+   //@}
+   //**********************************************************************************************
+
+private:
+   //**Member variables****************************************************************************
+   /*!\name Member variables */
+   //@{
+   typename ContainerType::iterator cur_;  //!< Pointer to the current memory location.
+   typename ContainerType::iterator end_;  //!< Pointer to the element one past the last element in the element range.
+   //@}
+   //**********************************************************************************************
+};
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Standard constructor for CastIterator.
+ *
+ * \param begin The beginning of the element range.
+ * \param end The end of the element range.
+ */
+template< typename C >  // Cast type
+inline RigidBodyCastIterator<C>::RigidBodyCastIterator( const typename ContainerType::iterator& begin,
+                                                        const typename ContainerType::iterator& end )
+   : cur_(begin)  // Pointer to the current memory location
+   , end_(end)    // Pointer to the element one past the last element in the element range
+{
+   cur_ = std::find_if(cur_, end_, [](const ContainerType::iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();});
+}
+//*************************************************************************************************
+
+//*************************************************************************************************
+/*!\brief Pre-increment operator.
+ *
+ * \return Reference to the incremented cast iterator.
+ */
+template< typename C >
+inline RigidBodyCastIterator<C>& RigidBodyCastIterator<C>::operator++()
+{
+   cur_ = std::find_if(++cur_, end_, [](const ContainerType::iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();});
+
+   return *this;
+}
+//*************************************************************************************************
+
+
+//**********************************************************************************************
+/*!\brief Equality comparison between two CastIterator objects.
+//
+// \param lhs The left hand side cast iterator.
+// \param rhs The right hand side cast iterator.
+// \return \a true if the iterators point to the same element, \a false if not.
+*/
+template< typename C >
+inline bool operator==( const RigidBodyCastIterator<C>& lhs, const RigidBodyCastIterator<C>& rhs )
+{
+   return lhs.cur_ == rhs.cur_;
+}
+//**********************************************************************************************
+
+//**********************************************************************************************
+/*!\brief Inequality comparison between two CastIterator objects.
+//
+// \param lhs The left hand side cast iterator.
+// \param rhs The right hand side cast iterator.
+// \return \a true if the iterators don't point to the same element, \a false if they do.
+*/
+template< typename C >
+inline bool operator!=( const RigidBodyCastIterator<C>& lhs, const RigidBodyCastIterator<C>& rhs )
+{
+   return !operator==(lhs, rhs);
+}
+//**********************************************************************************************
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+template <typename C>
+class ConstRigidBodyCastIterator
+{
+   static_assert(std::is_base_of<RigidBody, C>::value && !std::is_base_of<C, RigidBody>::value,
+                 "C has to be strictly derived from RigidBody");
+
+   template <typename C2>
+   friend bool operator==( const ConstRigidBodyCastIterator<C2>& lhs, const ConstRigidBodyCastIterator<C2>& rhs );
+   template <typename C2>
+   friend bool operator!=( const ConstRigidBodyCastIterator<C2>& lhs, const ConstRigidBodyCastIterator<C2>& rhs );
+public:
+   using ContainerType         = std::vector< std::unique_ptr<RigidBody> >;
+   //**Type definitions****************************************************************************
+   // STL iterator requirements
+   using iterator_category     = std::forward_iterator_tag;
+   using value_type            = C const;
+   using pointer               = C const *;
+   using reference             = C const &;
+   using difference_type       = std::ptrdiff_t;
+   //**********************************************************************************************
+
+   //**Constructors********************************************************************************
+   /*!\name Constructors */
+   //@{
+   inline ConstRigidBodyCastIterator() {}
+   explicit inline ConstRigidBodyCastIterator( const typename ContainerType::const_iterator& begin,
+                                               const typename ContainerType::const_iterator& end );
+
+   ConstRigidBodyCastIterator( const ConstRigidBodyCastIterator<C>& it) = default;
+   ConstRigidBodyCastIterator( ConstRigidBodyCastIterator<C>&& it) = default;
+
+   ConstRigidBodyCastIterator& operator=(const ConstRigidBodyCastIterator<C>& it) = default;
+   ConstRigidBodyCastIterator& operator=(ConstRigidBodyCastIterator<C>&& it) = default;
+
+   //**Operators***********************************************************************************
+   /*!\name Operators */
+   //@{
+   inline ConstRigidBodyCastIterator<C>&   operator++();
+   inline ConstRigidBodyCastIterator<C>    operator++( int ) {ConstRigidBodyCastIterator<C> tmp(*this); ++(*this); return tmp;}
+   //@}
+   //**********************************************************************************************
+
+   //**Access operators****************************************************************************
+   /*!\name Access operators */
+   //@{
+   inline reference operator*()   {return static_cast<reference>( *(cur_->get()) );}
+   inline pointer   operator->()  {return static_cast<pointer>(     cur_->get()  );}
+   //@}
+   //**********************************************************************************************
+
+   //**Utility functions***************************************************************************
+   /*!\name Utility functions */
+   //@{
+   inline pointer getBodyID() {return static_cast<pointer>(cur_->get());}
+   //@}
+   //**********************************************************************************************
+
+private:
+   //**Member variables****************************************************************************
+   /*!\name Member variables */
+   //@{
+   typename ContainerType::const_iterator cur_;  //!< Pointer to the current memory location.
+   typename ContainerType::const_iterator end_;  //!< Pointer to the element one past the last element in the element range.
+   //@}
+   //**********************************************************************************************
+};
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Standard constructor for CastIterator.
+ *
+ * \param begin The beginning of the element range.
+ * \param end The end of the element range.
+ */
+template< typename C >  // Cast type
+inline ConstRigidBodyCastIterator<C>::ConstRigidBodyCastIterator( const typename ContainerType::const_iterator& begin,
+                                                                  const typename ContainerType::const_iterator& end )
+   : cur_(begin)  // Pointer to the current memory location
+   , end_(end)    // Pointer to the element one past the last element in the element range
+{
+   cur_ = std::find_if(cur_, end_, [](const ContainerType::const_iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();});
+}
+//*************************************************************************************************
+
+//*************************************************************************************************
+/*!\brief Pre-increment operator.
+ *
+ * \return Reference to the incremented cast iterator.
+ */
+template< typename C >
+inline ConstRigidBodyCastIterator<C>& ConstRigidBodyCastIterator<C>::operator++()
+{
+   cur_ = std::find_if(++cur_, end_, [](const ContainerType::const_iterator::value_type& p) {return p->getTypeID() == C::getStaticTypeID();});
+
+   return *this;
+}
+//*************************************************************************************************
+
+
+//**********************************************************************************************
+/*!\brief Equality comparison between two CastIterator objects.
+//
+// \param lhs The left hand side cast iterator.
+// \param rhs The right hand side cast iterator.
+// \return \a true if the iterators point to the same element, \a false if not.
+*/
+template< typename C >
+inline bool operator==( const ConstRigidBodyCastIterator<C>& lhs, const ConstRigidBodyCastIterator<C>& rhs )
+{
+   return lhs.cur_ == rhs.cur_;
+}
+//**********************************************************************************************
+
+//**********************************************************************************************
+/*!\brief Inequality comparison between two CastIterator objects.
+//
+// \param lhs The left hand side cast iterator.
+// \param rhs The right hand side cast iterator.
+// \return \a true if the iterators don't point to the same element, \a false if they do.
+*/
+template< typename C >
+inline bool operator!=( const ConstRigidBodyCastIterator<C>& lhs, const ConstRigidBodyCastIterator<C>& rhs )
+{
+   return !operator==(lhs, rhs);
+}
+//**********************************************************************************************
+
+} // namespace pe
+} // namespace walberla
diff --git a/src/pe/rigidbody/RigidBodyIterator.h b/src/pe/rigidbody/RigidBodyIterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e2be67d2f299dde26ebb313b4a17e4c22642301
--- /dev/null
+++ b/src/pe/rigidbody/RigidBodyIterator.h
@@ -0,0 +1,367 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file RigidBodyIterator.h
+//! \author Klaus Iglberger
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include "RigidBody.h"
+
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+namespace walberla {
+namespace pe {
+
+//*************************************************************************************************
+/*!\brief Implementation of an iterator for pointer vectors.
+ *
+ * This iterator implementation will automatically dereference twice at dereference calls!
+ * Therefore the return types are not unique_ptrs but RigidBodys.
+ */
+class RigidBodyIterator
+{
+   friend inline bool operator==( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+   friend inline bool operator!=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+   friend inline bool operator>( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+   friend inline bool operator<( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+   friend inline bool operator>=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+   friend inline bool operator<=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs );
+public:
+   using ContainerType         = std::vector< std::unique_ptr<RigidBody> >;
+   //**Type definitions****************************************************************************
+   // STL iterator requirements
+   using iterator_category     = std::random_access_iterator_tag;
+   using value_type            = RigidBody;
+   using pointer               = RigidBody*;
+   using reference             = RigidBody&;
+   using difference_type       = std::ptrdiff_t;
+   //**********************************************************************************************
+
+   //**Constructors********************************************************************************
+   /*!\name Constructors */
+   //@{
+   inline RigidBodyIterator() {}
+   explicit inline RigidBodyIterator( const typename ContainerType::iterator& it ) : it_(it) {}
+
+   RigidBodyIterator( const RigidBodyIterator& it) = default;
+   RigidBodyIterator( RigidBodyIterator&& it) = default;
+
+   RigidBodyIterator& operator=(const RigidBodyIterator& it) = default;
+   RigidBodyIterator& operator=(RigidBodyIterator&& it) = default;
+
+   //**Operators***********************************************************************************
+   /*!\name Operators */
+   //@{
+   inline RigidBodyIterator&   operator++()                    {++it_; return *this;}
+   inline RigidBodyIterator    operator++( int )               {RigidBodyIterator tmp(*this); ++(*this); return tmp;}
+   inline RigidBodyIterator&   operator--()                    {--it_; return *this;}
+   inline RigidBodyIterator    operator--( int )               {RigidBodyIterator tmp(*this); --(*this); return tmp;}
+   inline RigidBodyIterator&   operator+=( difference_type n ) {it_ += n; return *this;}
+   inline RigidBodyIterator    operator+ ( difference_type n ) const {return RigidBodyIterator( it_ + n );}
+   inline RigidBodyIterator&   operator-=( difference_type n ) {it_ -= n; return *this;}
+   inline RigidBodyIterator    operator- ( difference_type n ) const {return RigidBodyIterator( it_ - n );}
+   inline difference_type      operator- ( const RigidBodyIterator& it ) const {return it_ - it.it_;}
+   //@}
+   //**********************************************************************************************
+
+   //**Access operators****************************************************************************
+   /*!\name Access operators */
+   //@{
+   inline reference operator[]( difference_type n ) const {return *it_[n];}
+   inline reference operator*()                     const {return **it_;}
+   inline pointer   operator->()                    const {return it_->get();}
+   //@}
+   //**********************************************************************************************
+
+   //**Utility functions***************************************************************************
+   /*!\name Utility functions */
+   //@{
+   inline pointer getBodyID() {return it_->get();}
+   inline ContainerType::iterator get() const {return it_;}
+   //@}
+   //**********************************************************************************************
+
+private:
+   //**Member variables****************************************************************************
+   /*!\name Member variables */
+   //@{
+   typename ContainerType::iterator it_;  //!< wrapped iterator
+   //@}
+   //**********************************************************************************************
+};
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Equality comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the iterators point to the same element, \a false if not.
+ */
+inline bool operator==( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return lhs.it_ == rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Inequality comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the iterators don't point to the same element, \a false if they do.
+ */
+inline bool operator!=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return !operator==(lhs, rhs);
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Less-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a lower element, \a false if not.
+ */
+inline bool operator<( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return lhs.it_ < rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Greater-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a higher element, \a false if not.
+ */
+inline bool operator>( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return lhs.it_ > rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Less-or-equal-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not.
+ */
+inline bool operator<=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return lhs.it_ <= rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Greater-or-equal-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not.
+ */
+inline bool operator>=( const RigidBodyIterator& lhs, const RigidBodyIterator& rhs )
+{
+   return lhs.it_ >= rhs.it_;
+}
+//*************************************************************************************************
+
+
+
+
+
+
+
+
+
+
+
+
+class ConstRigidBodyIterator
+{
+   friend inline bool operator==( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+   friend inline bool operator!=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+   friend inline bool operator>( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+   friend inline bool operator<( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+   friend inline bool operator>=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+   friend inline bool operator<=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs );
+public:
+   using ContainerType         = std::vector< std::unique_ptr<RigidBody> >;
+   //**Type definitions****************************************************************************
+   // STL iterator requirements
+   using iterator_category     = std::random_access_iterator_tag;
+   using value_type            = RigidBody const;
+   using pointer               = RigidBody const *;
+   using reference             = RigidBody const &;
+   using difference_type       = std::ptrdiff_t;
+   //**********************************************************************************************
+
+   //**Constructors********************************************************************************
+   /*!\name Constructors */
+   //@{
+   inline ConstRigidBodyIterator() {}
+   inline ConstRigidBodyIterator( const RigidBodyIterator& it ) : it_(it.get()) {}
+   explicit inline ConstRigidBodyIterator( const typename ContainerType::iterator& it ) : it_(it) {}
+   explicit inline ConstRigidBodyIterator( const typename ContainerType::const_iterator& it ) : it_(it) {}
+
+   ConstRigidBodyIterator( const ConstRigidBodyIterator& it) = default;
+   ConstRigidBodyIterator( ConstRigidBodyIterator&& it) = default;
+
+   ConstRigidBodyIterator& operator=(const ConstRigidBodyIterator& it) = default;
+   ConstRigidBodyIterator& operator=(ConstRigidBodyIterator&& it) = default;
+
+   //**Operators***********************************************************************************
+   /*!\name Operators */
+   //@{
+   inline ConstRigidBodyIterator&   operator++()                    {++it_; return *this;}
+   inline ConstRigidBodyIterator    operator++( int )               {ConstRigidBodyIterator tmp(*this); ++(*this); return tmp;}
+   inline ConstRigidBodyIterator&   operator--()                    {--it_; return *this;}
+   inline ConstRigidBodyIterator    operator--( int )               {ConstRigidBodyIterator tmp(*this); --(*this); return tmp;}
+   inline ConstRigidBodyIterator&   operator+=( difference_type n ) {it_ += n; return *this;}
+   inline ConstRigidBodyIterator    operator+ ( difference_type n ) const {return ConstRigidBodyIterator( it_ + n );}
+   inline ConstRigidBodyIterator&   operator-=( difference_type n ) {it_ -= n; return *this;}
+   inline ConstRigidBodyIterator    operator- ( difference_type n ) const {return ConstRigidBodyIterator( it_ - n );}
+   inline difference_type operator- ( const ConstRigidBodyIterator& it ) const {return it_ - it.it_;}
+   //@}
+   //**********************************************************************************************
+
+   //**Access operators****************************************************************************
+   /*!\name Access operators */
+   //@{
+   inline reference operator[]( difference_type n ) const {return *it_[n];}
+   inline reference operator*()                     const {return **it_;}
+   inline pointer   operator->()                    const {return it_->get();}
+   //@}
+   //**********************************************************************************************
+
+   //**Utility functions***************************************************************************
+   /*!\name Utility functions */
+   //@{
+   inline pointer getBodyID() const {return it_->get();}
+   inline ContainerType::const_iterator get() const {return it_;}
+   //@}
+   //**********************************************************************************************
+
+private:
+   //**Member variables****************************************************************************
+   /*!\name Member variables */
+   //@{
+   typename ContainerType::const_iterator it_;  //!< wrapped iterator
+   //@}
+   //**********************************************************************************************
+};
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Equality comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the iterators point to the same element, \a false if not.
+ */
+inline bool operator==( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return lhs.it_ == rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Inequality comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the iterators don't point to the same element, \a false if they do.
+ */
+inline bool operator!=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return !operator==(lhs, rhs);
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Less-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a lower element, \a false if not.
+ */
+inline bool operator<( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return lhs.it_ < rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Greater-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a higher element, \a false if not.
+ */
+inline bool operator>( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return lhs.it_ > rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Less-or-equal-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a lower or the same element, \a false if not.
+ */
+inline bool operator<=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return lhs.it_ <= rhs.it_;
+}
+//*************************************************************************************************
+
+
+//*************************************************************************************************
+/*!\brief Greater-or-equal-than comparison between two PtrIterator objects.
+ *
+ * \param lhs The left-hand side pointer iterator.
+ * \param rhs The right-hand side pointer iterator.
+ * \return \a true if the left-hand side iterator points to a higher or the same element, \a false if not.
+ */
+inline bool operator>=( const ConstRigidBodyIterator& lhs, const ConstRigidBodyIterator& rhs )
+{
+   return lhs.it_ >= rhs.it_;
+}
+//*************************************************************************************************
+
+} // namespace pe
+} // namespace walberla
diff --git a/src/pe/rigidbody/SphereFactory.cpp b/src/pe/rigidbody/SphereFactory.cpp
index c9487031def01e2876e0d2bf6d341c1e9681825b..d88774c45f10803f84eaa1ac9f8fcd5a21fb91c6 100644
--- a/src/pe/rigidbody/SphereFactory.cpp
+++ b/src/pe/rigidbody/SphereFactory.cpp
@@ -26,6 +26,9 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Sphere.h"
 
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
+
 namespace walberla {
 namespace pe {
 
@@ -39,32 +42,31 @@ SphereID createSphere( BodyStorage& globalStorage, BlockStorage& blocks, BlockDa
    if( radius <= real_c(0) )
       throw std::invalid_argument( "Invalid sphere radius" );
 
-   SphereID sphere = NULL;
+   SphereID sphere = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, false, true);
-      globalStorage.add(sphere);
+      SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, false, true);
+      sphere = static_cast<SphereID>(&globalStorage.add( std::move(sp) ));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
-            sphere->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(sphere);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            SpherePtr sp = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
+            sp->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            sphere = static_cast<SphereID>(&bs.add( std::move(sp) ));
          }
       }
    }
 
-   if (sphere != NULL)
+   if (sphere != nullptr)
    {
       // Logging the successful creation of the sphere
       WALBERLA_LOG_DETAIL(
diff --git a/src/pe/rigidbody/SquirmerFactory.cpp b/src/pe/rigidbody/SquirmerFactory.cpp
index 41b495b75aa008cf3aae1278b98ad450302b9cd7..7160ff2d0fa80e72dcf28a5f3fe7445e0679999f 100644
--- a/src/pe/rigidbody/SquirmerFactory.cpp
+++ b/src/pe/rigidbody/SquirmerFactory.cpp
@@ -24,6 +24,9 @@
 #include "pe/rigidbody/BodyStorage.h"
 #include "pe/rigidbody/Squirmer.h"
 
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
+
 namespace walberla {
 namespace pe {
 
@@ -38,32 +41,31 @@ SquirmerID createSquirmer( BodyStorage& globalStorage, BlockStorage& blocks, Blo
    if( radius <= real_c(0) )
       throw std::invalid_argument( "Invalid squirmer radius" );
 
-   SquirmerID squirmer = NULL;
+   SquirmerID squirmer = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      squirmer = new Squirmer(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true);
-      globalStorage.add(squirmer);
+      SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, false, true);
+      squirmer = static_cast<SquirmerID>(&globalStorage.add(std::move(sq)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            squirmer = new Squirmer(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass);
-            squirmer->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(squirmer);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            SquirmerPtr sq = std::make_unique<Squirmer>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, squirmerVelocity, squirmerBeta, material, global, communicating, infiniteMass);
+            sq->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            squirmer = static_cast<SquirmerID>(&bs.add( std::move(sq) ));
          }
       }
    }
 
-   if (squirmer != NULL)
+   if (squirmer != nullptr)
    {
       // Logging the successful creation of the squirmer
       WALBERLA_LOG_DETAIL(
diff --git a/src/pe/rigidbody/StorageDataHandling.h b/src/pe/rigidbody/StorageDataHandling.h
index 6e3b0d2dafad64473a5b63f325e00bdccd49eb38..2d49a98c84b21d11d4c3bf51da230e62c648ebae 100644
--- a/src/pe/rigidbody/StorageDataHandling.h
+++ b/src/pe/rigidbody/StorageDataHandling.h
@@ -88,8 +88,8 @@ void StorageDataHandling<BodyTuple>::serialize( IBlock * const block, const Bloc
       {
          WALBERLA_ABORT( "Body to be stored not contained within block!" );
       }
-      marshal( buffer, RigidBodyCopyNotification( **bodyIt ) );
-      MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt );
+      marshal( buffer, RigidBodyCopyNotification( *bodyIt ) );
+      MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt );
    }
 }
 
@@ -146,8 +146,8 @@ void StorageDataHandling<BodyTuple>::serializeCoarseToFine( Block * const block,
       }
       if( childAABB.contains( bodyIt->getPosition()) )
       {
-         marshal( buffer, RigidBodyCopyNotification( **bodyIt ) );
-         MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt );
+         marshal( buffer, RigidBodyCopyNotification( *bodyIt ) );
+         MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt );
          ++numOfParticles;
       }
    }
@@ -166,8 +166,8 @@ void StorageDataHandling<BodyTuple>::serializeFineToCoarse( Block * const block,
       {
          WALBERLA_ABORT( "Body to be stored not contained within block!" );
       }
-      marshal( buffer, RigidBodyCopyNotification( **bodyIt ) );
-      MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt );
+      marshal( buffer, RigidBodyCopyNotification( *bodyIt ) );
+      MarshalDynamically<BodyTuple>::execute( buffer, *bodyIt );
    }
 }
 
@@ -214,16 +214,16 @@ void StorageDataHandling<BodyTuple>::deserializeImpl( IBlock * const block, cons
       typename RigidBodyCopyNotification::Parameters objparam;
       unmarshal( buffer, objparam );
 
-      BodyID bd = UnmarshalDynamically<BodyTuple>::execute(buffer, objparam.geomType_, block->getBlockStorage().getDomain(), block->getAABB());
+      auto bd = UnmarshalDynamically<BodyTuple>::execute(buffer, objparam.geomType_, block->getBlockStorage().getDomain(), block->getAABB());
       bd->setRemote( false );
       bd->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
 
       if ( !block->getAABB().contains( bd->getPosition()) )
       {
-         WALBERLA_ABORT("Loaded body not contained within block!\n" << "aabb: " << block->getAABB() << "\nparticle:" << bd );
+         WALBERLA_ABORT("Loaded body not contained within block!\n" << "aabb: " << block->getAABB() << "\nparticle:" << *bd );
       }
       WALBERLA_ASSERT_EQUAL(localBodyStorage.find( bd->getSystemID() ), localBodyStorage.end());
-      localBodyStorage.add(bd);
+      localBodyStorage.add(std::move(bd));
 
       --numBodies;
    }
diff --git a/src/pe/rigidbody/Union.h b/src/pe/rigidbody/Union.h
index 81c8128f6a4253f8d17f43801fef4a39f9e056b7..fe6e0ce94f1e975feaae4cea68b97aa6aa85ad1d 100644
--- a/src/pe/rigidbody/Union.h
+++ b/src/pe/rigidbody/Union.h
@@ -27,7 +27,10 @@
 //*************************************************************************************************
 
 #include <pe/Config.h>
+#include <pe/rigidbody/BodyStorage.h>
 #include <pe/rigidbody/RigidBody.h>
+#include <pe/rigidbody/RigidBodyCastIterator.h>
+#include <pe/rigidbody/RigidBodyIterator.h>
 #include <pe/Types.h>
 
 #include <core/debug/Debug.h>
@@ -65,23 +68,24 @@ class Union : public RigidBody
 {
 public:
    //**Type definitions****************************************************************************
-   typedef BodyTypeTuple                     BodyTypeTupleT;
+   using BodyTypeTupleT        = BodyTypeTuple;
 
-   typedef PtrVector<RigidBody, PtrDelete>   Bodies;             //!< Iterator over the contained rigid bodies.
-   typedef Bodies::Iterator                  Iterator;           //!< Iterator over the contained rigid bodies.
-   typedef Bodies::ConstIterator             ConstIterator;      //!< Constant iterator over the contained rigid bodies.
-   //**++++++++++++++++****************************************************************************
+   //**********************************************************************************************
 
-   //**Forward declarations for nested classes*****************************************************
-//   template< typename C > class CastIterator;
-//   template< typename C > class ConstCastIterator;
+   using size_type             = BodyStorage::size_type;           //!< Size type of the body storage.
+   using iterator              = BodyStorage::iterator;            //!< Iterator over non-const bodies.
+   using const_iterator        = BodyStorage::const_iterator;      //!< Iterator over constant bodies.
+   template <typename C> //cast type
+   using cast_iterator         = BodyStorage::cast_iterator<C>;
+   template <typename C> //cast type
+   using const_cast_iterator   = BodyStorage::const_cast_iterator<C>;
    //**********************************************************************************************
 
    //**Constructors********************************************************************************
    /*!\name Constructors */
    //@{
    explicit Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
-                    const bool global, const bool communicating, const bool infiniteMass );
+                   const bool global, const bool communicating, const bool infiniteMass );
    //@}
    //**********************************************************************************************
 
@@ -95,28 +99,35 @@ public:
 
 public:
    //**Get functions*******************************************************************************
-   /*!\name Get functions */
+   /*!\name BodyStorage functions */
    //@{
-                          inline bool                 isEmpty() const;
-                          inline size_t               size()    const;
-   template< typename C > inline size_t               size()    const {return bodies_.size<C>();}
-                          inline BodyID               getBody( size_t index );
-                          inline ConstBodyID          getBody( size_t index ) const;
-
-                          inline Iterator                     begin()       {return bodies_.begin();}
-                          inline ConstIterator                begin() const {return bodies_.begin();}
-   template< typename C > inline Bodies::CastIterator<C>      begin()       {return bodies_.begin<C>();}
-   template< typename C > inline Bodies::ConstCastIterator<C> begin() const {return bodies_.begin<C>();}
-
-                          inline Iterator                     end()         {return bodies_.end();}
-                          inline ConstIterator                end() const   {return bodies_.end();}
-   template< typename C > inline Bodies::CastIterator<C>      end()         {return bodies_.end<C>();}
-   template< typename C > inline Bodies::ConstCastIterator<C> end() const   {return bodies_.end<C>();}
-
-   virtual inline real_t getVolume()         const;
+   inline bool                 isEmpty() const {return bodies_.isEmpty();}
+   inline size_t               size()    const {return bodies_.size();}
+
+   inline iterator       begin   ()       {return bodies_.begin();}
+   inline const_iterator begin   () const {return bodies_.begin();}
+   inline const_iterator cbegin  () const {return bodies_.cbegin();}
+   inline iterator       end     ()       {return bodies_.end();}
+   inline const_iterator end     () const {return bodies_.end();}
+   inline const_iterator cend    () const {return bodies_.cend();}
+
+   template< typename C >
+   inline cast_iterator<C> begin()              {return bodies_.begin<C>();}
+   template< typename C >
+   inline const_cast_iterator<C> begin() const  {return bodies_.begin<C>();}
+   template< typename C >
+   inline const_cast_iterator<C> cbegin() const {return bodies_.cbegin<C>();}
+   template< typename C >
+   inline cast_iterator<C> end()                {return bodies_.end<C>();}
+   template< typename C >
+   inline const_cast_iterator<C> end() const    {return bodies_.end<C>();}
+   template< typename C >
+   inline const_cast_iterator<C> cend() const   {return bodies_.cend<C>();}
    //@}
    //**********************************************************************************************
 
+   virtual inline real_t getVolume()         const;
+
    //**Set functions*******************************************************************************
    /*!\name Set functions */
    //@{
@@ -146,7 +157,7 @@ public:
    //**Rigid body manager functions****************************************************************
    /*!\name Rigid body manager functions */
    //@{
-   void add   ( BodyID body );
+   inline RigidBody& add( std::unique_ptr<RigidBody>&& body );
    //@}
    //**********************************************************************************************
 
@@ -183,18 +194,13 @@ protected:
    /*!\name Utility functions */
    //@{
    inline virtual void calcBoundingBox() WALBERLA_OVERRIDE;  // Calculation of the axis-aligned bounding box
-                  void calcCenterOfMass(); ///< updates the center of mass (gpos)
+   void calcCenterOfMass(); ///< updates the center of mass (gpos)
    inline         void calcInertia();      // Calculation of the moment of inertia
    //@}
    //**********************************************************************************************
 
-   //**Member variables****************************************************************************
-   /*!\name Member variables */
-   //@{
-   PtrVector<RigidBody, PtrDelete> bodies_;  //!< Rigid bodies contained in the union.
-   //@}
-   //**********************************************************************************************
 private:
+   BodyStorage bodies_;  //!< Rigid bodies contained in the union.
    std::vector<id_t> containedTypeIDs_;
 
    static id_t staticTypeID_;  //< type id of sphere, will be set by SetBodyTypeIDs
@@ -228,7 +234,7 @@ private:
  */
 template <typename BodyTypeTuple>
 Union<BodyTypeTuple>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& rpos, const Quat& q,
-                const bool global, const bool communicating, const bool /*infiniteMass*/ )
+                             const bool global, const bool communicating, const bool /*infiniteMass*/ )
    : RigidBody( getStaticTypeID(), sid, uid )  // Initialization of the parent class
 {
    // Initializing the instantiated union
@@ -241,7 +247,7 @@ Union<BodyTypeTuple>::Union( id_t sid, id_t uid, const Vec3& gpos, const Vec3& r
    calcInertia();
 
    setGlobal( global );
-//   setMass( infiniteMass );
+   //   setMass( infiniteMass );
    setCommunicating( communicating );
    setFinite( true );
 }
@@ -322,7 +328,7 @@ void Union<BodyTypeTuple>::calcBoundingBox()
    // Setting the bounding box of an empty union
    if( bodies_.isEmpty() ) {
       aabb_ = math::AABB(
-            gpos_[0] - real_t(0.01),
+                 gpos_[0] - real_t(0.01),
             gpos_[1] - real_t(0.01),
             gpos_[2] - real_t(0.01),
             gpos_[0] + real_t(0.01),
@@ -334,7 +340,7 @@ void Union<BodyTypeTuple>::calcBoundingBox()
    // Using the bounding box of the first contained bodies as initial bounding box
    // and merging it with the bounding boxes of all other bodies
    else {
-      aabb_ = bodies_[0]->getAABB();
+      aabb_ = bodies_.begin()->getAABB();
       for( auto b=bodies_.begin()+1; b!=bodies_.end(); ++b )
          aabb_.merge( b->getAABB() );
    }
@@ -366,7 +372,7 @@ void Union<BodyTypeTuple>::calcCenterOfMass()
    // Calculating the center of mass of a single body
    if( bodies_.size() == 1 )
    {
-      const BodyID body( bodies_[0] );
+      const BodyID body( bodies_.begin().getBodyID() );
       gpos_ = body->getPosition();
       mass_ = body->getMass();
       if( !isFixed() && mass_ > real_t(0) )
@@ -512,8 +518,8 @@ void Union<BodyTypeTuple>::setPositionImpl( real_t px, real_t py, real_t pz )
    gpos_ = gpos;
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dp );
+   for( auto& b : bodies_ )
+      b.update( dp );
 
    Union<BodyTypeTuple>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
@@ -548,8 +554,8 @@ void Union<BodyTypeTuple>::setOrientationImpl( real_t r, real_t i, real_t j, rea
    R_ = q_.toRotationMatrix();
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dq );
+   for( auto& b : bodies_ )
+      b.update( dq );
 
    Union<BodyTypeTuple>::calcBoundingBox();  // Setting the axis-aligned bounding box
    wake();             // Waking the union from sleep mode
@@ -586,8 +592,8 @@ void Union<BodyTypeTuple>::update( const Vec3& dp )
    gpos_ += dp;
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dp );
+   for( auto& b : bodies_ )
+      b.update( dp );
 
    // Setting the axis-aligned bounding box
    Union<BodyTypeTuple>::calcBoundingBox();
@@ -623,8 +629,8 @@ void Union<BodyTypeTuple>::update( const Quat& dq )
    R_ = q_.toRotationMatrix();
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dq );
+   for( auto& b : bodies_ )
+      b.update( dq );
 
    // Setting the axis-aligned bounding box
    Union<BodyTypeTuple>::calcBoundingBox();
@@ -694,38 +700,38 @@ void Union<BodyTypeTuple>::update( const Quat& dq )
  *    union (to make the entire union (in-)visible.
  */
 template <typename BodyTypeTuple>
-void Union<BodyTypeTuple>::add( BodyID body )
+RigidBody& Union<BodyTypeTuple>::add( std::unique_ptr<RigidBody>&& body )
 {
    // Checking for "self-assignment"
-   if( body == BodyID( this ) ) return;
+   if( body.get() == BodyID( this ) ) return *this;
 
    // Checking the global flags of the body and the union in MPI parallel simulations
    if( body->isGlobal() ^ global_ )
       throw std::logic_error( "Global flags of body and union do not match" );
 
+   // Registering the rigid body
+   auto& bd = bodies_.add( std::move(body) );
+
    Vec3 oldCenterOfMass = getPosition();
    Vec3 oldImpulse      = getLinearVel() * getMass();
 
-   Vec3 bodyCenterOfMass = body->getPosition();
-   Vec3 bodyImpulse      = body->getLinearVel() * body->getMass();
+   Vec3 bodyCenterOfMass = bd.getPosition();
+   Vec3 bodyImpulse      = bd.getLinearVel() * bd.getMass();
 
-
-   // Registering the rigid body
-   body->setSB(this);
-   bodies_.pushBack( body );
+   bd.setSB(this); //having a superbody will forward all getVel calls to superbody!!!
 
    // Updating the axis-aligned bounding box
    if( bodies_.size() == 1 )
-      aabb_ = body->getAABB();
+      aabb_ = bd.getAABB();
    else
-      aabb_.merge( body->getAABB() );
+      aabb_.merge( bd.getAABB() );
 
    // Setting the union's total mass and center of mass
    calcCenterOfMass();
 
    // Setting the contained primitives' relative position in reference to the center of mass
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      ( *b )->calcRelPosition();
+   for( auto& b : bodies_ )
+      b.calcRelPosition();
 
    // Setting the moment of inertia
    calcInertia();
@@ -735,11 +741,13 @@ void Union<BodyTypeTuple>::add( BodyID body )
    setAngularVel( Vec3(0,0,0) );
    addImpulseAtPos( oldImpulse, oldCenterOfMass);
    addImpulseAtPos( bodyImpulse, bodyCenterOfMass);
-   body->setLinearVel( Vec3(0,0,0) );
-   body->setAngularVel( Vec3(0,0,0) );
+   bd.setLinearVel( Vec3(0,0,0) );
+   bd.setAngularVel( Vec3(0,0,0) );
 
    // Signaling the internal modification to the superordinate body
    signalModification();
+
+   return bodies_.back();
 }
 //*************************************************************************************************
 
@@ -771,8 +779,8 @@ void Union<BodyTypeTuple>::translateImpl( real_t dx, real_t dy, real_t dz )
    gpos_ += dp;
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dp );
+   for( auto& b : bodies_ )
+      b.update( dp );
 
    Union<BodyTypeTuple>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
@@ -811,8 +819,8 @@ void Union<BodyTypeTuple>::rotateImpl( const Quat& dq )
    R_ = q_.toRotationMatrix();  // Updating the rotation of the union
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dq );
+   for( auto& b : bodies_ )
+      b.update( dq );
 
    Union<BodyTypeTuple>::calcBoundingBox();  // Setting the axis-aligned bounding box
    wake();             // Waking the union from sleep mode
@@ -843,8 +851,8 @@ void Union<BodyTypeTuple>::rotateAroundOriginImpl( const Quat& dq )
    gpos_ = dq.rotate( gpos_ );     // Updating the global position of the union
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dq );
+   for( auto& b : bodies_ )
+      b.update( dq );
 
    Union<BodyTypeTuple>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
@@ -876,8 +884,8 @@ void Union<BodyTypeTuple>::rotateAroundPointImpl( const Vec3& point, const Quat
    gpos_ = point + dq.rotate( dp );  // Updating the global position of the union
 
    // Updating the contained bodies
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      (*b)->update( dq );
+   for( auto& b : bodies_ )
+      b.update( dq );
 
    Union<BodyTypeTuple>::calcBoundingBox();    // Setting the axis-aligned bounding box
    wake();               // Waking the union from sleep mode
@@ -906,8 +914,8 @@ template <typename BodyTypeTuple>
 bool Union<BodyTypeTuple>::containsRelPointImpl( real_t px, real_t py, real_t pz ) const
 {
    const Vec3 gpos( pointFromBFtoWF( px, py, pz ) );
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      if( b->containsPoint( gpos ) ) return true;
+   for( auto& b : bodies_ )
+      if( b.containsPoint( gpos ) ) return true;
    return false;
 }
 //*************************************************************************************************
@@ -929,9 +937,10 @@ bool Union<BodyTypeTuple>::isSurfaceRelPointImpl( real_t px, real_t py, real_t p
    bool surface( false );
    const Vec3 gpos( pointFromBFtoWF( px, py, pz ) );
 
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b ) {
-      if( b->containsPoint( gpos ) ) return false;
-      else if( b->isSurfacePoint( gpos ) ) surface = true;
+   for( auto& b : bodies_ )
+   {
+      if( b.containsPoint( gpos ) ) return false;
+      else if( b.isSurfacePoint( gpos ) ) surface = true;
    }
 
    return surface;
@@ -974,8 +983,8 @@ void Union<BodyTypeTuple>::handleModification()
    calcCenterOfMass();
 
    // Setting the contained primitives' relative position in reference to the center of mass
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      ( *b )->calcRelPosition();
+   for( auto& b : bodies_ )
+      b.calcRelPosition();
 
    // Setting the moment of inertia
    calcInertia();
@@ -1004,8 +1013,8 @@ void Union<BodyTypeTuple>::handleTranslation()
    calcCenterOfMass();
 
    // Setting the contained bodies' relative position in reference to the center of mass
-   for( auto b=bodies_.begin(); b!=bodies_.end(); ++b )
-      ( *b )->calcRelPosition();
+   for( auto& b : bodies_ )
+      b.calcRelPosition();
 
    // Setting the moment of inertia
    calcInertia();
@@ -1155,65 +1164,6 @@ std::ostream& operator<<( std::ostream& os, Union<BodyTypeTuple> const * u )
 //
 //=================================================================================================
 
-//*************************************************************************************************
-/*!\brief Returns whether the union contains any bodies or not.
- *
- * \return \a true if the union is empty, \a false if it not.
- */
-template <typename BodyTypeTuple>
-inline bool Union<BodyTypeTuple>::isEmpty() const
-{
-   return bodies_.size() == 0;
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns the number of rigid bodies contained in the union.
- *
- * \return The number of rigid bodies.
- */
-template <typename BodyTypeTuple>
-inline size_t Union<BodyTypeTuple>::size() const
-{
-   return bodies_.size();
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a handle to the indexed rigid body.
- *
- * \param index Access index. The index has to be in the range \f$[0..size-1]\f$.
- * \return Handle to the accessed body.
- *
- * \b Note: No runtime check is performed to insure the validity of the access index.
- */
-template <typename BodyTypeTuple>
-inline BodyID Union<BodyTypeTuple>::getBody( size_t index )
-{
-   WALBERLA_ASSERT_LESS( index, bodies_.size(), "Invalid access index" );
-   return bodies_[index];
-}
-//*************************************************************************************************
-
-
-//*************************************************************************************************
-/*!\brief Returns a constant handle to the indexed rigid body.
- *
- * \param index Access index. The index has to be in the range \f$[0..size-1]\f$.
- * \return Constant handle to the accessed body.
- *
- * \b Note: No runtime check is performed to insure the validity of the access index.
- */
-template <typename BodyTypeTuple>
-inline ConstBodyID Union<BodyTypeTuple>::getBody( size_t index ) const
-{
-   WALBERLA_ASSERT_LESS( index, bodies_.size(), "Invalid access index" );
-   return bodies_[index];
-}
-//*************************************************************************************************
-
 
 //*************************************************************************************************
 /*!\brief Returns unique type id of this type
diff --git a/src/pe/rigidbody/UnionFactory.h b/src/pe/rigidbody/UnionFactory.h
index e237e0dd31d83642f80663ed48b7c083498cad63..eeff2ffe8c578fe05924c8fea440afb89b33e5e2 100644
--- a/src/pe/rigidbody/UnionFactory.h
+++ b/src/pe/rigidbody/UnionFactory.h
@@ -31,8 +31,10 @@
 #include "pe/rigidbody/Union.h"
 #include "pe/Types.h"
 
-#include "blockforest/BlockForest.h"
-#include "core/debug/Debug.h"
+#include <blockforest/BlockForest.h>
+#include <core/debug/Debug.h>
+#include <core/logging/Logging.h>
+#include <core/UniqueID.h>
 
 namespace walberla {
 namespace pe {
@@ -73,32 +75,31 @@ Union<BodyTypeTuple>* createUnion(   BodyStorage& globalStorage, BlockStorage& b
    if (Union<BodyTypeTuple>::getStaticTypeID() == std::numeric_limits<id_t>::max())
       throw std::runtime_error("Union TypeID not initalized!");
 
-   Union<BodyTypeTuple>* bd = NULL;
+   Union<BodyTypeTuple>* bd = nullptr;
 
    if (global)
    {
       const id_t sid = UniqueID<RigidBody>::createGlobal();
       WALBERLA_ASSERT_EQUAL(communicating, false);
       WALBERLA_ASSERT_EQUAL(infiniteMass, true);
-      bd = new Union<BodyTypeTuple>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, false, true);
-      globalStorage.add(bd);
+      auto un = std::make_unique<Union<BodyTypeTuple>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, false, true);
+      bd = static_cast<Union<BodyTypeTuple>*>(&globalStorage.add(std::move(un)));
    } else
    {
-      for (auto it = blocks.begin(); it != blocks.end(); ++it){
-         IBlock* block = (&(*it));
-         if (block->getAABB().contains(gpos))
+      for (auto& block : blocks){
+         if (block.getAABB().contains(gpos))
          {
             const id_t sid( UniqueID<RigidBody>::create() );
 
-            Storage* bs = block->getData<Storage>(storageID);
-            bd = new Union<BodyTypeTuple>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, communicating, infiniteMass);
-            bd->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block->getId().getID()));
-            (*bs)[0].add(bd);
+            BodyStorage& bs = (*block.getData<Storage>(storageID))[0];
+            auto un = std::make_unique<Union<BodyTypeTuple>>(sid, uid, gpos, Vec3(0,0,0), Quat(), global, communicating, infiniteMass);
+            un->MPITrait.setOwner(Owner(MPIManager::instance()->rank(), block.getId().getID()));
+            bd = static_cast<Union<BodyTypeTuple>*>(&bs.add(std::move(un)));
          }
       }
    }
 
-   if (bd != NULL)
+   if (bd != nullptr)
    {
       // Logging the successful creation of the box
       WALBERLA_LOG_DETAIL(
@@ -143,7 +144,6 @@ BoxID createBox( Union<BodyTypeTuple>* un,
    if( lengths[0] <= real_t(0) || lengths[1] <= real_t(0) || lengths[2] <= real_t(0) )
       throw std::invalid_argument( "Invalid side length" );
 
-   BoxID box = NULL;
    id_t  sid = 0;
 
    if (global)
@@ -156,9 +156,8 @@ BoxID createBox( Union<BodyTypeTuple>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   box = new Box(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
+   std::unique_ptr<Box> box = std::make_unique<Box>(sid, uid, gpos, Vec3(0,0,0), Quat(), lengths, material, global, communicating, infiniteMass);
    box->MPITrait.setOwner( un->MPITrait.getOwner() );
-   un->add(box);
 
    if (box != NULL)
    {
@@ -173,7 +172,7 @@ BoxID createBox( Union<BodyTypeTuple>* un,
                );
    }
 
-   return box;
+   return static_cast<BoxID> (&(un->add(std::move(box))));
 }
 
 //*************************************************************************************************
@@ -215,7 +214,6 @@ CapsuleID createCapsule( Union<BodyTypeTuple>* un,
    if( length <= real_c(0) )
       throw std::invalid_argument( "Invalid capsule length" );
 
-   CapsuleID capsule = NULL;
    id_t      sid     = 0;
 
    if (global)
@@ -228,16 +226,15 @@ CapsuleID createCapsule( Union<BodyTypeTuple>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   capsule = new Capsule(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
+   std::unique_ptr<Capsule> capsule = std::make_unique<Capsule>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, length, material, global, communicating, infiniteMass);
    capsule->MPITrait.setOwner( un->MPITrait.getOwner() );
-   un->add(capsule);
 
    if (capsule != NULL)
    {
-      WALBERLA_LOG_DETAIL("Created capsule " << capsule->getSystemID() << "\n" << capsule);
+      WALBERLA_LOG_DETAIL("Created capsule " << capsule->getSystemID() << "\n" << *capsule);
    }
 
-   return capsule;
+   return static_cast<CapsuleID>(&(un->add(std::move(capsule))));
 }
 
 //*************************************************************************************************
@@ -275,7 +272,6 @@ SphereID createSphere( Union<BodyTypeTuple>* un,
       throw std::invalid_argument( "Invalid sphere radius" );
 
    id_t sid(0);
-   SphereID sphere = NULL;
 
    if (global)
    {
@@ -288,9 +284,8 @@ SphereID createSphere( Union<BodyTypeTuple>* un,
       sid = UniqueID<RigidBody>::create();
    }
 
-   sphere = new Sphere(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
+   std::unique_ptr<Sphere> sphere = std::make_unique<Sphere>(sid, uid, gpos, Vec3(0,0,0), Quat(), radius, material, global, communicating, infiniteMass);
    sphere->MPITrait.setOwner( un->MPITrait.getOwner() );
-   un->add( sphere );
 
    if (sphere != NULL)
    {
@@ -305,7 +300,7 @@ SphereID createSphere( Union<BodyTypeTuple>* un,
                );
    }
 
-   return sphere;
+   return static_cast<SphereID>(&(un->add( std::move(sphere) )));
 }
 
 }  // namespace pe
diff --git a/src/pe/synchronization/RemoveAndNotify.h b/src/pe/synchronization/RemoveAndNotify.h
index 8eaf880fe6e80157b7199d37dbf5b75606925a53..6c8d27c0d89e6e7ec2f9cc34464f9c28c3593d4e 100644
--- a/src/pe/synchronization/RemoveAndNotify.h
+++ b/src/pe/synchronization/RemoveAndNotify.h
@@ -44,7 +44,7 @@ namespace pe {
  * This function removes the rigid body from the body storage and generates deletion notifications.
  */
 inline
-BodyStorage::Iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStorage& localStorage, BodyStorage::Iterator body )
+BodyStorage::iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStorage& localStorage, BodyStorage::iterator body )
 {
    using namespace walberla::pe::communication;
 
@@ -57,7 +57,7 @@ BodyStorage::Iterator removeAndNotify( Owner me, mpi::BufferSystem& bs, BodyStor
          WALBERLA_LOG_DETAIL( "__Notify registered process " << (*it) << " of deletion of body " << body->getSystemID() );
          mpi::SendBuffer& sb = bs.sendBuffer(it->rank_);
          if (sb.isEmpty()) sb << walberla::uint8_c(0);
-         packNotification(me, *it, sb, RigidBodyDeletionNotification( **body ));
+         packNotification(me, *it, sb, RigidBodyDeletionNotification( *body ));
       }
    }
 
diff --git a/src/pe/synchronization/SyncForces.h b/src/pe/synchronization/SyncForces.h
index 0bca535418797cfdfdf9f18979a169f607f80e87..aa83e65196722fd0fea23a262671ea97919de3ff 100644
--- a/src/pe/synchronization/SyncForces.h
+++ b/src/pe/synchronization/SyncForces.h
@@ -74,7 +74,7 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID )
 
          WALBERLA_LOG_DETAIL( "__Sending force contribution " << bodyIt->getForce() << ", " << bodyIt->getTorque() << " of body " <<
                               bodyIt->getSystemID() << " to owner block " << bodyIt->MPITrait.getOwner().blockID_ << ".\n");
-         packNotification(me, bodyIt->MPITrait.getOwner(), sb, RigidBodyForceNotification( *(*bodyIt) ) );
+         packNotification(me, bodyIt->MPITrait.getOwner(), sb, RigidBodyForceNotification( *bodyIt ) );
 
       }
 
@@ -135,7 +135,7 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID, BodyStorage& glo
       {
          if (it->hasInfiniteMass()) continue;
 
-         const Vec3 f( (*it)->getForce() ), tau( (*it)->getTorque() );
+         const Vec3 f( it->getForce() ), tau( it->getTorque() );
          reductionBuffer[i++] = f[0];
          reductionBuffer[i++] = f[1];
          reductionBuffer[i++] = f[2];
@@ -150,8 +150,8 @@ void reduceForces( BlockStorage& blocks, BlockDataID storageID, BodyStorage& glo
       for( auto it = globalBodyStorage.begin(); it != globalBodyStorage.end(); ++it )
       {
          if (it->hasInfiniteMass()) continue;
-         (*it)->setForce ( Vec3( reductionBuffer[i], reductionBuffer[i + 1], reductionBuffer[i + 2] ) );
-         (*it)->setTorque( Vec3( reductionBuffer[i + 3], reductionBuffer[i + 4], reductionBuffer[i + 5] ) );
+         it->setForce ( Vec3( reductionBuffer[i], reductionBuffer[i + 1], reductionBuffer[i + 2] ) );
+         it->setTorque( Vec3( reductionBuffer[i + 3], reductionBuffer[i + 4], reductionBuffer[i + 5] ) );
       }
    }
    WALBERLA_LOG_DETAIL( "Sync force on global bodies finished." );
@@ -198,7 +198,7 @@ void distributeForces( BlockStorage& blocks, BlockDataID storageID )
 
             WALBERLA_LOG_DETAIL( "__Sending force contribution " << bodyIt->getForce() << ", " << bodyIt->getTorque() << " of body " <<
                                  bodyIt->getSystemID() << " to shadow owner " << sownerIt->blockID_ << ".\n");
-            packNotification(me, *sownerIt, sb, RigidBodyForceNotification( *(*bodyIt) ) );
+            packNotification(me, *sownerIt, sb, RigidBodyForceNotification( *bodyIt ) );
          }
       }
 
diff --git a/src/pe/synchronization/SyncNextNeighbors.h b/src/pe/synchronization/SyncNextNeighbors.h
index 56da2bc958e39edf2994882fcc9e2b69fd5d2c77..63aa9a2081db232e11a8677cca8eec6253c7fd40 100644
--- a/src/pe/synchronization/SyncNextNeighbors.h
+++ b/src/pe/synchronization/SyncNextNeighbors.h
@@ -67,7 +67,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
       }
 
       const Vec3 gpos( body->getPosition() );
-      BodyID     b   ( *body );
+      BodyID     b   ( body.getBodyID() );
 
       if (body->isMarkedForDeletion())
       {
@@ -155,7 +155,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
             WALBERLA_LOG_DETAIL( "Sending deletion notifications for body " << body->getSystemID() << " due to outflow." );
 
             // Registered processes receive removal notification in the remove() routine.
-            //todelete.push_back( *body );
+            //todelete.push_back( body.getBodyID() );
             body = removeAndNotify( me, bs, localStorage, body );
 
             // Note: Attached shadow copies are not deleted here. Instead we rely on the deferred deletion since we no
@@ -189,8 +189,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
             b->setRemote( true );
 
             // Move body to shadow copy storage.
-            body = localStorage.release( body );
-            shadowStorage.add( b );
+            shadowStorage.add( localStorage.release( body ) );
 
             // Note: We cannot determine here whether we require the body since we do not have up to date shadow copies.
             // However, we will most likely have to keep the body since it typically still intersects the process subdomain.
diff --git a/src/pe/synchronization/SyncShadowOwners.h b/src/pe/synchronization/SyncShadowOwners.h
index e02cea958b435d39f54e749aa237c696cec6d8ca..cc0400d11d50f78597a9be5fd53666c84f386ae0 100644
--- a/src/pe/synchronization/SyncShadowOwners.h
+++ b/src/pe/synchronization/SyncShadowOwners.h
@@ -79,7 +79,7 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy
 
       for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); )
       {
-         BodyID b (*bodyIt);
+         BodyID b (bodyIt.getBodyID());
 
          if( !b->isCommunicating() && !syncNonCommunicatingBodies ) {
             ++bodyIt;
@@ -131,8 +131,7 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy
                b->setRemote( true );
 
                // Move body to shadow copy storage.
-               bodyIt = localStorage.release( bodyIt );
-               shadowStorage.add( b );
+               shadowStorage.add( localStorage.release( bodyIt ) );
 
                b->MPITrait.deregisterShadowOwner( owner );
 
@@ -220,7 +219,7 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r
 
       for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt)
       {
-         BodyID b (*bodyIt);
+         BodyID b (bodyIt.getBodyID());
 
          if( !b->isCommunicating() && !syncNonCommunicatingBodies ) continue;
 
@@ -256,7 +255,7 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r
       }
       for( auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); )
       {
-         BodyID b (*bodyIt);
+         BodyID b (bodyIt.getBodyID());
          WALBERLA_ASSERT(!b->isGlobal(), "Global body in ShadowStorage!");
          bool isInsideDomain = forest.getDomain().contains( b->getAABB(), -dx );
 
diff --git a/src/pe/utility/CreateWorld.cpp b/src/pe/utility/CreateWorld.cpp
index 3ede915c665701c38248f1a3e25d2b55552fca81..919840085ee8b298083a7fcafa13c51488c5fd9a 100644
--- a/src/pe/utility/CreateWorld.cpp
+++ b/src/pe/utility/CreateWorld.cpp
@@ -79,7 +79,7 @@ std::unique_ptr<SetupBlockForest> createSetupBlockForest(const math::AABB simula
       blocks[2] = 2;
    }
 
-   auto sforest = std::unique_ptr<SetupBlockForest>( new SetupBlockForest() );
+   auto sforest = std::make_unique<SetupBlockForest>( );
    sforest->addWorkloadMemorySUIDAssignmentFunction( blockforest::uniformWorkloadAndMemoryAssignment );
    sforest->addRefinementSelectionFunction( FixedRefinementLevelSelector(initialRefinementLevel) );
    sforest->init( simulationDomain, blocks[0], blocks[1], blocks[2], isPeriodic[0], isPeriodic[1], isPeriodic[2] );
@@ -103,7 +103,7 @@ shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain,
    }
 
    std::unique_ptr<SetupBlockForest> sforest( createSetupBlockForest( simulationDomain, blocks, isPeriodic, numberOfProcesses, initialRefinementLevel ));
-   return shared_ptr< BlockForest >( new BlockForest( uint_c( MPIManager::instance()->rank() ), *sforest, false ) );
+   return std::make_shared< BlockForest >( uint_c( MPIManager::instance()->rank() ), *sforest, false );
 }
 
 shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain,
@@ -142,13 +142,13 @@ shared_ptr<BlockForest> createBlockForest(const math::AABB simulationDomain,
 
    WALBERLA_LOG_INFO_ON_ROOT( "Production Run!" );
    WALBERLA_LOG_INFO_ON_ROOT( "Creating the block structure: loading from file \'" << sbffile << "\' ..." );
-   return shared_ptr< BlockForest >( new BlockForest( uint_c( MPIManager::instance()->rank() ), sbffile.c_str(), true, false ) );
+   return std::make_shared< BlockForest >( uint_c( MPIManager::instance()->rank() ), sbffile.c_str(), true, false );
 }
 
 
 shared_ptr<BlockForest> createBlockForestFromConfig(const Config::BlockHandle& mainConf)
 {
-   bool setupRun                 = mainConf.getParameter< bool >( "setupRun", true );
+   bool setupRun                 = mainConf.getParameter< bool >( "setupRun", false );
    Vec3 simulationCorner         = mainConf.getParameter<Vec3>("simulationCorner", Vec3(0, 0, 0));
    Vec3 simulationSize           = mainConf.getParameter<Vec3>("simulationDomain", Vec3(10, 10, 10));
    math::AABB simulationDomain   = math::AABB( simulationCorner, simulationCorner + simulationSize );
diff --git a/src/pe/utility/DestroyBody.h b/src/pe/utility/DestroyBody.h
index 189203fda04a9ed28db4049a2e1044ee8078bf39..20da0f1c86a8d84596e674adc1045b89c9b1ce13 100644
--- a/src/pe/utility/DestroyBody.h
+++ b/src/pe/utility/DestroyBody.h
@@ -49,7 +49,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s
    {
       for (auto bodyIt = globalStorage.begin(); bodyIt != globalStorage.end(); )
       {
-         if ( p(*bodyIt) )
+         if ( p(bodyIt.getBodyID()) )
          {
             bodyIt = globalStorage.remove( bodyIt );
          } else
@@ -68,7 +68,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s
          BodyStorage& localStorage = storage[StorageType::LOCAL];
          for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); )
          {
-            if ( p(*bodyIt) )
+            if ( p(bodyIt.getBodyID()) )
             {
                bodyIt = localStorage.remove( bodyIt );
             } else
@@ -82,7 +82,7 @@ void destroyBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID s
          BodyStorage& shadowStorage = storage[StorageType::SHADOW];
          for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); )
          {
-            if ( p(*bodyIt) )
+            if ( p(bodyIt.getBodyID()) )
             {
                bodyIt = shadowStorage.remove( bodyIt );
             } else
diff --git a/src/pe/utility/GetBody.cpp b/src/pe/utility/GetBody.cpp
index 31fc394cc8e5f3d30110fea8a342c9d639f43677..6d0b695f85915d2cae66ef9fb573420462b9a2ce 100644
--- a/src/pe/utility/GetBody.cpp
+++ b/src/pe/utility/GetBody.cpp
@@ -30,7 +30,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto
       auto bodyIt = globalStorage.find(sid);
       if (bodyIt != globalStorage.end())
       {
-         return *bodyIt;
+         return bodyIt.getBodyID();
       }
    }
 
@@ -44,7 +44,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto
          auto bodyIt = localStorage.find(sid);
          if (bodyIt != localStorage.end())
          {
-            return *bodyIt;
+            return bodyIt.getBodyID();
          }
       }
       if (storageSelect & StorageSelect::SHADOW)
@@ -53,7 +53,7 @@ BodyID getBody(BodyStorage& globalStorage, BlockStorage& blocks, BlockDataID sto
          auto bodyIt = shadowStorage.find(sid);
          if (bodyIt != shadowStorage.end())
          {
-            return *bodyIt;
+            return bodyIt.getBodyID();
          }
       }
    }
diff --git a/src/pe/vtk/BodyVtkOutput.cpp b/src/pe/vtk/BodyVtkOutput.cpp
index b2e154dc1248df49ad1a76db4fbf48814beb1137..6d13f3df3bc051fa85bfdb7e558d1d265f667cbd 100644
--- a/src/pe/vtk/BodyVtkOutput.cpp
+++ b/src/pe/vtk/BodyVtkOutput.cpp
@@ -44,14 +44,14 @@ std::vector< DefaultBodyVTKOutput::Attributes > DefaultBodyVTKOutput::getAttribu
 void DefaultBodyVTKOutput::configure()
 {
    bodies_.clear();
-   for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt )
+   for( const auto& block : blockStorage_ )
    {
 
-      const Storage& bs = *(blockIt->getData<const Storage>( storageID_ ));
+      const BodyStorage& bs = (*(block.getData<const Storage>( storageID_ )))[0];
 
-      for( auto it = bs[0].begin(); it != bs[0].end(); ++it )
+      for( const auto& body : bs )
       {
-         bodies_.push_back( *it );
+         bodies_.push_back( &body );
       }
    }
 }
diff --git a/src/pe/vtk/EllipsoidVtkOutput.cpp b/src/pe/vtk/EllipsoidVtkOutput.cpp
index 4ec85db3819595a1300a9999295d44ab91182b8d..816fb2028208731672f30f2cb8cb3e98dfadcdb0 100644
--- a/src/pe/vtk/EllipsoidVtkOutput.cpp
+++ b/src/pe/vtk/EllipsoidVtkOutput.cpp
@@ -47,16 +47,16 @@ void EllipsoidVtkOutput::configure()
    bodies_.clear();
    tensorGlyphs_.clear();
 
-   for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt )
+   for( auto& block : blockStorage_ )
    {
 
-      const Storage& bs = *(blockIt->getData<const Storage>( storageID_ ));
+      const BodyStorage& localStorage = (*(block.getData<const Storage>( storageID_ )))[0];
 
-      for( auto it = bs[0].begin(); it != bs[0].end(); ++it )
+      for( auto& body : localStorage )
       {
-         if (it->getTypeID() == Ellipsoid::getStaticTypeID())
+         if (body.getTypeID() == Ellipsoid::getStaticTypeID())
          {
-            auto ellipsoid = static_cast<ConstEllipsoidID> (*it);
+            auto ellipsoid = static_cast<ConstEllipsoidID> (&body);
             bodies_.push_back(ellipsoid);
 
             // compute tensor glyph for visualization with ParaView (tensorGlyph)
diff --git a/src/pe/vtk/EllipsoidVtkOutput.h b/src/pe/vtk/EllipsoidVtkOutput.h
index e12f91879e6aaf0d2eb3d74f04b5d5ab3103feea..680410dcea6377fa1eadd83f64664df7f1acb4ba 100644
--- a/src/pe/vtk/EllipsoidVtkOutput.h
+++ b/src/pe/vtk/EllipsoidVtkOutput.h
@@ -59,7 +59,7 @@ private:
 
    ConstBlockDataID storageID_;
    const BlockStorage & blockStorage_;
-   std::vector< ConstEllipsoidID > bodies_;
+   std::vector< Ellipsoid const * > bodies_;
    std::vector< std::array<real_t,6> > tensorGlyphs_;
 };
 
diff --git a/src/pe/vtk/SphereVtkOutput.cpp b/src/pe/vtk/SphereVtkOutput.cpp
index 90672a0f60d3ae642f87d21f325a5d3fcb992e9e..626685a43610f3c4cd205351f7b3835cb41a3655 100644
--- a/src/pe/vtk/SphereVtkOutput.cpp
+++ b/src/pe/vtk/SphereVtkOutput.cpp
@@ -49,49 +49,49 @@ std::vector< SphereVtkOutput::Attributes > SphereVtkOutput::getAttributes() cons
 void SphereVtkOutput::configure()
 {
    bodies_.clear();
-   for( auto blockIt = blockStorage_.begin(); blockIt != blockStorage_.end(); ++blockIt )
+   for( auto& block : blockStorage_ )
    {
 
-      const Storage& bs = *(blockIt->getData<const Storage>( storageID_ ));
+      const BodyStorage& localStorage = (*(block.getData<const Storage>( storageID_ )))[0];
 
-      for( auto it = bs[0].begin(); it != bs[0].end(); ++it )
+      for( auto& body : localStorage )
       {
-         if (it->getTypeID() == Sphere::getStaticTypeID() || it->getTypeID() == Squirmer::getStaticTypeID())
-            bodies_.push_back( static_cast<ConstSphereID> (*it) );
-         if (it->getTypeID() == Union<boost::tuple<Sphere> >::getStaticTypeID())
+         if (body.getTypeID() == Sphere::getStaticTypeID() || body.getTypeID() == Squirmer::getStaticTypeID())
+            bodies_.push_back( static_cast<Sphere const *> (&body) );
+         if (body.getTypeID() == Union<boost::tuple<Sphere> >::getStaticTypeID())
          {
-            auto un = static_cast<Union<boost::tuple<Sphere> > const * > (*it);
+            auto un = static_cast<Union<boost::tuple<Sphere> > const * > (&body);
             for( auto it2 = un->begin(); it2 != un->end(); ++it2 )
             {
                if (it2->getTypeID() == Sphere::getStaticTypeID())
-                  bodies_.push_back( static_cast<ConstSphereID> (*it2) );
+                  bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) );
             }
          }
-         if (it->getTypeID() == Union<boost::tuple<Squirmer> >::getStaticTypeID())
+         if (body.getTypeID() == Union<boost::tuple<Squirmer> >::getStaticTypeID())
          {
-            auto un = static_cast<Union<boost::tuple<Squirmer> > const * > (*it);
+            auto un = static_cast<Union<boost::tuple<Squirmer> > const * > (&body);
             for( auto it2 = un->begin(); it2 != un->end(); ++it2 )
             {
                if (it2->getTypeID() == Squirmer::getStaticTypeID())
-                  bodies_.push_back( static_cast<ConstSphereID> (*it2) );
+                  bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) );
             }
          }
-         if (it->getTypeID() == Union<boost::tuple<Sphere,Squirmer> >::getStaticTypeID())
+         if (body.getTypeID() == Union<boost::tuple<Sphere,Squirmer> >::getStaticTypeID())
          {
-            auto un = static_cast<Union<boost::tuple<Sphere,Squirmer> > const * > (*it);
+            auto un = static_cast<Union<boost::tuple<Sphere,Squirmer> > const * > (&body);
             for( auto it2 = un->begin(); it2 != un->end(); ++it2 )
             {
                if (it2->getTypeID() == Sphere::getStaticTypeID() || it2->getTypeID() == Squirmer::getStaticTypeID())
-                  bodies_.push_back( static_cast<ConstSphereID> (*it2) );
+                  bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) );
             }
          }
-         if (it->getTypeID() == Union<boost::tuple<Squirmer,Sphere> >::getStaticTypeID())
+         if (body.getTypeID() == Union<boost::tuple<Squirmer,Sphere> >::getStaticTypeID())
          {
-            auto un = static_cast<Union<boost::tuple<Squirmer,Sphere> > const * > (*it);
+            auto un = static_cast<Union<boost::tuple<Squirmer,Sphere> > const * > (&body);
             for( auto it2 = un->begin(); it2 != un->end(); ++it2 )
             {
                if (it2->getTypeID() == Sphere::getStaticTypeID() || it2->getTypeID() == Squirmer::getStaticTypeID())
-                  bodies_.push_back( static_cast<ConstSphereID> (*it2) );
+                  bodies_.push_back( static_cast<ConstSphereID> (it2.getBodyID()) );
             }
          }
       }
diff --git a/src/pe/vtk/SphereVtkOutput.h b/src/pe/vtk/SphereVtkOutput.h
index 238c1fa8e305fc95813ce798d841b7705b90f95b..1878795f32bab639db91289edf4318c57e019d5c 100644
--- a/src/pe/vtk/SphereVtkOutput.h
+++ b/src/pe/vtk/SphereVtkOutput.h
@@ -61,7 +61,7 @@ private:
 
    ConstBlockDataID storageID_;
    const BlockStorage & blockStorage_;
-   std::vector< ConstSphereID > bodies_;
+   std::vector< Sphere const * > bodies_;
 };
 
 
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h
index a318686d8865509b3597d3361852c51c42c1ffcc..c452f886443049220e2529456a8fc5673175bd98 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/AddedMassForceEvaluator.h
@@ -121,7 +121,7 @@ void AddedMassForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T >
 
       for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt )
       {
-         if(!dpmBodySelectorFct_(*bodyIt)) continue;
+         if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
          Vector3<real_t> forceOnFluid( real_t(0) );
 
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h
index 229be174ef1951b0e2601a65717457683c8d1467..7345398b7c123bd7aa83f658738a1d799dd209c5 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/BodyVelocityTimeDerivativeEvaluator.h
@@ -63,7 +63,7 @@ public:
       {
          for( auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
          {
-            if(!dpmBodySelectorFct_(*bodyIt)) continue;
+            if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
             bodyVelocityMap_.insert( std::pair<walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getLinearVel() ) );
          }
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h
index 33a2e7d76fa567bd754214a4ccba52280c31299e..17d3121898ec8e306502ffa55528c73fd9350282 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/InteractionForceEvaluator.h
@@ -136,7 +136,7 @@ void InteractionForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T
 
       for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt )
       {
-         if(!dpmBodySelectorFct_(*bodyIt)) continue;
+         if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
          Vector3<real_t> forceOnFluid( real_t(0) );
 
@@ -154,7 +154,7 @@ void InteractionForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T
 
          // evaluate drag force
          Vector3<real_t> bodyVelocity = bodyIt->getLinearVel();
-         real_t bodyDiameter = getSphereEquivalentDiameter( *(*bodyIt) );
+         real_t bodyDiameter = getSphereEquivalentDiameter( *bodyIt );
          real_t bodyVolume = bodyIt->getVolume();
          real_t fluidDensity( real_t(1) );
 
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h
index d04ca701ca8788abc87b424b4b9b3a3328109819..de8518349033f98cfddec3c1bd1f5678b440c151 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/LiftForceEvaluator.h
@@ -115,7 +115,7 @@ void LiftForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T >
 
       for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt )
       {
-         if(!dpmBodySelectorFct_(*bodyIt)) continue;
+         if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
          Vector3<real_t> forceOnFluid( real_t(0) );
 
@@ -123,7 +123,7 @@ void LiftForceEvaluator< FlagField_T, FieldInterpolator_T, Distributor_T >
          Vector3<real_t> bodyVelocity = bodyIt->getLinearVel();
 
          real_t fluidDensity( real_t(1) );
-         real_t bodyDiameter = getSphereEquivalentDiameter( *(*bodyIt) );
+         real_t bodyDiameter = getSphereEquivalentDiameter( *bodyIt );
 
          // interpolate fluid velocity and fluid curl to body position
          Vector3<real_t> fluidVelocity( real_t(0) );
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h
index e99d3e88f63befc5ef49a932eb395af4cad82a76..63723eaa49018c758a7052455cce4e628db3afb8 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/LubricationForceEvaluator.h
@@ -100,7 +100,7 @@ void LubricationForceEvaluator::operator ()()
          // lubrication forces for spheres
          if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() )
          {
-            pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It );
+            pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() );
 
             auto copyBody1It = body1It;
             // loop over all rigid bodies after current body1 to avoid double forces
@@ -109,7 +109,7 @@ void LubricationForceEvaluator::operator ()()
                // sphere-sphere lubrication
                if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() )
                {
-                  pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It );
+                  pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() );
                   treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() );
                }
             }
@@ -121,19 +121,19 @@ void LubricationForceEvaluator::operator ()()
       {
          if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() )
          {
-            pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It );
+            pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() );
 
             for (auto body2It = globalBodyStorage_->begin(); body2It != globalBodyStorage_->end(); ++body2It)
             {
                if ( body2It->getTypeID() == pe::Plane::getStaticTypeID() )
                {
                   // sphere-plane lubrication
-                  pe::PlaneID planeJ = static_cast<pe::PlaneID>( *body2It );
+                  pe::PlaneID planeJ = static_cast<pe::PlaneID>( body2It.getBodyID() );
                   treatLubricationSphrPlane( sphereI, planeJ );
                } else if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() )
                {
                   // sphere-sphere lubrication
-                  pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It );
+                  pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() );
                   treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() );
                }
             }
diff --git a/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h b/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h
index 1c83df74afc0eba7d192454f350932307f27bef4..586b51bc25d29259c632ed1bb76dcfc4cd08c43b 100644
--- a/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h
+++ b/src/pe_coupling/discrete_particle_methods/evaluators/SolidVolumeFractionFieldEvaluator.h
@@ -89,7 +89,7 @@ public:
       // assign the local bodies' volume to the cell, depending on the chosen Distributor_T
       for( auto bodyIt = pe::LocalBodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt )
       {
-         if(!dpmBodySelectorFct_(*bodyIt)) continue;
+         if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
          real_t bodyVolume = bodyIt->getVolume();
          const Vector3<real_t> bodyPosition = bodyIt->getPosition();
diff --git a/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h b/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h
index 75ebeef5b370820e5f306b06c0f954c45b7dd16e..9ffbad829435d7797e2727455005d769d752344c 100644
--- a/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h
+++ b/src/pe_coupling/discrete_particle_methods/utility/BodyVelocityInitializer.h
@@ -82,7 +82,7 @@ public:
 
          for( auto bodyIt = pe::LocalBodyIterator::begin(*blockIt, bodyStorageID_); bodyIt != pe::LocalBodyIterator::end(); ++bodyIt )
          {
-            if(!dpmBodySelectorFct_(*bodyIt)) continue;
+            if(!dpmBodySelectorFct_(bodyIt.getBodyID())) continue;
 
             Vector3<real_t> forceOnFluid( real_t(0) );
 
diff --git a/src/pe_coupling/mapping/BodyMapping.h b/src/pe_coupling/mapping/BodyMapping.h
index 4af2e9d3195ebaddc0ce3a6a08108c2c4d28d10d..48f05c2ee0a25b28f492ae927b052d9b9dbdc97d 100644
--- a/src/pe_coupling/mapping/BodyMapping.h
+++ b/src/pe_coupling/mapping/BodyMapping.h
@@ -106,14 +106,14 @@ void mapBodies( StructuredBlockStorage & blockStorage, const BlockDataID & bound
 
       for( auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct(*bodyIt))
-            mapBody<BoundaryHandling_T>( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, obstacle );
+         if( mappingBodySelectorFct(bodyIt.getBodyID()))
+            mapBody<BoundaryHandling_T>( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, obstacle );
       }
 
       for( auto bodyIt = globalBodyStorage.begin(); bodyIt != globalBodyStorage.end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct(*bodyIt))
-            mapBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, obstacle );
+         if( mappingBodySelectorFct(bodyIt.getBodyID()))
+            mapBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, obstacle );
       }
    }
 }
diff --git a/src/pe_coupling/momentum_exchange_method/BodyMapping.h b/src/pe_coupling/momentum_exchange_method/BodyMapping.h
index 7651386b613b476a00d5070c1550884930a003f9..c44bc77e6a525f78c41f91127bac7def5b59096a 100644
--- a/src/pe_coupling/momentum_exchange_method/BodyMapping.h
+++ b/src/pe_coupling/momentum_exchange_method/BodyMapping.h
@@ -102,13 +102,13 @@ public:
 
       for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct_(*bodyIt) )
-            mapBodyAndUpdateMapping(*bodyIt, block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz);
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()) )
+            mapBodyAndUpdateMapping(bodyIt.getBodyID(), block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz);
       }
       for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt)
       {
-         if( mappingBodySelectorFct_(*bodyIt))
-            mapBodyAndUpdateMapping(*bodyIt, block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz);
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()))
+            mapBodyAndUpdateMapping(bodyIt.getBodyID(), block, boundaryHandling, flagField , bodyField, obstacle, formerObstacle, dx, dy, dz);
       }
    }
 
@@ -273,13 +273,13 @@ void mapMovingBodies( StructuredBlockStorage & blockStorage, const BlockDataID &
    {
       for (auto bodyIt = pe::BodyIterator::begin(*blockIt, bodyStorageID); bodyIt != pe::BodyIterator::end(); ++bodyIt)
       {
-         if( mappingBodySelectorFct(*bodyIt))
-            mapMovingBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle );
+         if( mappingBodySelectorFct(bodyIt.getBodyID()))
+            mapMovingBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle );
       }
       for( auto bodyIt = globalBodyStorage.begin(); bodyIt != globalBodyStorage.end(); ++bodyIt)
       {
-         if( mappingBodySelectorFct(*bodyIt))
-            mapMovingBody< BoundaryHandling_T >( *bodyIt, *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle );
+         if( mappingBodySelectorFct(bodyIt.getBodyID()))
+            mapMovingBody< BoundaryHandling_T >( bodyIt.getBodyID(), *blockIt, blockStorage, boundaryHandlingID, bodyFieldID, obstacle );
       }
    }
 }
diff --git a/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h b/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h
index b23b33c83ef134373c739a7234c75fbce4073363..05fee404db1b0cb47a1d1a28216ee7de481dca1d 100644
--- a/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h
+++ b/src/pe_coupling/momentum_exchange_method/boundary/CurvedLinear.h
@@ -71,6 +71,12 @@ class CurvedLinear : public Boundary< typename FlagField_T::flag_t >
 
 public:
 
+   static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& )
+   {
+      WALBERLA_ABORT( "A CurvedLinear boundary cannot be created from a config file" );
+      return make_shared<BoundaryConfiguration>();
+   }
+
    inline CurvedLinear( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField,
                         BodyField_T * const bodyField,  const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block );
 
diff --git a/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h b/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h
index fa0b22852f6997a4ed9a4e7801ccc48222405c98..ea6fe8b665bcc9dfb7aab137774cfee05680a545 100644
--- a/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h
+++ b/src/pe_coupling/momentum_exchange_method/boundary/CurvedQuadratic.h
@@ -81,6 +81,12 @@ class CurvedQuadratic : public Boundary< typename FlagField_T::flag_t >
 
 public:
 
+   static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& )
+   {
+      WALBERLA_ABORT( "A CurvedQuadratic boundary cannot be created from a config file" );
+      return make_shared<BoundaryConfiguration>();
+   }
+
    inline CurvedQuadratic( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField,
                            BodyField_T * const bodyField,  const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block,
                            PDFField_T * const pdfFieldPreCollision );
diff --git a/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h b/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h
index cfe78d575837e17f1f6adc63179bf48a5a3ab93b..0d7af9d9ae3f9817147bbfdf4ed294c8f85ac848 100644
--- a/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h
+++ b/src/pe_coupling/momentum_exchange_method/boundary/SimpleBB.h
@@ -67,6 +67,12 @@ class SimpleBB : public Boundary< typename FlagField_T::flag_t >
 
 public:
 
+   static shared_ptr<BoundaryConfiguration> createConfiguration( const Config::BlockHandle& )
+   {
+      WALBERLA_ABORT( "A SimpleBB boundary cannot be created from a config file" );
+      return make_shared<BoundaryConfiguration>();
+   }
+
    inline SimpleBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField_T * const pdfField, const FlagField_T * const flagField,
                       BodyField * const bodyField,  const flag_t domain, const StructuredBlockStorage & blockStorage, const IBlock & block );
 
diff --git a/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h b/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h
index d21808bb3cc8bae4084ea24bff84b6051dd30253..808fc089f1038092a5a54460f5e6bee46eea3e12 100644
--- a/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h
+++ b/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h
@@ -163,18 +163,18 @@ void PDFReconstruction< LatticeModel_T, BoundaryHandling_T, Reconstructer_T >
 
       for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( !movingBodySelectorFct_(*bodyIt) )
+         if( !movingBodySelectorFct_(bodyIt.getBodyID()) )
             continue;
 
-         CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude );
+         CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude );
          reconstructPDFsInCells(cellBB, block, flagField, formerObstacle );
       }
       for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         if( !movingBodySelectorFct_(*bodyIt) )
+         if( !movingBodySelectorFct_(bodyIt.getBodyID()) )
             continue;
 
-         CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude );
+         CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude );
          reconstructPDFsInCells(cellBB, block, flagField, formerObstacle );
       }
    }
@@ -191,18 +191,18 @@ void PDFReconstruction< LatticeModel_T, BoundaryHandling_T, Reconstructer_T >
 
       for( auto bodyIt = pe::BodyIterator::begin(*block, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( !movingBodySelectorFct_(*bodyIt) )
+         if( !movingBodySelectorFct_(bodyIt.getBodyID()) )
             continue;
 
-         CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude );
+         CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude );
          updateFlags(cellBB, boundaryHandling, flagField, bodyField, formerObstacle, fluid);
       }
       for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         if( !movingBodySelectorFct_(*bodyIt) )
+         if( !movingBodySelectorFct_(bodyIt.getBodyID()) )
             continue;
 
-         CellInterval cellBB = getCellBB( *bodyIt, *block, *blockStorage_, numberOfGhostLayersToInclude );
+         CellInterval cellBB = getCellBB( bodyIt.getBodyID(), *block, *blockStorage_, numberOfGhostLayersToInclude );
          updateFlags(cellBB, boundaryHandling, flagField, bodyField, formerObstacle, fluid);
       }
    }
diff --git a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
index 9f28d42e6bd41f2226766c3e6b88bb8ad0b350ec..1a387105bd936ff7437c0d4b6cd102aecda40d0b 100644
--- a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
+++ b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
@@ -178,18 +178,18 @@ void BodyAndVolumeFractionMapping::initialize()
 
       for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct_(*bodyIt) )
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()) )
          {
-            mapPSMBodyAndVolumeFraction( *bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ );
+            mapPSMBodyAndVolumeFraction( bodyIt.getBodyID(), *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ );
             lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) );
          }
       }
 
       for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct_(*bodyIt) )
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()) )
          {
-            mapPSMBodyAndVolumeFraction(*bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_);
+            mapPSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_);
             lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) );
          }
       }
@@ -207,17 +207,17 @@ void BodyAndVolumeFractionMapping::update()
 
       for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct_(*bodyIt) )
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()) )
          {
-            updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
+            updatePSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
          }
       }
 
       for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         if( mappingBodySelectorFct_(*bodyIt) )
+         if( mappingBodySelectorFct_(bodyIt.getBodyID()) )
          {
-            updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
+            updatePSMBodyAndVolumeFraction(bodyIt.getBodyID(), *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
          }
       }
 
diff --git a/src/pe_coupling/utility/LubricationCorrection.h b/src/pe_coupling/utility/LubricationCorrection.h
index c318c66c6e42b3a3bdb3cafc50854b8f82c60569..4a5afa830d09352ff53ae87c69e88c96c7533eae 100644
--- a/src/pe_coupling/utility/LubricationCorrection.h
+++ b/src/pe_coupling/utility/LubricationCorrection.h
@@ -89,7 +89,7 @@ void LubricationCorrection::operator ()()
          // lubrication forces for spheres
          if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() )
          {
-            pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It );
+            pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() );
 
             auto copyBody1It = body1It;
             // loop over all rigid bodies after current body1 to avoid double forces
@@ -98,7 +98,7 @@ void LubricationCorrection::operator ()()
                // sphere-sphere lubrication
                if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() )
                {
-                  pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It );
+                  pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() );
                   treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() );
                }
             }
@@ -110,19 +110,19 @@ void LubricationCorrection::operator ()()
       {
          if ( body1It->getTypeID() == pe::Sphere::getStaticTypeID() )
          {
-            pe::SphereID sphereI = static_cast<pe::SphereID> ( *body1It );
+            pe::SphereID sphereI = static_cast<pe::SphereID> ( body1It.getBodyID() );
 
             for (auto body2It = globalBodyStorage_->begin(); body2It != globalBodyStorage_->end(); ++body2It)
             {
                if ( body2It->getTypeID() == pe::Plane::getStaticTypeID() )
                {
                   // sphere-plane lubrication
-                  pe::PlaneID planeJ = static_cast<pe::PlaneID>( *body2It );
+                  pe::PlaneID planeJ = static_cast<pe::PlaneID>( body2It.getBodyID() );
                   treatLubricationSphrPlane( sphereI, planeJ );
                } else if ( body2It->getTypeID() == pe::Sphere::getStaticTypeID() )
                {
                   // sphere-sphere lubrication
-                  pe::SphereID sphereJ = static_cast<pe::SphereID>( *body2It );
+                  pe::SphereID sphereJ = static_cast<pe::SphereID>( body2It.getBodyID() );
                   treatLubricationSphrSphr( sphereI, sphereJ, blockIt->getAABB() );
                }
             }
diff --git a/src/postprocessing/sqlite/SQLite.cpp b/src/postprocessing/sqlite/SQLite.cpp
index 049b5ed8b59144abecadc77620e8a097376d0f66..e83aa46e18a0627452791efb16568d07e07efcb6 100644
--- a/src/postprocessing/sqlite/SQLite.cpp
+++ b/src/postprocessing/sqlite/SQLite.cpp
@@ -34,43 +34,43 @@ namespace walberla {
 namespace postprocessing {
 
 
-   SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout )
-      : valid_(true), dbHandle_(NULL), file_( dbFile )
-   {
-      static const char * CREATE_RUN_TABLE =
-           "CREATE TABLE IF NOT EXISTS runs ("
-           " runId     INTEGER PRIMARY KEY, "
-           " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, "
-           " uuid      STRING );" ;
-
-      // Create tables if it does not exist
-      int retVal = sqlite3_open( file_.c_str(), &dbHandle_ );
-      if ( retVal != SQLITE_OK ) {
-         WALBERLA_LOG_WARNING( "Failed to open sqlite3 file." << dbFile );
-         valid_ = false;
-         return;
-      }
+SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout )
+   : valid_(true), dbHandle_(NULL), file_( dbFile )
+{
+   static const char * CREATE_RUN_TABLE =
+         "CREATE TABLE IF NOT EXISTS runs ("
+         " runId     INTEGER PRIMARY KEY, "
+         " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, "
+         " uuid      STRING );" ;
+
+   // Create tables if it does not exist
+   int retVal = sqlite3_open( file_.c_str(), &dbHandle_ );
+   if ( retVal != SQLITE_OK ) {
+      WALBERLA_LOG_WARNING( "Failed to open sqlite3 file." << dbFile );
+      valid_ = false;
+      return;
+   }
 
-      sqlite3_busy_timeout( dbHandle_, busyTimeout*1000 );
-      sqlite3_exec( dbHandle_, "PRAGMA foreign_keys = ON;",0,0,0 );
-      sqlite3_exec( dbHandle_, CREATE_RUN_TABLE, 0,0,0);
+   sqlite3_busy_timeout( dbHandle_, busyTimeout*1000 );
+   sqlite3_exec( dbHandle_, "PRAGMA foreign_keys = ON;",0,0,0 );
+   sqlite3_exec( dbHandle_, CREATE_RUN_TABLE, 0,0,0);
 
-      static const char* UPDATE_RUN_TABLE_CMD = "ALTER TABLE runs ADD COLUMN uuid STRING;";
-      sqlite3_exec( dbHandle_, UPDATE_RUN_TABLE_CMD, 0, 0, 0 );
+   static const char* UPDATE_RUN_TABLE_CMD = "ALTER TABLE runs ADD COLUMN uuid STRING;";
+   sqlite3_exec( dbHandle_, UPDATE_RUN_TABLE_CMD, 0, 0, 0 );
 
-   }
+}
 
 
-   SQLiteDB::~SQLiteDB ()
-   {
-      if ( valid_ )
-         sqlite3_close( dbHandle_ );
-   }
+SQLiteDB::~SQLiteDB ()
+{
+   if ( valid_ )
+      sqlite3_close( dbHandle_ );
+}
 
 
 
-   //*******************************************************************************************************************
-   /*! Store information about a simulation run into a Sqlite3 Database
+//*******************************************************************************************************************
+/*! Store information about a simulation run into a Sqlite3 Database
    *
    *  The generated database is called "runs". The columns of the table are the keys of the given maps.
    *  If a column does not yet exist, it is appended to the database. The entries that have no value in this column
@@ -80,152 +80,152 @@ namespace postprocessing {
    *  \param *Properties  Map of column names to value
    *  \returns            The primary key of the inserted data set.
    */
-   //*******************************************************************************************************************
-   template<typename IntType>
-   uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
-                        const map<string, IntType> & integerProperties,
-                        const map<string, string > & stringProperties,
-                        const map<string, double > & realProperties )
+//*******************************************************************************************************************
+template<typename IntType>
+uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
+                     const map<string, IntType> & integerProperties,
+                     const map<string, string > & stringProperties,
+                     const map<string, double > & realProperties )
+{
+   WALBERLA_ASSERT_NOT_NULLPTR( dbHandle );
+
+   sqlite3_exec( dbHandle, "BEGIN;",0,0,0 );
+
+   string insertRunCommand = "INSERT INTO runs (timestamp, uuid ";
+   std::stringstream values;
+   auto uuid = boost::uuids::random_generator()();
+   values << " VALUES ( CURRENT_TIMESTAMP, \"" << uuid << "\" ";
+   // Add columns for integer properties
+   for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i )
    {
-      WALBERLA_ASSERT_NOT_NULLPTR( dbHandle );
+      insertRunCommand += "," + i->first;
+      values  << ", " << i->second;
+      string command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+   }
 
-      sqlite3_exec( dbHandle, "BEGIN;",0,0,0 );
+   // Add columns for string properties
+   for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
+   {
+      insertRunCommand += "," + i->first;
+      values << ", " << "\"" << i->second << "\"";
+      string command = "ALTER TABLE runs ADD COLUMN " + i->first + " TEXT ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
 
-      string insertRunCommand = "INSERT INTO runs (timestamp, uuid ";
-      std::stringstream values;
-      auto uuid = boost::uuids::random_generator()();
-      values << " VALUES ( CURRENT_TIMESTAMP, \"" << uuid << "\" ";
-      // Add columns for integer properties
-      for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i )
-      {
-         insertRunCommand += "," + i->first;
-         values  << ", " << i->second;
-         string command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER ";
-         sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
-      }
+   }
 
-      // Add columns for string properties
-      for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
+   // Add columns for real_t properties
+   for ( auto i = realProperties.begin(); i != realProperties.end(); ++i )
+   {
+      if( math::finite( i->second ) )
       {
          insertRunCommand += "," + i->first;
-         values << ", " << "\"" << i->second << "\"";
-         string command = "ALTER TABLE runs ADD COLUMN " + i->first + " TEXT ";
-         sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
-
+         values << ", " << i->second;
+         string command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE ";
+         sqlite3_exec( dbHandle, command.c_str(), 0, 0, 0 ); // ignore errors (column can exist already)
       }
-
-      // Add columns for real_t properties
-       for ( auto i = realProperties.begin(); i != realProperties.end(); ++i )
-       {
-          if( math::finite( i->second ) )
-          {
-             insertRunCommand += "," + i->first;
-             values << ", " << i->second;
-             string command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE ";
-             sqlite3_exec( dbHandle, command.c_str(), 0, 0, 0 ); // ignore errors (column can exist already)
-          }
-          else
-          {
-             WALBERLA_LOG_WARNING( "Skipping column \"" << i->first << "\" while inserting a row into the run table of the "
-                                   "sqlite3 database \"" << filename << "\" due to non-finite value \"" << i->second << "\"." );
-          }
-       }
-
-      // Add columns for global state selectors
-      for( auto i = uid::globalState().begin(); i != uid::globalState().end(); ++i )
+      else
       {
-         insertRunCommand += "," + i->getIdentifier();
-         values << " ,1";
-         // no boolean in sqlite3, use integer instead
-         string command = "ALTER TABLE runs ADD COLUMN " + i->getIdentifier() + " INTEGER ";
-         sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+         WALBERLA_LOG_WARNING( "Skipping column \"" << i->first << "\" while inserting a row into the run table of the "
+                                                                   "sqlite3 database \"" << filename << "\" due to non-finite value \"" << i->second << "\"." );
       }
+   }
 
-      insertRunCommand += " )  ";
-      values << "); ";
-      insertRunCommand += values.str();
-
-      int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 );
-      if ( ret != SQLITE_OK) {
-         WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
-      }
-      uint_t generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) );
+   // Add columns for global state selectors
+   for( auto i = uid::globalState().begin(); i != uid::globalState().end(); ++i )
+   {
+      insertRunCommand += "," + i->getIdentifier();
+      values << " ,1";
+      // no boolean in sqlite3, use integer instead
+      string command = "ALTER TABLE runs ADD COLUMN " + i->getIdentifier() + " INTEGER ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+   }
 
-      sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 );
+   insertRunCommand += " )  ";
+   values << "); ";
+   insertRunCommand += values.str();
 
-      return generatedPrimaryKey;
+   int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 );
+   if ( ret != SQLITE_OK) {
+      WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
    }
+   uint_t generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) );
+
+   sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 );
 
-   //*******************************************************************************************************************
-   /*! Stores information in another table, referencing the "run" table
+   return generatedPrimaryKey;
+}
+
+//*******************************************************************************************************************
+/*! Stores information in another table, referencing the "run" table
    *
    * \param runId       result of storeRun() member function, primary key of the run to store information for
    * \param tableName   name of the table where the information is stored in
    *                    is created if it does not yet exist
    * \param *Properties Map of column names to value
    */
-   //*******************************************************************************************************************
-   template<typename IntType>
-   void storeAdditionalRunInfoImpl( sqlite3 * dbHandle,
-                                    uint_t runId, const std::string & tableName,
-                                    const map<string, IntType> & integerProperties,
-                                    const map<string, string > & stringProperties ,
-                                    const map<string, double > & realProperties )
+//*******************************************************************************************************************
+template<typename IntType>
+void storeAdditionalRunInfoImpl( sqlite3 * dbHandle,
+                                 uint_t runId, const std::string & tableName,
+                                 const map<string, IntType> & integerProperties,
+                                 const map<string, string > & stringProperties ,
+                                 const map<string, double > & realProperties )
+{
+   sqlite3_exec( dbHandle, "BEGIN;",0,0,0 );
+   std::string CREATE_TABLE =
+         "CREATE TABLE IF NOT EXISTS " + tableName +
+         " (runId     INTEGER, "
+         " FOREIGN KEY (runId) REFERENCES runs(runId) "
+         " );" ;
+
+   sqlite3_exec( dbHandle, CREATE_TABLE.c_str(), 0,0,0);
+
+   string insertRunCommand = "INSERT INTO " + tableName + "( runId";
+   std::stringstream values;
+   values << " VALUES (  " << runId;
+   // Add columns for integer properties
+   for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i )
    {
-      sqlite3_exec( dbHandle, "BEGIN;",0,0,0 );
-      std::string CREATE_TABLE =
-           "CREATE TABLE IF NOT EXISTS " + tableName +
-           " (runId     INTEGER, "
-           " FOREIGN KEY (runId) REFERENCES runs(runId) "
-           " );" ;
-
-      sqlite3_exec( dbHandle, CREATE_TABLE.c_str(), 0,0,0);
-
-      string insertRunCommand = "INSERT INTO " + tableName + "( runId";
-      std::stringstream values;
-      values << " VALUES (  " << runId;
-      // Add columns for integer properties
-      for ( auto i = integerProperties.begin(); i != integerProperties.end(); ++i )
-      {
-         insertRunCommand += "," + i->first;
-         values  << ", " << i->second;
-         string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER ";
-         sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
-      }
+      insertRunCommand += "," + i->first;
+      values  << ", " << i->second;
+      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+   }
 
-      // Add columns for string properties
-      for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
-      {
-         insertRunCommand += "," + i->first;
-         values << ", " << "\"" << i->second << "\"";
-         string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " TEXT ";
-         sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+   // Add columns for string properties
+   for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
+   {
+      insertRunCommand += "," + i->first;
+      values << ", " << "\"" << i->second << "\"";
+      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " TEXT ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
 
-      }
+   }
 
-      // Add columns for real_t properties
-       for ( auto i = realProperties.begin(); i != realProperties.end(); ++i )
-       {
-          insertRunCommand += "," + i->first;
-          values << ", " << i->second ;
-          string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " DOUBLE ";
-          sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
-       }
-
-      insertRunCommand += " )  ";
-      values << "); ";
-      insertRunCommand += values.str();
-
-      int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 );
-      if ( ret != SQLITE_OK) {
-         WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
-      }
-      sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 );
+   // Add columns for real_t properties
+   for ( auto i = realProperties.begin(); i != realProperties.end(); ++i )
+   {
+      insertRunCommand += "," + i->first;
+      values << ", " << i->second ;
+      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " DOUBLE ";
+      sqlite3_exec ( dbHandle, command.c_str(), 0,0,0 ); // ignore errors (column can exist already)
+   }
+
+   insertRunCommand += " )  ";
+   values << "); ";
+   insertRunCommand += values.str();
+
+   int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), 0, 0, 0 );
+   if ( ret != SQLITE_OK) {
+      WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
    }
+   sqlite3_exec( dbHandle, "END TRANSACTION;",0,0,0 );
+}
 
 
-   //*******************************************************************************************************************
-   /*! Store information about a simulation run into a Sqlite3 Database
+//*******************************************************************************************************************
+/*! Store information about a simulation run into a Sqlite3 Database
    *
    *  The generated database is called "runs". The columns of the table are the keys of the given maps.
    *  If a column does not yet exist, it is appended to the database. The entries that have no value in this column
@@ -235,52 +235,52 @@ namespace postprocessing {
    *  \param *Properties  Map of column names to value
    *  \returns            The primary key of the inserted data set.
    */
-   //*******************************************************************************************************************
-   uint_t SQLiteDB::storeRun( const map<string, int>     & integerProperties,
-                              const map<string, string > & stringProperties,
-                              const map<string, double > & realProperties )
-   {
-      return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties);
-   }
-   /// \see storeRun
-   uint_t SQLiteDB::storeRun( const map<string, int64_t> & integerProperties,
-                              const map<string, string > & stringProperties,
-                              const map<string, double > & realProperties )
-   {
-      return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties);
-   }
-
-
-
-   //*******************************************************************************************************************
-   /*! Stores information in another table, referencing the "run" table
+//*******************************************************************************************************************
+uint_t SQLiteDB::storeRun( const map<string, int>     & integerProperties,
+                           const map<string, string > & stringProperties,
+                           const map<string, double > & realProperties )
+{
+   return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties);
+}
+/// \see storeRun
+uint_t SQLiteDB::storeRun( const map<string, int64_t> & integerProperties,
+                           const map<string, string > & stringProperties,
+                           const map<string, double > & realProperties )
+{
+   return storeRunImpl(dbHandle_, file_, integerProperties, stringProperties, realProperties);
+}
+
+
+
+//*******************************************************************************************************************
+/*! Stores information in another table, referencing the "run" table
    *
    * \param runId       result of storeRun() member function, primary key of the run to store information for
    * \param tableName   name of the table where the information is stored in
    *                    is created if it does not yet exist
    * \param *Properties Map of column names to value
    */
-   //*******************************************************************************************************************
-   void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
-                                          const map<string, int>     & integerProperties,
-                                          const map<string, string > & stringProperties ,
-                                          const map<string, double > & realProperties )
-   {
-      return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties);
-   }
-   /// \see storeAdditionalRunInfo
-   void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
-                                          const map<string, int64_t> & integerProperties,
-                                          const map<string, string > & stringProperties ,
-                                          const map<string, double > & realProperties )
-   {
-      return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties);
-   }
-
-
-
-   //*******************************************************************************************************************
-   /*! Stores a TimingPool in a Sqlite3 Database, and links it to a run
+//*******************************************************************************************************************
+void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
+                                       const map<string, int>     & integerProperties,
+                                       const map<string, string > & stringProperties ,
+                                       const map<string, double > & realProperties )
+{
+   return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties);
+}
+/// \see storeAdditionalRunInfo
+void SQLiteDB::storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
+                                       const map<string, int64_t> & integerProperties,
+                                       const map<string, string > & stringProperties ,
+                                       const map<string, double > & realProperties )
+{
+   return storeAdditionalRunInfoImpl( dbHandle_, runId, tableName, integerProperties, stringProperties, realProperties);
+}
+
+
+
+//*******************************************************************************************************************
+/*! Stores a TimingPool in a Sqlite3 Database, and links it to a run
    *
    * The generated table is called "timingPools"
    *
@@ -288,16 +288,16 @@ namespace postprocessing {
    * \param tp      the TimingPool to store
    * \param name    name of the timing pool ( as written to database column )
    */
-   //*******************************************************************************************************************
-   void SQLiteDB::storeTimingPool ( uint_t runId,
-                                    const WcTimingPool & tp,
-                                    const std::string & timingPoolName )
-   {
-      sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 );
+//*******************************************************************************************************************
+void SQLiteDB::storeTimingPool ( uint_t runId,
+                                 const WcTimingPool & tp,
+                                 const std::string & timingPoolName )
+{
+   sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 );
 
-      assert ( timingPoolName.length() > 0 && timingPoolName.length() < 255 );
+   assert ( timingPoolName.length() > 0 && timingPoolName.length() < 255 );
 
-      static const char * CREATE_TIMINGPOOL_TABLE =
+   static const char * CREATE_TIMINGPOOL_TABLE =
          "CREATE TABLE IF NOT EXISTS timingPool ("
          " runId       INTEGER, "
          " name        VARCHAR(255),"
@@ -312,47 +312,47 @@ namespace postprocessing {
          " );" ;
 
 
-      static const char * INSERT_STATEMENT =
-                " INSERT INTO timingPool (runId,name,sweep,average,min,max,count,variance,percentage) "
-                " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+   static const char * INSERT_STATEMENT =
+         " INSERT INTO timingPool (runId,name,sweep,average,min,max,count,variance,percentage) "
+         " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? )";
 
-      sqlite3_exec( dbHandle_, CREATE_TIMINGPOOL_TABLE, 0,0,0 );
+   sqlite3_exec( dbHandle_, CREATE_TIMINGPOOL_TABLE, 0,0,0 );
 
-      sqlite3_stmt *stmt = NULL;
-      auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 );
-      if ( retVal != SQLITE_OK ) {
-         WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement." << file_ );
-         return;
-      }
+   sqlite3_stmt *stmt = NULL;
+   auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 );
+   if ( retVal != SQLITE_OK ) {
+      WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement." << file_ );
+      return;
+   }
 
 
-      double totalTime = 0;
-      for ( auto i = tp.begin(); i != tp.end(); ++i )
-         totalTime += i->second.total();
+   double totalTime = 0;
+   for ( auto i = tp.begin(); i != tp.end(); ++i )
+      totalTime += i->second.total();
 
 
-      for ( auto i = tp.begin(); i != tp.end(); ++i )
-      {
-         sqlite3_bind_int64 ( stmt, 1, int64_c(runId) );
-         sqlite3_bind_text  ( stmt, 2, timingPoolName.c_str() , -1, SQLITE_STATIC );
-         sqlite3_bind_text  ( stmt, 3, i->first.c_str() , -1, SQLITE_STATIC );
-         sqlite3_bind_double( stmt, 4, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.average() ) ) );
-         sqlite3_bind_double( stmt, 5, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.min() ) ) );
-         sqlite3_bind_double( stmt, 6, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.max() ) ) );
-         sqlite3_bind_int64 ( stmt, 7, int64_c   ( i->second.getCounter() ));
-         sqlite3_bind_double( stmt, 8, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.variance() ) ) );
-         sqlite3_bind_double( stmt, 9, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.total() / totalTime ) ) );
-
-         sqlite3_step ( stmt );  // execute statement
-         sqlite3_reset ( stmt ); // undo binding
-      }
-      sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 );
+   for ( auto i = tp.begin(); i != tp.end(); ++i )
+   {
+      sqlite3_bind_int64 ( stmt, 1, int64_c(runId) );
+      sqlite3_bind_text  ( stmt, 2, timingPoolName.c_str() , -1, SQLITE_STATIC );
+      sqlite3_bind_text  ( stmt, 3, i->first.c_str() , -1, SQLITE_STATIC );
+      sqlite3_bind_double( stmt, 4, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.average() ) ) );
+      sqlite3_bind_double( stmt, 5, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.min() ) ) );
+      sqlite3_bind_double( stmt, 6, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.max() ) ) );
+      sqlite3_bind_int64 ( stmt, 7, int64_c   ( i->second.getCounter() ));
+      sqlite3_bind_double( stmt, 8, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.variance() ) ) );
+      sqlite3_bind_double( stmt, 9, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.total() / totalTime ) ) );
 
-      sqlite3_finalize( stmt ); // free prepared statement
+      sqlite3_step ( stmt );  // execute statement
+      sqlite3_reset ( stmt ); // undo binding
    }
+   sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 );
+
+   sqlite3_finalize( stmt ); // free prepared statement
+}
 
-   //*******************************************************************************************************************
-   /*! Stores a TimingTree in a Sqlite3 Database, and links it to a run
+//*******************************************************************************************************************
+/*! Stores a TimingTree in a Sqlite3 Database, and links it to a run
    *
    * The generated table is called "timingTree"
    *
@@ -360,16 +360,16 @@ namespace postprocessing {
    * \param tt      the TimingTree to store
    * \param name    name of the timing tree ( as written to database column )
    */
-   //*******************************************************************************************************************
-   void SQLiteDB::storeTimingTree ( uint_t runId,
-                                    const WcTimingTree & tt,
-                                    const std::string & timingTreeName )
-   {
-      sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 );
+//*******************************************************************************************************************
+void SQLiteDB::storeTimingTree ( uint_t runId,
+                                 const WcTimingTree & tt,
+                                 const std::string & timingTreeName )
+{
+   sqlite3_exec( dbHandle_, "BEGIN;",0,0,0 );
 
-      assert ( timingTreeName.length() > 0 && timingTreeName.length() < 255 );
+   assert ( timingTreeName.length() > 0 && timingTreeName.length() < 255 );
 
-      static const char * CREATE_TIMINGTREE_TABLE =
+   static const char * CREATE_TIMINGTREE_TABLE =
          "CREATE TABLE IF NOT EXISTS timingTree ("
          " id          INTEGER PRIMARY KEY, "
          " runId       INTEGER, "
@@ -385,110 +385,134 @@ namespace postprocessing {
          " FOREIGN KEY (runId) REFERENCES runs(runId)  "
          " );" ;
 
-      sqlite3_exec( dbHandle_, CREATE_TIMINGTREE_TABLE, 0,0,0 );
+   sqlite3_exec( dbHandle_, CREATE_TIMINGTREE_TABLE, 0,0,0 );
 
-      double totalTime = 0.0;
-      for (auto it = tt.getRawData().tree_.begin(); it != tt.getRawData().tree_.end(); ++it)
-      {
-         totalTime += it->second.timer_.total();
-      }
+   double totalTime = 0.0;
+   for (auto it = tt.getRawData().tree_.begin(); it != tt.getRawData().tree_.end(); ++it)
+   {
+      totalTime += it->second.timer_.total();
+   }
 
-      storeTimingNode(runId, std::numeric_limits<int>::max(), tt.getRawData(), timingTreeName, "Total", totalTime);
+   storeTimingNode(runId, std::numeric_limits<int>::max(), tt.getRawData(), timingTreeName, "Total", totalTime);
 
-      sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 );
-   }
+   sqlite3_exec( dbHandle_, "END TRANSACTION;",0,0,0 );
+}
 
-   //*******************************************************************************************************************
-   /*! Stores a TimingNode recursively in a Sqlite3 Database, and links it together
+//*******************************************************************************************************************
+/*! Stores a TimingNode recursively in a Sqlite3 Database, and links it together
    *
    * \param runId   primary key of the run, as returned by storeRun()
    * \param parentId   parent key of the node
    * \param tn      the TimingNode to store
    * \param name    name of the timing tree ( as written to database column )
    */
-   //*******************************************************************************************************************
-   void SQLiteDB::storeTimingNode ( const uint_t runId,
-                                    const int    parentId,
-                                    const WcTimingNode & tn,
-                                    const std::string & timingTreeName,
-                                    const std::string & sweep,
-                                    const double totalTime )
-   {
-      static const char * INSERT_STATEMENT =
-                " INSERT INTO timingTree (runId,name,parentId,sweep,average,min,max,count,variance,percentage) "
-                " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
-
-      sqlite3_stmt *stmt = NULL;
-      auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 );
-      if ( retVal != SQLITE_OK ) {
-         WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement (" << retVal << ")." );
-         return;
-      }
-
-      sqlite3_bind_int64 ( stmt, 1, int64_c(runId) );
-      sqlite3_bind_text  ( stmt, 2, timingTreeName.c_str() , -1, SQLITE_STATIC );
-      sqlite3_bind_int64 ( stmt, 3, parentId );
-      sqlite3_bind_text  ( stmt, 4, sweep.c_str() , -1, SQLITE_STATIC );
-      sqlite3_bind_double( stmt, 5, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.average() ) ) );
-      sqlite3_bind_double( stmt, 6, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.min() ) ) );
-      sqlite3_bind_double( stmt, 7, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.max() ) ) );
-      sqlite3_bind_int64 ( stmt, 8, int64_c   ( tn.timer_.getCounter() ));
-      sqlite3_bind_double( stmt, 9, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.variance() ) ) );
-      sqlite3_bind_double( stmt,10, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.total() / totalTime ) ) );
-
-      sqlite3_step ( stmt );  // execute statement
-      sqlite3_reset ( stmt ); // undo binding
-      sqlite3_finalize( stmt ); // free prepared statement
-
-      int currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) );
-
-      for ( auto i = tn.tree_.begin(); i != tn.tree_.end(); ++i )
-      {
-         storeTimingNode( runId, currentId, i->second, timingTreeName, i->first, totalTime);
-      }
+//*******************************************************************************************************************
+void SQLiteDB::storeTimingNode ( const uint_t runId,
+                                 const int    parentId,
+                                 const WcTimingNode & tn,
+                                 const std::string & timingTreeName,
+                                 const std::string & sweep,
+                                 const double totalTime )
+{
+   static const char * INSERT_STATEMENT =
+         " INSERT INTO timingTree (runId,name,parentId,sweep,average,min,max,count,variance,percentage) "
+         " VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+
+   sqlite3_stmt *stmt = NULL;
+   auto retVal = sqlite3_prepare_v2(dbHandle_, INSERT_STATEMENT, -1, &stmt, 0 );
+   if ( retVal != SQLITE_OK ) {
+      WALBERLA_LOG_WARNING( "Failed to prepare SQL Insert statement (" << retVal << ")." );
+      return;
    }
 
+   sqlite3_bind_int64 ( stmt, 1, int64_c(runId) );
+   sqlite3_bind_text  ( stmt, 2, timingTreeName.c_str() , -1, SQLITE_STATIC );
+   sqlite3_bind_int64 ( stmt, 3, parentId );
+   sqlite3_bind_text  ( stmt, 4, sweep.c_str() , -1, SQLITE_STATIC );
+   sqlite3_bind_double( stmt, 5, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.average() ) ) );
+   sqlite3_bind_double( stmt, 6, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.min() ) ) );
+   sqlite3_bind_double( stmt, 7, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.max() ) ) );
+   sqlite3_bind_int64 ( stmt, 8, int64_c   ( tn.timer_.getCounter() ));
+   sqlite3_bind_double( stmt, 9, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.variance() ) ) );
+   sqlite3_bind_double( stmt,10, ( ( tn.timer_.getCounter() == uint_t(0) ) ? 0.0 : double_c( tn.timer_.total() / totalTime ) ) );
 
+   sqlite3_step ( stmt );  // execute statement
+   sqlite3_reset ( stmt ); // undo binding
+   sqlite3_finalize( stmt ); // free prepared statement
 
+   int currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) );
 
-
-   uint_t storeRunInSqliteDB( const string               & dbFile,
-                              const map<string, int>     & integerProperties,
-                              const map<string, string > & stringProperties,
-                              const map<string, double > & realProperties,
-                              const int                    busyTimeout )
-   {
-      SQLiteDB db ( dbFile, busyTimeout );
-      return db.storeRun( integerProperties, stringProperties, realProperties );
-   }
-   uint_t storeRunInSqliteDB( const string               & dbFile,
-                              const map<string, int64_t> & integerProperties,
-                              const map<string, string > & stringProperties,
-                              const map<string, double > & realProperties,
-                              const int                    busyTimeout )
-   {
-      SQLiteDB db ( dbFile, busyTimeout );
-      return db.storeRun( integerProperties, stringProperties, realProperties );
-   }
-
-
-   void storeTimingPoolInSqliteDB ( const string & dbFile, uint_t runId,
-                                    const WcTimingPool & tp,
-                                    const std::string & timingPoolName,
-                                    const int           busyTimeout )
-   {
-      SQLiteDB db ( dbFile, busyTimeout );
-      db.storeTimingPool( runId, tp, timingPoolName );
-   }
-
-   void storeTimingTreeInSqliteDB ( const string & dbFile, uint_t runId,
-                                    const WcTimingTree & tt,
-                                    const std::string & timingTreeName,
-                                    const int           busyTimeout )
+   for ( auto i = tn.tree_.begin(); i != tn.tree_.end(); ++i )
    {
-      SQLiteDB db ( dbFile, busyTimeout );
-      db.storeTimingTree( runId, tt, timingTreeName );
+      storeTimingNode( runId, currentId, i->second, timingTreeName, i->first, totalTime);
    }
+}
+
+
+
+
+
+uint_t storeRunInSqliteDB( const string               & dbFile,
+                           const map<string, int>     & integerProperties,
+                           const map<string, string > & stringProperties,
+                           const map<string, double > & realProperties,
+                           const int                    busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   return db.storeRun( integerProperties, stringProperties, realProperties );
+}
+uint_t storeRunInSqliteDB( const string               & dbFile,
+                           const map<string, int64_t> & integerProperties,
+                           const map<string, string > & stringProperties,
+                           const map<string, double > & realProperties,
+                           const int                    busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   return db.storeRun( integerProperties, stringProperties, realProperties );
+}
+
+
+void storeAdditionalRunInfoInSqliteDB( const uint_t                 runId,
+                                       const string               & dbFile,
+                                       const string               & tableName,
+                                       const map<string, int>     & integerProperties,
+                                       const map<string, string > & stringProperties,
+                                       const map<string, double > & realProperties,
+                                       const int                    busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   return db.storeAdditionalRunInfo( runId, tableName, integerProperties, stringProperties, realProperties );
+}
+void storeAdditionalRunInfoInSqliteDB( const uint_t                 runId,
+                                       const string               & dbFile,
+                                       const string               & tableName,
+                                       const map<string, int64_t> & integerProperties,
+                                       const map<string, string > & stringProperties,
+                                       const map<string, double > & realProperties,
+                                       const int                    busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   return db.storeAdditionalRunInfo( runId, tableName, integerProperties, stringProperties, realProperties );
+}
+
+
+void storeTimingPoolInSqliteDB ( const string & dbFile, uint_t runId,
+                                 const WcTimingPool & tp,
+                                 const std::string & timingPoolName,
+                                 const int           busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   db.storeTimingPool( runId, tp, timingPoolName );
+}
+
+void storeTimingTreeInSqliteDB ( const string & dbFile, uint_t runId,
+                                 const WcTimingTree & tt,
+                                 const std::string & timingTreeName,
+                                 const int           busyTimeout )
+{
+   SQLiteDB db ( dbFile, busyTimeout );
+   db.storeTimingTree( runId, tt, timingTreeName );
+}
 
 } // namespace postprocessing
 } // namespace walberla
diff --git a/src/postprocessing/sqlite/SQLite.h b/src/postprocessing/sqlite/SQLite.h
index c4bf4650eaaf4e074c48a9b31e27645f1e535186..19e0855fa474cb4f055b634f4768a320b54e3cff 100644
--- a/src/postprocessing/sqlite/SQLite.h
+++ b/src/postprocessing/sqlite/SQLite.h
@@ -37,74 +37,86 @@ struct sqlite3;
 namespace walberla {
 namespace postprocessing {
 
-   using std::string;
-   using std::map;
-
-
-   // Time in seconds the process waits if database is locked
-   const int BUSY_TIMEOUT = 30;
-
-
-
-   class SQLiteDB
-   {
-   private:
-
-   public:
-      SQLiteDB ( const string & dbFile, const int busyTimeout = BUSY_TIMEOUT );
-      ~SQLiteDB();
-
-      uint_t storeRun ( const map<string, int>     & integerProperties,
-                        const map<string, string > & stringProperties ,
-                        const map<string, double > & realProperties);
-
-      uint_t storeRun ( const map<string, int64_t> & integerProperties,
-                        const map<string, string > & stringProperties ,
-                        const map<string, double > & realProperties);
-
-      void storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
-                                   const map<string, int>     & integerProperties,
-                                   const map<string, string > & stringProperties ,
-                                   const map<string, double > & realProperties );
-
-      void storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
-                                   const map<string, int64_t> & integerProperties,
-                                   const map<string, string > & stringProperties ,
-                                   const map<string, double > & realProperties );
-
-      void storeTimingPool ( uint_t runId, const WcTimingPool & tp, const std::string & name  );
-      void storeTimingTree ( uint_t runId, const WcTimingTree & tt, const std::string & timingTreeName  );
-
-   private:
-      void storeTimingNode ( const uint_t runId,
-                             const int    parentId,
-                             const WcTimingNode & tn,
-                             const std::string & timingTreeName,
-                             const std::string & sweep,
-                             const double totalTime );
-
-      bool valid_;
-      sqlite3 * dbHandle_;
-      std::string file_;
-   };
-
-   uint_t storeRunInSqliteDB( const string               & dbFile,
-                              const map<string, int>     & integerProperties= map<string,int>(),
-                              const map<string, string > & stringProperties = map<string,string>(),
-                              const map<string, double > & realProperties   = map<string,double>(),
-                              const int                    busyTimeout      = BUSY_TIMEOUT );
-
-   uint_t storeRunInSqliteDB( const string               & dbFile,
-                              const map<string, int64_t> & integerProperties= map<string,int64_t>(),
-                              const map<string, string > & stringProperties = map<string,string>(),
-                              const map<string, double > & realProperties   = map<string,double>(),
-                              const int                    busyTimeout      = BUSY_TIMEOUT );
-
-   void storeTimingPoolInSqliteDB( const string & dbFile, uint_t runId, const WcTimingPool & tp,
-                                   const std::string & name, const int busyTimeout = BUSY_TIMEOUT );
-
-   void storeTimingTreeInSqliteDB( const string & dbFile, uint_t runId, const WcTimingTree & tt,
-                                   const std::string & name, const int busyTimeout = BUSY_TIMEOUT );
+using std::string;
+using std::map;
+
+
+// Time in seconds the process waits if database is locked
+const int BUSY_TIMEOUT = 30;
+
+
+
+class SQLiteDB
+{
+private:
+
+public:
+   SQLiteDB ( const string & dbFile, const int busyTimeout = BUSY_TIMEOUT );
+   ~SQLiteDB();
+
+   uint_t storeRun ( const map<string, int>     & integerProperties,
+                     const map<string, string > & stringProperties ,
+                     const map<string, double > & realProperties);
+
+   uint_t storeRun ( const map<string, int64_t> & integerProperties,
+                     const map<string, string > & stringProperties ,
+                     const map<string, double > & realProperties);
+
+   void storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
+                                const map<string, int>     & integerProperties,
+                                const map<string, string > & stringProperties ,
+                                const map<string, double > & realProperties );
+
+   void storeAdditionalRunInfo( uint_t runId, const std::string & tableName,
+                                const map<string, int64_t> & integerProperties,
+                                const map<string, string > & stringProperties ,
+                                const map<string, double > & realProperties );
+
+   void storeTimingPool ( uint_t runId, const WcTimingPool & tp, const std::string & name  );
+   void storeTimingTree ( uint_t runId, const WcTimingTree & tt, const std::string & timingTreeName  );
+
+private:
+   void storeTimingNode ( const uint_t runId,
+                          const int    parentId,
+                          const WcTimingNode & tn,
+                          const std::string & timingTreeName,
+                          const std::string & sweep,
+                          const double totalTime );
+
+   bool valid_;
+   sqlite3 * dbHandle_;
+   std::string file_;
+};
+
+uint_t storeRunInSqliteDB( const string               & dbFile,
+                           const map<string, int>     & integerProperties= map<string,int>(),
+                           const map<string, string > & stringProperties = map<string,string>(),
+                           const map<string, double > & realProperties   = map<string,double>(),
+                           const int                    busyTimeout      = BUSY_TIMEOUT );
+
+uint_t storeRunInSqliteDB( const string               & dbFile,
+                           const map<string, int64_t> & integerProperties= map<string,int64_t>(),
+                           const map<string, string > & stringProperties = map<string,string>(),
+                           const map<string, double > & realProperties   = map<string,double>(),
+                           const int                    busyTimeout      = BUSY_TIMEOUT );
+
+void storeAdditionalRunInfoInSqliteDB( const string               & dbFile,
+                                       const map<string, int>     & integerProperties= map<string,int>(),
+                                       const map<string, string > & stringProperties = map<string,string>(),
+                                       const map<string, double > & realProperties   = map<string,double>(),
+                                       const int                    busyTimeout      = BUSY_TIMEOUT );
+
+void storeAdditionalRunInfoInSqliteDB( const string               & dbFile,
+                                       const map<string, int64_t> & integerProperties= map<string,int64_t>(),
+                                       const map<string, string > & stringProperties = map<string,string>(),
+                                       const map<string, double > & realProperties   = map<string,double>(),
+                                       const int                    busyTimeout      = BUSY_TIMEOUT );
+
+void storeTimingPoolInSqliteDB( const string & dbFile, uint_t runId, const WcTimingPool & tp,
+                                const std::string & name, const int busyTimeout = BUSY_TIMEOUT );
+
+void storeTimingTreeInSqliteDB( const string & dbFile, uint_t runId, const WcTimingTree & tt,
+                                const std::string & name, const int busyTimeout = BUSY_TIMEOUT );
 
 
 
diff --git a/src/python_coupling/DictWrapper.h b/src/python_coupling/DictWrapper.h
index 912ce3a830aa9930ca1130b096a34ec0b4a9d2dc..0d2f0cab139433909ec078d7f1cf2b44e15e0a72 100644
--- a/src/python_coupling/DictWrapper.h
+++ b/src/python_coupling/DictWrapper.h
@@ -28,7 +28,9 @@
 #include "PythonWrapper.h"
 #include "core/DataTypes.h"
 #include "core/Abort.h"
-#include <boost/bind.hpp>
+
+#include <functional>
+
 
 namespace walberla {
 namespace python_coupling {
diff --git a/src/python_coupling/DictWrapper.impl.h b/src/python_coupling/DictWrapper.impl.h
index 400eb2e7f09e4855cd2d1ffdb630b2dfb6ac6448..b6ffecb9be49db88624e5461c1f9b20ab5670d1b 100644
--- a/src/python_coupling/DictWrapper.impl.h
+++ b/src/python_coupling/DictWrapper.impl.h
@@ -19,6 +19,8 @@
 //
 //======================================================================================================================
 
+#include <functional>
+
 namespace walberla {
 namespace python_coupling {
 
@@ -113,7 +115,7 @@ inline void runPythonObject( boost::python::object obj ) {
 template<>
 inline std::function<void()> DictWrapper::get( const std::string & name ) {
    boost::python::object obj ( d_[name] );
-   return boost::bind( &runPythonObject, obj );
+   return std::bind( &runPythonObject, obj );
 }
 
 template<>
diff --git a/src/python_coupling/Manager.h b/src/python_coupling/Manager.h
index b6294b6fb0a6f218585b1e75bcc9d1bf5ba262ed..ed843ff11649c00ecfedf7b3e02713d8ce4afdb5 100644
--- a/src/python_coupling/Manager.h
+++ b/src/python_coupling/Manager.h
@@ -61,7 +61,7 @@ namespace python_coupling {
    boost::python::object testBlockData( IBlock & block, BlockDataID blockDataID )
    {
       BlockDataToObjectTester tester( &block, blockDataID );
-      for_each_noncopyable_type< TypeList > ( boost::ref(tester) );
+      for_each_noncopyable_type< TypeList > ( std::ref(tester) );
       return tester.getResult();
    }
 
diff --git a/src/python_coupling/basic_exports/BasicExports.cpp b/src/python_coupling/basic_exports/BasicExports.cpp
index a3e4a8f31cbeb1715515319c2b6ff0e37bbe1e42..724efcfce421d3d171604a59617c3e4d6dfa15bc 100644
--- a/src/python_coupling/basic_exports/BasicExports.cpp
+++ b/src/python_coupling/basic_exports/BasicExports.cpp
@@ -43,6 +43,8 @@
 
 #include <boost/version.hpp>
 
+#include <functional>
+
 using namespace boost::python;
 
 
@@ -842,7 +844,7 @@ object * blockDataCreationHelper( IBlock * block, StructuredBlockStorage * bs,
 uint_t StructuredBlockStorage_addBlockData( StructuredBlockStorage & s, const std::string & name, object functionPtr )
 {
    BlockDataID res = s.addStructuredBlockData(name)
-               << StructuredBlockDataCreator<object>( boost::bind( &blockDataCreationHelper, _1,_2, functionPtr ) );
+               << StructuredBlockDataCreator<object>( std::bind( &blockDataCreationHelper, std::placeholders::_1, std::placeholders::_2, functionPtr ) );
    //TODO extend this for moving block data ( packing und unpacking with pickle )
    return res;
 }
diff --git a/src/python_coupling/helper/MplHelpers.h b/src/python_coupling/helper/MplHelpers.h
index 640f45637b09d10dc54904250749830dea43fbc8..d9b0086647f491efacf3d7bf56c060124819b66c 100644
--- a/src/python_coupling/helper/MplHelpers.h
+++ b/src/python_coupling/helper/MplHelpers.h
@@ -28,8 +28,8 @@
 #include <boost/mpl/pair.hpp>
 #include <boost/mpl/transform.hpp>
 
-#include <boost/bind.hpp>
 
+#include <functional>
 #include <map>
 
 
@@ -102,7 +102,7 @@ public:
          return map_[ blockDataID ];
 
       Exporter exporter( block_, blockDataID );
-      for_each_noncopyable_type< FieldTypeList>  ( boost::ref(exporter) );
+      for_each_noncopyable_type< FieldTypeList>  ( std::ref(exporter) );
       map_[ blockDataID ] = exporter.result;
       return exporter.result;
    }
diff --git a/src/timeloop/PerformanceMeter.cpp b/src/timeloop/PerformanceMeter.cpp
index 7af5f847d18ba2ae2bc51049fbe8706a3d30a0a7..8842912156ab1971cd1ca5a41984d550174f9934 100644
--- a/src/timeloop/PerformanceMeter.cpp
+++ b/src/timeloop/PerformanceMeter.cpp
@@ -53,7 +53,7 @@ namespace timeloop {
     *******************************************************************************************************************/
    std::function<void () > PerformanceMeter::getBeforeFunction()
    {
-      return boost::bind ( &PerformanceMeter::timingStart, this );
+      return std::bind ( &PerformanceMeter::timingStart, this );
    }
 
 
@@ -66,7 +66,7 @@ namespace timeloop {
     *******************************************************************************************************************/
    std::function<void () > PerformanceMeter::getAfterFunction()
    {
-      return boost::bind ( &PerformanceMeter::timingEnd, this );
+      return std::bind ( &PerformanceMeter::timingEnd, this );
    }
 
 
diff --git a/src/timeloop/PerformanceMeter.h b/src/timeloop/PerformanceMeter.h
index 732121789149a1553e927fe2eb5d24e8ffa07846..731f968fe7046e95e03f7ac2e7953119fce48f57 100644
--- a/src/timeloop/PerformanceMeter.h
+++ b/src/timeloop/PerformanceMeter.h
@@ -23,9 +23,7 @@
 #include "core/timing/Timer.h"
 #include "domain_decomposition/StructuredBlockStorage.h"
 
-#include <boost/bind.hpp>
 #include <functional>
-
 #include <iostream>
 #include <map>
 #include <string>
@@ -180,7 +178,7 @@ namespace timeloop {
                                                           typename FField::flag_t activeMask,
                                                           uint_t countFreq , real_t scaling )
    {
-      this->addMeasurement( name, boost::bind( flagFieldCountFunction<FField>, _1, flagFieldID, activeMask ),
+      this->addMeasurement( name, std::bind( flagFieldCountFunction<FField>,  std::placeholders::_1, flagFieldID, activeMask ),
                            countFreq, scaling );
    }
 
diff --git a/src/timeloop/SelectableFunctionCreators.h b/src/timeloop/SelectableFunctionCreators.h
index b6762e469e37afc1f3c093c76af35c822731ec82..4deaa2ce49eea46714205b7198935b105a9d7b1b 100644
--- a/src/timeloop/SelectableFunctionCreators.h
+++ b/src/timeloop/SelectableFunctionCreators.h
@@ -25,7 +25,6 @@
 #include "core/uid/SUID.h"
 #include "domain_decomposition/BlockStorage.h"
 
-#include <boost/bind.hpp>
 #include <functional>
 #include <string>
 
@@ -177,7 +176,7 @@ namespace timeloop {
          BlockDataID bdId = bs_.addBlockData() << bdCreator;
 
          // add a sweep function that fetches the block data sweep and executes it
-         auto sweepFunc = boost::bind ( executeSweepOnBlock<SweepClass>, _1, bdId );
+         auto sweepFunc = std::bind ( executeSweepOnBlock<SweepClass>,  std::placeholders::_1, bdId );
          ( *this ) << Sweep ( sweepFunc, sw.identifier_, sw.requiredSelectors_, sw.incompatibleSelectors_  );
 
          return *this;
diff --git a/src/vtk/Initialization.cpp b/src/vtk/Initialization.cpp
index d551086d5192ed5c2a824c7eef9cbe3a5a2adfa2..bac98bdb96f8871e12f92510aa86f968c1993c3b 100644
--- a/src/vtk/Initialization.cpp
+++ b/src/vtk/Initialization.cpp
@@ -29,7 +29,8 @@
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/algorithm/string/split.hpp>
-#include <boost/bind.hpp>
+
+#include <functional>
 
 
 namespace walberla {
@@ -43,7 +44,7 @@ static void splitVector( T& x, T& y, T& z, const Config::BlockHandle& bb, const
    std::vector< std::string > coordinates;
    std::string vector = bb.getParameter< std::string >( vertex );
    boost::split( coordinates, vector, boost::is_any_of("<,> \t") );
-   coordinates.erase( std::remove_if( coordinates.begin(), coordinates.end(), boost::bind( &std::string::empty, _1 ) ), coordinates.end() );
+   coordinates.erase( std::remove_if( coordinates.begin(), coordinates.end(), std::bind( &std::string::empty,  std::placeholders::_1 ) ), coordinates.end() );
 
    if( coordinates.size() != 3 )
       WALBERLA_ABORT( errorMsg );
@@ -60,7 +61,7 @@ static std::vector< std::string > splitList( const std::string& string )
    std::vector< std::string > list;
 
    boost::split( list, string, boost::is_any_of(", \t") );
-   list.erase( std::remove_if( list.begin(), list.end(), boost::bind( &std::string::empty, _1 ) ), list.end() );
+   list.erase( std::remove_if( list.begin(), list.end(), std::bind( &std::string::empty,  std::placeholders::_1 ) ), list.end() );
 
    return list;
 }
@@ -71,7 +72,7 @@ static void addStates( Set<SUID>& set, const std::string& string )
 {
    std::vector< std::string > states;
    boost::split( states, string, boost::is_any_of(", \t") );
-   states.erase( std::remove_if( states.begin(), states.end(), boost::bind( &std::string::empty, _1 ) ), states.end() );
+   states.erase( std::remove_if( states.begin(), states.end(), std::bind( &std::string::empty,  std::placeholders::_1 ) ), states.end() );
 
    for( auto it = states.begin(); it != states.end(); ++it )
       set += SUID( *it );
diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt
index 6885cf97661fa507cc240a45207b63a62aec4a43..ddb9907147e78dbba1d6a9d5fd07be6f2dc033e6 100644
--- a/tests/core/CMakeLists.txt
+++ b/tests/core/CMakeLists.txt
@@ -143,13 +143,6 @@ waLBerla_execute_test( NAME SetReductionTest27 COMMAND $<TARGET_FILE:SetReductio
 waLBerla_compile_test( FILES mpi/ProbeVsExtraMessage.cpp DEPENDS postprocessing)
 
 
-##############
-# ptrvector #
-##############
-
-waLBerla_compile_test( NAME PtrVector FILES ptrvector/PtrVector.cpp )
-waLBerla_execute_test( NAME PtrVector )
-
 ##############
 # selectable #
 ##############
diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp
index c34a1ef8e89d2a138031ba1dde8092be69e7f40a..741edc1f85340215798bc848b7a275adeb9e30c6 100644
--- a/tests/core/mpi/BufferTest.cpp
+++ b/tests/core/mpi/BufferTest.cpp
@@ -122,6 +122,16 @@ void initBoostArray( boost::array< T, N > & array )
       *it = dist( rng );
 }
 
+template<typename T, std::size_t N>
+void initStdArray( std::array< T, N > & array )
+{
+   static std::mt19937 rng;
+   std::uniform_int_distribution<T> dist;
+
+   for( auto it = array.begin(); it != array.end(); ++it )
+      *it = dist( rng );
+}
+
 
 /// Simulates one send and receive operation
 /// data is put into send buffer and copied to RecvBuffer
@@ -153,6 +163,7 @@ void bufferTest()
    std::multimap<unsigned int, walberla::int64_t> stdMultiMap, stdMultiMapEmpty;
 
    boost::array< unsigned int, 19 > boostArray;
+   std::array  < unsigned int, 19 > stdArray;
 
    initVecBool(boolStdVec);
    initIntegerContainer(stdVec);
@@ -163,6 +174,7 @@ void bufferTest()
    initIntegerMap(stdMap);
    initIntegerMap(stdMultiMap);
    initBoostArray(boostArray);
+   initStdArray(stdArray);
 
    // Create send buffer and put two values in it
    GenericSendBuffer<T> sb;
@@ -178,7 +190,7 @@ void bufferTest()
    sb << stdMultiSet << stdMultiSetEmpty;
    sb << stdMap      << stdMapEmpty;
    sb << stdMultiMap << stdMultiMapEmpty;
-   sb << boostArray;
+   sb << boostArray  << stdArray;
 
    // Copying
    //RecvBuffer<T> rb;
@@ -209,6 +221,7 @@ void bufferTest()
    std::multimap<unsigned int, walberla::int64_t> recvStdMultiMap, recvStdMultiMapEmpty;
 
    boost::array<unsigned int, 19> recvBoostArray;
+   std::array  <unsigned int, 19> recvStdArray;
 
    rb >> recvD           >> recvI;
    rb >> recvVec         >> recvMat;
@@ -222,7 +235,7 @@ void bufferTest()
    rb >> recvStdMultiSet >> recvStdMultiSetEmpty;
    rb >> recvStdMap      >> recvStdMapEmpty;
    rb >> recvStdMultiMap >> recvStdMultiMapEmpty;
-   rb >> recvBoostArray;
+   rb >> recvBoostArray  >> recvStdArray;
 
    // Validate
    WALBERLA_CHECK_FLOAT_EQUAL(recvD,testDouble);
@@ -254,6 +267,7 @@ void bufferTest()
    WALBERLA_CHECK_EQUAL(recvStdMultiMapEmpty, stdMultiMapEmpty);
 
    WALBERLA_CHECK_EQUAL(recvBoostArray, boostArray);
+   WALBERLA_CHECK_EQUAL(recvStdArray,   stdArray);
 }
 
 
diff --git a/tests/core/ptrvector/PtrVector.cpp b/tests/core/ptrvector/PtrVector.cpp
deleted file mode 100644
index 8ae38bdeaff93a71ac5187d7c223f87670de0b7f..0000000000000000000000000000000000000000
--- a/tests/core/ptrvector/PtrVector.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-//======================================================================================================================
-//
-//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
-//
-//! \file PtrVector.cpp
-//! \ingroup field
-//! \author Sebastian Eibl <sebastian.eibl@fau.de>
-//
-//======================================================================================================================
-
-#include "core/ptrvector/PtrVector.h"
-#include "core/ptrvector/policies/NoDelete.h"
-
-#include "core/debug/TestSubsystem.h"
-   
-using namespace walberla;
-
-struct A{
-    int c;
-    int val;
-    static int refCount;
-
-    explicit A(int v = 0) : c(0), val(v) { ++refCount; }
-    virtual ~A(){ --refCount; }
-};
-
-struct B : public A {
-    B() : A(1) {}
-};
-
-struct C : public A {
-    C() : A(2) {}
-};
-
-int A::refCount = 0;
-
-int main( int /*argc*/, char** /*argv*/ )
-{
-    debug::enterTestMode();
-    {
-        auto a = new A();
-        auto b = new B();
-        auto c = new C();
-
-        WALBERLA_CHECK_EQUAL(A::refCount, 3);
-
-        PtrVector<A, PtrDelete> vec;
-        vec.pushBack(a);
-        vec.pushBack(b);
-        vec.pushBack(c);
-
-        WALBERLA_CHECK_EQUAL(A::refCount, 3);
-
-        for (auto it = vec.begin(); it!=vec.end(); ++it){
-            ++(it->c);
-        }
-        for (auto it = vec.begin<B>(); it!=vec.end<B>(); ++it){
-            ++(it->c);
-        }
-
-        WALBERLA_CHECK_EQUAL(a->c, 1);
-        WALBERLA_CHECK_EQUAL(b->c, 2);
-
-        vec.erase(++vec.begin());
-        int sum = 0;
-        for (auto it = vec.begin(); it!=vec.end(); ++it){
-            sum += it->val;
-        }
-
-        WALBERLA_CHECK_EQUAL(sum, 2);
-    }
-    WALBERLA_CHECK_EQUAL(A::refCount, 0);
-
-    auto a = new A();
-    auto b = new B();
-    WALBERLA_CHECK_EQUAL(A::refCount, 2);
-    {
-        PtrVector<A, NoDelete> vec;
-        vec.pushBack(a);
-        vec.pushBack(b);
-        WALBERLA_CHECK_EQUAL(A::refCount, 2);
-    }
-    WALBERLA_CHECK_EQUAL(A::refCount, 2);
-
-    delete a;
-    delete b;
-}
diff --git a/tests/domain_decomposition/CMakeLists.txt b/tests/domain_decomposition/CMakeLists.txt
index 9ab9ff72cb0418ca4ce77b09fe7e945c29ecb42e..2c7cae2624be9baca0d50259c941223c233aa4f9 100644
--- a/tests/domain_decomposition/CMakeLists.txt
+++ b/tests/domain_decomposition/CMakeLists.txt
@@ -6,3 +6,6 @@
 
 waLBerla_compile_test( NAME PeriodicIntersect FILES PeriodicIntersect.cpp DEPENDS core blockforest )
 waLBerla_execute_test( NAME PeriodicIntersect )
+
+waLBerla_compile_test( NAME PeriodicIntersectionVolume FILES PeriodicIntersectionVolume.cpp DEPENDS core blockforest )
+waLBerla_execute_test( NAME PeriodicIntersectionVolume )
diff --git a/tests/domain_decomposition/PeriodicIntersectionVolume.cpp b/tests/domain_decomposition/PeriodicIntersectionVolume.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cb48e5777aef6ecd6054ad984c1a62b0a6a7ad45
--- /dev/null
+++ b/tests/domain_decomposition/PeriodicIntersectionVolume.cpp
@@ -0,0 +1,99 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla 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.
+//  
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file DataTypesTest.cpp
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include "core/Environment.h"
+#include "core/math/AABB.h"
+#include "core/debug/Debug.h"
+#include "core/debug/TestSubsystem.h"
+#include "core/logging/Logging.h"
+
+#include "domain_decomposition/PeriodicIntersectionVolume.h"
+
+#include "stencil/D3Q27.h"
+
+int main( int argc, char** argv )
+{
+   using namespace walberla;
+   using namespace walberla::domain_decomposition;
+
+   debug::enterTestMode();
+
+   Environment walberlaEnv( argc, argv );
+   WALBERLA_UNUSED(walberlaEnv);
+
+   std::array< bool, 3 > periodic{{true, true, true}};
+   math::AABB domain(real_t(0),real_t(0),real_t(0),real_t(100),real_t(100),real_t(100));
+   math::AABB box1(real_t(0),real_t(0),real_t(0),real_t(10),real_t(10),real_t(10));
+   math::AABB box2(real_t(0),real_t(0),real_t(0),real_t(10),real_t(10),real_t(10));
+
+   for (int multiple = 0; multiple < 3; ++multiple)
+   {
+      for (auto dir = stencil::D3Q27::beginNoCenter(); dir != stencil::D3Q27::end(); ++dir)
+      {
+         Vector3<real_t> shift(
+               real_c(dir.cx()) * (real_t(9) + domain.xSize() * real_c(multiple)),
+               real_c(dir.cy()) * (real_t(9) + domain.ySize() * real_c(multiple)),
+               real_c(dir.cz()) * (real_t(9) + domain.zSize() * real_c(multiple)));
+         box2.setCenter(shift + box1.center());
+         real_t vol = periodicIntersectionVolume(periodic, domain, box1, box2);
+
+         switch (dir.direction())
+         {
+         case stencil::BNE:
+         case stencil::BNW:
+         case stencil::BSE:
+         case stencil::BSW:
+         case stencil::TNE:
+         case stencil::TNW:
+         case stencil::TSE:
+         case stencil::TSW:
+            WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(1));
+            break;
+         case stencil::BN:
+         case stencil::BW:
+         case stencil::BS:
+         case stencil::BE:
+         case stencil::TN:
+         case stencil::TW:
+         case stencil::TS:
+         case stencil::TE:
+         case stencil::NE:
+         case stencil::NW:
+         case stencil::SE:
+         case stencil::SW:
+            WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(10));
+            break;
+         case stencil::B:
+         case stencil::T:
+         case stencil::N:
+         case stencil::W:
+         case stencil::S:
+         case stencil::E:
+            WALBERLA_CHECK_FLOAT_EQUAL(vol, real_t(100));
+            break;
+         default:
+            WALBERLA_CHECK(false, "Should not end up here!");
+            break;
+         }
+      }
+   }
+
+   return EXIT_SUCCESS;
+}
diff --git a/tests/fft/FftTest.cpp b/tests/fft/FftTest.cpp
index 58d80c486de68e7c33d9e2a14263fd08cdd0eeb7..99e934dbfca25d21ad8fb7883634ac6d591c6bd4 100644
--- a/tests/fft/FftTest.cpp
+++ b/tests/fft/FftTest.cpp
@@ -41,7 +41,7 @@ int main (int argc, char** argv)
    {
       Field_T *data_in = block->getData< Field_T >( originalFieldId );
       Field_T *data_out = block->getData< Field_T >( fftFieldId );
-      WALBERLA_FOR_ALL_CELLS_XYZ(data_in, {
+      WALBERLA_FOR_ALL_CELLS_XYZ_OMP(data_in, omp critical, {
          Vector3<real_t> point( real_c(x), real_c(y), real_c(z) );
          blocks->transformBlockLocalToGlobal(point, *block);
          data_in->get(x,y,z) = real_c(std::ranlux48_base(uint_c(point[0])+(uint_c(point[1])*L+uint_c(point[2]))*L)())*real_c(std::pow(2,-48));
diff --git a/tests/geometry/VoxelFileTest.cpp b/tests/geometry/VoxelFileTest.cpp
index 3d6d18fa1654edfacffe3637801e0f4274576557..e93b1cfa157ae4c023c8fe1bcbf330d2e3ac8775 100644
--- a/tests/geometry/VoxelFileTest.cpp
+++ b/tests/geometry/VoxelFileTest.cpp
@@ -53,7 +53,7 @@
 #include "core/mpi/MPIManager.h"
 
 #include "core/Filesystem.h"
-#include <boost/foreach.hpp>
+
 #include <random>
 
 #ifdef _MSC_VER
diff --git a/tests/lbm/DiffusionTest.cpp b/tests/lbm/DiffusionTest.cpp
index a6f126a35deeea6364a809f6c18edcfe5d97f79a..4bed8c474f97b469ff3893fcfe3049fa4fe10a3c 100644
--- a/tests/lbm/DiffusionTest.cpp
+++ b/tests/lbm/DiffusionTest.cpp
@@ -79,6 +79,8 @@
 
 #include <boost/lexical_cast.hpp>
 
+#include <functional>
+
 
 namespace walberla {
 
@@ -280,16 +282,16 @@ int run( int argc, char **argv )
    scheme.addPackInfo( make_shared< field::communication::PackInfo<  AdvDiffPDFField > >( srcFieldID ) );
    timeloop.addFuncBeforeTimeStep( scheme, "Communication" );
 
-   using boost::ref;
+   using std::ref;
 
-   timeloop.add() << Sweep( boost::bind( hydroFunc, _1, velFieldID, u, tperiod, ref(timestep) ), "Hydro Func" );
+   timeloop.add() << Sweep( std::bind( hydroFunc, std::placeholders::_1, velFieldID, u, tperiod, ref(timestep) ), "Hydro Func" );
    
    timeloop.add() << Sweep( makeSharedSweep( lbm::makeCellwiseAdvectionDiffusionSweep< AdvDiffLatticeModel, VectorField, MyFlagField >(
                                                 srcFieldID, velFieldID, flagFieldID, getFluidFlag() ) ), "LBM_SRT" );
   
-   timeloop.add() << BeforeFunction( boost::bind( prepFunc, u[dim], dv, D, cperiod, tperiod, ref(timestep), ref(cosi), ref(sisi), ref(sexp) ), "prepare test" )
-                  << Sweep         ( boost::bind( testFunc<AdvDiffPDFField>, _1, srcFieldID, dim, v, cperiod, ref(cosi), ref(sisi), ref(sexp), ref(E_mean_) ), "Test Func" ) 
-                  << AfterFunction ( boost::bind( incTimeFunc, ref(timestep) ), "increment time" );
+   timeloop.add() << BeforeFunction( std::bind( prepFunc, u[dim], dv, D, cperiod, tperiod, ref(timestep), ref(cosi), ref(sisi), ref(sexp) ), "prepare test" )
+                  << Sweep         ( std::bind( testFunc<AdvDiffPDFField>, std::placeholders::_1, srcFieldID, dim, v, cperiod, ref(cosi), ref(sisi), ref(sexp), ref(E_mean_) ), "Test Func" ) 
+                  << AfterFunction ( std::bind( incTimeFunc, ref(timestep) ), "increment time" );
 
    // --- run timeloop --- //
 
diff --git a/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp b/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp
index d28603a3feb1553d8d321d7b2ab216bc3ef14960..1d4e95008f8987b97e9606d8230bfae2fa6b4990 100644
--- a/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp
+++ b/tests/lbm/boundary/SimpleDiffusionDirichlet.cpp
@@ -76,6 +76,7 @@
 
 #include <stdexcept>
 #include <array>
+#include <functional>
 
 #include "gather/GnuPlotGraphWriter.h"
 #include "field/vtk/FlagFieldCellFilter.h"
@@ -85,7 +86,6 @@
 #include "vtk/VTKOutput.h"
 
 
-
 namespace walberla {
 
 typedef GhostLayerField< real_t, 1 >          ScalarField;
@@ -138,7 +138,7 @@ shared_ptr< StructuredBlockForest > makeStructuredBlockStorage( uint_t length, u
 
     uint_t cells[]  = { length, width, width  };
     uint_t blocks[] = { uint_t(1u), uint_t(1u), uint_t(1u) };
-    sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, refinement ) );
+    sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, refinement ) );
     sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
     sforest.init(
@@ -249,6 +249,7 @@ public:
 #ifdef TEST_USES_VTK_OUTPUT
         error_.resize(time_);
 #endif
+        WALBERLA_UNUSED(maxValue_);
 }
 
    void operator()();
diff --git a/tests/lbm/codegen/SrtWithForceFieldModel.gen.py b/tests/lbm/codegen/SrtWithForceFieldModel.gen.py
index 2ecb139fbbba9d4562a6781441f2d929f9404086..f004d38404605dc00412da91fccd66876f9e28d2 100644
--- a/tests/lbm/codegen/SrtWithForceFieldModel.gen.py
+++ b/tests/lbm/codegen/SrtWithForceFieldModel.gen.py
@@ -1,34 +1,34 @@
 import sympy as sp
 from lbmpy.boundaries import NoSlip, UBB
-from lbmpy_walberla import Field, generateLatticeModelFiles, RefinementScaling
-from lbmpy.creationfunctions import createLatticeBoltzmannMethod
-from lbmpy_walberla.boundary import createBoundaryClass
+from lbmpy_walberla import Field, generate_lattice_model_files, RefinementScaling
+from lbmpy.creationfunctions import create_lb_method
+from lbmpy_walberla.boundary import create_boundary_class
 from pystencils_walberla.cmake_integration import codegen
+import pystencils as ps
 
 # ------------- Lattice Model ------------------------------
-forceField = Field.createGeneric('force', spatialDimensions=3, indexDimensions=1, layout='fzyx')
-force = [forceField(0), forceField(1), forceField(2)]
+force_field = ps.fields("force(3): [3D]", layout='fzyx')
 
 omega = sp.Symbol("omega")
 
 scaling = RefinementScaling()
-scaling.addStandardRelaxationRateScaling(omega)
-scaling.addForceScaling(forceField)
+scaling.add_standard_relaxation_rate_scaling(omega)
+scaling.add_force_scaling(force_field)
 
-generateLatticeModelFiles(className='SrtWithForceFieldModel',
-                          method='srt', stencil='D3Q19', forceModel='guo', force=force,
-                          relaxationRates=[omega], refinementScaling=scaling)
+generate_lattice_model_files(class_name='SrtWithForceFieldModel',
+                             method='srt', stencil='D3Q19', force_model='guo', force=force_field.center_vector,
+                             relaxation_rates=[omega], refinement_scaling=scaling)
 
 
 def genBoundary():
     boundary = UBB([0.05, 0, 0], dim=3, name="MyUBB")
-    method = createLatticeBoltzmannMethod(stencil='D3Q19', method='srt')
-    return createBoundaryClass(boundary, method)
+    method = create_lb_method(stencil='D3Q19', method='srt')
+    return create_boundary_class(boundary, method)
 
 def genNoSlip():
     boundary = NoSlip(name='MyNoSlip')
-    method = createLatticeBoltzmannMethod(stencil='D3Q19', method='srt')
-    return createBoundaryClass(boundary, method)
+    method = create_lb_method(stencil='D3Q19', method='srt')
+    return create_boundary_class(boundary, method)
 
 codegen.register(['MyUBB.h', 'MyUBB.cpp'], genBoundary)
 codegen.register(['MyNoSlip.h', 'MyNoSlip.cpp',], genNoSlip)
diff --git a/tests/lbm/refinement/CommunicationEquivalence.cpp b/tests/lbm/refinement/CommunicationEquivalence.cpp
index 32f029d77f0f9cc621afa930578847da88f7e92f..6cd232235ec3695c4e0bae3ac14abc11b373b390 100644
--- a/tests/lbm/refinement/CommunicationEquivalence.cpp
+++ b/tests/lbm/refinement/CommunicationEquivalence.cpp
@@ -50,11 +50,10 @@
 
 #include "timeloop/SweepTimeloop.h"
 
-#include <boost/bind.hpp>
-
 #include <algorithm>
 #include <cstdlib>
 #include <fstream>
+#include <functional>
 
 //#define TEST_USES_VTK_OUTPUT
 #ifdef TEST_USES_VTK_OUTPUT
@@ -190,7 +189,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const uint_t le
    // initialize SetupBlockForest = determine domain decomposition
    SetupBlockForest sforest;
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, levels ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, levels ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ),
diff --git a/tests/lbm/refinement/NonConstantDiffusion.cpp b/tests/lbm/refinement/NonConstantDiffusion.cpp
index 12d96631abb827c9af7307103731a678c5b92999..dca9d0529341ce97b1e291f8ab0f92731e895722 100644
--- a/tests/lbm/refinement/NonConstantDiffusion.cpp
+++ b/tests/lbm/refinement/NonConstantDiffusion.cpp
@@ -75,6 +75,7 @@
 #include <boost/lexical_cast.hpp>
 
 #include <stdexcept>
+#include <functional>
 
 #include "gather/GnuPlotGraphWriter.h"
 #include "field/vtk/FlagFieldCellFilter.h"
@@ -137,7 +138,7 @@ shared_ptr< StructuredBlockForest > makeStructuredBlockStorage( uint_t length, u
 
     uint_t cells[]  = { length, width, width  };
     uint_t blocks[] = { uint_t(1u), uint_t(1u), uint_t(1u) };
-    sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, refinement ) );
+    sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, refinement ) );
     sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
     sforest.init(
diff --git a/tests/lbm/refinement/Uniformity.cpp b/tests/lbm/refinement/Uniformity.cpp
index 67e73915a3d4c01ee772e0688052e7365cb054bf..aabd8d6fb6fad931c7a3bcb91c038373a77c33ef 100644
--- a/tests/lbm/refinement/Uniformity.cpp
+++ b/tests/lbm/refinement/Uniformity.cpp
@@ -50,10 +50,9 @@
 
 #include "timeloop/SweepTimeloop.h"
 
-#include <boost/bind.hpp>
-
 #include <algorithm>
 #include <cstdlib>
+#include <functional>
 
 //#define TEST_USES_VTK_OUTPUT
 #ifdef TEST_USES_VTK_OUTPUT
@@ -150,7 +149,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const uint_t le
    // initialize SetupBlockForest = determine domain decomposition
    SetupBlockForest sforest;
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, levels ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, levels ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c( numberOfXBlocks * numberOfXCellsPerBlock ),
diff --git a/tests/mesh/MeshContainmentOctreeTest.cpp b/tests/mesh/MeshContainmentOctreeTest.cpp
index 4e922e17a8e5f6a4a54f49437fccc32037052b91..40f542ddbfa20cc3afae192c5b70e9f875938af6 100644
--- a/tests/mesh/MeshContainmentOctreeTest.cpp
+++ b/tests/mesh/MeshContainmentOctreeTest.cpp
@@ -69,9 +69,9 @@ int main( int argc, char * argv[] )
 
    auto aabb = computeAABB( *mesh );
 
-  static const mesh::TriangleMesh::Point xAxis( 1, 0, 0 );
-  static const mesh::TriangleMesh::Point yAxis( 0, 1, 0 );
-  static const mesh::TriangleMesh::Point zAxis( 0, 0, 1 );
+  //static const mesh::TriangleMesh::Point xAxis( 1, 0, 0 );
+  //static const mesh::TriangleMesh::Point yAxis( 0, 1, 0 );
+  //static const mesh::TriangleMesh::Point zAxis( 0, 0, 1 );
   
   mesh::TriangleMesh::Point r = mesh::toOpenMesh( ( aabb.minCorner() - aabb.maxCorner() ).getNormalized() );
   
@@ -124,4 +124,4 @@ int main( int argc, char * argv[] )
 int main( int argc, char * argv[] )
 {
    return walberla::mesh::main( argc, argv );
-}
\ No newline at end of file
+}
diff --git a/tests/mesh/MeshInitilizationTest.cpp b/tests/mesh/MeshInitilizationTest.cpp
index cc98a3e5150eedb4a57374cee41d6ec88fae8827..494f212fb68abf7c99e626196168fa156f542092 100644
--- a/tests/mesh/MeshInitilizationTest.cpp
+++ b/tests/mesh/MeshInitilizationTest.cpp
@@ -102,7 +102,7 @@ void test( const std::string & meshFile, const uint_t numProcesses, const uint_t
    WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with StaticLevelwiseCurveBalanceWeighted Partitioner" );
    bfc.setTargetProcessAssignmentFunction( blockforest::StaticLevelwiseCurveBalanceWeighted() );
    auto sbf_default = bfc.createSetupBlockForest( Vector3<uint_t>(64,64,64), numProcesses );
-   sbf_default->writeVTKOutput("sbf_default");
+   //sbf_default->writeVTKOutput("sbf_default");
    WALBERLA_LOG_INFO_ON_ROOT( sbf_default->toString() );
 
    return;
@@ -137,6 +137,37 @@ void test( const std::string & meshFile, const uint_t numProcesses, const uint_t
 #endif
 }
 
+template< typename MeshType >
+void testHelperFunctions( const std::string & meshFile, const uint_t numTotalBlocks )
+{
+   auto mesh = make_shared<MeshType>();
+   mesh::readAndBroadcast( meshFile, *mesh);
+   auto triDist = make_shared< mesh::TriangleDistance<MeshType> >( mesh );
+   auto distanceOctree = make_shared< DistanceOctree< MeshType > >( triDist );
+
+   const real_t meshVolume  = real_c( computeVolume( *mesh ) );
+   const real_t blockVolume = meshVolume / real_c( numTotalBlocks );
+   static const real_t cellsPersBlock = real_t(1000);
+   const real_t cellVolume = blockVolume / cellsPersBlock;
+   const real_t dx = std::pow( cellVolume, real_t(1) / real_t(3) );
+
+   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
+   auto sbf0 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, numTotalBlocks );
+   
+   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
+   Vector3<uint_t> blockSize( sbf0->getNumberOfXCells(), sbf0->getNumberOfYCells(), sbf0->getNumberOfZCells() );
+   auto sbf1 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, blockSize );
+
+   auto exteriorAabb = computeAABB( *mesh ).getScaled( real_t(2) );
+
+   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
+   auto sbf2 = mesh::createStructuredBlockStorageOutsideMesh( exteriorAabb, distanceOctree, dx, numTotalBlocks );
+
+   WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
+   blockSize = Vector3<uint_t>( sbf2->getNumberOfXCells(), sbf2->getNumberOfYCells(), sbf2->getNumberOfZCells() );
+   auto sbf3 = mesh::createStructuredBlockStorageOutsideMesh( exteriorAabb, distanceOctree, dx, blockSize );
+}
+
 int main( int argc, char * argv[] )
 {
    debug::enterTestMode();
@@ -155,6 +186,8 @@ int main( int argc, char * argv[] )
    //test< mesh::FloatTriangleMesh >( meshFile, numProcesses, numTotalBlocks );
    //test< mesh::PythonTriangleMesh >( meshFile, numProcesses, numTotalBlocks );
 
+   testHelperFunctions< mesh::TriangleMesh >( meshFile, numTotalBlocks );
+
    return EXIT_SUCCESS;
 }
 
diff --git a/tests/mesh/PeVTKMeshWriterTest.cpp b/tests/mesh/PeVTKMeshWriterTest.cpp
index a765f30c4290e09240027168fd90591314c48eb4..5399af727b70e2a4a5015f3d6a74527127c8f5f4 100644
--- a/tests/mesh/PeVTKMeshWriterTest.cpp
+++ b/tests/mesh/PeVTKMeshWriterTest.cpp
@@ -42,6 +42,7 @@
 #include <postprocessing/sqlite/SQLite.h>
 #include <vtk/VTKOutput.h>
 
+#include <functional>
 #include <random>
 
 using namespace walberla;
@@ -142,7 +143,7 @@ int main( int argc, char ** argv )
    cr.setRelaxationParameter( real_t(0.7) );
    cr.setGlobalLinearAcceleration( Vec3(0,0,5) );
 
-   std::function<void(void)> syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+   std::function<void(void)> syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
 
    typedef mesh::FloatPolyMesh OutputMeshType;
    typedef mesh::pe::DefaultTesselation<OutputMeshType> TesselationType;
diff --git a/tests/pde/MGTest.cpp b/tests/pde/MGTest.cpp
index e673a61090673c62fff051a88fa2d7fa9fa5a9dc..fa08a2bf8a08a5b6df3006fe842c032a90d38f43 100644
--- a/tests/pde/MGTest.cpp
+++ b/tests/pde/MGTest.cpp
@@ -160,6 +160,8 @@ int main( int argc, char** argv )
    for( int i = 1; i < argc; ++i )
       if( std::strcmp( argv[i], "--shortrun" ) == 0 ) shortrun = true;
 
+   const uint_t numLvl = shortrun ? uint_t(3) : uint_t(5);
+
    const uint_t xBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2);
    const uint_t yBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2);
    const uint_t zBlocks = ( processes == uint_t(1) ) ? uint_t(1) : uint_t(2);
@@ -201,19 +203,19 @@ int main( int argc, char** argv )
    weights[ Stencil_T::idx[ stencil::T ] ] = real_t(-1) / ( blocks->dx() * blocks->dz() );
    weights[ Stencil_T::idx[ stencil::B ] ] = real_t(-1) / ( blocks->dx() * blocks->dz() );
 
-   auto solver = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, weights,
-                                                                    shortrun ? uint_t(1) : uint_t(20),                                              // iterations
-                                                                    shortrun ? uint_t(3) : uint_t(5),                                               // levels
-                                                                    3, 3, 10,                                                                       // pre-smoothing, post-smoothing, coarse-grid iterations
-                                                                    pde::ResidualNorm< Stencil_T >( blocks->getBlockStorage(), uId, fId, weights ), // residual norm functor
-                                                                    real_c(1e-12) );                                                                // target precision
-   timeloop.addFuncBeforeTimeStep( makeSharedFunctor(solver), "Cell-centered multigrid V-cycles" );
+   auto solverDCA = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, weights,
+                                                                       shortrun ? uint_t(1) : uint_t(20),                                              // iterations
+                                                                       numLvl,                                               							// levels
+                                                                       3, 3, 10,                                                                       // pre-smoothing, post-smoothing, coarse-grid iterations
+                                                                       pde::ResidualNorm< Stencil_T >( blocks->getBlockStorage(), uId, fId, weights ), // residual norm functor
+                                                                       real_c(1e-12) );                                                                // target precision
+   timeloop.addFuncBeforeTimeStep( makeSharedFunctor(solverDCA), "Cell-centered multigrid V-cycles with uniformly constant stencil" );
 
    timeloop.run();
 
    if( !shortrun )
    {
-      auto & convrate = solver->convergenceRate();
+      auto & convrate = solverDCA->convergenceRate();
       for (uint_t i = 1; i < convrate.size(); ++i)
       {
          WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]);
@@ -224,7 +226,7 @@ int main( int argc, char** argv )
       field::createVTKOutput< PdeField_T >( uId, *blocks, "solution" )();
    }
 
-   // rerun the test with a stencil field
+   // rerun the test with a stencil field and DCA
 
    clearField<PdeField_T>( blocks, uId);
    initU( blocks, uId );
@@ -235,19 +237,52 @@ int main( int argc, char** argv )
 
    copyWeightsToStencilField( blocks, weights, stencilId );
 
-   solver = walberla::make_shared<pde::VCycles< Stencil_T > >( blocks, uId, fId, stencilId,
-                                                              shortrun ? uint_t(1) : uint_t(20),                                              // iterations
-                                                              shortrun ? uint_t(3) : uint_t(5),                                               // levels
+   pde::CoarsenStencilFieldsDCA<Stencil_T>  coarsenWithDCA( blocks, numLvl, uint_t(2));		// Set up DCA object with operator order 2 (Laplace)
+
+   solverDCA = walberla::make_shared<pde::VCycles< Stencil_T, decltype(coarsenWithDCA) > >(
+		   	   	   	   	   	   	   	   	   	   	   	   	   	  blocks, uId, fId, stencilId, coarsenWithDCA,
+                                                              shortrun ? uint_t(1) : uint_t(20),                                              	// iterations
+                                                              numLvl,                                               							// levels
+                                                              3, 3, 10,                                                                       	// pre-smoothing, post-smoothing, coarse-grid iterations
+                                                              pde::ResidualNormStencilField< Stencil_T >( blocks->getBlockStorage(), uId, fId, stencilId ), // residual norm functor
+                                                              real_c(1e-12) );                                                                	// target precision
+   timeloop2.addFuncBeforeTimeStep( makeSharedFunctor(solverDCA), "Cell-centered multigrid V-cycles with stencil field and direct coarsening " );
+
+   timeloop2.run();
+
+   if( !shortrun )
+   {
+      auto & convrate = solverDCA->convergenceRate();
+      for (uint_t i = 1; i < convrate.size(); ++i)
+      {
+         WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]);
+         WALBERLA_CHECK_LESS(convrate[i], real_t(0.1));
+      }
+   }
+
+   // rerun the test with a stencil field and GCA
+
+   clearField<PdeField_T>( blocks, uId);
+   initU( blocks, uId );
+
+   SweepTimeloop timeloop3( blocks, uint_t(1) );
+
+   pde::CoarsenStencilFieldsGCA<Stencil_T>  coarsenWithGCA( blocks, numLvl, real_t(2));		// Set up GCA object with overrelaxation factor 2 (only valid for Poisson equation)
+
+   auto solverGCA = walberla::make_shared<pde::VCycles< Stencil_T, decltype(coarsenWithGCA) > >(
+		                                                      blocks, uId, fId, stencilId, coarsenWithGCA,
+                                                              shortrun ? uint_t(1) : uint_t(20),                                            // iterations
+                                                              numLvl,                                               						// levels
                                                               3, 3, 10,                                                                       // pre-smoothing, post-smoothing, coarse-grid iterations
                                                               pde::ResidualNormStencilField< Stencil_T >( blocks->getBlockStorage(), uId, fId, stencilId ), // residual norm functor
                                                               real_c(1e-12) );                                                                // target precision
-   timeloop2.addFuncBeforeTimeStep( makeSharedFunctor(solver), "Cell-centered multigrid V-cycles" );
+   timeloop3.addFuncBeforeTimeStep( makeSharedFunctor(solverGCA), "Cell-centered multigrid V-cycles with stencil field and Galerkin coarsening " );
 
-   timeloop2.run();
+   timeloop3.run();
 
    if( !shortrun )
    {
-      auto & convrate = solver->convergenceRate();
+      auto & convrate = solverGCA->convergenceRate();
       for (uint_t i = 1; i < convrate.size(); ++i)
       {
          WALBERLA_LOG_RESULT_ON_ROOT("Convergence rate in iteration " << i << ": " << convrate[i]);
diff --git a/tests/pe/BodyFlags.cpp b/tests/pe/BodyFlags.cpp
index 901e85c71bf41bb6b0c4238fc8fff6aa6e550db1..db7e82ce8f6b3c4890ffb3949bbe5fba7b3dcc4f 100644
--- a/tests/pe/BodyFlags.cpp
+++ b/tests/pe/BodyFlags.cpp
@@ -71,12 +71,12 @@ int main( int argc, char ** argv )
 
    MaterialID iron = Material::find("iron");
 
-   SphereID refGlobalSphere = new Sphere(1, 0, Vec3(9, 9, 9), Vec3(0,0,0), Quat(), 3, iron, true, false, true);
-   refGlobalSphere->setLinearVel(Vec3(2,2,2));
+   Sphere refGlobalSphere(1, 0, Vec3(9, 9, 9), Vec3(0,0,0), Quat(), 3, iron, true, false, true);
+   refGlobalSphere.setLinearVel(Vec3(2,2,2));
    SphereID globalSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,9), 3, iron, true, false, true);
    globalSphere->setLinearVel(Vec3(2,2,2));
 
-   SphereID refFixedSphere = new Sphere(2, 0, Vec3(9,9,14), Vec3(0,0,0), Quat(), 3, iron, false, false, true);
+   Sphere refFixedSphere(2, 0, Vec3(9,9,14), Vec3(0,0,0), Quat(), 3, iron, false, false, true);
    SphereID fixedSphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, Vec3(9,9,14), 3, iron, false, false, true);
    walberla::id_t fixedSphereID = 0;
    if (fixedSphere != NULL) fixedSphereID = fixedSphere->getSystemID();
@@ -87,16 +87,16 @@ int main( int argc, char ** argv )
 
    cr.setGlobalLinearAcceleration(Vec3(0, 0, real_c(-9.81)));
 
-   checkVitalParameters(refGlobalSphere, globalSphere);
+   checkVitalParameters(&refGlobalSphere, globalSphere);
    for (auto it = forest->begin(); it != forest->end(); ++it)
    {
       blockforest::Block& block = *(dynamic_cast<blockforest::Block*>(&(*it)));
-      if (block.getAABB().intersects(refFixedSphere->getAABB()))
+      if (block.getAABB().intersects(refFixedSphere.getAABB()))
       {
          SphereID fixed = static_cast<SphereID> (getBody(*globalStorage, forest->getBlockStorage(), storageID, fixedSphereID));
          WALBERLA_ASSERT_NOT_NULLPTR(fixed);
-         checkVitalParameters(refFixedSphere,fixed);
-         if (!block.getAABB().contains(refFixedSphere->getPosition()))
+         checkVitalParameters(&refFixedSphere,fixed);
+         if (!block.getAABB().contains(refFixedSphere.getPosition()))
          {
             WALBERLA_ASSERT(fixed->isRemote());
          }
@@ -108,17 +108,17 @@ int main( int argc, char ** argv )
    syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID, NULL, real_c(0.0), false);
    WALBERLA_LOG_PROGRESS_ON_ROOT("*** SIMULATION - END ***");
 
-   refGlobalSphere->setPosition(Vec3(11,11,11));
-   checkVitalParameters(refGlobalSphere, globalSphere);
+   refGlobalSphere.setPosition(Vec3(11,11,11));
+   checkVitalParameters(&refGlobalSphere, globalSphere);
    for (auto it = forest->begin(); it != forest->end(); ++it)
    {
       blockforest::Block& block = *(dynamic_cast<blockforest::Block*>(&(*it)));
-      if (block.getAABB().intersects(refFixedSphere->getAABB()))
+      if (block.getAABB().intersects(refFixedSphere.getAABB()))
       {
          SphereID fixed = static_cast<SphereID> (getBody(*globalStorage, forest->getBlockStorage(), storageID, fixedSphereID));
          WALBERLA_ASSERT_NOT_NULLPTR(fixed);
-         checkVitalParameters(refFixedSphere, fixed);
-         if (!block.getAABB().contains(refFixedSphere->getPosition()))
+         checkVitalParameters(&refFixedSphere, fixed);
+         if (!block.getAABB().contains(refFixedSphere.getPosition()))
          {
             WALBERLA_ASSERT(fixed->isRemote());
          }
diff --git a/tests/pe/BodyIterators.cpp b/tests/pe/BodyIterators.cpp
index a14fc38c543ae11787bd3ed28bda4f1ed1f1f803..0dbfcc53cbeb966e45afd28e7fdbb1d36294e8ce 100644
--- a/tests/pe/BodyIterators.cpp
+++ b/tests/pe/BodyIterators.cpp
@@ -14,7 +14,7 @@
 //  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
 //! \file BodyIterators.cpp
-//! \author Florian Schornbaum <florian.schornbaum@fau.de>
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
 //
 //======================================================================================================================
 
diff --git a/tests/pe/BodyStorage.cpp b/tests/pe/BodyStorage.cpp
index 644f29a1c063de596a9d15081778b2bd23ef784f..498f973944f7d2529ea84072253a4516616104db 100644
--- a/tests/pe/BodyStorage.cpp
+++ b/tests/pe/BodyStorage.cpp
@@ -54,18 +54,21 @@ int main( int argc, char** argv )
     MaterialID iron = Material::find("iron");
     {
         BodyStorage storage;
-        auto bd1 = new Body1(1, iron);
-        auto bd2 = new Body2(2, iron);
-        auto bd3 = new Body2(3, iron);
-        auto bd4 = new Body2(4, iron);
+        auto bd1Ptr = std::make_unique<Body1>(1, iron);
+        auto bd2Ptr = std::make_unique<Body2>(2, iron);
+        auto bd3Ptr = std::make_unique<Body2>(3, iron);
+        auto bd4Ptr = std::make_unique<Body2>(4, iron);
+
+        auto bd2 = bd2Ptr.get();
+        auto bd3 = bd3Ptr.get();
 
         WALBERLA_CHECK_EQUAL(Body1::refCount, 1);
         WALBERLA_CHECK_EQUAL(Body2::refCount, 3);
 
-        storage.add(bd1);
-        storage.add(bd2);
-        storage.add(bd3);
-        storage.add(bd4);
+        storage.add(std::move(bd1Ptr));
+        storage.add(std::move(bd2Ptr));
+        storage.add(std::move(bd3Ptr));
+        storage.add(std::move(bd4Ptr));
 
         WALBERLA_CHECK_EQUAL(storage.size(), 4);
         WALBERLA_CHECK_EQUAL(Body1::refCount, 1);
diff --git a/tests/pe/CMakeLists.txt b/tests/pe/CMakeLists.txt
index 4cb798ed7bca97708c06190be9e2f298947a8fb3..49002bdc955b67fb6b97361a3a7e38f50e592fa4 100644
--- a/tests/pe/CMakeLists.txt
+++ b/tests/pe/CMakeLists.txt
@@ -22,7 +22,7 @@ waLBerla_execute_test( NAME   PE_CHECKVITALPARAMETERS )
 waLBerla_compile_test( NAME   PE_COLLISION FILES Collision.cpp DEPENDS core  )
 waLBerla_execute_test( NAME   PE_COLLISION )
 
-waLBerla_compile_test( NAME   PE_COLLISIONTOBIASGJK FILES CollisionTobiasGJK.cpp DEPENDS core  )
+waLBerla_compile_test( NAME   PE_COLLISIONTOBIASGJK FILES CollisionTobiasGJK.cpp DEPENDS core )
 waLBerla_execute_test( NAME   PE_COLLISIONTOBIASGJK )
 
 waLBerla_compile_test( NAME   PE_CREATEWORLD FILES CreateWorld.cpp DEPENDS core  )
diff --git a/tests/pe/Collision.cpp b/tests/pe/Collision.cpp
index 98ce1fc4a43f00854911c54a7373f0c86e50cbf8..bd77d39c049c6fd6dc3ec7ad7c629f159afa2615 100644
--- a/tests/pe/Collision.cpp
+++ b/tests/pe/Collision.cpp
@@ -18,7 +18,6 @@
 //
 //======================================================================================================================
 
-#include "pe/collision/GJKEPAHelper.h"
 #include "pe/fcd/AnalyticCollisionDetection.h"
 #include "pe/utility/BodyCast.h"
 
@@ -31,6 +30,7 @@
 #include "pe/rigidbody/Sphere.h"
 #include "pe/rigidbody/Plane.h"
 #include "pe/rigidbody/Union.h"
+#include "pe/rigidbody/UnionFactory.h"
 
 #include "pe/rigidbody/SetBodyTypeIDs.h"
 #include "pe/Types.h"
@@ -125,20 +125,14 @@ void BoxTest()
    std::vector<Contact> contacts;
    fcd::AnalyticCollideFunctor< std::vector<Contact> > collideFunc(contacts);
 
-   real_t penetrationDepth = real_t(0);
-   Vec3   contactPoint = Vec3();
-   Vec3   contactNormal = Vec3();
-
 //   std::vector<Contact> contacts;
 
    // BOX <-> BOX
    WALBERLA_LOG_INFO("BOX <-> BOX");
-   WALBERLA_CHECK( !collideGJK(&b1, &b3, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( !collideFunc(&b1, &b3) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
 //   WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth);
-   WALBERLA_CHECK(  collideGJK(&b1, &b2, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK(  collideFunc(&b1, &b2) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
@@ -146,29 +140,24 @@ void BoxTest()
 
 
    b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.999);
-   WALBERLA_CHECK( collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( collideFunc(&b1, &b4) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contacts.back().getPosition());
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contacts.back().getNormal());
 //   WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance());
 
    b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.001);
-   WALBERLA_CHECK( !collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( !collideFunc(&b1, &b4) );
 
    b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.99);
-   WALBERLA_CHECK( collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( collideFunc(&b1, &b5) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contacts.back().getPosition());
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contacts.back().getNormal());
 //   WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance());
 
    b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.01);
-   WALBERLA_CHECK( !collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( !collideFunc(&b1, &b5) );
 
    Sphere s1(126, 0, Vec3(real_t(1.5), real_t(1.5), real_t(1.5)), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   WALBERLA_CHECK( collideGJK(&b1, &s1, contactPoint, contactNormal, penetrationDepth) );
    WALBERLA_CHECK( collideFunc(&b1, &s1) );
 //   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
 //   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
@@ -186,13 +175,6 @@ void CapsuleTest()
 
    // CAPSULE <-> SPHERE
    WALBERLA_LOG_INFO("CAPSULE <-> SPHERE");
-   sp1.setPosition(real_t(2.9), 0, 0);
-   WALBERLA_CHECK( collideGJK(&c1, &sp1, contacts) );
-//   WALBERLA_LOG_WARNING("contactPoint    : " << contacts.at(0).getPosition());
-//   WALBERLA_LOG_WARNING("contactNormal   : " << contacts.at(0).getNormal());
-//   WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance());
-   sp1.setPosition(real_t(3.1), 0, 0);
-   WALBERLA_CHECK( !collideGJK(&c1, &sp1, contacts) );
 
    sp1.setPosition(0, real_t(1.9), 0);
    WALBERLA_CHECK( collideFunc(&c1, &sp1) );
@@ -224,8 +206,6 @@ void CapsuleTest()
 
 void CapsuleTest2()
 {
-   setMaxGJKIterations(10000);
-   setEPATolerance(real_t(0.00000001));
    const real_t   static_cof  ( real_t(0.1) / 2 );   // Coefficient of static friction. Roughly 0.85 with high variation depending on surface roughness for low stresses. Note: pe doubles the input coefficient of friction for material-material contacts.
    const real_t   dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction.
    MaterialID     material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 );
@@ -239,10 +219,6 @@ void CapsuleTest2()
    WALBERLA_LOG_DEVEL( c1 );
    WALBERLA_LOG_DEVEL( sp1 );
 
-   real_t penetrationDepth = real_t(0);
-   Vec3   contactPoint = Vec3();
-   Vec3   contactNormal = Vec3();
-
    WALBERLA_LOG_INFO("CAPSULE TEST");
    Vec2 distance;
    distance[0] = (sp1.getPosition() - c1.getPosition())[0];
@@ -250,36 +226,20 @@ void CapsuleTest2()
 
    std::cout << std::setprecision(10);
    WALBERLA_LOG_DEVEL("DISTANCE: " << distance.length());
-   WALBERLA_LOG_DEVEL("GJK: " << getMaxGJKIterations());
-   WALBERLA_LOG_DEVEL("EPA: " << getEPATolerance() );
-   WALBERLA_LOG_DEVEL(" CAPSULE <-> SPHERE (GJK) ");
-   WALBERLA_LOG_DEVEL( collideGJK(&c1, &sp1, contactPoint, contactNormal, penetrationDepth) );
-   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
-   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
-   WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth);
-   WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (GJK) ");
-   WALBERLA_LOG_DEVEL( collideGJK(&sp1, &c1, contactPoint, contactNormal, penetrationDepth) );
-   WALBERLA_LOG_WARNING("contactPoint    : " << contactPoint);
-   WALBERLA_LOG_WARNING("contactNormal   : " << contactNormal);
-   WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth);
    WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (ANALYTICAL) ");
    WALBERLA_LOG_DEVEL( collide(&sp1, &c1, contacts) );
    WALBERLA_LOG_WARNING("contactPoint    : " << contacts.at(0).getPosition());
    WALBERLA_LOG_WARNING("contactNormal   : " << contacts.at(0).getNormal());
    WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance());
-
 }
 
 void UnionTest()
 {
    typedef Union< boost::tuple<Sphere> > UnionT;
-   MaterialID iron = Material::find("iron");
    UnionT  un1(120, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false);
    UnionT  un2(121, 0, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), false, true, false);
-   SphereID sp1 = new Sphere(123, 1, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   un1.add(sp1);
-   SphereID sp2 = new Sphere(124, 2, Vec3(real_t(1.5),0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   un2.add(sp2);
+   auto sp1 = createSphere(&un1, 123, Vec3(0,0,0), 1);
+   auto sp2 = createSphere(&un2, 124, Vec3(real_t(1.5),0,0), 1);
 
    std::vector<Contact> contacts;
 
diff --git a/tests/pe/CollisionTobiasGJK.cpp b/tests/pe/CollisionTobiasGJK.cpp
index e800d11f80e76aed81568a148406c1e21578716b..46889c1eab92e2fb883173cb525fb324a510e00b 100644
--- a/tests/pe/CollisionTobiasGJK.cpp
+++ b/tests/pe/CollisionTobiasGJK.cpp
@@ -32,6 +32,7 @@
 #include "pe/rigidbody/Sphere.h"
 #include "pe/rigidbody/Plane.h"
 #include "pe/rigidbody/Union.h"
+#include "pe/rigidbody/UnionFactory.h"
 #include "pe/rigidbody/Ellipsoid.h"
 
 #include "pe/rigidbody/SetBodyTypeIDs.h"
@@ -48,7 +49,7 @@
 using namespace walberla;
 using namespace walberla::pe;
 
-typedef boost::tuple<Box, Capsule, Plane, Sphere, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>, Ellipsoid> BodyTuple ;
+typedef boost::tuple<Box, Capsule, Plane, Sphere, Union<boost::tuple<Sphere>>, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>, Ellipsoid> BodyTuple ;
 
 bool gjkEPAcollideHybrid(GeomPrimitive &geom1, GeomPrimitive &geom2, Vec3& normal, Vec3& contactPoint, real_t& penetrationDepth)
 {
@@ -63,6 +64,7 @@ bool gjkEPAcollideHybrid(GeomPrimitive &geom1, GeomPrimitive &geom2, Vec3& norma
       //2. If collision is possible perform EPA.
       //std::cerr << "Peforming EPA.";
       EPA epa;
+      epa.useSphereOptimization( true );
       return epa.doEPAmargin(geom1, geom2, gjk, normal, contactPoint, penetrationDepth, margin);
    }else{
       return false;
@@ -354,32 +356,29 @@ void UnionTest(){
    Box box(179, 179, Vec3(0,0,0), Vec3(0,0,0), Quat(), Vec3(real_t(10),real_t(2), real_t(10)), iron, false, true, false);
 
 
-   Union<boost::tuple<Sphere>> *unsub = new Union<boost::tuple<Sphere>>(192, 192, Vec3(0,real_t(3.8),0), Vec3(0,0,0), Quat(), false, true, false);
+   using UnionT = Union<boost::tuple<Sphere>>;
+   auto unsub = std::make_unique<UnionT>(192, 192, Vec3(0,real_t(3.8),0), Vec3(0,0,0), Quat(), false, true, false);
 
-   Sphere sp1( 180, 180, Vec3(-3,real_t(3.8),0), Vec3(0,0,0), Quat(), real_t(3.0)  , iron, false, true, false );
-   Sphere sp2( 181, 181, Vec3(3,real_t(3.8),0), Vec3(0,0,0), Quat(), real_t(3.0), iron, false, true, false );
-
-   Sphere sp3( 182, 182, Vec3(0,real_t(6),0), Vec3(0,0,0), Quat(), real_t(3.0), iron, false, true, false );
-   unsub->add(&sp1);
-   unsub->add(&sp2);
+   auto sp1 = createSphere(unsub.get(), 180, Vec3(-3,real_t(3.8),0), real_t(3.0));
+   auto sp2 = createSphere(unsub.get(), 181, Vec3(3,real_t(3.8),0), real_t(3.0));
 
    //Create another union, and add sub union
-   Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>> *un = new Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>(193, 193, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), false, true, false);
-   un->add(&sp3);
-   un->add(unsub);
+   Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>> un(193, 193, Vec3(0, 0, 0), Vec3(0,0,0), Quat(), false, true, false);
+   createSphere(&un, 182, Vec3(0,real_t(6),0), real_t(3.0));
+   un.add(std::move(unsub));
 
 
    PossibleContacts pcs;
-   pcs.push_back(std::pair<Union<boost::tuple<Sphere,Union<boost::tuple<Sphere>>>>*, Box*>(un, &box));
+   pcs.push_back(std::pair<Union<boost::tuple<Sphere,Union<boost::tuple<Sphere>>>>*, Box*>(&un, &box));
    Contacts& container = testFCD.generateContacts(pcs);
    WALBERLA_CHECK(container.size() == 2);
 
    Contact &c = container.back();
    WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() );
    if(c.getBody1()->getID() == 181) {
-      checkContact( c, Contact(&sp2, &box,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(sp2, &box,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else if (c.getBody1()->getID() == 179) {
-      checkContact( c, Contact(&box, &sp2,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(&box, sp2,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else {
       WALBERLA_ABORT("Unknown ID!");
    }
@@ -389,25 +388,25 @@ void UnionTest(){
    c = container.back();
    WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() );
    if(c.getBody1()->getID() == 180) {
-      checkContact( c, Contact(&sp1, &box,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(sp1, &box,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else if (c.getBody1()->getID() == 179) {
-      checkContact( c, Contact(&box, &sp1,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(&box, sp1,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else {
       WALBERLA_ABORT("Unknown ID!");
    }
    pcs.clear();
 
    //Vice Versa
-   pcs.push_back(std::pair<Box*, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>* >(&box, un));
+   pcs.push_back(std::pair<Box*, Union<boost::tuple<Sphere, Union<boost::tuple<Sphere>>>>* >(&box, &un));
    container = testFCD.generateContacts(pcs);
    WALBERLA_CHECK(container.size() == 2);
 
    c = container.back();
    WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() );
    if(c.getBody1()->getID() == 181) {
-      checkContact( c, Contact(&sp2, &box,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(sp2, &box,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else if (c.getBody1()->getID() == 179) {
-      checkContact( c, Contact(&box, &sp2,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(&box, sp2,  Vec3(real_t(3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else {
       WALBERLA_ABORT("Unknown ID!");
    }
@@ -416,9 +415,9 @@ void UnionTest(){
    c = container.back();
    WALBERLA_LOG_DEVEL( c.getDistance() << " " << c.getNormal() << " " << c.getPosition() );
    if(c.getBody1()->getID() == 180) {
-      checkContact( c, Contact(&sp1, &box,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(sp1, &box,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, 1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else if (c.getBody1()->getID() == 179) {
-      checkContact( c, Contact(&box, &sp1,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
+      checkContact( c, Contact(&box, sp1,  Vec3(real_t(-3), real_t(0.9), 0), Vec3(0, -1, 0), real_t(-0.2)), Vec3(0,0,0));
    } else {
       WALBERLA_ABORT("Unknown ID!");
    }
diff --git a/tests/pe/DeleteBody.cpp b/tests/pe/DeleteBody.cpp
index 64f03d42a807a89b5cce96903acf13ee7fe5220d..a37e73bff82f8443dc943da092bee612795d60ad 100644
--- a/tests/pe/DeleteBody.cpp
+++ b/tests/pe/DeleteBody.cpp
@@ -31,6 +31,8 @@
 #include "core/debug/TestSubsystem.h"
 #include "core/math/Random.h"
 
+#include <functional>
+
 using namespace walberla;
 using namespace walberla::pe;
 
@@ -83,10 +85,10 @@ int main( int argc, char** argv )
     std::function<void(void)> syncCall;
     if (!syncShadowOwners)
     {
-       syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+       syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
     } else
     {
-       syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+       syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
     }
 
     pe::createSphere(*globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5), 2);
diff --git a/tests/pe/ForceSync.cpp b/tests/pe/ForceSync.cpp
index f0901d1b7039d9082dd6ed3569af9bf364d72f40..b97d408077ded3ce50672eddca66ff49b0bc35a0 100644
--- a/tests/pe/ForceSync.cpp
+++ b/tests/pe/ForceSync.cpp
@@ -98,12 +98,12 @@ int main( int argc, char ** argv )
 
       for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt)
       {
-         BodyID b = *bodyIt;
+         BodyID b = bodyIt.getBodyID();
          b->addForce( Vec3(1,0,0) );
       }
       for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt)
       {
-         BodyID b = *bodyIt;
+         BodyID b = bodyIt.getBodyID();
          b->addForce( Vec3(0,1,0) );
       }
    }
@@ -127,12 +127,12 @@ int main( int argc, char ** argv )
 
 //      for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt)
 //      {
-//         BodyID b = *bodyIt;
+//         BodyID b = bodyIt.getBodyID();
 //         WALBERLA_LOG_DEVEL("LOCAL\n" << b << "\nForce: " << b->getForce());
 //      }
 //      for (auto bodyIt = shadowStorage.begin(); bodyIt != shadowStorage.end(); ++bodyIt)
 //      {
-//         BodyID b = *bodyIt;
+//         BodyID b = bodyIt.getBodyID();
 //         WALBERLA_LOG_DEVEL("SHADOW\n" << b << "\nForce: " << b->getForce());
 //      }
 //   }
diff --git a/tests/pe/HCSITS.cpp b/tests/pe/HCSITS.cpp
index 3a133974f2ed1cf861dabad3e002a799728f31ea..c5e3a2d742e0d058448270ba9e285a003df6a6b5 100644
--- a/tests/pe/HCSITS.cpp
+++ b/tests/pe/HCSITS.cpp
@@ -93,6 +93,10 @@ void normalReactionTest(cr::HCSITS& cr, SphereID sp)
    cr.timestep( real_c( real_t(1.0) ) );
    WALBERLA_CHECK_FLOAT_EQUAL( sp->getPosition() , Vec3(5,5,real_t(6.1)) );
    WALBERLA_CHECK_FLOAT_EQUAL( sp->getLinearVel(), Vec3(0,0,real_t(-0.1)) );
+
+   cr.timestep( real_c( real_t(1.0) ) );
+   WALBERLA_CHECK_FLOAT_EQUAL( sp->getPosition() , Vec3(5,5,real_t(6.1)) );
+   WALBERLA_CHECK_FLOAT_EQUAL( sp->getLinearVel(), Vec3(0,0,real_t(0)) );
    contactThreshold = Thresholds<real_t>::contactThreshold();
 }
 
diff --git a/tests/pe/HashGrids.cpp b/tests/pe/HashGrids.cpp
index a1790653be79c8c55fb3a8edab2b760371948bcb..7b203cbe8e0baf7173e7d4f3ee231f2996d883b9 100644
--- a/tests/pe/HashGrids.cpp
+++ b/tests/pe/HashGrids.cpp
@@ -115,7 +115,8 @@ int main( int argc, char** argv )
                      iron, true, false, true);
 
     syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID);
-    for (int step=0; step < 100; ++step){
+    for (int step=0; step < 100; ++step)
+    {
        cr( real_c(0.1) );
        syncShadowOwners<BodyTuple>( forest->getBlockForest(), storageID);
 
diff --git a/tests/pe/Marshalling.cpp b/tests/pe/Marshalling.cpp
index 30da9d3be10fbad20a2e545dbfa915a85a988ac0..985269bd619ad65d799ffc62efb6524deefa82e1 100644
--- a/tests/pe/Marshalling.cpp
+++ b/tests/pe/Marshalling.cpp
@@ -41,11 +41,14 @@ using namespace walberla::pe::communication;
 typedef boost::tuple<Sphere>       UnionTypeTuple;
 typedef Union< UnionTypeTuple >    UnionT;
 typedef UnionT*                    UnionID;
+typedef std::unique_ptr<UnionT>    UnionPtr;
 
 typedef boost::tuple<Box, Capsule, Sphere, Squirmer, UnionT, Ellipsoid> BodyTuple ;
 
 void testBox()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testBox ***");
+
    MaterialID iron = Material::find("iron");
 
    Box b1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(1,2,3), iron, false, true, false);
@@ -56,7 +59,8 @@ void testBox()
    MarshalDynamically<BodyTuple>::execute(sb, b1);
    mpi::RecvBuffer rb(sb);
 
-   BoxID b2 = static_cast<BoxID> (UnmarshalDynamically<BodyTuple>::execute(rb, Box::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto bPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Box::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   BoxID b2 = static_cast<BoxID>(bPtr.get());
 
    WALBERLA_CHECK_FLOAT_EQUAL(b1.getPosition(), b2->getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(b1.getLinearVel(), b2->getLinearVel());
@@ -68,6 +72,8 @@ void testBox()
 
 void testCapsule()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testCapsule ***");
+
    MaterialID iron = Material::find("iron");
 
    Capsule c1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, 7, iron, false, false, false);
@@ -78,7 +84,8 @@ void testCapsule()
    MarshalDynamically<BodyTuple>::execute(sb, c1);
    mpi::RecvBuffer rb(sb);
 
-   CapsuleID c2 = static_cast<CapsuleID> (UnmarshalDynamically<BodyTuple>::execute(rb, Capsule::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto cPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Capsule::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   CapsuleID c2 = static_cast<CapsuleID> (cPtr.get());
 
    WALBERLA_CHECK_FLOAT_EQUAL(c1.getPosition(), c2->getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(c1.getLinearVel(), c2->getLinearVel());
@@ -91,6 +98,8 @@ void testCapsule()
 
 void testSphere()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testSphere ***");
+
    MaterialID iron = Material::find("iron");
 
    Sphere s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), 5, iron, false, false, false);
@@ -101,7 +110,8 @@ void testSphere()
    MarshalDynamically<BodyTuple>::execute(sb, s1);
    mpi::RecvBuffer rb(sb);
 
-   SphereID s2 = static_cast<SphereID> (UnmarshalDynamically<BodyTuple>::execute(rb, Sphere::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto sPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Sphere::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   SphereID s2 = static_cast<SphereID> (sPtr.get());
 
    WALBERLA_CHECK_FLOAT_EQUAL(s1.getPosition(), s2->getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(s1.getLinearVel(), s2->getLinearVel());
@@ -113,6 +123,8 @@ void testSphere()
 
 void testSquirmer()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testSquirmer ***");
+
    MaterialID iron = Material::find("iron");
 
    Squirmer s1(759846, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), real_c(5), real_c(0.1), real_c(4.93), iron, false, false, false);
@@ -123,7 +135,8 @@ void testSquirmer()
    MarshalDynamically<BodyTuple>::execute(sb, s1);
    mpi::RecvBuffer rb(sb);
 
-   SquirmerID s2 = static_cast<SquirmerID> (UnmarshalDynamically<BodyTuple>::execute(rb, Squirmer::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto sPtr = UnmarshalDynamically<BodyTuple>::execute(rb, Squirmer::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   SquirmerID s2 = static_cast<SquirmerID> (sPtr.get());
 
    WALBERLA_CHECK_FLOAT_EQUAL(s1.getSquirmerVelocity(), s2->getSquirmerVelocity());
    WALBERLA_CHECK_FLOAT_EQUAL(s1.getSquirmerBeta(), s2->getSquirmerBeta());
@@ -131,6 +144,8 @@ void testSquirmer()
 
 void testEllipsoid()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testEllipsoid ***");
+
    MaterialID iron = Material::find("iron");
 
    Ellipsoid e1(759847, 1234795, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), Vec3(3,1,5), iron, false, false, false);
@@ -141,7 +156,8 @@ void testEllipsoid()
    MarshalDynamically<BodyTuple>::execute(sb, e1);
    mpi::RecvBuffer rb(sb);
 
-   EllipsoidID e2 = static_cast<EllipsoidID> (UnmarshalDynamically<BodyTuple>::execute(rb, Ellipsoid::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto ePtr = UnmarshalDynamically<BodyTuple>::execute(rb, Ellipsoid::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   EllipsoidID e2 = static_cast<EllipsoidID>(ePtr.get());
 
    WALBERLA_CHECK_FLOAT_EQUAL(e1.getPosition(), e2->getPosition());
    WALBERLA_CHECK_FLOAT_EQUAL(e1.getLinearVel(), e2->getLinearVel());
@@ -153,6 +169,7 @@ void testEllipsoid()
 
 void testUnion()
 {
+   WALBERLA_LOG_INFO_ON_ROOT("*** testUnion ***");
    UnionT u1(159, 423, Vec3(real_c(1), real_c(2), real_c(3)), Vec3(0,0,0), Quat(), false, false, false);
    SphereID s11 = createSphere< UnionTypeTuple >(&u1, 1234794, Vec3(real_c(1), real_c(2), real_c(3)), 2);
    SphereID s21 = createSphere< UnionTypeTuple >(&u1, 4567789, Vec3(real_c(3), real_c(2), real_c(3)), real_c(1.5));
@@ -163,15 +180,16 @@ void testUnion()
    MarshalDynamically<BodyTuple>::execute(sb, u1);
    mpi::RecvBuffer rb(sb);
 
-   UnionID u2 = static_cast<UnionID> (UnmarshalDynamically<BodyTuple>::execute(rb, UnionT::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100))));
+   auto uPtr = UnmarshalDynamically<BodyTuple>::execute(rb, UnionT::getStaticTypeID(), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)), math::AABB(Vec3(-100,-100,-100), Vec3(100,100,100)));
+   UnionID u2 = static_cast<UnionID>(uPtr.get());
    WALBERLA_CHECK_NOT_NULLPTR( u2 );
 
    WALBERLA_CHECK_EQUAL(u1.size(), 2);
    WALBERLA_CHECK_EQUAL(u1.size(), u2->size());
 
    //getting spheres of second union
-   SphereID s12 = static_cast<SphereID> (*(u2->begin()));
-   SphereID s22 = static_cast<SphereID> (*(++(u2->begin())));
+   SphereID s12 = static_cast<SphereID> (u2->begin().getBodyID());
+   SphereID s22 = static_cast<SphereID> ((++(u2->begin())).getBodyID());
    WALBERLA_CHECK_UNEQUAL( s12, s22 );
 
    WALBERLA_CHECK_FLOAT_EQUAL( s11->getPosition(),    s12->getPosition());
diff --git a/tests/pe/MinMaxRefinement.cpp b/tests/pe/MinMaxRefinement.cpp
index 458052c0e4f1853e3ab03b8f45e91c040915699e..3c13d4cfbc7fc6aa974a9cb6f0688e98d813965c 100644
--- a/tests/pe/MinMaxRefinement.cpp
+++ b/tests/pe/MinMaxRefinement.cpp
@@ -144,7 +144,7 @@ int main( int argc, char ** argv )
       ccd->reloadBodies();
    }
 
-   WALBERLA_CHECK_EQUAL( blockforest.size(), mpi::MPIManager::instance()->worldRank() == 6 ? 1 : 0);
+   WALBERLA_CHECK_EQUAL( blockforest.size(), mpi::MPIManager::instance()->worldRank() == 0 ? 1 : 0);
    WALBERLA_LOG_DEVEL( infoCollection->size() );
 
    for (unsigned int i = 0; i < 30; ++i)
diff --git a/tests/pe/ParallelEquivalence.cpp b/tests/pe/ParallelEquivalence.cpp
index 6a211cd6739ad9613e682832b7269d9d5184531a..03aac6f6fa2f73fdc69422287f9dc6e1a45504cf 100644
--- a/tests/pe/ParallelEquivalence.cpp
+++ b/tests/pe/ParallelEquivalence.cpp
@@ -157,7 +157,7 @@ void sim(shared_ptr< StructuredBlockForest > forest, std::vector<BodyData>& res,
       BodyStorage& localStorage = (*storage)[0];
       for (auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt)
       {
-         BodyID b = *bodyIt;
+         BodyID b = bodyIt.getBodyID();
          res.push_back(BodyData(b->getID(), b->getPosition(), b->getLinearVel()));
       }
    }
diff --git a/tests/pe/RigidBody.cpp b/tests/pe/RigidBody.cpp
index 58926892dfa4786e5baaa3a9413bbf04df96390c..ad3e0facb2e5fb3900fccbc4c042b5a341640c1c 100644
--- a/tests/pe/RigidBody.cpp
+++ b/tests/pe/RigidBody.cpp
@@ -39,10 +39,6 @@ void move( BodyStorage& storage, real_t dt )
       WALBERLA_ASSERT( it->checkInvariants(), "Invalid capsule state detected" );
       WALBERLA_ASSERT( !it->hasSuperBody(), "Invalid superordinate body detected" );
 
-      // Resetting the contact node and removing all attached contacts
-//      it->resetNode();
-      it->clearContacts();
-
       // Moving the capsule according to the acting forces (don't move a sleeping body)
       if( it->isAwake() ) {
          if( !it->hasInfiniteMass() ) {
@@ -86,10 +82,10 @@ void move( BodyStorage& storage, real_t dt )
 void checkRotationFunctions()
 {
    MaterialID iron = Material::find("iron");
-   auto sp1 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) );
-   auto sp2 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) );
-   auto sp3 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) );
-   auto sp4 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false) );
+   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false );
+   auto sp2 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false );
+   auto sp3 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false );
+   auto sp4 = std::make_shared<Sphere>( 0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false );
 
    sp1->rotate( 1, 0, 0, math::M_PI * real_t(0.5));
    sp1->rotate( 0, 1, 0, math::M_PI * real_t(0.5));
@@ -125,7 +121,7 @@ void checkRotationFunctions()
 void checkPointFunctions()
 {
    MaterialID iron = Material::find("iron");
-   auto sp1 = shared_ptr<Sphere>( new Sphere(0, 0, Vec3(10,10,10), Vec3(0,0,0), Quat(), 1, iron, false, true, false) );
+   auto sp1 = std::make_shared<Sphere>( 0, 0, Vec3(10,10,10), Vec3(0,0,0), Quat(), 1, iron, false, true, false );
 
    WALBERLA_CHECK( sp1->containsPoint( 10, 10, 10 ) );
    WALBERLA_CHECK( sp1->containsPoint( real_c(10.9), 10, 10 ) );
@@ -152,8 +148,8 @@ int main( int argc, char** argv )
 
    MaterialID iron = Material::find("iron");
    BodyStorage storage;
-   SphereID sphere = new Sphere(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
-   storage.add(sphere);
+   SpherePtr spPtr = std::make_unique<Sphere>(0, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), 1, iron, false, true, false);
+   SphereID sphere = static_cast<SphereID>(&storage.add(std::move(spPtr)));
 
    Vec3 x0 = Vec3(-2,2,0);
    Vec3 v0 = Vec3(-1,-1,1);
diff --git a/tests/pe/ShadowCopy.cpp b/tests/pe/ShadowCopy.cpp
index cbd4958e34ede91c698393f37f42633925f15abc..8c5dba7c4ad95888979f9b6c88f6109fc763d475 100644
--- a/tests/pe/ShadowCopy.cpp
+++ b/tests/pe/ShadowCopy.cpp
@@ -19,6 +19,7 @@
 //======================================================================================================================
 
 #include "pe/basic.h"
+#include "pe/rigidbody/UnionFactory.h"
 #include "pe/utility/GetBody.h"
 #include "pe/utility/DestroyBody.h"
 
@@ -28,6 +29,8 @@
 
 #include "core/debug/TestSubsystem.h"
 
+#include <functional>
+
 using namespace walberla;
 using namespace walberla::pe;
 
@@ -65,10 +68,10 @@ int main( int argc, char** argv )
    std::function<void(void)> syncCall;
    if (!syncShadowOwners)
    {
-      syncCall = boost::bind( pe::syncNextNeighbors<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
    } else
    {
-      syncCall = boost::bind( pe::syncShadowOwners<BodyTuple>, boost::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
+      syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(forest->getBlockForest()), storageID, static_cast<WcTimingTree*>(NULL), real_c(0.0), false );
    }
 
    WALBERLA_LOG_PROGRESS_ON_ROOT( " *** SPHERE *** ");
@@ -93,12 +96,9 @@ int main( int argc, char** argv )
    destroyBodyBySID( *globalBodyStorage, forest->getBlockStorage(), storageID, sid );
 
    WALBERLA_LOG_PROGRESS_ON_ROOT( " *** UNION *** ");
-   MaterialID iron = Material::find("iron");
    UnionT* un   = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(2,2,2) );
-   SphereID sp1 = new Sphere( 10, 0, Vec3(real_t(4.9),2,2), Vec3(0,0,0), Quat(), real_t(1)  , iron, false, true, false );
-   SphereID sp2 = new Sphere( 11, 0, Vec3(3,2,2)          , Vec3(0,0,0), Quat(), real_t(1.5), iron, false, true, false );
-   un->add(sp1);
-   un->add(sp2);
+   auto sp1 = createSphere(un, 10, Vec3(real_t(4.9),2,2), real_t(1));
+   auto sp2 = createSphere(un, 11, Vec3(3,2,2), real_t(1.5));
    un->setPosition( Vec3( real_t(4.9), 2, 2) );
    auto relPosSp1 = sp1->getRelPosition();
    auto relPosSp2 = sp2->getRelPosition();
@@ -111,8 +111,8 @@ int main( int argc, char** argv )
    syncCall();
 
    un  = static_cast<UnionT*> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL ));
-   sp1 = static_cast<SphereID> (*(un->begin()));
-   sp2 = static_cast<SphereID> (*(++(un->begin())));
+   sp1 = static_cast<SphereID> (un->begin().getBodyID());
+   sp2 = static_cast<SphereID> ((++(un->begin())).getBodyID());
    WALBERLA_CHECK_NOT_NULLPTR(sp1);
    WALBERLA_CHECK_NOT_NULLPTR(sp2);
    WALBERLA_CHECK_EQUAL( sp1->getTypeID(), Sphere::getStaticTypeID() );
@@ -150,8 +150,8 @@ int main( int argc, char** argv )
 
    posUnion = Vec3(real_t(0.9),2,2);
    un  = static_cast<UnionT*> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL ));
-   sp1 = static_cast<SphereID> (*(un->begin()));
-   sp2 = static_cast<SphereID> (*(++(un->begin())));
+   sp1 = static_cast<SphereID> (un->begin().getBodyID());
+   sp2 = static_cast<SphereID> ((++(un->begin())).getBodyID());
    WALBERLA_CHECK_NOT_NULLPTR(sp1);
    WALBERLA_CHECK_NOT_NULLPTR(sp2);
    WALBERLA_CHECK_EQUAL( sp1->getTypeID(), Sphere::getStaticTypeID() );
diff --git a/tests/pe/SimpleCCD.cpp b/tests/pe/SimpleCCD.cpp
index cd0095811a842b11aa2d3bc2d54d95c60d93a0b9..527a846383cb8931c3215e5a16352093918f4699 100644
--- a/tests/pe/SimpleCCD.cpp
+++ b/tests/pe/SimpleCCD.cpp
@@ -19,18 +19,19 @@
 //======================================================================================================================
 
 #include "pe/Materials.h"
-#include "pe/rigidbody/Sphere.h"
 #include "pe/Types.h"
 #include "pe/rigidbody/BodyStorage.h"
+#include "pe/rigidbody/SetBodyTypeIDs.h"
+#include "pe/rigidbody/Sphere.h"
 #include "pe/ccd/SimpleCCD.h"
 #include "pe/ccd/HashGrids.h"
 #include "pe/fcd/SimpleFCD.h"
-#include "core/DataTypes.h"
 
+#include "core/DataTypes.h"
+#include "core/UniqueID.h"
 #include "core/timing/TimingPool.h"
 #include "core/debug/TestSubsystem.h"
 #include "core/math/Random.h"
-#include "core/UniqueID.h"
 
 using namespace walberla;
 using namespace walberla::pe;
@@ -43,6 +44,8 @@ int main( int argc, char** argv )
 
     walberla::MPIManager::instance()->initializeMPI( &argc, &argv );
 
+    SetBodyTypeIDs<BodyTuple>::execute();
+
     MaterialID iron = Material::find("iron");
 
     BodyStorage globalStorage;
@@ -57,7 +60,7 @@ int main( int argc, char** argv )
     math::seedRandomGenerator(1337);
 
     for (uint_t i = 0; i < 100; ++i)
-      storage[0].add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) );
+      storage[0].add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) );
 
     sccd.generatePossibleContacts();
 
@@ -67,7 +70,7 @@ int main( int argc, char** argv )
 
     WALBERLA_LOG_DEVEL( s_fcd.getContacts().size() );
 
-    BodyID bd = *(storage[0].begin() + 5);
+    BodyID bd = (storage[0].begin() + 5).getBodyID();
     storage[0].remove( bd );
 
     sccd.generatePossibleContacts();
@@ -81,14 +84,14 @@ int main( int argc, char** argv )
 
     bs.clear();
 
-    bs.add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) );
+    bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 1, iron, false, false, false) );
 
     WcTimingPool pool;
     for (int runs = 0; runs < 10; ++runs)
     {
        auto oldSize = bs.size();
        for (uint_t i = 0; i < oldSize; ++i)
-         bs.add( new Sphere(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 0.5, iron, false, false, false) );
+         bs.add( std::make_unique<Sphere>(UniqueID<Sphere>::createGlobal(), 0, Vec3( math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10)), math::realRandom(real_c(0), real_c(10))), Vec3(0,0,0), Quat(), 0.5, iron, false, false, false) );
        pool["SCCD"].start();
        sccd.generatePossibleContacts();
        pool["SCCD"].end();
diff --git a/tests/pe/SyncEquivalence.cpp b/tests/pe/SyncEquivalence.cpp
index c311e1d6728ebd00a11b86451b0a8b208ef94d33..6afd4f8670bc0ceeac07567021c9581516887241 100644
--- a/tests/pe/SyncEquivalence.cpp
+++ b/tests/pe/SyncEquivalence.cpp
@@ -115,7 +115,7 @@ void createSimulation(math::AABB& simulationDomain,
     info.ccdID               = info.forest->addBlockData(ccd::createHashGridsDataHandling( info.globalBodyStorage, info.storageID ), "CCD");
     info.fcdID               = info.forest->addBlockData(fcd::createGenericFCDDataHandling<BodyTuple, fcd::AnalyticCollideFunctor>(), "FCD");
 
-    info.cr = shared_ptr<cr::ICR>(new cr::HCSITS(info.globalBodyStorage, info.forest->getBlockStoragePointer(), info.storageID, info.ccdID, info.fcdID) );
+    info.cr = std::make_shared<cr::HCSITS>(info.globalBodyStorage, info.forest->getBlockStoragePointer(), info.storageID, info.ccdID, info.fcdID );
 
     int numParticles = int_c(0);
 
@@ -227,7 +227,7 @@ int main( int argc, char ** argv )
                   WALBERLA_CHECK_EQUAL(shadowOwnersIt1->blockID_, shadowOwnersIt2->blockID_);
                }
 
-               checkVitalParameters( static_cast<SphereID>(*bodyIt1), static_cast<SphereID>(*bodyIt2) );
+               checkVitalParameters( static_cast<SphereID>(bodyIt1.getBodyID()), static_cast<SphereID>(bodyIt2.getBodyID()) );
 
             }
         }
diff --git a/tests/pe/Synchronization.cpp b/tests/pe/Synchronization.cpp
index c8ad534ffe4d84a832ba4e4986eacc1e62d72501..17d33c41be16009ad7a04fd91239f9f76ccdaaa1 100644
--- a/tests/pe/Synchronization.cpp
+++ b/tests/pe/Synchronization.cpp
@@ -39,7 +39,7 @@ using namespace walberla::blockforest;
 
 typedef boost::tuple<Sphere> BodyTuple ;
 
-void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla::id_t sid, SphereID ref, const Vec3& newPos)
+void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla::id_t sid, Sphere& ref, const Vec3& newPos)
 {
    for (auto it = forest.begin(); it != forest.end(); ++it)
    {
@@ -47,37 +47,37 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla:
       Storage& storage  = *(block.getData<Storage>(storageID));
       BodyStorage& shadowStorage = storage[1];
 
-      if (block.getAABB().contains( ref->getPosition() ))
+      if (block.getAABB().contains( ref.getPosition() ))
       {
-         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1, "pos: " <<  ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
-         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
-         SphereID bd = static_cast<SphereID> (*(storage[StorageType::LOCAL].find( sid )));
+         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1, "pos: " <<  ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
+         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
+         SphereID bd = static_cast<SphereID> (storage[StorageType::LOCAL].find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
-         checkVitalParameters(bd, ref);
+         checkVitalParameters(bd, &ref);
          WALBERLA_LOG_DEVEL("#shadows: " << bd->MPITrait.sizeShadowOwners() << " #block states set: " << bd->MPITrait.getBlockStateSize() << "\nowner domain: " << block.getAABB() << "\nowner: " << bd->MPITrait.getOwner());
          bd->setPosition( newPos );
-      } else if (forest.periodicIntersect(block.getAABB(), ref->getAABB()) )
+      } else if (forest.periodicIntersect(block.getAABB(), ref.getAABB()) )
       {
-         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
-         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
-         SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid )));
+         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
+         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
+         SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
-         auto backupPos =ref->getPosition();
-         auto correctedPos = ref->getPosition();
+         auto backupPos =ref.getPosition();
+         auto correctedPos = ref.getPosition();
          pe::communication::correctBodyPosition(forest.getDomain(), block.getAABB().center(), correctedPos);
-         ref->setPosition(correctedPos);
-         checkVitalParameters(bd, ref);
-         ref->setPosition(backupPos);
+         ref.setPosition(correctedPos);
+         checkVitalParameters(bd, &ref);
+         ref.setPosition(backupPos);
       } else
       {
-         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
-         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref->getPosition() << "\nradius: " << ref->getRadius() <<  "\ndomain: " << block.getAABB() );
+         WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
+         WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0, "pos: " << ref.getPosition() << "\nradius: " << ref.getRadius() <<  "\ndomain: " << block.getAABB() );
       }
    }
-   WALBERLA_LOG_PROGRESS("checked pos: " << ref->getPosition() << " | new pos: " << newPos);
+   WALBERLA_LOG_PROGRESS("checked pos: " << ref.getPosition() << " | new pos: " << newPos);
    auto temp = newPos;
    forest.mapToPeriodicDomain(temp);
-   ref->setPosition(temp);
+   ref.setPosition(temp);
 }
 
 int main( int argc, char ** argv )
@@ -117,9 +117,9 @@ int main( int argc, char ** argv )
 
    MaterialID iron = Material::find("iron");
    walberla::id_t sid = 123;
-   SphereID refSphere = new Sphere(1, 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false);
-   refSphere->setLinearVel(4, 5, 6);
-   refSphere->setAngularVel( 1, 2, 3);
+   Sphere refSphere(1, 0, Vec3(15, 15, 15), Vec3(0,0,0), Quat(), 3, iron, false, true, false);
+   refSphere.setLinearVel(4, 5, 6);
+   refSphere.setAngularVel( 1, 2, 3);
    Vec3 gpos = Vec3(15, 15, 15);
 
    SphereID sphere = createSphere( globalStorage, forest->getBlockStorage(), storageID, 0, gpos, 3);
diff --git a/tests/pe/SynchronizationLargeBody.cpp b/tests/pe/SynchronizationLargeBody.cpp
index ab7123da2b10ac22081e798867e8584315fdc9d7..6bf99cc4700baa403698e23964c9a73139c14953 100644
--- a/tests/pe/SynchronizationLargeBody.cpp
+++ b/tests/pe/SynchronizationLargeBody.cpp
@@ -51,7 +51,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla:
       {
          WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1 );
          WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0 );
-         SphereID bd = static_cast<SphereID> (*(storage[0].find( sid )));
+         SphereID bd = static_cast<SphereID> (storage[0].find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
          checkVitalParameters(bd, ref);
          bd->setPosition( newPos );
@@ -59,7 +59,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla:
       {
          WALBERLA_CHECK_EQUAL( storage[0].size(), 0 );
          WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1 );
-         SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid )));
+         SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
          auto backupPos =ref->getPosition();
          auto correctedPos = ref->getPosition();
@@ -92,7 +92,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla:
       {
          WALBERLA_CHECK_EQUAL( storage[StorageType::LOCAL].size(), 1 );
          WALBERLA_CHECK_EQUAL( shadowStorage.size(), 0 );
-         SphereID bd = static_cast<SphereID> (*(storage[0].find( sid )));
+         SphereID bd = static_cast<SphereID> (storage[0].find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
          checkVitalParameters(bd, ref);
          bd->setPosition( newPos );
@@ -100,7 +100,7 @@ void checkSphere(StructuredBlockForest& forest, BlockDataID storageID, walberla:
       {
          WALBERLA_CHECK_EQUAL( storage[0].size(), 0 );
          WALBERLA_CHECK_EQUAL( shadowStorage.size(), 1, "ref_sphere: " << ref << "\n" << block.getAABB() );
-         SphereID bd = static_cast<SphereID> (*(shadowStorage.find( sid )));
+         SphereID bd = static_cast<SphereID> (shadowStorage.find( sid ).getBodyID());
          WALBERLA_CHECK_NOT_NULLPTR(bd);
          auto backupPos =ref->getPosition();
          auto correctedPos = ref->getPosition();
@@ -161,9 +161,9 @@ int main( int argc, char ** argv )
    walberla::id_t sid = 123;
    Vec3 gpos = Vec3(3.5, 3.5, 3.5);
    const real_t r = real_c(1.6);
-   SphereID refSphere = new Sphere(1, 0, gpos, Vec3(0,0,0), Quat(), r, iron, false, true, false);
-   refSphere->setLinearVel(4, 5, 6);
-   refSphere->setAngularVel( 1, 2, 3);
+   Sphere refSphere(1, 0, gpos, Vec3(0,0,0), Quat(), r, iron, false, true, false);
+   refSphere.setLinearVel(4, 5, 6);
+   refSphere.setAngularVel( 1, 2, 3);
 
 
    SphereID sphere = createSphere( *globalStorage, forest->getBlockStorage(), storageID, 0, gpos, r);
@@ -203,10 +203,10 @@ int main( int argc, char ** argv )
       for (int i = 0; i < 21; ++i)
       {
          syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID);
-         Vec3 pos = refSphere->getPosition() + delta;
+         Vec3 pos = refSphere.getPosition() + delta;
          if (!forest->getDomain().contains( pos, real_c(0.5) ))
             forest->mapToPeriodicDomain(pos);
-         checkSphere(*forest, storageID, sid, refSphere, pos);
+         checkSphere(*forest, storageID, sid, &refSphere, pos);
       }
    }
    WALBERLA_LOG_PROGRESS("TEST WITHOUT DX ... finished");
@@ -225,10 +225,10 @@ int main( int argc, char ** argv )
       for (int i = 0; i < 21; ++i)
       {
          syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID, NULL, dx);
-         Vec3 pos = refSphere->getPosition() + delta;
+         Vec3 pos = refSphere.getPosition() + delta;
          if (!forest->getDomain().contains( pos, real_c(0.5) ))
             forest->mapToPeriodicDomain(pos);
-         checkSphere(*forest, storageID, sid, refSphere, pos, dx);
+         checkSphere(*forest, storageID, sid, &refSphere, pos, dx);
       }
    }
    syncShadowOwners<BodyTuple>(forest->getBlockForest(), storageID, NULL, dx);
diff --git a/tests/pe/Union.cpp b/tests/pe/Union.cpp
index 6cd0aec53e1e26b978b0085a67a04ae74b15fc0e..1a814c28a1a6a789eadf5a34d1c352f23b0baf8b 100644
--- a/tests/pe/Union.cpp
+++ b/tests/pe/Union.cpp
@@ -25,6 +25,7 @@
 
 #include "pe/basic.h"
 #include "pe/rigidbody/Union.h"
+#include "pe/rigidbody/UnionFactory.h"
 #include "pe/ccd/SimpleCCDDataHandling.h"
 #include "pe/synchronization/SyncNextNeighbors.h"
 #include "pe/vtk/BodyVtkOutput.h"
@@ -75,12 +76,9 @@ void SnowManFallingOnPlane()
 
    createPlane( *globalBodyStorage, 0, Vec3(0,0,1), Vec3(0,0,0) );
 
-   MaterialID iron = Material::find("iron");
-   UnionType* un   = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5) );
-   SphereID sp1 = new Sphere( 10, 0, Vec3(5,5,1), Vec3(0,0,0), Quat(), real_t(1)  , iron, false, true, false );
-   SphereID sp2 = new Sphere( 11, 0, Vec3(real_t(6.7),5,real_t(1.2)), Vec3(0,0,0), Quat(), real_t(1.1), iron, false, true, false );
-   un->add(sp1);
-   un->add(sp2);
+   UnionType* un  = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(5,5,5) );
+   auto sp1       = createSphere(un, 10, Vec3(5,5,1), real_t(1));
+   auto sp2       = createSphere(un, 11, Vec3(real_t(6.7),5,real_t(1.2)), real_t(1.1));
 
    auto distance = (sp1->getPosition() - sp2->getPosition()).length();
 
@@ -106,14 +104,15 @@ void ImpulsCarryover()
 {
    MaterialID iron = Material::find("iron");
 
-   UnionType* un   = new Union< boost::tuple<Sphere> >(12, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false);
-   SphereID sp1    = new Sphere( 10, 0, Vec3( 1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
-   SphereID sp2    = new Sphere( 11, 0, Vec3(-1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto un  = std::make_unique<UnionType>(12, 0, Vec3(0,0,0), Vec3(0,0,0), Quat(), false, true, false);
+   auto sp1 = std::make_unique<Sphere>( 10, 0, Vec3( 1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+   auto sp2 = std::make_unique<Sphere>( 11, 0, Vec3(-1,0,0), Vec3(0,0,0), Quat(), real_t(1), iron, false, true, false );
+
    sp1->setLinearVel(Vec3(0,real_c(+1),0));
    sp2->setLinearVel(Vec3(0,real_c(-1),0));
 
-   un->add(sp1);
-   un->add(sp2);
+   un->add( std::move(sp1) );
+   un->add( std::move(sp2) );
 
    WALBERLA_CHECK_FLOAT_EQUAL( un->getPosition(),  Vec3(0,0,0) );
    WALBERLA_CHECK_FLOAT_EQUAL( un->getLinearVel(), Vec3(0,0,0) );
diff --git a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
index d9fd267079e1b78d322a80ff1e7afdd1aabc3755..ca71c9f03e5f806abae1842c53190c4847dae8fd 100644
--- a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
@@ -44,6 +44,7 @@
 
 #include "vtk/VTKOutput.h"
 
+#include <functional>
 #include <vector>
 #include <iomanip>
 #include <iostream>
@@ -851,7 +852,7 @@ int main( int argc, char **argv )
 
    // connect to pe
    const real_t overlap = real_t( 1.5 ) * dx;
-   auto syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   auto syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
    shared_ptr<CollisionPropertiesEvaluator> collisionPropertiesEvaluator = walberla::make_shared<CollisionPropertiesEvaluator>( *cr );
 
    // create the spheres
@@ -1147,7 +1148,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1155,7 +1156,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::IKernel) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -1165,7 +1166,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1173,7 +1174,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::ITrilinear) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -1183,7 +1184,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -1191,7 +1192,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       }
    }
@@ -1211,7 +1212,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1219,7 +1220,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1230,7 +1231,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1238,7 +1239,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1249,7 +1250,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1257,7 +1258,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1271,7 +1272,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1279,7 +1280,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1290,7 +1291,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1298,7 +1299,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1309,7 +1310,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1317,7 +1318,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1329,13 +1330,13 @@ int main( int argc, char **argv )
       {
          typedef pe_coupling::LubricationCorrection LE_T;
          shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance );
-         lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval);
+         lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval);
       }
       else
       {
          typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T;
          shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance );
-         lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval);
+         lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval);
       }
    } else {
       lubricationEvaluationFunction = emptyFunction;
@@ -1343,7 +1344,7 @@ int main( int argc, char **argv )
 
 
    // function to evaluate the mean fluid velocity
-   std::function<Vector3<real_t> ()> evaluateMeanFluidVelocity = boost::bind(getGNSMeanFluidVelocity, blocks, pdfFieldID, svfFieldID, domainVolume);
+   std::function<Vector3<real_t> ()> evaluateMeanFluidVelocity = std::bind(getGNSMeanFluidVelocity, blocks, pdfFieldID, svfFieldID, domainVolume);
 
 
    //////////////////////////////
diff --git a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
index 5ec32af40e6dc4dae10443bdb2f31f1bd01c791f..052676d3f0adcc1d0cf63abbd1888f9e1222ce9d 100644
--- a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
@@ -44,6 +44,7 @@
 #include "vtk/VTKOutput.h"
 
 #include <vector>
+#include <functional>
 #include <iomanip>
 #include <iostream>
 #include <random>
@@ -698,7 +699,7 @@ int main( int argc, char **argv )
 
    // connect to pe
    const real_t overlap = real_t( 1.5 ) * dx;
-   auto syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   auto syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create the sphere
    const real_t restitutionCoeff = real_t(0.97);
@@ -943,7 +944,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::NearestNeighborFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -951,7 +952,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::IKernel) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -961,7 +962,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::KernelFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -969,7 +970,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       } else if (interpol == Interpolation::ITrilinear) {
          if (dist == Distribution::DNearestNeighbor) {
@@ -979,7 +980,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          } else if (dist == Distribution::DKernel) {
             typedef pe_coupling::discrete_particle_methods::InteractionForceEvaluator<FlagField_T, field::TrilinearFieldInterpolator, field::KernelDistributor> IFE_T;
             shared_ptr<IFE_T> forceEvaluatorPtr = make_shared<IFE_T>(blocks, dragForceFieldID, bodyStorageID,
@@ -987,7 +988,7 @@ int main( int argc, char **argv )
                                                                      velocityFieldID, svfFieldID,
                                                                      pressureGradientFieldID, dragCorrelationFunction,
                                                                      viscosity);
-            dragAndPressureForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+            dragAndPressureForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
          }
       }
    }
@@ -1007,7 +1008,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1015,7 +1016,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1026,7 +1027,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1034,7 +1035,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1045,7 +1046,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1053,7 +1054,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, liftForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         velocityFieldID, velocityCurlFieldID, liftCorrelationFunction,
                                                                         viscosity );
-         liftForceEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         liftForceEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1068,7 +1069,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1076,7 +1077,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::IKernel )
@@ -1087,7 +1088,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1095,7 +1096,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
    else if( interpol == Interpolation::ITrilinear )
@@ -1106,7 +1107,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
       else if( dist == Distribution::DKernel )
       {
@@ -1114,7 +1115,7 @@ int main( int argc, char **argv )
          shared_ptr< IFE_T > forceEvaluatorPtr = make_shared< IFE_T > ( blocks, amForceFieldID, bodyStorageID, flagFieldID, Fluid_Flag,
                                                                         timeDerivativeVelocityFieldID, addedMassCorrelationFunction,
                                                                         bodyVelocityTimeDerivativeEvaluator );
-         addedMassEvaluationFunction = boost::bind(&IFE_T::operator(), forceEvaluatorPtr);
+         addedMassEvaluationFunction = std::bind(&IFE_T::operator(), forceEvaluatorPtr);
       }
    }
 
@@ -1126,13 +1127,13 @@ int main( int argc, char **argv )
       {
          typedef pe_coupling::LubricationCorrection LE_T;
          shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance );
-         lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval);
+         lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval);
       }
       else
       {
          typedef pe_coupling::discrete_particle_methods::LubricationForceEvaluator LE_T;
          shared_ptr<LE_T> lubEval = make_shared<LE_T>( blocks, globalBodyStorage, bodyStorageID, viscosity, lubricationCutOffDistance );
-         lubricationEvaluationFunction = boost::bind(&LE_T::operator(), lubEval);
+         lubricationEvaluationFunction = std::bind(&LE_T::operator(), lubEval);
       }
    } else {
       lubricationEvaluationFunction = emptyFunction;
diff --git a/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp b/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp
index 4133741c77ebb5f7bf427b77ad096f0ab0c2ea33..bbf5224bf01124e9f8a0864e5e53130c21145105 100644
--- a/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/BodyAtBlockBoarderCheck.cpp
@@ -64,6 +64,7 @@
 #include <vector>
 #include <iomanip>
 #include <iostream>
+#include <functional>
 
 namespace body_at_block_boarder_check
 {
@@ -132,7 +133,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( AABB domainAABB
                                                      uint_c(domainAABB.zMax()) / blockSizeInCells[2] );
 
    AABB refinementBox( domainAABB.xMin(), domainAABB.yMin(), domainAABB.zMin(), domainAABB.xMax() * real_c(0.5), domainAABB.yMax(), domainAABB.zMax() );
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], true, true, true );
@@ -281,7 +282,7 @@ int main( int argc, char **argv )
 
    // connect to pe
    const real_t overlap = real_c( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    auto sphereMaterialID = pe::createMaterial( "sphereMat", real_c(1) , real_c(0.3), real_c(0.2), real_c(0.2), real_c(0.24), real_c(200), real_c(200), real_c(0), real_c(0) );
    // create two spheres: one which overlaps with a block boundary and one inside the block
diff --git a/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp
index a084604c75313af11681480e13bc5ba1d11fcaba..33371ade972cb4f1315a3edb6838e8cad5a7c011 100644
--- a/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/DragForceSphereMEMRefinement.cpp
@@ -67,6 +67,7 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
 #include <vector>
 #include <iomanip>
 #include <iostream>
@@ -165,7 +166,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const Setup & s
    // initialize SetupBlockForest = determine domain decomposition
    SetupBlockForest sforest;
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, setup.levels, setup.radius * real_c(2), setup.length ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, setup.levels, setup.radius * real_c(2), setup.length ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( AABB( real_c(0), real_c(0), real_c(0), setup.length, setup.length, setup.length ),
diff --git a/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp
index 27626a2e5d93b95e14850edf93265aebfd06bca5..393df5213fede9b51d2596568193800f5a474a8f 100644
--- a/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/GlobalBodyAsBoundaryMEMStaticRefinement.cpp
@@ -60,6 +60,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace global_body_as_boundary_mem_static_refinement
 {
 
@@ -163,7 +165,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false );
diff --git a/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp b/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp
index d0d021395ac9fdebda1baca45cb0bc78b13449ae..26a984714fff6dac3d8c0452df6e79331aacffc6 100644
--- a/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/LubricationCorrectionMEM.cpp
@@ -57,6 +57,8 @@
 #include "pe_coupling/momentum_exchange_method/all.h"
 #include "pe_coupling/utility/all.h"
 
+#include <functional>
+
 
 namespace lubrication_correction_mem
 {
@@ -163,14 +165,14 @@ private:
       {
          for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt )
          {
-            pe::SphereID sphereI = ( *curSphereIt );
+            pe::SphereID sphereI = ( curSphereIt.getBodyID() );
             if ( sphereI->getID() == id1_ )
             {
                for( auto blockIt2 = blocks_->begin(); blockIt2 != blocks_->end(); ++blockIt2 )
                {
                   for( auto oSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt2, bodyStorageID_); oSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++oSphereIt )
                   {
-                     pe::SphereID sphereJ = ( *oSphereIt );
+                     pe::SphereID sphereJ = ( oSphereIt.getBodyID() );
                      if ( sphereJ->getID() == id2_ )
                      {
                         gap = pe::getSurfaceDistance( sphereI, sphereJ );
@@ -283,14 +285,14 @@ private:
       {
          for( auto curSphereIt = pe::BodyIterator::begin<pe::Sphere>( *blockIt, bodyStorageID_); curSphereIt != pe::BodyIterator::end<pe::Sphere>(); ++curSphereIt )
          {
-            pe::SphereID sphereI = ( *curSphereIt );
+            pe::SphereID sphereI = ( curSphereIt.getBodyID() );
             if ( sphereI->getID() == id1_ )
             {
                for( auto globalBodyIt = globalBodyStorage_->begin(); globalBodyIt != globalBodyStorage_->end(); ++globalBodyIt)
                {
                   if( globalBodyIt->getID() == id2_ )
                   {
-                     pe::PlaneID planeJ = static_cast<pe::PlaneID>( *globalBodyIt );
+                     pe::PlaneID planeJ = static_cast<pe::PlaneID>( globalBodyIt.getBodyID() );
                      gap = pe::getSurfaceDistance(sphereI, planeJ);
                      break;
                   }
@@ -789,7 +791,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_c( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create the material
    const auto myMat = pe::createMaterial( "myMat", real_c(1.4), real_t(0), real_t(1), real_t(1), real_t(0), real_t(1), real_t(1), real_t(0), real_t(0) );
diff --git a/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp b/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp
index ef64aa7a87b345e84e5bd1390f18b008667064a7..bbf831d830ea84b7e37aa22d1668787256275546 100644
--- a/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/PeriodicParticleChannelMEM.cpp
@@ -65,6 +65,7 @@
 
 #include "vtk/all.h"
 
+#include <functional>
 #include <vector>
 
 namespace periodic_particle_channel_mem
@@ -413,7 +414,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_c( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create pe bodies
    const auto material = pe::createMaterial( "granular", real_c(1.2), real_c(0.25), real_c(0.4), real_c(0.4), real_c(0.35), real_c(1.39e11), real_c(5.18e7), real_c(1.07e2), real_c(1.07e2) );
diff --git a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
index 6ccc9f5c7d5156ba058991860ccb271ecbcbfe91..c05c2636c7caa4c300f94c5dadfd0f2177bc947e 100644
--- a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
@@ -65,6 +65,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace segre_silberberg_mem
 {
 
@@ -549,10 +551,10 @@ int main( int argc, char **argv )
    std::function<void(void)> syncCall;
    if (!syncShadowOwners)
    {
-      syncCall = boost::bind( pe::syncNextNeighbors<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+      syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
    } else
    {
-      syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+      syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
    }
 
    // create pe bodies
@@ -670,9 +672,9 @@ int main( int argc, char **argv )
    }
 
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
 
    bodiesFTContainer2->store();
 
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
index 6674cde01316e65119f1738ef249945b0614fca2..ed9c8da8cfdb28470feee2022e07ad3f299873af 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
@@ -63,6 +63,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace settling_sphere_mem
 {
 
@@ -457,7 +459,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_t( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
 
    // create pe bodies
@@ -530,11 +532,11 @@ int main( int argc, char **argv )
                   ( blocks, boundaryHandlingID, bodyStorageID, globalBodyStorage, bodyFieldID, reconstructor, FormerMO_Flag, Fluid_Flag ), "PDF Restore" );
 
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
index 44b17eb70ee97b509d096e0b09133d97bc40efc8..6ebde5403e925066e172980f9286ca4f4455311d 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
@@ -65,6 +65,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace settling_sphere_mem_dynamic_refinement
 {
 
@@ -251,7 +253,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false );
@@ -677,7 +679,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_t( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create pe bodies
 
@@ -728,12 +730,12 @@ int main( int argc, char **argv )
 
    // force averaging functionality
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(0.5));
-   std::function<void(void)> setForceScalingFactorToOne = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToOne = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1));
+   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
@@ -869,9 +871,18 @@ int main( int argc, char **argv )
       {
          auto & forest = blocks->getBlockForest();
          pe::createWithNeighborhood(forest, bodyStorageID, *peInfoCollection);
-         pe::clearSynchronization( blockforest, bodyStorageID);
 
+         uint_t stampBefore = blocks->getBlockForest().getModificationStamp();
          blocks->refresh();
+         uint_t stampAfter = blocks->getBlockForest().getModificationStamp();
+
+         if(stampBefore == stampAfter)
+         {
+            // nothing has changed
+            continue;
+         }
+
+         pe::clearSynchronization( blockforest, bodyStorageID);
 
          for( uint_t syncStep = 0; syncStep < uint_c(diameter / real_c(minBlockSizeInCells)) + 1; ++syncStep)
             syncCall();
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
index 391ab7b8947bd32cc518760d4fc726c96ceae4c6..b8cbd96b2793d02b8c52bae95f38038e7263992d 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
@@ -63,6 +63,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace settling_sphere_mem_static_refinement
 {
 
@@ -170,7 +172,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], false, false, false );
@@ -544,7 +546,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_t( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
 
    // create pe bodies
@@ -595,11 +597,11 @@ int main( int argc, char **argv )
 
    // force averaging functionality
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = boost::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = boost::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
diff --git a/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp b/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp
index 82fd1093713a0421ace63341e6a65225b41f2534..08a7ad4d2b61ebaa7c6108255619423a10127763 100644
--- a/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SquirmerTest.cpp
@@ -66,6 +66,7 @@
 #include "lbm/vtk/Velocity.h"
 #include "vtk/VTKOutput.h"
 
+#include <functional>
 
 namespace squirmer
 {
@@ -289,8 +290,8 @@ int main(int argc, char **argv) {
       return EXIT_FAILURE;
    }
 
-   std::function<void(void)> syncCall = boost::bind(pe::syncShadowOwners<BodyTypeTuple>,
-                                                      boost::ref(blocks->getBlockForest()), bodyStorageID,
+   std::function<void(void)> syncCall = std::bind(pe::syncShadowOwners<BodyTypeTuple>,
+                                                      std::ref(blocks->getBlockForest()), bodyStorageID,
                                                       static_cast<WcTimingTree *>(NULL), overlap, false);
 
    const auto myMat = pe::createMaterial("myMat", real_c(1), real_t(0), real_t(1), real_t(1), real_t(0), real_t(1),
diff --git a/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp b/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp
index e6d43a5d0039a43d1aee67b9723f95d971e0b4de..54cf9698ead46a8afeb1a6b90a6cbca1ac4715b8 100644
--- a/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/TaylorCouetteFlowMEM.cpp
@@ -57,6 +57,8 @@
 
 #include "vtk/all.h"
 
+#include <functional>
+
 namespace taylor_coette_flow_mem
 {
 
@@ -303,7 +305,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_t( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create pe bodies
    const auto material = pe::createMaterial( "granular", real_t(1.2), real_t(0.25), real_t(0.4), real_t(0.4), real_t(0.35), real_t(1.39e11), real_t(5.18e7), real_t(1.07e2), real_t(1.07e2) );
diff --git a/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp b/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp
index f29f7d650c9e0bbd02ada920f48b4dd2cde1efee..d3b4fce22a25f4972df158c1331b29cc5d9e789e 100644
--- a/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp
+++ b/tests/pe_coupling/partially_saturated_cells_method/DragForceSpherePSMRefinement.cpp
@@ -67,6 +67,7 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
 #include <vector>
 #include <iomanip>
 #include <iostream>
@@ -185,7 +186,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const Setup & s
    // initialize SetupBlockForest = determine domain decomposition
    SetupBlockForest sforest;
 
-   sforest.addRefinementSelectionFunction( boost::bind( refinementSelection, _1, setup.levels, setup.radius * real_c(2), real_c(setup.length) ) );
+   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, setup.levels, setup.radius * real_c(2), real_c(setup.length) ) );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( AABB( real_c(0), real_c(0), real_c(0), real_c(setup.length), real_c(setup.length), real_c(setup.length) ),
diff --git a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
index 7e0ad3250d28b0cb1f219bbae034dfdc77e817e2..f0153483fe0b11da945750d7f428fed8b22e02ac 100644
--- a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
+++ b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
@@ -64,6 +64,8 @@
 #include "field/vtk/all.h"
 #include "lbm/vtk/all.h"
 
+#include <functional>
+
 namespace segre_silberberg_psm
 {
 
@@ -502,7 +504,7 @@ int main( int argc, char **argv )
 
    // set up synchronization procedure
    const real_t overlap = real_c( 1.5 ) * dx;
-   std::function<void(void)> syncCall = boost::bind( pe::syncShadowOwners<BodyTypeTuple>, boost::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
+   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, static_cast<WcTimingTree*>(NULL), overlap, false );
 
    // create pe bodies