diff --git a/Tests/Kernels/testBlockedTree.cpp b/Tests/Kernels/testBlockedTree.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..810d2a84f88ee7ffaec5a1749ecbe2cdb5d13863
--- /dev/null
+++ b/Tests/Kernels/testBlockedTree.cpp
@@ -0,0 +1,340 @@
+
+#include "../../Src/Utils/FAssert.hpp"
+#include "../../Src/Containers/FTreeCoordinate.hpp"
+
+#include <list>
+#include <functional>
+
+template <class CellClass>
+class FBlockedTree {
+protected:
+    /**
+     * @brief The FBlockOfCells class manages the cells in block allocation.
+     */
+    class FBlockOfCells {
+        /** One header is allocated at the beginning of each block */
+        struct BlockHeader{
+            MortonIndex startingIndex;
+            MortonIndex endingIndex;
+            int numberOfCellsInBlock;
+            int blockIndexesTableSize;
+        };
+        //< This value is for not used cells
+        static const int CellIsEmptyFlag = -1;
+
+    protected:
+        //< Pointer to a block memory
+        unsigned char* memoryBuffer;
+
+        //< Pointer to the header inside the block memory
+        BlockHeader*    blockHeader;
+        //< Pointer to the indexes table inside the block memory
+        int*            blockIndexesTable;
+        //< Pointer to the cells inside the block memory
+        CellClass*      blockCells;
+
+    public:
+        /**
+         * @brief FBlockOfCells
+         * @param inStartingIndex first cell morton index
+         * @param inEndingIndex last cell morton index + 1
+         * @param inNumberOfCells total number of cells in the interval (should be <= inEndingIndex-inEndingIndex)
+         */
+        FBlockOfCells(const MortonIndex inStartingIndex, const MortonIndex inEndingIndex, const int inNumberOfCells)
+            : memoryBuffer(0), blockHeader(0), blockIndexesTable(0), blockCells(0){
+            // Find the number of cell to allocate in the blocks
+            const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex);
+            FAssertLF(inNumberOfCells <= blockIndexesTableSize);
+            // Total number of bytes in the block
+            const size_t memoryToAlloc = sizeof(BlockHeader) + (blockIndexesTableSize*sizeof(int)) + (inNumberOfCells*sizeof(CellClass));
+
+            // Allocate
+            memoryBuffer = new unsigned char[memoryToAlloc];
+            FAssertLF(memoryBuffer);
+            memset(memoryBuffer, 0, memoryToAlloc);
+
+            // Move the pointers to the correct position
+            blockHeader         = reinterpret_cast<BlockHeader*>(memoryBuffer);
+            blockIndexesTable   = reinterpret_cast<int*>(memoryBuffer+sizeof(BlockHeader));
+            blockCells          = reinterpret_cast<CellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockIndexesTableSize*sizeof(int)));
+
+            // Init header
+            blockHeader->startingIndex = inStartingIndex;
+            blockHeader->endingIndex   = inEndingIndex;
+            blockHeader->numberOfCellsInBlock  = inNumberOfCells;
+            blockHeader->blockIndexesTableSize = blockIndexesTableSize;
+
+            // Set all index to not used
+            for(int idxCellPtr = 0 ; idxCellPtr < blockIndexesTableSize ; ++idxCellPtr){
+                blockIndexesTable[idxCellPtr] = CellIsEmptyFlag;
+            }
+        }
+
+        /** Call the destructor of cells and dealloc block memory */
+        ~FBlockOfCells(){
+            for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
+                if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
+                    (&blockCells[blockIndexesTable[idxCellPtr]])->~CellClass();
+                }
+            }
+            delete[] memoryBuffer;
+        }
+
+        /** The index of the fist cell (set from the constructor) */
+        MortonIndex getStartingIndex() const {
+            return blockHeader->startingIndex;
+        }
+
+        /** The index of the last cell + 1 (set from the constructor) */
+        MortonIndex getEndingIndex() const {
+            return blockHeader->endingIndex;
+        }
+
+        /** The number of cell (set from the constructor) */
+        int getNumberOfCellsInBlock() const {
+            return blockHeader->numberOfCellsInBlock;
+        }
+
+        /** The size of the interval endingIndex-startingIndex (set from the constructor) */
+        int getSizeOfInterval() const {
+            return blockHeader->blockIndexesTableSize;
+        }
+
+        /** Return true if inIndex should be located in the current block */
+        bool isInside(const MortonIndex inIndex) const{
+            return blockHeader->startingIndex <= inIndex && inIndex < blockHeader->endingIndex;
+        }
+
+        /** Return true if inIndex is located in the current block and is not empty */
+        bool exists(const MortonIndex inIndex) const {
+            return isInside(inIndex) && (blockIndexesTable[inIndex-blockHeader->startingIndex] != CellIsEmptyFlag);
+        }
+
+        /** Return the address of the cell if it exists (or NULL) */
+        CellClass* getCell(const MortonIndex inIndex){
+            if( exists(inIndex) ) return &blockCells[blockIndexesTable[inIndex-blockHeader->startingIndex]];
+            else return 0;
+        }
+
+        /** Return the address of the cell if it exists (or NULL) */
+        const CellClass* getCell(const MortonIndex inIndex) const {
+            if( exists(inIndex) ) return &blockCells[blockIndexesTable[inIndex-blockHeader->startingIndex]];
+            else return 0;
+        }
+
+        /** Allocate a new cell by calling its constructor */
+        template<typename... CellConstructorParams>
+        void newCell(const MortonIndex inIndex, const int id, CellConstructorParams... args){
+            FAssertLF(isInside(inIndex));
+            FAssertLF(!exists(inIndex));
+            FAssertLF(id < blockHeader->blockIndexesTableSize);
+            new((void*)&blockCells[id]) CellClass(args...);
+            blockIndexesTable[inIndex-blockHeader->startingIndex] = id;
+        }
+
+        /** Iterate on each allocated cells */
+        template<typename... FunctionParams>
+        void forEachCell(std::function<void(CellClass*)> function, FunctionParams... args){
+            for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
+                if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
+                    function(&blockCells[blockIndexesTable[idxCellPtr]], args...);
+                }
+            }
+        }
+    };
+
+    //< height of the tree (1 => only the root)
+    const int treeHeight;
+    //< max number of cells in a block
+    const int nbCellsPerBlocks;
+    //< all the blocks of the tree
+    std::list<FBlockOfCells*>* cellBlocksPerLevel;
+
+public:
+    /** This constructor create a blocked octree from a usual octree
+     * The cell are allocated as in the usual octree (no copy constructor are called!)
+     * Once allocated each cell receive its morton index and tree coordinate.
+     * No blocks are allocated at level 0.
+     */
+    template<class OctreeClass>
+    FBlockedTree(const int inTreeHeight, const int inNbCellsPerBlock, OctreeClass*const inOctreeSrc)
+        : treeHeight(inTreeHeight), nbCellsPerBlocks(inNbCellsPerBlock), cellBlocksPerLevel(0){
+        cellBlocksPerLevel = new std::list<FBlockOfCells*>[treeHeight];
+
+        // Iterate on the tree and build
+        typename OctreeClass::Iterator octreeIterator(inOctreeSrc);
+        octreeIterator.gotoBottomLeft();
+
+        // For each level from heigth - 1 to 1
+        for(int idxLevel = treeHeight-1; idxLevel > 0 ; --idxLevel){
+            typename OctreeClass::Iterator avoidGotoLeft = octreeIterator;
+            // For each cell at this level
+            do {
+                typename OctreeClass::Iterator blockIteratorInOctree = octreeIterator;
+                // Move the iterator per nbCellsPerBlocks (or until it cannot move right)
+                int sizeOfBlock = 1;
+                while(sizeOfBlock < nbCellsPerBlocks && octreeIterator.moveRight()){
+                    sizeOfBlock += 1;
+                }
+
+                // Create a block with the apropriate parameters
+                FBlockOfCells*const newBlock = new FBlockOfCells(blockIteratorInOctree.getCurrentGlobalIndex(),
+                                                                 octreeIterator.getCurrentGlobalIndex()+1,
+                                                                 sizeOfBlock);
+                // Initialize each cell of the block
+                int cellIdInBlock = 0;
+                while(cellIdInBlock != sizeOfBlock){
+                    const CellClass*const oldNode = blockIteratorInOctree.getCurrentCell();
+                    newBlock->newCell(oldNode->getMortonIndex(), cellIdInBlock);
+
+                    CellClass* newNode = newBlock->getCell(oldNode->getMortonIndex());
+                    newNode->setMortonIndex(oldNode->getMortonIndex());
+                    newNode->setCoordinate(oldNode->getCoordinate());
+
+                    cellIdInBlock += 1;
+                    blockIteratorInOctree.moveRight();
+                }
+
+                // Keep the block
+                cellBlocksPerLevel[idxLevel].push_back(newBlock);
+
+                // If we can move right then add another block
+            } while(octreeIterator.moveRight());
+
+            avoidGotoLeft.moveUp();
+            octreeIterator = avoidGotoLeft;
+        }
+    }
+
+    /** This function dealloc the tree by deleting each block */
+    ~FBlockedTree(){
+        for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
+            std::list<FBlockOfCells*>& levelBlocks = cellBlocksPerLevel[idxLevel];
+            for (FBlockOfCells* &block: levelBlocks){
+                delete block;
+            }
+        }
+        delete[] cellBlocksPerLevel;
+    }
+
+
+    /////////////////////////////////////////////////////////
+    // Lambda function to apply to all member
+    /////////////////////////////////////////////////////////
+
+    /**
+     * @brief forEachLeaf iterate on the leaf and apply the function
+     * @param function
+     */
+    //void forEachLeaf(std::function<void(LeafClass*)> function){
+        // TODO
+    //}
+
+    /**
+     * @brief forEachLeaf iterate on the cell and apply the function
+     * @param function
+     */
+    void forEachCell(std::function<void(CellClass*)> function){
+        for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
+            std::list<FBlockOfCells*>& levelBlocks = cellBlocksPerLevel[idxLevel];
+            for (FBlockOfCells* &block: levelBlocks){
+                block->forEachCell(function);
+            }
+        }
+    }
+
+    /**
+     * @brief forEachLeaf iterate on the cell and apply the function
+     * @param function
+     */
+    void forEachCellWithLevel(std::function<void(CellClass*,const int)> function){
+        for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
+            std::list<FBlockOfCells*>& levelBlocks = cellBlocksPerLevel[idxLevel];
+            for (FBlockOfCells* &block: levelBlocks){
+                block->forEachCell(function, idxLevel);
+            }
+        }
+    }
+
+    /**
+     * @brief forEachLeaf iterate on the cell and apply the function
+     * @param function
+     */
+    //void forEachCellLeaf(std::function<void(CellClass*,LeafClass*)> function){
+        // TODO
+    //}
+};
+
+
+
+
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Containers/FVector.hpp"
+
+#include "../../Src/Containers/FOctree.hpp"
+
+#include "../../Src/Core/FFmmAlgorithm.hpp"
+
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
+#include "../../Src/Kernels/Rotation/FRotationKernel.hpp"
+#include "../../Src/Kernels/Rotation/FRotationCell.hpp"
+
+#include "../../Src/Utils/FMath.hpp"
+#include "../../Src/Utils/FMemUtils.hpp"
+#include "../../Src/Utils/FParameters.hpp"
+
+#include "../../Src/Core/FFmmAlgorithm.hpp"
+#include "../../Src/Core/FFmmAlgorithmThread.hpp"
+#include "../../Src/Core/FFmmAlgorithmTask.hpp"
+
+#include "../../Src/Files/FFmaLoader.hpp"
+
+
+
+int main(int argc, char* argv[]){
+    static const int P = 9;
+    typedef FRotationCell<P>               CellClass;
+    typedef FP2PParticleContainer          ContainerClass;
+
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FRotationKernel< CellClass, ContainerClass , P>   KernelClass;
+    typedef FBlockedTree< CellClass >  BlockedOctreeClass;
+
+    FTic counter;
+    const int NbLevels      = FParameters::getValue(argc,argv,"-h", 5);
+    const int SizeSubLevels = FParameters::getValue(argc,argv,"-sh", 3);
+    const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
+
+    FFmaLoader loader(filename);
+    FAssertLF(loader.isOpen());
+
+    OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
+
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
+
+    std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.tacAndElapsed() << "s)." << std::endl;
+
+    const int blockSize      = FParameters::getValue(argc,argv,"-bs", 250);
+
+    counter.tic();
+    BlockedOctreeClass blockedTree(NbLevels, blockSize, &tree);
+    std::cout << "Done  " << "(@Converting the tree = " << counter.tacAndElapsed() << "s). Block size is " << blockSize << "." << std::endl;
+
+    blockedTree.forEachCell([&](CellClass * cell){
+        std::cout << "Cell " << cell->getMortonIndex() << std::endl;
+    });
+
+    return 0;
+}
+
+
+
+
+