diff --git a/src/domain_decomposition/MapPointToPeriodicDomain.cpp b/src/domain_decomposition/MapPointToPeriodicDomain.cpp
index 82f365e0e5d9bd733f7207eb407a7a7cadc57036..1c86e7364e0ca2622d9a540b1cb496f3aed42c3e 100644
--- a/src/domain_decomposition/MapPointToPeriodicDomain.cpp
+++ b/src/domain_decomposition/MapPointToPeriodicDomain.cpp
@@ -40,7 +40,7 @@ void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AAB
          shift = std::max( shift, real_t(0) );
          x = domain.xMax() - shift;
          if( isIdentical( x, domain.xMax() ) || x < domain.xMin() )
-            x = domain.xMin();
+            x = std::nextafter(domain.xMax(), domain.xMin());
       }
       else if( x >= domain.xMax() )
       {
@@ -61,7 +61,7 @@ void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AAB
          shift = std::max( shift, real_t(0) );
          y = domain.yMax() - shift;
          if( isIdentical( y, domain.yMax() ) || y < domain.yMin() )
-            y = domain.yMin();
+            y = std::nextafter(domain.yMax(), domain.yMin());
       }
       else if( y >= domain.yMax() )
       {
@@ -82,7 +82,7 @@ void mapPointToPeriodicDomain( const std::array< bool, 3 > & periodic, const AAB
          shift = std::max( shift, real_t(0) );
          z = domain.zMax() - shift;
          if( isIdentical( z, domain.zMax() ) || z < domain.zMin() )
-            z = domain.zMin();
+            z = std::nextafter(domain.zMax(), domain.zMin());
       }
       else if( z >= domain.zMax() )
       {
diff --git a/src/pe/synchronization/SyncNextNeighbors.h b/src/pe/synchronization/SyncNextNeighbors.h
index 63aa9a2081db232e11a8677cca8eec6253c7fd40..a546dae5b53fe8a23bee24565f9fa98a6e4a8bbb 100644
--- a/src/pe/synchronization/SyncNextNeighbors.h
+++ b/src/pe/synchronization/SyncNextNeighbors.h
@@ -41,6 +41,7 @@
 #include "blockforest/BlockForest.h"
 #include "core/mpi/BufferSystem.h"
 #include "core/timing/TimingTree.h"
+#include "domain_decomposition/MapPointToPeriodicDomain.h"
 
 namespace walberla {
 namespace pe {
@@ -56,7 +57,16 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
    WALBERLA_LOG_DETAIL( "Assembling of body synchronization message starts..." );
 
    // position update
-   for( auto body = localStorage.begin(); body != localStorage.end(); ) {
+   for( auto body = localStorage.begin(); body != localStorage.end(); )
+   {
+      //correct position to make sure body is always inside the domain!
+      if (!body->isFixed())
+      {
+         auto pos = body->getPosition();
+         block.getBlockStorage().mapToPeriodicDomain(pos);
+         body->setPosition(pos);
+      }
+
       bool isInsideDomain = domain.contains( body->getAABB(), -dx );
 
       WALBERLA_ASSERT( !body->isRemote(), "Central body storage contains remote bodies." );
@@ -146,7 +156,7 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
       {
          // Body is no longer locally owned (body is about to be migrated).
          Owner owner( findContainingProcess( block, gpos ) );
-         WALBERLA_ASSERT_UNEQUAL( owner.blockID_, me.blockID_, "Position is " << gpos );
+         WALBERLA_ASSERT_UNEQUAL( owner.blockID_, me.blockID_, "Position is " << gpos << "\nlocal Block is: " << block.getAABB() );
 
          WALBERLA_LOG_DETAIL( "Local body " << b->getSystemID() << " is no longer on process " << body->MPITrait.getOwner() << " but on process " << owner );
 
@@ -189,6 +199,11 @@ void generateSynchonizationMessages(mpi::BufferSystem& bs, const Block& block, B
             b->setRemote( true );
 
             // Move body to shadow copy storage.
+            {
+               auto pos = b->getPosition();
+               correctBodyPosition(domain, block.getAABB().center(), pos);
+               b->setPosition(pos);
+            }
             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.
diff --git a/src/pe/synchronization/SyncShadowOwners.h b/src/pe/synchronization/SyncShadowOwners.h
index cc0400d11d50f78597a9be5fd53666c84f386ae0..49752ae1746f0eb5c77490e01a261da07731a3ee 100644
--- a/src/pe/synchronization/SyncShadowOwners.h
+++ b/src/pe/synchronization/SyncShadowOwners.h
@@ -81,6 +81,14 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy
       {
          BodyID b (bodyIt.getBodyID());
 
+         //correct position to make sure body is always inside the domain!
+         if (!b->isFixed())
+         {
+            auto pos = b->getPosition();
+            block.getBlockStorage().mapToPeriodicDomain(pos);
+            b->setPosition(pos);
+         }
+
          if( !b->isCommunicating() && !syncNonCommunicatingBodies ) {
             ++bodyIt;
             continue;
@@ -131,6 +139,11 @@ void updateAndMigrate( BlockForest& forest, BlockDataID storageID, const bool sy
                b->setRemote( true );
 
                // Move body to shadow copy storage.
+               {
+                  auto pos = b->getPosition();
+                  correctBodyPosition(forest.getDomain(), block.getAABB().center(), pos);
+                  b->setPosition(pos);
+               }
                shadowStorage.add( localStorage.release( bodyIt ) );
 
                b->MPITrait.deregisterShadowOwner( owner );
@@ -215,7 +228,7 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r
       BodyStorage& shadowStorage = (*storage)[1];
 
       const Owner me( int_c(block.getProcess()), block.getId().getID() );
-//      const math::AABB& blkAABB = block->getAABB();
+      //      const math::AABB& blkAABB = block->getAABB();
 
       for( auto bodyIt = localStorage.begin(); bodyIt != localStorage.end(); ++bodyIt)
       {
@@ -238,10 +251,10 @@ void checkAndResolveOverlap( BlockForest& forest, BlockDataID storageID, const r
 
             if (b->MPITrait.getOwner() == nbProcess) continue; // dont send to owner!!
             if (b->MPITrait.getBlockState( nbProcess.blockID_ )) continue; // only send to neighbor which do not know this body
-//            WALBERLA_LOG_DEVEL("neighobur aabb: " << block.getNeighborAABB(nb));
-//            WALBERLA_LOG_DEVEL("isInsideDomain: " << isInsideDomain);
-//            WALBERLA_LOG_DEVEL("body AABB: " << b->getAABB());
-//            WALBERLA_LOG_DEVEL("neighbour AABB: " << block.getNeighborAABB(nb));
+            //            WALBERLA_LOG_DEVEL("neighobur aabb: " << block.getNeighborAABB(nb));
+            //            WALBERLA_LOG_DEVEL("isInsideDomain: " << isInsideDomain);
+            //            WALBERLA_LOG_DEVEL("body AABB: " << b->getAABB());
+            //            WALBERLA_LOG_DEVEL("neighbour AABB: " << block.getNeighborAABB(nb));
 
             if( (isInsideDomain ? block.getNeighborAABB(nb).intersects( b->getAABB(), dx ) : block.getBlockStorage().periodicIntersect(block.getNeighborAABB(nb), b->getAABB(), dx)) )
             {
diff --git a/tests/pe/CMakeLists.txt b/tests/pe/CMakeLists.txt
index 49002bdc955b67fb6b97361a3a7e38f50e592fa4..11635dd21f59b545248bd3f7f2bc740dac89a825 100644
--- a/tests/pe/CMakeLists.txt
+++ b/tests/pe/CMakeLists.txt
@@ -94,8 +94,9 @@ set_property( TEST PE_SERIALIZEDESERIALIZE04 PROPERTY DEPENDS PE_SERIALIZEDESERI
 set_property( TEST PE_SERIALIZEDESERIALIZE08 PROPERTY DEPENDS PE_SERIALIZEDESERIALIZE04 ) #serialize runs of tets to avoid i/o conflicts when running ctest with -jN
 endif()
 
-waLBerla_compile_test( NAME   PE_SHADOWCOPY FILES ShadowCopy.cpp DEPENDS core blockforest  )
-waLBerla_execute_test( NAME   PE_SHADOWCOPY )
+waLBerla_compile_test( NAME   PE_SHADOWCOPY FILES ShadowCopy.cpp DEPENDS core blockforest domain_decomposition  )
+waLBerla_execute_test( NAME   PE_SHADOWCOPY_NN COMMAND $<TARGET_FILE:PE_SHADOWCOPY> )
+waLBerla_execute_test( NAME   PE_SHADOWCOPY_SO COMMAND $<TARGET_FILE:PE_SHADOWCOPY> --syncShadowOwners )
 
 waLBerla_compile_test( NAME   PE_SIMPLECCD FILES SimpleCCD.cpp DEPENDS core  )
 waLBerla_execute_test( NAME   PE_SIMPLECCD )
diff --git a/tests/pe/ShadowCopy.cpp b/tests/pe/ShadowCopy.cpp
index 8c5dba7c4ad95888979f9b6c88f6109fc763d475..4a1670316768363246310de09f0e3c4e463c0441 100644
--- a/tests/pe/ShadowCopy.cpp
+++ b/tests/pe/ShadowCopy.cpp
@@ -42,6 +42,19 @@ int main( int argc, char** argv )
    walberla::debug::enterTestMode();
    walberla::MPIManager::instance()->initializeMPI( &argc, &argv );
 
+   bool syncShadowOwners = false;
+   for( int i = 1; i < argc; ++i )
+   {
+      if( std::strcmp( argv[i], "--syncShadowOwners" ) == 0 ) syncShadowOwners = true;
+   }
+   if (syncShadowOwners)
+   {
+      WALBERLA_LOG_DEVEL("running with syncShadowOwners");
+   } else
+   {
+      WALBERLA_LOG_DEVEL("running with syncNextNeighbour");
+   }
+
    shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
 
    // create blocks
@@ -64,7 +77,7 @@ int main( int argc, char** argv )
 //   logging::Logging::instance()->setFileLogLevel(logging::Logging::DETAIL);
 //   logging::Logging::instance()->includeLoggingToFile("ShadowCopy");
 
-   bool syncShadowOwners = false;
+
    std::function<void(void)> syncCall;
    if (!syncShadowOwners)
    {
@@ -95,6 +108,23 @@ int main( int argc, char** argv )
    WALBERLA_CHECK_FLOAT_EQUAL( sp->getRadius(), real_t(1.2) );
    destroyBodyBySID( *globalBodyStorage, forest->getBlockStorage(), storageID, sid );
 
+   WALBERLA_LOG_PROGRESS_ON_ROOT( " *** SPHERE AT BLOCK EDGE *** ");
+   sp = pe::createSphere(
+            *globalBodyStorage,
+            forest->getBlockStorage(),
+            storageID,
+            999999999,
+            Vec3(0,2,2),
+            real_c(1.2));
+   sid = sp->getSystemID();
+   syncCall();
+   sp = static_cast<SphereID> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL ));
+   sp->setPosition(real_c(-1)*std::numeric_limits<real_t>::epsilon(),2,2);
+   syncCall();
+   sp = static_cast<SphereID> (getBody( *globalBodyStorage, forest->getBlockStorage(), storageID, sid, StorageSelect::LOCAL ));
+   WALBERLA_CHECK_NOT_NULLPTR(sp);
+   destroyBodyBySID( *globalBodyStorage, forest->getBlockStorage(), storageID, sid );
+
    WALBERLA_LOG_PROGRESS_ON_ROOT( " *** UNION *** ");
    UnionT* un   = createUnion< boost::tuple<Sphere> >( *globalBodyStorage, forest->getBlockStorage(), storageID, 0, Vec3(2,2,2) );
    auto sp1 = createSphere(un, 10, Vec3(real_t(4.9),2,2), real_t(1));