diff --git a/src/pe/rigidbody/StorageDataHandling.h b/src/pe/rigidbody/StorageDataHandling.h
index 9c8419567e9b902a031ccdea1866f95542fe24f3..6e3b0d2dafad64473a5b63f325e00bdccd49eb38 100644
--- a/src/pe/rigidbody/StorageDataHandling.h
+++ b/src/pe/rigidbody/StorageDataHandling.h
@@ -37,20 +37,47 @@ namespace pe{
 
 
 template<typename BodyTuple>
-class StorageDataHandling : public domain_decomposition::BlockDataHandling<Storage>{
+class StorageDataHandling : public blockforest::BlockDataHandling<Storage>{
 public:
-   Storage * initialize( IBlock * const /*block*/ ) {return new Storage();}
+   virtual ~StorageDataHandling() {}
 
    /// must be thread-safe !
-   virtual inline void serialize( IBlock * const block, const BlockDataID & id, mpi::SendBuffer & buffer );
+   virtual Storage * initialize( IBlock * const block ) WALBERLA_OVERRIDE;
+
+   /// must be thread-safe !
+   virtual void serialize( IBlock * const block, const BlockDataID & id, mpi::SendBuffer & buffer ) WALBERLA_OVERRIDE;
+   /// must be thread-safe !
+   virtual Storage * deserialize( IBlock * const block ) WALBERLA_OVERRIDE;
+   /// must be thread-safe !
+   virtual void deserialize( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer ) WALBERLA_OVERRIDE;
+
+   /// must be thread-safe !
+   virtual void serializeCoarseToFine( Block * const block, const BlockDataID & id, mpi::SendBuffer & buffer, const uint_t child ) WALBERLA_OVERRIDE;
+   /// must be thread-safe !
+   virtual void serializeFineToCoarse( Block * const block, const BlockDataID & id, mpi::SendBuffer & buffer ) WALBERLA_OVERRIDE;
+
+   /// must be thread-safe !
+   virtual Storage * deserializeCoarseToFine( Block * const block ) WALBERLA_OVERRIDE;
+   /// must be thread-safe !
+   virtual Storage * deserializeFineToCoarse( Block * const block ) WALBERLA_OVERRIDE;
+
    /// must be thread-safe !
-   virtual inline  Storage * deserialize( IBlock * const block );
+   virtual void deserializeCoarseToFine( Block * const block, const BlockDataID & id, mpi::RecvBuffer & buffer ) WALBERLA_OVERRIDE;
    /// must be thread-safe !
-   virtual inline void deserialize( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer );
+   virtual void deserializeFineToCoarse( Block * const block, const BlockDataID & id, mpi::RecvBuffer & buffer, const uint_t child ) WALBERLA_OVERRIDE;
+
+private:
+   void deserializeImpl( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer );
 };
 
 template<typename BodyTuple>
-inline void StorageDataHandling<BodyTuple>::serialize( IBlock * const block, const BlockDataID & id, mpi::SendBuffer & buffer )
+Storage * StorageDataHandling<BodyTuple>::initialize( IBlock * const /*block*/ )
+{
+   return new Storage();
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::serialize( IBlock * const block, const BlockDataID & id, mpi::SendBuffer & buffer )
 {
    using namespace walberla::pe::communication;
    BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
@@ -67,18 +94,119 @@ inline void StorageDataHandling<BodyTuple>::serialize( IBlock * const block, con
 }
 
 template<typename BodyTuple>
-inline  Storage * StorageDataHandling<BodyTuple>::deserialize( IBlock * const block )
+Storage * StorageDataHandling<BodyTuple>::deserialize( IBlock * const block )
 {
    return initialize(block);
 }
 
 template<typename BodyTuple>
-inline void StorageDataHandling<BodyTuple>::deserialize( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer )
+void StorageDataHandling<BodyTuple>::deserialize( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer )
+{
+   WALBERLA_DEBUG_SECTION()
+   {
+      BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
+      WALBERLA_CHECK_EQUAL( localBodyStorage.size(), 0);
+   }
+   deserializeImpl( block, id, buffer);
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::serializeCoarseToFine( Block * const block, const BlockDataID & id, mpi::SendBuffer & buffer, const uint_t child )
+{
+   // get child aabb
+   const math::AABB aabb = block->getAABB();
+   const real_t xMid = (aabb.xMax() + aabb.xMin()) * real_t(0.5);
+   const real_t yMid = (aabb.yMax() + aabb.yMin()) * real_t(0.5);
+   const real_t zMid = (aabb.zMax() + aabb.zMin()) * real_t(0.5);
+
+   const real_t xMin = (child & uint_t(1)) ? xMid : aabb.xMin();
+   const real_t xMax = (child & uint_t(1)) ? aabb.xMax() : xMid;
+
+   const real_t yMin = (child & uint_t(2)) ? yMid : aabb.yMin();
+   const real_t yMax = (child & uint_t(2)) ? aabb.yMax() : yMid;
+
+   const real_t zMin = (child & uint_t(4)) ? zMid : aabb.zMin();
+   const real_t zMax = (child & uint_t(4)) ? aabb.zMax() : zMid;
+
+   const math::AABB childAABB(xMin, yMin, zMin, xMax, yMax, zMax);
+   //WALBERLA_LOG_DEVEL( (child & uint_t(1)) << (child & uint_t(2)) << (child & uint_t(4)) << "\naabb: " << aabb << "\nchild: " << childAABB );
+
+   using namespace walberla::pe::communication;
+
+   BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
+
+   decltype(localBodyStorage.size()) numOfParticles = 0;
+
+   auto ptr = buffer.allocate<decltype(localBodyStorage.size())>();
+   for (auto bodyIt = localBodyStorage.begin(); bodyIt != localBodyStorage.end(); ++bodyIt)
+   {
+      if ( !block->getAABB().contains( bodyIt->getPosition()) )
+      {
+         WALBERLA_ABORT( "Body to be stored not contained within block!" );
+      }
+      if( childAABB.contains( bodyIt->getPosition()) )
+      {
+         marshal( buffer, RigidBodyCopyNotification( **bodyIt ) );
+         MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt );
+         ++numOfParticles;
+      }
+   }
+   *ptr = numOfParticles;
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::serializeFineToCoarse( Block * const block, const BlockDataID & id, mpi::SendBuffer & buffer )
+{
+   using namespace walberla::pe::communication;
+   BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
+   buffer << localBodyStorage.size();
+   for (auto bodyIt = localBodyStorage.begin(); bodyIt != localBodyStorage.end(); ++bodyIt)
+   {
+      if ( !block->getAABB().contains( bodyIt->getPosition()) )
+      {
+         WALBERLA_ABORT( "Body to be stored not contained within block!" );
+      }
+      marshal( buffer, RigidBodyCopyNotification( **bodyIt ) );
+      MarshalDynamically<BodyTuple>::execute( buffer, **bodyIt );
+   }
+}
+
+template<typename BodyTuple>
+Storage * StorageDataHandling<BodyTuple>::deserializeCoarseToFine( Block * const block )
+{
+   return initialize(block);
+}
+
+template<typename BodyTuple>
+Storage * StorageDataHandling<BodyTuple>::deserializeFineToCoarse( Block * const block )
+{
+   return initialize(block);
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::deserializeCoarseToFine( Block * const block, const BlockDataID & id, mpi::RecvBuffer & buffer )
+{
+   WALBERLA_DEBUG_SECTION()
+   {
+      BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
+      WALBERLA_CHECK_EQUAL( localBodyStorage.size(), 0);
+   }
+   deserializeImpl( block, id, buffer);
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::deserializeFineToCoarse( Block * const block, const BlockDataID & id, mpi::RecvBuffer & buffer, const uint_t /*child*/ )
+{
+   deserializeImpl( block, id, buffer);
+}
+
+template<typename BodyTuple>
+void StorageDataHandling<BodyTuple>::deserializeImpl( IBlock * const block, const BlockDataID & id, mpi::RecvBuffer & buffer )
 {
    using namespace walberla::pe::communication;
 
    BodyStorage& localBodyStorage = (*(block->getData< Storage >( id )))[0];
-   auto numBodies = localBodyStorage.size(); // just to get type right!!! can be replaced by decltype (C++11)
+   decltype(localBodyStorage.size()) numBodies = 0;
    buffer >> numBodies;
 
    while( numBodies > 0 )
@@ -88,10 +216,11 @@ inline void StorageDataHandling<BodyTuple>::deserialize( IBlock * const block, c
 
       BodyID 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" << block->getAABB() << "\n" << 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);