diff --git a/CMakeLists.txt b/CMakeLists.txt
index 013862580918abfcf4418dc924b4c9153d11c789..0586465a8f1c5bd2fe4acdc1a719921c2ecf5841 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -163,7 +163,8 @@ if( CMAKE_CXX_COMPILER MATCHES "icpc" OR CMAKE_CXX_COMPILER_ARG1 MATCHES "icpc"
     ENDIF(XILD)
     MARK_AS_ADVANCED(XILD)
     if( CMAKE_VERSION VERSION_LESS 3.6.0 )
-      add_flag ( CMAKE_CXX_FLAGS "-std=c++14" )
+      set( CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14" )
+      add_flag ( CMAKE_CXX_FLAGS ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
     endif()
 else()
     option ( WALBERLA_CXX_COMPILER_IS_INTEL "Use Intel compiler" OFF  )
@@ -278,9 +279,10 @@ if( WALBERLA_CXX_COMPILER_IS_GNU OR WALBERLA_CXX_COMPILER_IS_INTEL )
    add_flag ( CMAKE_CXX_FLAGS "-Wall -Wconversion -Wshadow" )
 endif()
 
-# C++11 language features for NEC compiler
+# C++ language features for NEC compiler
 if( WALBERLA_CXX_COMPILER_IS_NEC )
-   add_flag ( CMAKE_CXX_FLAGS "-Kcpp14 -Krtti -Kexceptions -size_t64 -Kgcc" )
+   set( CMAKE_CXX14_STANDARD_COMPILE_OPTION "-Kcpp14" )
+   add_flag ( CMAKE_CXX_FLAGS "${CMAKE_CXX14_STANDARD_COMPILE_OPTION} -Krtti -Kexceptions -size_t64 -Kgcc" )
    add_flag ( CMAKE_CXX_FLAGS "-D__BIG_ENDIAN -D__BYTE_ORDER=__BIG_ENDIAN" )
    add_flag ( CMAKE_CXX_FLAGS "-Tnoauto,used" )
    add_flag ( CMAKE_EXE_LINKER_FLAGS "-Wl,-h,muldefs" )
@@ -436,6 +438,70 @@ endif()
 
 
 
+############################################################################################################################
+##
+##  Find optional C++ libraries
+##
+############################################################################################################################
+
+try_compile( WALBERLA_USE_STD_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_FILESYSTEM ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+if( WALBERLA_USE_STD_FILESYSTEM )
+   message( STATUS "Found std::filesystem")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      message( STATUS "Found std::experimental::filesystem")
+   endif()
+   if( NOT WALBERLA_CXX_COMPILER_IS_MSVC AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      unset( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM CACHE )
+      try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                   COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM ${CMAKE_CXX14_STANDARD_COMPILE_OPTION}
+                   LINK_LIBRARIES stdc++fs )
+      if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+         message( STATUS "Found std::experimental::filesystem in libstdc++fs")
+      list ( APPEND SERVICE_LIBS -lstdc++fs )
+      endif()
+   endif()
+   if( NOT WALBERLA_CXX_COMPILER_IS_MSVC AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+      unset( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM CACHE )
+      try_compile( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdFilesystem.cpp"
+                   COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM ${CMAKE_CXX14_STANDARD_COMPILE_OPTION}
+                   LINK_LIBRARIES c++experimental )
+      if( WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+         message( STATUS "Found std::experimental::filesystem in libc++experimental")
+         list ( APPEND SERVICE_LIBS -lc++experimental )
+      endif()
+   endif()
+endif()
+
+try_compile( WALBERLA_USE_STD_ANY "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdAny.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_ANY ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+if( WALBERLA_USE_STD_ANY )
+   message( STATUS "Found std::any")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_ANY "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdAny.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_ANY ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_ANY )
+      message( STATUS "Found std::experimental::any")
+   endif()
+endif()
+
+try_compile( WALBERLA_USE_STD_OPTIONAL "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdOptional.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_OPTIONAL ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+if( WALBERLA_USE_STD_OPTIONAL )
+   message( STATUS "Found std::optional")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdOptional.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL ${CMAKE_CXX14_STANDARD_COMPILE_OPTION} )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL )
+      message( STATUS "Found std::experimental::optional")
+   endif()
+endif()
+
+
+
 ############################################################################################################################
 ##
 ##  Visual Studio Setup
@@ -574,7 +640,11 @@ endif()
 #############################################################################################################################
 set ( waLBerla_REQUIRED_MIN_BOOST_VERSION "1.48")
 
-list ( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS filesystem system )
+if ( NOT WALBERLA_USE_STD_FILESYSTEM AND NOT WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM )
+  list ( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS filesystem system )
+else()
+  list ( APPEND waLBerla_OPTIONAL_BOOST_COMPONENTS system )
+endif()
 
 if ( WALBERLA_BUILD_WITH_PYTHON AND WALBERLA_CXX_COMPILER_IS_MSVC )
     list( APPEND waLBerla_REQUIRED_BOOST_COMPONENTS python3 )
@@ -601,14 +671,14 @@ if ( NOT BOOST_ROOT )
    endforeach ( )
 endif ( )
 
-find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} COMPONENTS ${waLBerla_REQUIRED_BOOST_COMPONENTS} QUIET )
+find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} COMPONENTS ${waLBerla_REQUIRED_BOOST_COMPONENTS} OPTIONAL_COMPONENTS ${waLBerla_OPTIONAL_BOOST_COMPONENTS} QUIET )
 
 if( NOT Boost_FOUND )
    message ( WARNING
       "The specified configuration of the BOOST libraries was not found on your system! Now trying some other configuration..." )
    foreach ( Boost_USE_STATIC_LIBS ON OFF )
       foreach ( Boost_USE_MULTITHREADED ON OFF )
-         find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} COMPONENTS ${waLBerla_REQUIRED_BOOST_COMPONENTS} QUIET )
+         find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} COMPONENTS ${waLBerla_REQUIRED_BOOST_COMPONENTS} OPTIONAL_COMPONENTS ${waLBerla_OPTIONAL_BOOST_COMPONENTS} QUIET )
          if ( Boost_FOUND )
             set ( Boost_USE_STATIC_LIBS   ${Boost_USE_STATIC_LIBS}   CACHE BOOL "Use boost static libraries"        FORCE )
             set ( Boost_USE_MULTITHREADED ${Boost_USE_MULTITHREADED} CACHE BOOL "Use boost multithreaded libraries" FORCE )
@@ -631,8 +701,10 @@ if ( Boost_FOUND )
    else()
       include_directories ( SYSTEM ${Boost_INCLUDE_DIRS} )
    endif()
-   link_directories ( ${Boost_LIBRARY_DIRS} )
-   list ( APPEND SERVICE_LIBS ${Boost_LIBRARIES} )
+   if( waLBerla_REQUIRED_BOOST_COMPONENTS )
+      link_directories ( ${Boost_LIBRARY_DIRS} )
+      list ( APPEND SERVICE_LIBS ${Boost_LIBRARIES} )
+   endif()
    add_definitions ( -DBOOST_ALL_NO_LIB ) # Disable Boost auto-linking (CMAKE does that for us...)
 
    #fix for static lib usage: http://stackoverflow.com/questions/11812463/boost-python-link-errors-under-windows-msvc10
@@ -649,7 +721,7 @@ if ( Boost_FOUND )
 
 else( Boost_FOUND )
    # Search again, this time with the REQUIRED option. This will give a CMAKE error and a detailed error message for the user
-   find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} REQUIRED ${waLBerla_REQUIRED_BOOST_COMPONENTS} )
+   find_package ( Boost ${waLBerla_REQUIRED_MIN_BOOST_VERSION} REQUIRED ${waLBerla_REQUIRED_BOOST_COMPONENTS} OPTIONAL_COMPONENTS ${waLBerla_OPTIONAL_BOOST_COMPONENTS} )
 endif( Boost_FOUND )
 
 
diff --git a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
index c54228f176723996ef2af2d457265dcc714429ac..fc6a084ffb1451de776451618b6d60e4c1873040 100644
--- a/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
+++ b/apps/benchmarks/MotionSingleHeavySphere/MotionSingleHeavySphere.cpp
@@ -944,9 +944,9 @@ int main( int argc, char **argv )
    WALBERLA_LOG_INFO_ON_ROOT("Basefolder for simulation results: " << basefolder);
 
    // create base directory if it does not yet exist
-   boost::filesystem::path tpath( basefolder );
-   if( !boost::filesystem::exists( tpath ) )
-      boost::filesystem::create_directory( tpath );
+   filesystem::path tpath( basefolder );
+   if( !filesystem::exists( tpath ) )
+      filesystem::create_directory( tpath );
 
    // setup of the LBM communication for synchronizing the pdf field between neighboring blocks
    std::function< void () > commFunction;
@@ -1255,9 +1255,9 @@ int main( int argc, char **argv )
    pdfFieldVTK->addBeforeFunction(VTKInfoLogger( &timeloop, blocks, bodyStorageID, basefolder, uInfty ));
 
    // create folder for log_vtk files to not pollute the basefolder
-   boost::filesystem::path tpath2( basefolder+"/log_vtk" );
-   if( !boost::filesystem::exists( tpath2 ) )
-      boost::filesystem::create_directory( tpath2 );
+   filesystem::path tpath2( basefolder+"/log_vtk" );
+   if( !filesystem::exists( tpath2 ) )
+      filesystem::create_directory( tpath2 );
 
 
    field::FlagFieldCellFilter< FlagField_T > fluidFilter( flagFieldID );
diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
index 695cc61f63a56b412975a7cc9c912dc39fe016af..ed907fc37b06df8e3e54691bebc52bc7ea7c495f 100644
--- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
+++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
@@ -1285,7 +1285,7 @@ public:
       markEmptyBlocks_( markEmptyBlocks ), state_( state )
    {}
    
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
@@ -1309,7 +1309,7 @@ struct Pseudo2DPhantomWeightPackUnpack
       buffer << block.getData< Pseudo2DPhantomWeight >().weight();
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       Pseudo2DPhantomWeight::weight_t w;
       buffer >> w;
diff --git a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
index 03a294859449bb7417dd3bad16c530ef6345aa5d..de0512d8dd7e24c7ae85cf706293d63e28b2a368 100644
--- a/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
+++ b/apps/showcases/BidisperseFluidizedBed/BidisperseFluidizedBedDPM.cpp
@@ -740,9 +740,9 @@ int main( int argc, char **argv ) {
    if( !funcTest )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( vtkBaseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( vtkBaseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
 
diff --git a/apps/tools/povrayFileCompressor/main.cpp b/apps/tools/povrayFileCompressor/main.cpp
index 86f1f9ee41b95a0a4eff496f6f53484eca7e71c3..4d56bc779ec523376c8aedab6ed0ef0867d95c25 100644
--- a/apps/tools/povrayFileCompressor/main.cpp
+++ b/apps/tools/povrayFileCompressor/main.cpp
@@ -21,17 +21,16 @@
 #include "geometry/mesh/TriangleMesh.h"
 #include "geometry/mesh/TriangleMeshIO.h"
 #include "core/Regex.h"
+#include "core/Filesystem.h"
 
 #include <fstream>
 #include <iomanip>
 #include <iostream>
 
 
-#define BOOST_FILESYSTEM_NO_DEPRECATED
-#include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
 
-namespace fs = boost::filesystem;
+namespace filesystem = walberla::filesystem;
 
 bool verbose;
 bool quiet;
@@ -90,29 +89,29 @@ int main(int argc, char** argv)
    if( quiet && verbose )
       PRINT_ERR( "PovrayFileCompressor can't be quiet (-q) and verbose (-v) at the same time\n" )
 
-   fs::path inPath(argv[argc-2]);
-   if( !fs::exists(inPath) || !fs::is_directory(inPath) )
+   filesystem::path inPath(argv[argc-2]);
+   if( !filesystem::exists(inPath) || !filesystem::is_directory(inPath) )
       PRINT_ERR( "Path " << inPath << " does not exist or is not a directory!\n" );
 
-   fs::path outPath(argv[argc-1]);
-   if( !fs::exists(outPath) )
-      fs::create_directories(outPath);
+   filesystem::path outPath(argv[argc-1]);
+   if( !filesystem::exists(outPath) )
+      filesystem::create_directories(outPath);
 
    PRINT_DEF( "Input Path: " << inPath << "\nOutput Path: " << outPath << "\n" )
 
 
-   std::vector< std::vector<fs::path> > infiles;
+   std::vector< std::vector<filesystem::path> > infiles;
 
    PRINT_DEF( "Collecting files to compress ..." )
 
-   for(auto pit = fs::directory_iterator(inPath); pit != fs::directory_iterator(); ++pit)
+   for(auto pit = filesystem::directory_iterator(inPath); pit != filesystem::directory_iterator(); ++pit)
    {
-      if( !fs::is_directory( pit->status() ) )
+      if( !filesystem::is_directory( pit->status() ) )
          continue;
 
       PRINT_VER( "\nCollecting files to compress in: " << pit->path())
-      std::vector<fs::path> pfiles;
-      for(auto tit = fs::directory_iterator(pit->path()); tit != fs::directory_iterator(); ++tit)
+      std::vector<filesystem::path> pfiles;
+      for(auto tit = filesystem::directory_iterator(pit->path()); tit != filesystem::directory_iterator(); ++tit)
       {
          static const walberla::regex extensionExpression("\\.dat");
          if( walberla::regex_match( tit->path().extension().string(), extensionExpression ) )
@@ -140,14 +139,14 @@ int main(int argc, char** argv)
    {
       PRINT_VER( "Compress timestep " << t << "\n" )
       PRINT_VER( "Merge Splitted Meshes: \n" )
-      PRINT_VER( "Merge Mesh: " << fs::absolute(infiles[0][t]).string().c_str() << "\n" )
-      std::ifstream is( fs::absolute(infiles[0][t]).string().c_str() );
+      PRINT_VER( "Merge Mesh: " << filesystem::absolute(infiles[0][t]).string().c_str() << "\n" )
+      std::ifstream is( filesystem::absolute(infiles[0][t]).string().c_str() );
       walberla::geometry::readMeshPov(is, mesh, true);
       is.close();
 
       for( size_t p = 1u; p < processes; ++p ){
-         PRINT_VER( "Merge Mesh: " << fs::absolute(infiles[p][t]).string().c_str() << "\n" )
-         std::ifstream tis( fs::absolute(infiles[p][t]).string().c_str() );
+         PRINT_VER( "Merge Mesh: " << filesystem::absolute(infiles[p][t]).string().c_str() << "\n" )
+         std::ifstream tis( filesystem::absolute(infiles[p][t]).string().c_str() );
          walberla::geometry::readMeshPov(tis, mesh, false);
          tis.close();
       }
@@ -172,7 +171,7 @@ int main(int argc, char** argv)
          }
       }
 
-      fs::path oPath = fs::absolute(outPath) / infiles[0][t].filename();
+      filesystem::path oPath = filesystem::absolute(outPath) / infiles[0][t].filename();
       PRINT_VER( "Write New Mesh File: " << (oPath.string().c_str()) << "\n" )
       std::ofstream os( oPath.string().c_str() );
       walberla::geometry::writeMeshPov( os, mesh, 0u, n );
diff --git a/cmake/TestStdAny.cpp b/cmake/TestStdAny.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b7e22269737d293cab1daba5d4030c186b5fcd8
--- /dev/null
+++ b/cmake/TestStdAny.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_ANY)
+#include <any>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+#include <experimental/any>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_ANY)
+   auto a = std::any(42);
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+   auto a = std::experimental::any(42);
+#endif
+   std::cout << std::experimental::any_cast<int>(a) << std::endl;
+   return 0;
+}
diff --git a/cmake/TestStdFilesystem.cpp b/cmake/TestStdFilesystem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1caf5057db6c1253635b8810e2a7792bd56d249f
--- /dev/null
+++ b/cmake/TestStdFilesystem.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+#include <filesystem>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+#include <experimental/filesystem>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+   std::filesystem::path p("/tmp/test.txt");
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+   std::experimental::filesystem::path p("/tmp/test.txt");
+#endif
+   std::cout << p.extension().string() << std::endl;
+   return 0;
+}
diff --git a/cmake/TestStdOptional.cpp b/cmake/TestStdOptional.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc3a148c128e534eb37fc635c697d1e88961a6db
--- /dev/null
+++ b/cmake/TestStdOptional.cpp
@@ -0,0 +1,19 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+#include <optional>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+#include <experimental/optional>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+   auto a = std::optional<int>();
+   auto b = std::optional<int>(42);
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+   auto a = std::experimental::optional<int>();
+   auto b = std::experimental::optional<int>(42);
+#endif
+   if (b)
+      std::cout << a.value_or(b.value()) << std::endl;
+   return 0;
+}
diff --git a/src/blockforest/PhantomBlock.h b/src/blockforest/PhantomBlock.h
index a209e1a17b4a87e79351360c2e314ece047b342e..7f42061abc56b1332af0be31cd1fdfbeda83beb3 100644
--- a/src/blockforest/PhantomBlock.h
+++ b/src/blockforest/PhantomBlock.h
@@ -28,11 +28,10 @@
 #include "core/debug/Debug.h"
 #include "core/math/AABB.h"
 #include "core/uid/SUID.h"
+#include "core/Any.h"
 
 #include <vector>
 
-#include <boost/any.hpp>
-
 
 
 namespace walberla {
@@ -86,7 +85,7 @@ public:
    void addData( const T & data ) { data_ = data; }
    
    template< typename T >
-   T getData() const { return boost::any_cast<T>( data_ ); }
+   T getData() const { return walberla::any_cast<T>( data_ ); }
    
    bool hasData() const { return !(data_.empty()); }
    
@@ -143,7 +142,7 @@ private:
    uint_t level_;
 
    // set by the user/application via callback
-   boost::any data_;
+   walberla::any data_;
 
    std::vector< NeighborBlock* > neighborhoodSection_[26]; // the 26 neighborhood sections (can be restored from 'neighborhood_')
    std::vector< NeighborBlock  > neighborhood_;            // all neighbor blocks
diff --git a/src/blockforest/PhantomBlockForest.cpp b/src/blockforest/PhantomBlockForest.cpp
index 691cfe744bffa45cf7c790c86699f7a5e84dcba5..196ba5529e2b24b8825ea8a5903d9191cc83814f 100644
--- a/src/blockforest/PhantomBlockForest.cpp
+++ b/src/blockforest/PhantomBlockForest.cpp
@@ -256,13 +256,13 @@ void PhantomBlockForest::assignBlockData( const PhantomBlockDataAssignmentFuncti
 {
    if( function )
    {
-      std::vector< std::pair< const PhantomBlock *, boost::any > > blockData;
+      std::vector< std::pair< const PhantomBlock *, walberla::any > > blockData;
    
       for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
       {
          auto & block = it->second;
          WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
-         blockData.push_back( std::make_pair( block.get(), boost::any() ) );
+         blockData.push_back( std::make_pair( block.get(), walberla::any() ) );
       }
       
       function( blockData, *this );
@@ -484,7 +484,7 @@ void PhantomBlockForest::migrate( const PhantomBlockDataPackFunction & packBlock
          if( unpackBlockData )
          {
             WALBERLA_ASSERT( static_cast<bool>(packBlockData) );
-            boost::any data;
+            walberla::any data;
             unpackBlockData( buffer, *phantom, data );
             phantom->addData( data );
          }
diff --git a/src/blockforest/PhantomBlockForest.h b/src/blockforest/PhantomBlockForest.h
index 797a29cbe28ee0a0463d69a9cd5417e90347a8b6..1c7285167da9295ab15394133195f812406e1626 100644
--- a/src/blockforest/PhantomBlockForest.h
+++ b/src/blockforest/PhantomBlockForest.h
@@ -45,7 +45,7 @@ public:
    typedef std::function< Set<SUID> ( const std::vector< std::pair< BlockID, Set<SUID> > > & source, const BlockID & destintation ) >
            BlockStateDeterminationFunction;
 
-   typedef std::function< void ( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData,
+   typedef std::function< void ( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData,
                                    const PhantomBlockForest & phantomForest ) >
            PhantomBlockDataAssignmentFunction;
 
@@ -58,7 +58,7 @@ public:
            MigrationPreparationFunction; // = load balancing
 
    typedef std::function< void ( mpi::SendBuffer & buffer, const PhantomBlock & block ) >                    PhantomBlockDataPackFunction;
-   typedef std::function< void ( mpi::RecvBuffer & buffer, const PhantomBlock & block, boost::any & data ) > PhantomBlockDataUnpackFunction;
+   typedef std::function< void ( mpi::RecvBuffer & buffer, const PhantomBlock & block, walberla::any & data ) > PhantomBlockDataUnpackFunction;
 
 
 
diff --git a/src/blockforest/loadbalancing/DynamicParMetis.h b/src/blockforest/loadbalancing/DynamicParMetis.h
index 1fa7667ee3aa4932015291edccd2fbd87c336d0b..927ca25698c5257a667674535d9838191634c1a6 100644
--- a/src/blockforest/loadbalancing/DynamicParMetis.h
+++ b/src/blockforest/loadbalancing/DynamicParMetis.h
@@ -119,7 +119,7 @@ struct DynamicParMetisBlockInfoPackUnpack
       block.getData< DynamicParMetisBlockInfo >().toBuffer( buffer );
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       data = DynamicParMetisBlockInfo( buffer );
    }
diff --git a/src/blockforest/loadbalancing/PODPhantomData.h b/src/blockforest/loadbalancing/PODPhantomData.h
index ccf514a1f6ec3af8192d70cd48f58e07af1e5561..2be8c77cecf13525222529e9dfbc2d31dfd35cea 100644
--- a/src/blockforest/loadbalancing/PODPhantomData.h
+++ b/src/blockforest/loadbalancing/PODPhantomData.h
@@ -53,7 +53,7 @@ struct PODPhantomWeightPackUnpack
       buffer << block.getData< PODPhantomWeight<T> >().weight();
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       typename PODPhantomWeight<T>::weight_t w;
       buffer >> w;
diff --git a/src/core/Any.h b/src/core/Any.h
new file mode 100644
index 0000000000000000000000000000000000000000..2799c1e8525fc4176e6dc7b98c3e791716c43f13
--- /dev/null
+++ b/src/core/Any.h
@@ -0,0 +1,48 @@
+//======================================================================================================================
+//
+//  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 Any.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_ANY)
+#include <any>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+#include <experimental/any>
+#else
+#include <boost/any.hpp>
+#endif
+
+
+
+namespace walberla {
+
+#if defined(WALBERLA_USE_STD_ANY)
+using std::any;
+using std::any_cast;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+using std::experimental::any;
+using std::experimental::any_cast;
+#else
+using boost::any;
+using boost::any_cast;
+#endif
+
+}
diff --git a/src/core/Filesystem.h b/src/core/Filesystem.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7bdf2e1246e875854fe19eb681d35928baf7667
--- /dev/null
+++ b/src/core/Filesystem.h
@@ -0,0 +1,47 @@
+//======================================================================================================================
+//
+//  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 Filesystem.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+#include <filesystem>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+#include <experimental/filesystem>
+#else
+#include <boost/filesystem.hpp>
+#endif
+
+
+
+namespace walberla {
+namespace filesystem {
+
+#if defined(WALBERLA_USE_STD_FILESYSTEM)
+using namespace std::filesystem;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM)
+using namespace std::experimental::filesystem;
+#else
+using namespace boost::filesystem;
+#endif
+
+}
+}
diff --git a/src/core/Optional.h b/src/core/Optional.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad23d1666a07716c717591f4b188291869a74626
--- /dev/null
+++ b/src/core/Optional.h
@@ -0,0 +1,48 @@
+//======================================================================================================================
+//
+//  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) OPTIONAL later version.
+//
+//  waLBerla is distributed in the hope that it will be useful, but WITHOUT
+//  OPTIONAL 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 Optional.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+#include <optional>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+#include <experimental/optional>
+#else
+#include <boost/optional.hpp>
+#endif
+
+
+
+namespace walberla {
+
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+using std::optional;
+using std::nullopt;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+using std::experimental::optional;
+using std::experimental::nullopt;
+#else
+using boost::optional;
+const boost::none_t nullopt = boost::none;
+#endif
+
+}
diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp
index 8660f50522529a23e278096380f1beb25b442390..48277f3bc6336d225909ff0172e98da0a76233bf 100644
--- a/src/core/config/Config.cpp
+++ b/src/core/config/Config.cpp
@@ -262,7 +262,7 @@ void Config::parseFromFile( const char* filename, Block& block, unsigned int lev
             }
             else {
                removeTrailingWhiteSpaces( value );
-               std::string file( (boost::filesystem::path( getDirectory( filename ) ) / value).string() );
+               std::string file( (filesystem::path( getDirectory( filename ) ) / value).string() );
                parseFromFile( file.c_str(), block, level+1 );
             }
          }
@@ -395,7 +395,7 @@ void Config::extractBlock( const char* filename, std::stringstream& input, Block
             }
             else {
                removeTrailingWhiteSpaces( value );
-               std::string file( (boost::filesystem::path( getDirectory( filename ) ) / value).string() );
+               std::string file( (filesystem::path( getDirectory( filename ) ) / value).string() );
                parseFromFile( file.c_str(), block, level+1 );
             }
          }
diff --git a/src/core/config/Config.h b/src/core/config/Config.h
index d83f9baa1922c43c4cfa8fe39c8f47146a9e80bd..9ed1ce81984b627e25cb4c4b7ef014a9e786dacc 100644
--- a/src/core/config/Config.h
+++ b/src/core/config/Config.h
@@ -37,11 +37,7 @@
 
 // boost includes
 #include <boost/algorithm/string/predicate.hpp>
-#include <boost/filesystem/path.hpp>
-
-#ifndef BOOST_FILESYSTEM_VERSION
-#define BOOST_FILESYSTEM_VERSION 1
-#endif
+#include "core/Filesystem.h"
 
 
 
@@ -687,13 +683,8 @@ inline void Config::convertToLowerCase( std::string& s )
  */
 inline std::string Config::getDirectory( const std::string& path )
 {
-   boost::filesystem::path p( path );
-#        if BOOST_FILESYSTEM_VERSION>2
-   return p.branch_path().string();
-#        else
-#        warning BOOST FILESYSTEM VERSION IS RATHER OLD! PLEASE USE BOOST VERSION 1.46 OR HIGHER
+   filesystem::path p( path );
    return p.parent_path().string();
-#        endif
 }
 //**********************************************************************************************************************
 
@@ -707,12 +698,8 @@ inline std::string Config::getDirectory( const std::string& path )
  */
 inline std::string Config::getFilename( const std::string& path )
 {
-   boost::filesystem::path p( path );
-#        if BOOST_FILESYSTEM_VERSION>2
-   return p.leaf().string();
-#        else
-   return p.filename();
-#        endif
+   filesystem::path p( path );
+   return p.filename().string();
 }
 //**********************************************************************************************************************
 
diff --git a/src/core/logging/Logging.cpp b/src/core/logging/Logging.cpp
index ea8bde365749b10c36bdd9ac669d81927fb9411f..60fc970bc461b770558d9dd674ef5e0060ca639d 100644
--- a/src/core/logging/Logging.cpp
+++ b/src/core/logging/Logging.cpp
@@ -21,8 +21,7 @@
 
 #include "Logging.h"
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include "core/Filesystem.h"
 #include <ctime>
 
 
@@ -105,9 +104,9 @@ void Logging::includeLoggingToFile( const std::string & file, bool append )
    std::ostringstream filename;
    if( file.empty() )
    {
-      boost::filesystem::path logDir( "logging" );
-      if( !boost::filesystem::exists( logDir ) )
-         boost::filesystem::create_directory( logDir );
+      filesystem::path logDir( "logging" );
+      if( !filesystem::exists( logDir ) )
+         filesystem::create_directory( logDir );
 
       if( numberOfProcesses_ == 1 )
          filename << "logging/logfile.txt";
@@ -120,7 +119,7 @@ void Logging::includeLoggingToFile( const std::string & file, bool append )
          filename << file;
       else
       {
-         boost::filesystem::path filePath( file );
+         filesystem::path filePath( file );
          const std::string stem      = filePath.stem().string();
          const std::string extension = filePath.extension().string();
          const std::string modifiedFilename = stem + std::string("_") + rank.str() + extension;
diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h
index 47d22bacac8bbdd0659dedc8792762289ce1e60a..b05128c4a193aebd46f9f31fec2ed89dc41c30ec 100644
--- a/src/core/mpi/BufferDataTypeExtensions.h
+++ b/src/core/mpi/BufferDataTypeExtensions.h
@@ -27,10 +27,10 @@
 #include "SendBuffer.h"
 #include "core/Conversion.h"
 #include "core/DataTypes.h"
+#include "core/Optional.h"
 
 #include <boost/array.hpp>
 #include <boost/integer.hpp>
-#include <boost/optional.hpp>
 #include <boost/uuid/uuid.hpp>
 
 #include <deque>
@@ -465,18 +465,18 @@ struct BufferSizeTrait< std::multimap<K,T,C,A> > { static const bool constantSiz
 
 
 // ---------------------------------------------------------------------------------------------------------------------
-// ------------------------------------- Boost optional Support --------------------------------------------------------
+// ------------------------------------------- optional Support --------------------------------------------------------
 // ---------------------------------------------------------------------------------------------------------------------
 
 template< typename T,    // Element type of SendBuffer
           typename G,    // Growth policy of SendBuffer
           typename OT>   // Optional type
-GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const boost::optional<OT> & o )
+GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const walberla::optional<OT> & o )
 {
    buf.addDebugMarker( "op" );
 
    bool hasContent = true;
-   if (o == boost::none)
+   if (o == walberla::nullopt)
       hasContent = false;
 
    buf << hasContent;
@@ -489,7 +489,7 @@ GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const boost::o
 
 template< typename T,    // Element type of RecvBuffer
           typename OT>   // Optional type
-GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, boost::optional<OT> & o )
+GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, walberla::optional<OT> & o )
 {
    buf.readDebugMarker( "op" );
 
@@ -509,7 +509,7 @@ GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, boost::optional<OT
    }
    else
    {
-      o = boost::none;
+      o = walberla::nullopt;
    }
 
    return buf;
diff --git a/src/gather/FileGatherScheme.cpp b/src/gather/FileGatherScheme.cpp
index b19f8d93c3c529d7a88a61a8c1e81ea5a4477a19..0aa2e40d7121db5eacbda388a5f55afcabe434c9 100644
--- a/src/gather/FileGatherScheme.cpp
+++ b/src/gather/FileGatherScheme.cpp
@@ -27,7 +27,7 @@
 #include "core/mpi/RecvBuffer.h"
 #include "core/mpi/SendBuffer.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 #include <boost/lexical_cast.hpp>
 
 
@@ -56,7 +56,7 @@ FileGatherScheme::~FileGatherScheme()
 
 void FileGatherScheme::deleteTemporaryFiles()
 {
-   using namespace boost::filesystem;
+   using namespace filesystem;
    using std::string;
 
    for(int rank=0; rank < MPIManager::instance()->numProcesses(); ++rank)
@@ -108,7 +108,7 @@ void FileGatherScheme::writeToFile()
 
 void FileGatherScheme::collectFromFiles()
 {
-   using namespace boost::filesystem;
+   using namespace filesystem;
    using namespace std;
 
    if ( fileStream_.is_open() )
diff --git a/src/mesh/MeshIO.h b/src/mesh/MeshIO.h
index 493276526791bae35fae634563c112ccc7b7374c..119fdddff7538133b1855c17f170379536de7656 100644
--- a/src/mesh/MeshIO.h
+++ b/src/mesh/MeshIO.h
@@ -28,7 +28,7 @@
 #include <fstream>
 #include <string>
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #ifdef _MSC_VER
 #  pragma warning(push)
@@ -57,10 +57,10 @@ namespace mesh {
 template< typename MeshType >
 void readAndBroadcast( const std::string & filename, MeshType & mesh )
 {
-   if( !boost::filesystem::exists( filename ) )
+   if( !filesystem::exists( filename ) )
       WALBERLA_ABORT( "The mesh file \"" << filename << "\" does not exist!" );
 
-   std::string extension = boost::filesystem::extension( filename );
+   std::string extension = filesystem::path( filename ).extension().string();
 
    std::string str;
 
diff --git a/src/mesh/vtk/VTKMeshWriter.h b/src/mesh/vtk/VTKMeshWriter.h
index 85f47c12b900cf5090a94861029c2db795822d88..cf01acf7e4c5451faa2459703a845228f9a9a8e0 100644
--- a/src/mesh/vtk/VTKMeshWriter.h
+++ b/src/mesh/vtk/VTKMeshWriter.h
@@ -29,7 +29,7 @@
 #include "vtk/Base64Writer.h"
 #include "vtk/UtilityFunctions.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #include <iostream>
 #include <vector>
@@ -198,15 +198,15 @@ VTKMeshWriter<MeshType>::VTKMeshWriter( const shared_ptr<const MeshType> & mesh,
    {
       std::ostringstream folder;
       folder << baseFolder_ << '/' << identifier_;
-      if( boost::filesystem::exists( folder.str() ) )
-         boost::filesystem::remove_all( folder.str() );
+      if( filesystem::exists( folder.str() ) )
+         filesystem::remove_all( folder.str() );
 
       std::ostringstream pvdFile;
       pvdFile << baseFolder_ << '/' << identifier_ << ".pvd";
-      if( boost::filesystem::exists( pvdFile.str() ) )
-         boost::filesystem::remove( pvdFile.str() );
+      if( filesystem::exists( pvdFile.str() ) )
+         filesystem::remove( pvdFile.str() );
 
-      boost::filesystem::create_directories( folder.str() );
+      filesystem::create_directories( folder.str() );
    }
    WALBERLA_MPI_BARRIER();
 }
diff --git a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
index 3b03af49e8dfcf5b48772351c7afac2678f7204f..bed28616694dbdbff30914cba828d0ed22c6d6fe 100644
--- a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
@@ -38,7 +38,7 @@ public:
    MetisAssignmentFunctor( const shared_ptr<InfoCollection>& ic ) : ic_( ic )
    {}
 
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
index f83c8080ab6a0588031c560046c3e212c921ed8c..1632bc596e1c3b01fc9d090e5fd29ca6c1f18ad0 100644
--- a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
@@ -37,7 +37,7 @@ public:
 
    WeightAssignmentFunctor( shared_ptr<InfoCollection>& ic, const real_t baseWeight = real_t(10.0) ) : ic_(ic), baseWeight_(baseWeight) {}
 
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
diff --git a/src/python_coupling/PythonCallback.cpp b/src/python_coupling/PythonCallback.cpp
index 5573970b16bac2a30d89b2fe675baa70ec02626e..c469b10dfc877aeee8a83af26dbe153032cdc181 100644
--- a/src/python_coupling/PythonCallback.cpp
+++ b/src/python_coupling/PythonCallback.cpp
@@ -29,9 +29,13 @@
 #include "core/Abort.h"
 #include "core/logging/Logging.h"
 #include "helper/ExceptionHandling.h"
+#include "core/Filesystem.h"
 
-
-#include <boost/filesystem.hpp>
+#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20160609
+#define CURRENT_PATH_WORKAROUND
+#include <unistd.h>
+#include <errno.h>
+#endif
 
 namespace walberla {
 namespace python_coupling {
@@ -52,16 +56,38 @@ namespace python_coupling {
          code << "'" << *argStrIt  << "',";
       code << "] \n";
 
+      filesystem::path path ( fileOrModuleName );
+#ifdef CURRENT_PATH_WORKAROUND
+      // workaround for double free in filesystem::current_path in libstdc++ 5.4 and lower
+      size_t cwd_size = 16;
+      char * cwd_buf = (char*) std::malloc(cwd_size * sizeof(char));
 
-      boost::filesystem::path path ( fileOrModuleName );
-      path = boost::filesystem::absolute( path );
+      while( getcwd( cwd_buf, cwd_size ) == NULL )
+      {
+         if (errno == ERANGE)
+         {
+            cwd_size *= 2;
+            cwd_buf = (char*) std::realloc( cwd_buf, cwd_size * sizeof(char) );
+         }
+         else
+         {
+            python_coupling::terminateOnPythonException( std::string("Could not determine working directory") );
+         }
+      }
+
+      std::string cwd(cwd_buf);
+      std::free(cwd_buf);
+#else
+      filesystem::path cwd = filesystem::current_path();
+#endif
+      path = filesystem::absolute( path, cwd );
       if ( path.extension() == ".py" )
       {
          moduleName = path.stem().string();
 
 
          if ( ! path.parent_path().empty() )  {
-            std::string p = boost::filesystem::canonical(path.parent_path()).string();
+            std::string p = filesystem::canonical(path.parent_path(), cwd).string();
             code << "sys.path.append( r'" << p << "')" << "\n";
          }
       }
diff --git a/src/vtk/VTKOutput.cpp b/src/vtk/VTKOutput.cpp
index b9a5e0f7d4e7b6a3d0105ff5a107c8609fb95a33..7e660ac3157ab190a038781ea2f9ee8840a7f251 100644
--- a/src/vtk/VTKOutput.cpp
+++ b/src/vtk/VTKOutput.cpp
@@ -138,20 +138,20 @@ void VTKOutput::init( const std::string & identifier )
 
    WALBERLA_ROOT_SECTION()
    {
-      boost::filesystem::path path( baseFolder_ + "/" + identifier_ );
-      if( boost::filesystem::exists( path ) && executionCounter_ == 0 )
-         boost::filesystem::remove_all( path );
+      filesystem::path path( baseFolder_ + "/" + identifier_ );
+      if( filesystem::exists( path ) && executionCounter_ == 0 )
+         filesystem::remove_all( path );
 
-      boost::filesystem::path pvd( baseFolder_ + "/" + identifier_ + ".pvd" );
-      if( boost::filesystem::exists( pvd ) && executionCounter_ == 0 )
+      filesystem::path pvd( baseFolder_ + "/" + identifier_ + ".pvd" );
+      if( filesystem::exists( pvd ) && executionCounter_ == 0 )
          std::remove( pvd.string().c_str() );
 
-      boost::filesystem::path basePath( baseFolder_ );
-      if( !boost::filesystem::exists( basePath ) )
-         boost::filesystem::create_directories( basePath );
+      filesystem::path basePath( baseFolder_ );
+      if( !filesystem::exists( basePath ) )
+         filesystem::create_directories( basePath );
 
-      if ( !boost::filesystem::exists( path ) )
-         boost::filesystem::create_directories( path );
+      if ( !filesystem::exists( path ) )
+         filesystem::create_directories( path );
    }
 
    WALBERLA_MPI_WORLD_BARRIER();
@@ -181,9 +181,9 @@ void VTKOutput::forceWrite( uint_t number, const bool immediatelyWriteCollectors
    {
       if( !useMPIIO_ )
       {
-         boost::filesystem::path tpath( path.str() );
-         if( !boost::filesystem::exists( tpath ) )
-            boost::filesystem::create_directory( tpath );
+         filesystem::path tpath( path.str() );
+         if( !filesystem::exists( tpath ) )
+            filesystem::create_directory( tpath );
       }
    }
    WALBERLA_MPI_WORLD_BARRIER();
@@ -1730,7 +1730,7 @@ void VTKOutput::writePVTI( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1780,7 +1780,7 @@ void VTKOutput::writePVTI_sampled( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1928,7 +1928,7 @@ void VTKOutput::writePVTU( const uint_t collector ) const
 
    ofs << "  </PCellData>\n";
 
-   std::vector< boost::filesystem::path > files;
+   std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
    for( auto file = files.begin(); file != files.end(); ++file )
@@ -1980,17 +1980,17 @@ bool VTKOutput::writeCombinedVTU( std::string localPart, const uint_t collector
 
 
 
-void VTKOutput::getFilenames( std::vector< boost::filesystem::path >& files, const uint_t collector ) const
+void VTKOutput::getFilenames( std::vector< filesystem::path >& files, const uint_t collector ) const
 {
    std::ostringstream path;
    path << baseFolder_ << "/" << identifier_ << "/" << executionFolder_ << "_" << collector;
-   boost::filesystem::path directory( path.str() );
+   filesystem::path directory( path.str() );
 
-   WALBERLA_ASSERT( boost::filesystem::exists( directory ) );
+   WALBERLA_ASSERT( filesystem::exists( directory ) );
 
-   for( boost::filesystem::directory_iterator file( directory ); file != boost::filesystem::directory_iterator(); ++file )
+   for( filesystem::directory_iterator file( directory ); file != filesystem::directory_iterator(); ++file )
    {
-      WALBERLA_ASSERT( boost::filesystem::is_regular_file( file->path() ) && !boost::filesystem::is_directory( file->path() ) );
+      WALBERLA_ASSERT( filesystem::is_regular_file( file->path() ) && !filesystem::is_directory( file->path() ) );
       files.push_back( file->path() );
    }
 }
diff --git a/src/vtk/VTKOutput.h b/src/vtk/VTKOutput.h
index 2f51b9b21f7ad5f8d8232b5f4c119601ed8a4c3b..9b5945630446d443c88bfd5adda6b0bf77b3fc76 100644
--- a/src/vtk/VTKOutput.h
+++ b/src/vtk/VTKOutput.h
@@ -33,8 +33,7 @@
 
 #include "domain_decomposition/StructuredBlockStorage.h"
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
+#include "core/Filesystem.h"
 #include <functional>
 #include <boost/tuple/tuple.hpp>
 
@@ -271,7 +270,7 @@ private:
    bool writeCombinedVTI_sampled( std::string localPart, const uint_t collector ) const;
    bool writeCombinedVTU(std::string localPart, const uint_t collector) const;
 
-   void getFilenames( std::vector< boost::filesystem::path >& blocks, const uint_t collector ) const;
+   void getFilenames( std::vector< filesystem::path >& blocks, const uint_t collector ) const;
    void writePPointData( std::ofstream& ofs ) const;
    void writePCellData( std::ofstream& ofs ) const;
 
diff --git a/src/waLBerlaDefinitions.in.h b/src/waLBerlaDefinitions.in.h
index 0c4408a40bc7daaedc4f3ef00ff4de125f8c378e..26b6627685ab451ae693fb32f8af4dfe0080d8aa 100644
--- a/src/waLBerlaDefinitions.in.h
+++ b/src/waLBerlaDefinitions.in.h
@@ -42,6 +42,13 @@
 #cmakedefine WALBERLA_CXX_COMPILER_IS_MSVC
 #cmakedefine WALBERLA_CXX_COMPILER_IS_CLANG
 
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM
+#cmakedefine WALBERLA_USE_STD_FILESYSTEM
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_ANY
+#cmakedefine WALBERLA_USE_STD_ANY
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL
+#cmakedefine WALBERLA_USE_STD_OPTIONAL
+
 // SIMD
 #cmakedefine WALBERLA_SIMD_FORCE_SCALAR
 
diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp
index 34f961f1a5505211c2e538e5dcf82edf758424ef..c34a1ef8e89d2a138031ba1dde8092be69e7f40a 100644
--- a/tests/core/mpi/BufferTest.cpp
+++ b/tests/core/mpi/BufferTest.cpp
@@ -263,7 +263,7 @@ void bufferTestUInt8()
 {
    std::string stdString("Hello World!"), stdStringEmpty;
 
-   boost::optional<int> optional0, optional1, optional2, optional3;
+   walberla::optional<int> optional0, optional1, optional2, optional3;
    optional2 = 23;
    optional3 = 42;
 
@@ -277,7 +277,7 @@ void bufferTestUInt8()
 
    std::string recvStdString, recvStdStringEmpty;
 
-   boost::optional<int> recvOptional0, recvOptional1, recvOptional2, recvOptional3;
+   walberla::optional<int> recvOptional0, recvOptional1, recvOptional2, recvOptional3;
 
    recvOptional0 = 123;
    recvOptional1 = 123;
diff --git a/tests/core/mpi/MPITextFileTest.cpp b/tests/core/mpi/MPITextFileTest.cpp
index a1551d8bde94a902052e39d9385e3604a88318d1..1500d730f0fdbada5b765286d26b27e5727fa438 100644
--- a/tests/core/mpi/MPITextFileTest.cpp
+++ b/tests/core/mpi/MPITextFileTest.cpp
@@ -27,7 +27,7 @@
 #include "core/mpi/MPIManager.h"
 #include "core/mpi/MPITextFile.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 
 #include <vector>
 #include <sstream>
@@ -61,8 +61,8 @@ void testSameSizeFile( const std::string & filename, const size_t chunkSize )
    WALBERLA_MPI_BARRIER();
    WALBERLA_ROOT_SECTION()
    {
-      if( boost::filesystem::exists( filename ) )
-         boost::filesystem::remove( filename );
+      if( filesystem::exists( filename ) )
+         filesystem::remove( filename );
    }
    WALBERLA_MPI_BARRIER();
 }
@@ -98,8 +98,8 @@ void testDifferentSizeFile( const std::string & filename, const size_t minChunkS
    WALBERLA_MPI_BARRIER();
    WALBERLA_ROOT_SECTION()
    {
-      if( boost::filesystem::exists( filename ) )
-         boost::filesystem::remove( filename );
+      if( filesystem::exists( filename ) )
+         filesystem::remove( filename );
    }
    WALBERLA_MPI_BARRIER();
 }
diff --git a/tests/geometry/VoxelFileTest.cpp b/tests/geometry/VoxelFileTest.cpp
index 8de8c21567b9e00c046a58cc60b5469ba40da4f0..3d6d18fa1654edfacffe3637801e0f4274576557 100644
--- a/tests/geometry/VoxelFileTest.cpp
+++ b/tests/geometry/VoxelFileTest.cpp
@@ -52,7 +52,7 @@
 #include "core/logging/Logging.h"
 #include "core/mpi/MPIManager.h"
 
-#include <boost/filesystem.hpp>
+#include "core/Filesystem.h"
 #include <boost/foreach.hpp>
 #include <random>
 
@@ -209,14 +209,12 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    using namespace walberla;
    using geometry::VoxelFileReader;
 
-   namespace fs = boost::filesystem;
-
    WALBERLA_LOG_INFO( "Running Test with size " << xSize << "x" << ySize << "x" << zSize << " T = " << typeid(T).name() );
 
-   fs::path path(filename);
+   filesystem::path path(filename);
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
    CellInterval aabb(0, 0, 0, cell_idx_c(xSize - 1), cell_idx_c(ySize - 1), cell_idx_c(zSize - 1));
    uint_t numCells = aabb.numCells();
@@ -249,8 +247,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
 
    data.clear();
 
-   WALBERLA_CHECK( fs::exists( path ) );
-   WALBERLA_CHECK( fs::is_regular_file( path ) );
+   WALBERLA_CHECK( filesystem::exists( path ) );
+   WALBERLA_CHECK( filesystem::is_regular_file( path ) );
 
    geometryFile.open(filename);
    WALBERLA_CHECK( geometryFile.isOpen() );
@@ -396,8 +394,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    geometryFile.close();
    WALBERLA_CHECK( !geometryFile.isOpen() );
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
    geometryFile.create(filename, xSize, ySize, zSize);
 
@@ -465,8 +463,8 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    }
    WALBERLA_CHECK( runtimeErrorThrown );
    geometryFile.close();
-   if( fs::exists( fs::path(filename + "0") ) )
-      fs::remove( fs::path(filename + "0") );
+   if( filesystem::exists( filesystem::path(filename + "0") ) )
+      filesystem::remove( filesystem::path(filename + "0") );
 
    if(xSize > 0)
    {
@@ -487,12 +485,12 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
       }
       WALBERLA_CHECK( runtimeErrorThrown );
       geometryFile.close();
-      if( fs::exists( fs::path(filename + "1") ) )
-         fs::remove( fs::path(filename + "1") );
+      if( filesystem::exists( filesystem::path(filename + "1") ) )
+         filesystem::remove( filesystem::path(filename + "1") );
    }
 
-   if( fs::exists( path ) )
-      fs::remove( path );
+   if( filesystem::exists( path ) )
+      filesystem::remove( path );
 
 }
 
diff --git a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
index c3cdade9e67b14fedd9ffba308b7791f9c425c3b..d9fd267079e1b78d322a80ff1e7afdd1aabc3755 100644
--- a/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/HinderedSettlingDynamicsDPM.cpp
@@ -703,9 +703,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    ///////////////////////////////
diff --git a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
index b6c7eaab553d0431115e2d3e468d3640eb14840d..5ec32af40e6dc4dae10443bdb2f31f1bd01c791f 100644
--- a/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
+++ b/tests/pe_coupling/discrete_particle_methods/SphereWallCollisionBehaviorDPM.cpp
@@ -595,9 +595,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    ///////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
index 1b0d57f8e085afef600e8b85d0b9d2bfef6b0ba4..6674cde01316e65119f1738ef249945b0614fca2 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEM.cpp
@@ -312,9 +312,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
index 469892c98be27ce0920bcf5c52e4c609f838e9f5..44b17eb70ee97b509d096e0b09133d97bc40efc8 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMDynamicRefinement.cpp
@@ -516,9 +516,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////
diff --git a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
index 7a0734d33b7845eb778b275d79e6b0b043202fcd..391ab7b8947bd32cc518760d4fc726c96ceae4c6 100644
--- a/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SettlingSphereMEMStaticRefinement.cpp
@@ -405,9 +405,9 @@ int main( int argc, char **argv )
    if( fileIO )
    {
       // create base directory if it does not yet exist
-      boost::filesystem::path tpath( baseFolder );
-      if( !boost::filesystem::exists( tpath ) )
-         boost::filesystem::create_directory( tpath );
+      filesystem::path tpath( baseFolder );
+      if( !filesystem::exists( tpath ) )
+         filesystem::create_directory( tpath );
    }
 
    //////////////////////////////////////