From d940c321ea21d2591aa9dd08cc26b84594ff96f7 Mon Sep 17 00:00:00 2001
From: bramas <berenger.bramas@inria.fr>
Date: Thu, 6 Jun 2013 12:30:47 +0200
Subject: [PATCH] Major update to move to new leaf a smaller revision will come
 after test and comments

---
 Src/Arranger/FOctreeArranger.hpp              |  38 +-
 Src/Components/FAbstractLeaf.hpp              |  10 +-
 ...cle.hpp => FAbstractParticleContainer.hpp} |  29 +-
 Src/Components/FBasicCell.hpp                 |   1 -
 Src/Components/FBasicParticleContainer.hpp    | 204 ++++++++
 ...Particle.hpp => FFmaParticleContainer.hpp} |  29 +-
 Src/Components/FSimpleLeaf.hpp                |   9 +-
 Src/Components/FTestKernels.hpp               |  44 +-
 Src/Components/FTestParticle.hpp              |  73 ---
 ...article.hpp => FTestParticleContainer.hpp} |  35 +-
 Src/Components/FTypedLeaf.hpp                 |  13 +-
 Src/Containers/FOctree.hpp                    |  65 ++-
 Src/Containers/FSubOctree.hpp                 | 127 +++--
 Src/Containers/FTreeCoordinate.hpp            |  22 +
 Src/Core/FFmmAlgorithm.hpp                    |   2 +-
 Src/Core/FFmmAlgorithmPeriodic.hpp            |  33 +-
 Src/Core/FFmmAlgorithmSectionTask.hpp         |   2 +-
 Src/Core/FFmmAlgorithmTask.hpp                |   2 +-
 Src/Core/FFmmAlgorithmThread.hpp              |   2 +-
 Src/Core/FFmmAlgorithmThreadProc.hpp          |   2 +-
 Src/Core/FFmmAlgorithmThreadTsm.hpp           |   6 +-
 Src/Core/FFmmAlgorithmTsm.hpp                 |   6 +-
 Src/Extensions/FExtendForces.hpp              |  87 ----
 Src/Extensions/FExtendParticleType.hpp        | 105 ----
 Src/Extensions/FExtendPhysicalValue.hpp       |  74 ---
 Src/Extensions/FExtendPosition.hpp            |  93 ----
 Src/Extensions/FExtendPotential.hpp           |  78 ---
 Src/Extensions/FExtendVelocity.hpp            |  88 ----
 Src/Files/FAbstractLoader.hpp                 |  21 +-
 Src/Files/FBasicLoader.hpp                    |   7 +-
 Src/Files/FEwalLoader.hpp                     |  94 +---
 Src/Files/FFmaBinLoader.hpp                   |   9 +-
 Src/Files/FFmaLoader.hpp                      |   9 +-
 Src/Files/FFmaScanfLoader.hpp                 |   9 +-
 Src/Files/FFmaTsmLoader.hpp                   |  13 +-
 Src/Files/FHLoader.hpp                        |   9 +-
 Src/Files/FMpiFmaLoader.hpp                   |   9 +-
 Src/Files/FRandomLoader.hpp                   |  20 +-
 Src/Files/FTreeCsvSaver.hpp                   |  33 +-
 Src/Files/FTreeIO.hpp                         |  58 +--
 Src/Kernels/Chebyshev/FAbstractChebKernel.hpp | 176 +------
 Src/Kernels/Chebyshev/FChebFlopsSymKernel.hpp |  30 +-
 Src/Kernels/Chebyshev/FChebInterpolator.hpp   | 110 ++--
 Src/Kernels/Chebyshev/FChebKernel.hpp         |   9 +-
 Src/Kernels/Chebyshev/FChebParticle.hpp       |  45 --
 Src/Kernels/Chebyshev/FChebSymKernel.hpp      |   7 +-
 Src/Kernels/P2P/FP2P.hpp                      | 469 ++++++++++++++++++
 Src/Kernels/P2P/FP2PParticleContainer.hpp     |  66 +++
 .../P2P/FP2PParticleContainerIndexed.hpp      |  25 +
 Src/Kernels/Rotation/FRotationKernel.hpp      | 173 ++-----
 .../Rotation/FRotationOriginalKernel.hpp      | 153 ++----
 Src/Kernels/Rotation/FRotationParticle.hpp    |  58 ---
 .../Rotation/FRotationParticleContainer.hpp   |  66 +++
 .../Spherical/FAbstractSphericalKernel.hpp    | 281 +++--------
 .../Spherical/FSphericalBlasKernel.hpp        |   6 +-
 .../Spherical/FSphericalBlockBlasKernel.hpp   |   6 +-
 Src/Kernels/Spherical/FSphericalKernel.hpp    |   6 +-
 Src/Kernels/Spherical/FSphericalParticle.hpp  |  58 ---
 .../Spherical/FSphericalRotationKernel.hpp    |   6 +-
 Tests/Kernels/testChebAlgorithm.cpp           |  34 +-
 Tests/Kernels/testCompareKernels.cpp          | 309 +++---------
 Tests/Kernels/testFlopsChebAlgorithm.cpp      |  35 +-
 Tests/Kernels/testRotationAlgorithm.cpp       |  54 +-
 Tests/Kernels/testSphericalAlgorithm.cpp      |  55 +-
 Tests/Kernels/testSphericalBench.cpp          | 149 +++---
 Tests/Kernels/testSphericalBlasAlgorithm.cpp  |  55 +-
 .../testSphericalBlockBlasAlgorithm.cpp       |  56 ++-
 Tests/Kernels/testSphericalEwalAlgorithm.cpp  | 181 ++++---
 Tests/Kernels/testSphericalGalaxyCsv.cpp      | 126 +++--
 .../testSphericalRotationAlgorithm.cpp        |  55 +-
 Tests/Kernels/testSphericalTsmAlgorithm.cpp   |  52 +-
 Tests/Kernels/testSphericalTsmNoTsm.cpp       | 200 --------
 Tests/Kernels/testTuneSphericalBlockBlas.cpp  |  25 +-
 Tests/Utils/testChebInterpolator.cpp          |  62 ++-
 Tests/Utils/testChebOctree.cpp                |  40 +-
 Tests/Utils/testChebSxUCBSy.cpp               |  67 +--
 Tests/Utils/testCompareIOTree.cpp             |  21 +-
 Tests/Utils/testFmmAlgorithm.cpp              |  25 +-
 Tests/Utils/testFmmAlgorithmPeriodic.cpp      |  56 +--
 Tests/Utils/testFmmAlgorithmProc.cpp          |   2 +-
 Tests/Utils/testFmmAlgorithmTsm.cpp           |  34 +-
 Tests/Utils/testFmmDemonstration.cpp          | 112 +++--
 Tests/Utils/testLoader.cpp                    |  17 +-
 Tests/Utils/testLoaderFMA.cpp                 |  18 +-
 Tests/Utils/testLoaderFMATsm.cpp              |  29 +-
 Tests/Utils/testMemStats.cpp                  |  26 +-
 Tests/Utils/testMortonIndex.cpp               | 194 --------
 Tests/Utils/testOctree.cpp                    |  16 +-
 Tests/Utils/testOctreeFuncteur.cpp            |  25 +-
 Tests/Utils/testOctreeIter.cpp                |  14 +-
 Tests/Utils/testOctreeRearrange.cpp           |  93 +++-
 Tests/Utils/testStatsTree.cpp                 |  26 +-
 Tests/Utils/testTreeIO.cpp                    |  23 +-
 UTests/utestChebyshevDirect.cpp               | 159 +++---
 UTests/utestChebyshevDirectPeriodic.cpp       | 153 +++---
 UTests/utestOctree.cpp                        |  14 +-
 UTests/utestRotationDirect.cpp                | 107 ++--
 UTests/utestRotationDirectPeriodic.cpp        | 128 +++--
 UTests/utestSphericalDirect.cpp               | 140 +++---
 UTests/utestSphericalDirectPeriodic.cpp       | 121 ++---
 UTests/utestSphericalWithPrevious.cpp         |  48 +-
 101 files changed, 2869 insertions(+), 3607 deletions(-)
 rename Src/Components/{FAbstractParticle.hpp => FAbstractParticleContainer.hpp} (73%)
 create mode 100755 Src/Components/FBasicParticleContainer.hpp
 rename Src/Components/{FFmaParticle.hpp => FFmaParticleContainer.hpp} (60%)
 delete mode 100755 Src/Components/FTestParticle.hpp
 rename Src/Components/{FBasicParticle.hpp => FTestParticleContainer.hpp} (57%)
 delete mode 100755 Src/Extensions/FExtendForces.hpp
 delete mode 100755 Src/Extensions/FExtendParticleType.hpp
 delete mode 100755 Src/Extensions/FExtendPhysicalValue.hpp
 delete mode 100755 Src/Extensions/FExtendPosition.hpp
 delete mode 100755 Src/Extensions/FExtendPotential.hpp
 delete mode 100755 Src/Extensions/FExtendVelocity.hpp
 delete mode 100755 Src/Kernels/Chebyshev/FChebParticle.hpp
 create mode 100644 Src/Kernels/P2P/FP2P.hpp
 create mode 100644 Src/Kernels/P2P/FP2PParticleContainer.hpp
 create mode 100644 Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp
 delete mode 100755 Src/Kernels/Rotation/FRotationParticle.hpp
 create mode 100755 Src/Kernels/Rotation/FRotationParticleContainer.hpp
 delete mode 100755 Src/Kernels/Spherical/FSphericalParticle.hpp
 delete mode 100755 Tests/Kernels/testSphericalTsmNoTsm.cpp
 delete mode 100755 Tests/Utils/testMortonIndex.cpp

diff --git a/Src/Arranger/FOctreeArranger.hpp b/Src/Arranger/FOctreeArranger.hpp
index d5c074cf9..614e3c4e0 100755
--- a/Src/Arranger/FOctreeArranger.hpp
+++ b/Src/Arranger/FOctreeArranger.hpp
@@ -32,7 +32,7 @@
   * to move the particles in the tree instead of building a new
   * tree.
   */
-template <class OctreeClass, class ContainerClass, class ParticleClass>
+template <class OctreeClass, class ContainerClass, class ExtractorClass>
 class FOctreeArranger : FAssertable {
     OctreeClass* const tree; //< The tree to work on
 
@@ -45,7 +45,7 @@ public:
     /** Arrange */
     void rearrange(const int isPeriodic = DirNone){
         // This vector is to keep the moving particles
-        FVector<ParticleClass> tomove;
+        ExtractorClass extractor;
 
         // For periodic
         const FReal boxWidth = tree->getBoxWidth();
@@ -53,14 +53,17 @@ public:
         const FPoint max(tree->getBoxCenter(),boxWidth/2);
 
         { // iterate on the leafs and found particle to remove
+            FVector<int> indexesToExtract;
+
             typename OctreeClass::Iterator octreeIterator(tree);
             octreeIterator.gotoBottomLeft();
             do{
                 const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
-
-                typename ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-                while( iter.hasNotFinished() ){
-                    FPoint partPos = iter.data().getPosition();
+                ContainerClass* particles = octreeIterator.getCurrentLeaf()->getSrc();
+                for(int idxPart = 0 ; idxPart < particles->getNbParticles(); ++idxPart){
+                    FPoint partPos( particles->getPositions()[0][idxPart],
+                            particles->getPositions()[1][idxPart],
+                            particles->getPositions()[2][idxPart] );
                     // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                     if( TestPeriodicCondition(isPeriodic, DirPlusX) ){
                         while(partPos.getX() >= max.getX()){
@@ -119,24 +122,25 @@ public:
                         printf("Application is exiting...\n");
                     }
                     // set pos
-                    iter.data().setPosition(partPos);
+                    particles->getWPositions()[0][idxPart] = partPos.getX();
+                    particles->getWPositions()[1][idxPart] = partPos.getY();
+                    particles->getWPositions()[2][idxPart] = partPos.getZ();
 
-                    const MortonIndex particuleIndex = tree->getMortonFromPosition(iter.data().getPosition());
+                    const MortonIndex particuleIndex = tree->getMortonFromPosition(partPos);
                     if(particuleIndex != currentIndex){
-                        tomove.push(iter.data());
-                        iter.remove();
-                    }
-                    else {
-                        iter.gotoNext();
+                        indexesToExtract.push(idxPart);
                     }
                 }
+                // remove from leaf
+                extractor.extractParticles(particles, indexesToExtract.data(), indexesToExtract.getSize());
+                particles->removeParticles(indexesToExtract.data(), indexesToExtract.getSize());
+                indexesToExtract.clear();
+
             } while(octreeIterator.moveRight());
         }
 
         { // insert particles that moved
-            for(int idxPart = 0 ; idxPart < tomove.getSize() ; ++idxPart){
-                tree->insert(tomove[idxPart]);
-            }
+            extractor.reinsertInTree(tree);
         }
 
         { // Remove empty leaves
@@ -145,7 +149,7 @@ public:
             bool workOnNext = true;
             do{
                 // Empty leaf
-                if( octreeIterator.getCurrentListTargets()->getSize() == 0 ){
+                if( octreeIterator.getCurrentListTargets()->getNbParticles() == 0 ){
                     const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
                     workOnNext = octreeIterator.moveRight();
                     tree->removeLeaf( currentIndex );
diff --git a/Src/Components/FAbstractLeaf.hpp b/Src/Components/FAbstractLeaf.hpp
index bb9271ccf..a14527a95 100755
--- a/Src/Components/FAbstractLeaf.hpp
+++ b/Src/Components/FAbstractLeaf.hpp
@@ -16,7 +16,8 @@
 #ifndef FABSTRACTLEAF_HPP
 #define FABSTRACTLEAF_HPP
 
-
+#include "../Utils/FPoint.hpp"
+#include "../Utils/FDebug.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -26,7 +27,7 @@
 * This class is used to enable the use of typed particles
 * (source XOR target) or simple system (source AND target)
 */
-template< class ParticleClass, class ContainerClass >
+template< class ContainerClass >
 class FAbstractLeaf {
 public:
     /** Default destructor */
@@ -39,7 +40,10 @@ public:
         * Depending on the system to use the class that inherit
         * this interface can sort the particle as they like.
         */
-    virtual void push(const ParticleClass& particle) = 0;
+    template<typename... Args>
+    void push(const FPoint& /*inParticlePosition*/, Args ... /*args*/){
+        FDEBUG( FDebug::Controller.write("Warning, push is not implemented!").write(FDebug::Flush) );
+    }
 
     /**
         * To get all the sources in a leaf
diff --git a/Src/Components/FAbstractParticle.hpp b/Src/Components/FAbstractParticleContainer.hpp
similarity index 73%
rename from Src/Components/FAbstractParticle.hpp
rename to Src/Components/FAbstractParticleContainer.hpp
index ab62efe00..0345163d4 100755
--- a/Src/Components/FAbstractParticle.hpp
+++ b/Src/Components/FAbstractParticleContainer.hpp
@@ -13,9 +13,11 @@
 // "http://www.cecill.info". 
 // "http://www.gnu.org/licenses".
 // ===================================================================================
-#ifndef FABSTRACTPARTICLE_HPP
-#define FABSTRACTPARTICLE_HPP
+#ifndef FABSTRACTPARTICLECONTAINER_HPP
+#define FABSTRACTPARTICLECONTAINER_HPP
 
+#include "../Utils/FGlobal.hpp"
+#include "../Utils/FDebug.hpp"
 
 /* forward declaration to avoid include */
 class FPoint;
@@ -36,20 +38,19 @@ class FPoint;
 *
 * @warning Inherite from this class when implement a specific particle type
 */
-class FAbstractParticle{
-public:	
-	/** Default destructor */
-	virtual ~FAbstractParticle(){
-	}
-
-	/**
-	* Must be implemented by each user Particle class
-	* @return the position of the current cell
-	*/
-        virtual const FPoint& getPosition() const = 0;
+class FAbstractParticleContainer {
+public:
+    /** Default destructor */
+    virtual ~FAbstractParticleContainer(){
+    }
+
+    template<typename... Args>
+    void push(const FPoint& /*inParticlePosition*/, Args ... /*args*/){
+        FDEBUG( FDebug::Controller.write("Warning, push is not implemented!").write(FDebug::Flush) );
+    }
 };
 
 
-#endif //FABSTRACTPARTICLE_HPP
+#endif //FABSTRACTPARTICLECONTAINER_HPP
 
 
diff --git a/Src/Components/FBasicCell.hpp b/Src/Components/FBasicCell.hpp
index 81f435eda..647a50b99 100755
--- a/Src/Components/FBasicCell.hpp
+++ b/Src/Components/FBasicCell.hpp
@@ -17,7 +17,6 @@
 #define FBASICCELL_HPP
 
 
-#include "../Extensions/FExtendPosition.hpp"
 #include "../Extensions/FExtendMortonIndex.hpp"
 #include "../Extensions/FExtendCoordinate.hpp"
 
diff --git a/Src/Components/FBasicParticleContainer.hpp b/Src/Components/FBasicParticleContainer.hpp
new file mode 100755
index 000000000..7173fca9f
--- /dev/null
+++ b/Src/Components/FBasicParticleContainer.hpp
@@ -0,0 +1,204 @@
+// ===================================================================================
+// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
+// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
+// This software is a computer program whose purpose is to compute the FMM.
+//
+// This software is governed by the CeCILL-C and LGPL licenses and
+// abiding by the rules of distribution of free software.  
+// 
+// This program 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 and CeCILL-C Licenses for more details.
+// "http://www.cecill.info". 
+// "http://www.gnu.org/licenses".
+// ===================================================================================
+#ifndef FBASICPARTICLECONTAINER_HPP
+#define FBASICPARTICLECONTAINER_HPP
+
+#include "FAbstractParticleContainer.hpp"
+
+#include <type_traits>
+
+/**
+* @author Berenger Bramas (berenger.bramas@inria.fr)
+* @class FBasicParticle
+* Please read the license
+*
+* This class defines a basic particle used for examples. It extends
+* the mininum, only what is needed by FOctree and FFmmAlgorithm
+* to make the things working.
+* By using this extension it will implement the FAbstractParticle without
+* inheriting from it.
+*/
+template <unsigned NbAttributesPerParticle, class AttributeClass = FReal >
+class FBasicParticleContainer : public FAbstractParticleContainer {
+protected:
+    int nbParticles;
+    FReal* positions[3];
+    AttributeClass* attributes[NbAttributesPerParticle];
+
+    int allocatedParticles;
+
+    template<int index>
+    void addParticleValue(const int /*insertPosition*/){
+    }
+
+    template<int index, typename... Args>
+    void addParticleValue(const int insertPosition, const AttributeClass value, Args... args){
+        static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
+        attributes[index][insertPosition] = value;
+        addParticleValue<index+1>( insertPosition, args...);
+    }
+
+public:
+    FBasicParticleContainer(const FBasicParticleContainer&) = delete;
+    FBasicParticleContainer& operator=(const FBasicParticleContainer&) = delete;
+
+    FBasicParticleContainer() : nbParticles(0), allocatedParticles(0){
+        memset(positions, 0, sizeof(positions[0]) * 3);
+        memset(attributes, 0, sizeof(attributes[0]) * NbAttributesPerParticle);
+    }
+
+    ~FBasicParticleContainer(){
+        delete[] reinterpret_cast<char*>(positions[0]);
+    }
+
+    int getNbParticles() const{
+        return nbParticles;
+    }
+
+    const FReal*const*const getPositions() const {
+        return positions;
+    }
+
+    FReal*const*const getWPositions() {
+        return positions;
+    }
+
+    AttributeClass* getAttribute(const int index) {
+        return attributes[index];
+    }
+
+    const AttributeClass* getAttribute(const int index) const {
+        return attributes[index];
+    }
+
+    template <int index>
+    AttributeClass* getAttribute() {
+        static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
+        return attributes[index];
+    }
+
+    template <int index>
+    const AttributeClass* getAttribute() const {
+        static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
+        return attributes[index];
+    }
+
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, Args... args){
+        if( nbParticles == allocatedParticles ){
+            allocatedParticles = FMath::Max(10,int(FReal(nbParticles+1)*1.5));
+            FReal* newData  = reinterpret_cast<FReal*>(new char[(sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles]);
+            memset( newData, 0, (sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles);
+
+            const char*const toDelete  = reinterpret_cast<const char*>(positions[0]);
+            for(int idx = 0 ; idx < 3 ; ++idx){
+                memcpy(newData + (allocatedParticles * idx), positions[idx], sizeof(FReal) * nbParticles);
+                positions[idx] = newData + (allocatedParticles * idx);
+            }
+            AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
+            for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+                memcpy(startAddress + (allocatedParticles * idx), attributes[idx], sizeof(AttributeClass) * nbParticles);
+                attributes[idx] = startAddress + (idx * allocatedParticles);
+            }
+            delete[] toDelete;
+        }
+        positions[0][nbParticles] = inParticlePosition.getX();
+        positions[1][nbParticles] = inParticlePosition.getY();
+        positions[2][nbParticles] = inParticlePosition.getZ();
+        addParticleValue<0>( nbParticles, args...);
+        nbParticles += 1;
+    }
+
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, const bool /*isTarget*/, Args... args){
+        push(inParticlePosition, args...);
+    }
+
+    void clear(){
+        nbParticles = 0;
+    }
+
+    /** Save the current cell in a buffer */
+    void save(FBufferWriter& buffer) const{
+        buffer << nbParticles;
+        for(int idx = 0 ; idx < 3 ; ++idx){
+            buffer.write(positions[idx], nbParticles);
+        }
+        for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+            buffer.write(attributes[idx], nbParticles);
+        }
+    }
+    /** Restore the current cell from a buffer */
+    void restore(FBufferReader& buffer){
+        buffer >> nbParticles;
+        if( nbParticles >= allocatedParticles ){
+            allocatedParticles = FMath::Max(10,int(FReal(nbParticles+1)*1.5));
+            FReal* newData  = reinterpret_cast<FReal*>(new char[(sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles]);
+            memset( newData, 0, (sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles);
+
+            delete[] reinterpret_cast<char*>(positions[0]);
+            for(int idx = 0 ; idx < 3 ; ++idx){
+                positions[idx] = newData + (allocatedParticles * idx);
+            }
+            AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
+            for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+                attributes[idx] = startAddress + (idx * allocatedParticles);
+            }
+        }
+        for(int idx = 0 ; idx < 3 ; ++idx){
+            buffer.fillArray(positions[idx], nbParticles);
+        }
+        for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+            buffer.fillArray(attributes[idx], nbParticles);
+        }
+    }
+
+    /** to enable rearranging */
+    void removeParticles(const int indexesToRemove[], const int nbParticlesToRemove){
+        int offset = 1;
+        int idxIndexes = 1;
+        int idxIns = indexesToRemove[0] + 1;
+        for( ; idxIns < nbParticles && idxIndexes < nbParticlesToRemove ; ++idxIns){
+            if( idxIns == indexesToRemove[idxIndexes] ){
+                idxIndexes += 1;
+                offset += 1;
+            }
+            else{
+                for(int idx = 0 ; idx < 3 ; ++idx){
+                    positions[idx][idxIns-offset] = positions[idx][idxIns];
+                }
+                for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+                    attributes[idx][idxIns-offset] = attributes[idx][idxIns];
+                }
+            }
+        }
+        for( ; idxIns < nbParticles ; ++idxIns){
+            for(int idx = 0 ; idx < 3 ; ++idx){
+                positions[idx][idxIns-offset] = positions[idx][idxIns];
+            }
+            for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
+                attributes[idx][idxIns-offset] = attributes[idx][idxIns];
+            }
+        }
+        nbParticles -= nbParticlesToRemove;
+    }
+
+};
+
+
+#endif //FBASICPARTICLECONTAINER_HPP
+
+
diff --git a/Src/Components/FFmaParticle.hpp b/Src/Components/FFmaParticleContainer.hpp
similarity index 60%
rename from Src/Components/FFmaParticle.hpp
rename to Src/Components/FFmaParticleContainer.hpp
index 99f5ebf63..fcd2eed18 100755
--- a/Src/Components/FFmaParticle.hpp
+++ b/Src/Components/FFmaParticleContainer.hpp
@@ -13,12 +13,10 @@
 // "http://www.cecill.info". 
 // "http://www.gnu.org/licenses".
 // ===================================================================================
-#ifndef FFmaPARTICLE_HPP
-#define FFmaPARTICLE_HPP
+#ifndef FFMAPARTICLECONTAINER_HPP
+#define FFMAPARTICLECONTAINER_HPP
 
-
-#include "../Extensions/FExtendPosition.hpp"
-#include "../Extensions/FExtendPhysicalValue.hpp"
+#include "FBasicParticleContainer.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -26,23 +24,22 @@
 * Please read the license
 *
 * This class defines a particle for FMA loader.
-* As defined in FFmaLoader it needs {FBasicParticle,FExtendPhysicalValue}
+* As defined in FFmaLoader it needs
 */
-class FFmaParticle : public FExtendPosition, public FExtendPhysicalValue {
+class FFmaParticleContainer : public FBasicParticleContainer<1> {
+    typedef FBasicParticleContainer<1> Parent;
+
 public:
-    /** Save the current cell in a buffer */
-    void save(FBufferWriter& buffer) const{
-        FExtendPosition::save(buffer);
-        FExtendPhysicalValue::save(buffer);
+    FReal* getPhysicalValues(){
+        return Parent::getAttribute(0);
     }
-    /** Restore the current cell from a buffer */
-    void restore(FBufferReader& buffer){
-        FExtendPosition::restore(buffer);
-        FExtendPhysicalValue::restore(buffer);
+
+    const FReal* getPhysicalValues() const {
+        return Parent::getAttribute(0);
     }
 };
 
 
-#endif //FFmaPARTICLE_HPP
+#endif //FFMAPARTICLECONTAINER_HPP
 
 
diff --git a/Src/Components/FSimpleLeaf.hpp b/Src/Components/FSimpleLeaf.hpp
index 100893d5a..89942950f 100755
--- a/Src/Components/FSimpleLeaf.hpp
+++ b/Src/Components/FSimpleLeaf.hpp
@@ -27,8 +27,8 @@
 * This class is used as a leaf in simple system (source AND target)
 * here there is only one list that store all particles.
 */
-template< class ParticleClass , class ContainerClass>
-class FSimpleLeaf : public FAbstractLeaf<ParticleClass,ContainerClass> {
+template< class ContainerClass>
+class FSimpleLeaf : public FAbstractLeaf<ContainerClass> {
     ContainerClass particles;
 
 public:
@@ -40,8 +40,9 @@ public:
         * To add a new particle in the leaf
         * @param particle the new particle to store in the current leaf
         */
-    void push(const ParticleClass& particle){
-        this->particles.push(particle);
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, Args ...  args){
+        this->particles.push(inParticlePosition, args...);
     }
 
     /**
diff --git a/Src/Components/FTestKernels.hpp b/Src/Components/FTestKernels.hpp
index 2981ba79a..c9be456fa 100755
--- a/Src/Components/FTestKernels.hpp
+++ b/Src/Components/FTestKernels.hpp
@@ -83,8 +83,8 @@ public:
     /** After Downward */
     void L2P(const CellClass* const  local, ContainerClass*const particles){
         // The particles is impacted by the parent cell      
-        int*const particlesAttributes = targets->getDataDown();
-        for(int idxPart = 0 ; idxPart < targets ; ++idxPart){
+        long long int*const particlesAttributes = particles->getDataDown();
+        for(int idxPart = 0 ; idxPart < particles->getNbParticles() ; ++idxPart){
             particlesAttributes[idxPart] += local->getDataDown();
         }
     }
@@ -95,7 +95,7 @@ public:
                  ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
                  ContainerClass* const directNeighborsParticles[27], const int ){
         // Each particles targeted is impacted by the particles sources
-        long long int inc = sources->getSize();
+        long long int inc = sources->getNbParticles();
         if(targets == sources){
             inc -= 1;
         }
@@ -105,8 +105,8 @@ public:
             }
         }
 
-        int*const particlesAttributes = targets->getDataDown();
-        for(int idxPart = 0 ; idxPart < targets ; ++idxPart){
+        long long int*const particlesAttributes = targets->getDataDown();
+        for(int idxPart = 0 ; idxPart < targets->getNbParticles() ; ++idxPart){
             particlesAttributes[idxPart] += inc;
         }
     }
@@ -123,8 +123,8 @@ public:
             }
         }
 
-        int*const particlesAttributes = targets->getDataDown();
-        for(int idxPart = 0 ; idxPart < targets ; ++idxPart){
+        long long int*const particlesAttributes = targets->getDataDown();
+        for(int idxPart = 0 ; idxPart < targets->getNbParticles() ; ++idxPart){
             particlesAttributes[idxPart] += inc;
         }
     }
@@ -140,15 +140,13 @@ void ValidateFMMAlgo(OctreeClass* const tree){
     const int TreeHeight = tree->getHeight();
     long long int NbPart = 0;
     { // Check that each particle has been summed with all other
-        typename OctreeClass::Iterator octreeIterator(tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            if(octreeIterator.getCurrentCell()->getDataUp() != octreeIterator.getCurrentListSrc()->getSize() ){
-                    std::cout << "Problem P2M : " << octreeIterator.getCurrentCell()->getDataUp() <<
-                                 " (should be " << octreeIterator.getCurrentListSrc()->getSize() << ")\n";
+        tree->forEachCellLeaf([&](CellClass* cell, LeafClass* leaf){
+            if(cell->getDataUp() != leaf->getSrc()->getNbParticles() ){
+                    std::cout << "Problem P2M : " << cell->getDataUp() <<
+                                 " (should be " << leaf->getSrc()->getNbParticles() << ")\n";
             }
-            NbPart += octreeIterator.getCurrentListSrc()->getSize();
-        } while(octreeIterator.moveRight());
+            NbPart += leaf->getSrc()->getNbParticles();
+        });
     }
     { // Ceck if there is number of NbPart summed at level 1
         typename OctreeClass::Iterator octreeIterator(tree);
@@ -180,18 +178,14 @@ void ValidateFMMAlgo(OctreeClass* const tree){
         typename OctreeClass::Iterator octreeIterator(tree);
         octreeIterator.gotoBottomLeft();
         do{
-            typename ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-
             const bool isUsingTsm = (octreeIterator.getCurrentListTargets() != octreeIterator.getCurrentListSrc());
-
-            while( iter.hasNotFinished() ){
-                // If a particles has been impacted by less than NbPart - 1 (the current particle)
-                // there is a problem
-                if( (!isUsingTsm && iter.data().getDataDown() != NbPart - 1) ||
-                    (isUsingTsm && iter.data().getDataDown() != NbPart) ){
-                    std::cout << "Problem L2P + P2P : " << iter.data().getDataDown() << "(" << octreeIterator.getCurrentGlobalIndex() << ")\n";
+            const long long int* dataDown = octreeIterator.getCurrentListTargets()->getDataDown();
+            for(int idxPart = 0 ; idxPart < octreeIterator.getCurrentListTargets()->getNbParticles() ; ++idxPart){
+                if( (!isUsingTsm && dataDown[idxPart] != NbPart - 1) ||
+                    (isUsingTsm && dataDown[idxPart] != NbPart) ){
+                    std::cout << "Problem L2P + P2P : " << dataDown[idxPart] <<
+                                 "(" << octreeIterator.getCurrentGlobalIndex() << ")\n";
                 }
-                iter.gotoNext();
             }
         } while(octreeIterator.moveRight());
     }
diff --git a/Src/Components/FTestParticle.hpp b/Src/Components/FTestParticle.hpp
deleted file mode 100755
index d4287abdc..000000000
--- a/Src/Components/FTestParticle.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FTESTPARTICLE_HPP
-#define FTESTPARTICLE_HPP
-
-
-#include "FBasicParticle.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FTestParticle
-* Please read the license
-*
-* This class is used in the FTestKernels, please
-* look at this class to know whit it is.
-*
-* Particles just need the data down (after and run with FTestKernel the
-* value shoud be NB PARTICLES (-1)).
-*/
-class FTestParticle : public FBasicParticle {
-protected:
-    // To store data during downard pass
-    long long int dataDown;
-public:
-    FTestParticle(): dataDown(0){
-    }
-
-    /** Default destructor */
-    virtual ~FTestParticle(){
-    }
-
-    /** Get the down data */
-    long long int getDataDown() const {
-        return this->dataDown;
-    }
-
-    /** Set down data */
-    void setDataDown(const long long int inData){
-        this->dataDown = inData;
-    }
-
-    //////////////////////////////////////////////////
-
-    /** Save the current cell in a buffer */
-    void save(FBufferWriter& buffer) const{
-        FBasicParticle::save(buffer);
-        buffer << dataDown;
-    }
-
-    /** Restore the current cell from a buffer */
-    void restore(FBufferReader& buffer){
-        FBasicParticle::restore(buffer);
-        buffer >> dataDown;
-    }
-};
-
-
-#endif //FTESTPARTICLE_HPP
-
-
diff --git a/Src/Components/FBasicParticle.hpp b/Src/Components/FTestParticleContainer.hpp
similarity index 57%
rename from Src/Components/FBasicParticle.hpp
rename to Src/Components/FTestParticleContainer.hpp
index 52cc2be83..61593c554 100755
--- a/Src/Components/FBasicParticle.hpp
+++ b/Src/Components/FTestParticleContainer.hpp
@@ -13,36 +13,37 @@
 // "http://www.cecill.info". 
 // "http://www.gnu.org/licenses".
 // ===================================================================================
-#ifndef FBASICPARTICLE_HPP
-#define FBASICPARTICLE_HPP
+#ifndef FTESTPARTICLECONTAINER_HPP
+#define FTESTPARTICLECONTAINER_HPP
 
 
-#include "../Extensions/FExtendPosition.hpp"
+#include "FBasicParticleContainer.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FBasicParticle
+* @class FTestParticle
 * Please read the license
 *
-* This class defines a basic particle used for examples. It extends
-* the mininum, only what is needed by FOctree and FFmmAlgorithm
-* to make the things working.
-* By using this extension it will implement the FAbstractParticle without
-* inheriting from it.
+* This class is used in the FTestKernels, please
+* look at this class to know whit it is.
+*
+* Particles just need the data down (after and run with FTestKernel the
+* value shoud be NB PARTICLES (-1)).
 */
-class FBasicParticle : public FExtendPosition{
+class FTestParticleContainer : public FBasicParticleContainer<1, long long int> {
+    typedef FBasicParticleContainer<1, long long int> Parent;
+
 public:
-    /** Save the current cell in a buffer */
-    void save(FBufferWriter& buffer) const{
-        FExtendPosition::save(buffer);
+    long long int* getDataDown(){
+        return Parent::getAttribute(0);
     }
-    /** Restore the current cell from a buffer */
-    void restore(FBufferReader& buffer){
-        FExtendPosition::restore(buffer);
+
+    const long long int* getDataDown() const {
+        return Parent::getAttribute(0);
     }
 };
 
 
-#endif //FBASICPARTICLE_HPP
+#endif //FTESTPARTICLECONTAINER_HPP
 
 
diff --git a/Src/Components/FTypedLeaf.hpp b/Src/Components/FTypedLeaf.hpp
index 23edff486..1dc1c1e39 100755
--- a/Src/Components/FTypedLeaf.hpp
+++ b/Src/Components/FTypedLeaf.hpp
@@ -30,8 +30,8 @@
 *
 * Particles should be typed to enable targets/sources difference.
 */
-template< class ParticleClass , class ContainerClass>
-class FTypedLeaf  : public FAbstractLeaf<ParticleClass,ContainerClass>, public FAssertable {
+template< class ContainerClass>
+class FTypedLeaf  : public FAbstractLeaf<ContainerClass>, public FAssertable {
     ContainerClass sources; //< The sources containers
     ContainerClass targets; //< The targets containers
 
@@ -44,11 +44,10 @@ public:
         * To add a new particle in the leaf
         * @param particle the new particle
         */
-    void push(const ParticleClass& particle){
-        // Test if is source or target particle
-        if(particle.isTarget()) this->targets.push(particle);
-        else if(particle.isSource()) this->sources.push(particle);
-        else fassert(false, "Error particle has undefined type.", __LINE__, __FILE__);
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, const bool isTarget, Args ... args){
+        if(isTarget) targets.push(inParticlePosition, args...);
+        else sources.push(inParticlePosition, args...);
     }
 
     /**
diff --git a/Src/Containers/FOctree.hpp b/Src/Containers/FOctree.hpp
index 5dca8c7a6..21b6b8648 100755
--- a/Src/Containers/FOctree.hpp
+++ b/Src/Containers/FOctree.hpp
@@ -4,13 +4,13 @@
 // This software is a computer program whose purpose is to compute the FMM.
 //
 // This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
+// abiding by the rules of distribution of free software.
+//
 // This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
+// "http://www.cecill.info".
 // "http://www.gnu.org/licenses".
 // ===================================================================================
 #ifndef FOCTREE_HPP
@@ -50,10 +50,12 @@
  * If the octree as an height H, then it goes from 0 to H-1
  * at level 0 the space is not split
  */
-template< class ParticleClass, class CellClass, class ContainerClass, class LeafClass>
+template< class CellClass, class ContainerClass, class LeafClass>
 class FOctree : protected FAssertable, public FNoCopyable {
+    typedef FSubOctreeWithLeafs< CellClass , ContainerClass, LeafClass> SubOctreeWithLeaves;
+    typedef FSubOctree< CellClass , ContainerClass, LeafClass> SubOctree;
 
-    FAbstractSubOctree< ParticleClass, CellClass , ContainerClass, LeafClass>* root;   //< root suboctree
+    FAbstractSubOctree< CellClass , ContainerClass, LeafClass>* root;   //< root suboctree
 
     FReal*const boxWidthAtLevel;	//< to store the width of each boxs at all levels
 
@@ -116,10 +118,10 @@ public:
         fassert(subHeight <= height - 1, "Subheight cannot be greater than height", __LINE__, __FILE__ );
         // Does we only need one suboctree?
         if(subHeight == height - 1){
-            root = new FSubOctreeWithLeafs< ParticleClass, CellClass , ContainerClass, LeafClass>(0, 0, this->subHeight, 1);
+            root = new FSubOctreeWithLeafs< CellClass , ContainerClass, LeafClass>(0, 0, this->subHeight, 1);
         }
         else {// if(subHeight < height - 1)
-            root = new FSubOctree< ParticleClass, CellClass , ContainerClass, LeafClass>(0, 0, this->subHeight, 1);
+            root = new FSubOctree< CellClass , ContainerClass, LeafClass>(0, 0, this->subHeight, 1);
         }
 
         FReal tempWidth = this->boxWidth;
@@ -185,10 +187,29 @@ public:
      * ask node to insert this particle
      * @param inParticle the particle to insert (must inherite from FAbstractParticle)
      */
-    void insert(const ParticleClass& inParticle){
-        const FTreeCoordinate host = getCoordinateFromPosition( inParticle.getPosition() );
+    template<typename... Args>
+    void insert(const FPoint& inParticlePosition, Args... args){
+        const FTreeCoordinate host = getCoordinateFromPosition( inParticlePosition );
         const MortonIndex particleIndex = host.getMortonIndex(leafIndex);
-        root->insert( particleIndex, host, inParticle, this->height);
+        if(root->isLeafPart()){
+            ((SubOctreeWithLeaves*)root)->insert( particleIndex, host, this->height, inParticlePosition, args... );
+        }
+        else{
+            ((SubOctree*)root)->insert( particleIndex, host, this->height, inParticlePosition, args... );
+        }
+    }
+
+    /** Remove a leaf from its morton index
+      * @param indexToRemove the index of the leaf to remove
+      */
+    LeafClass* createLeaf(const MortonIndex indexToCreate ){
+        const FTreeCoordinate host(indexToCreate,this->height-1);
+        if(root->isLeafPart()){
+            return ((SubOctreeWithLeaves*)root)->createLeaf( indexToCreate, host, this->height );
+        }
+        else{
+            return ((SubOctree*)root)->createLeaf( indexToCreate, host, this->height );
+        }
     }
 
     /** Remove a leaf from its morton index
@@ -214,18 +235,18 @@ public:
           * depending if we are working on the bottom of the tree.
           */
     union SubOctreeTypes {
-        FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* tree;     //< Usual pointer to work
-        FSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* middleTree;       //< To access to sub-octree under
-        FSubOctreeWithLeafs<ParticleClass,CellClass,ContainerClass,LeafClass>* leafTree;//< To access to particles lists
+        FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* tree;     //< Usual pointer to work
+        FSubOctree<CellClass,ContainerClass,LeafClass>* middleTree;       //< To access to sub-octree under
+        FSubOctreeWithLeafs<CellClass,ContainerClass,LeafClass>* leafTree;//< To access to particles lists
     };
 
     /**
           * This class is a const SubOctreeTypes
           */
     union SubOctreeTypesConst {
-        const FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* tree;     //< Usual pointer to work
-        const FSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* middleTree;       //< To access to sub-octree under
-        const FSubOctreeWithLeafs<ParticleClass,CellClass,ContainerClass,LeafClass>* leafTree;//< To access to particles lists
+        const FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* tree;     //< Usual pointer to work
+        const FSubOctree<CellClass,ContainerClass,LeafClass>* middleTree;       //< To access to sub-octree under
+        const FSubOctreeWithLeafs<CellClass,ContainerClass,LeafClass>* leafTree;//< To access to particles lists
     };
 
     /**
@@ -1129,15 +1150,9 @@ public:
         Iterator octreeIterator(this);
         octreeIterator.gotoBottomLeft();
 
-        Iterator avoidGoLeft(octreeIterator);
-
-        for(int idx = 0 ; idx < this->height - 1 ; ++idx ){
-            do{
-                function(octreeIterator.getCurrentCell(),octreeIterator.getCurrentLeaf());
-            } while(octreeIterator.moveRight());
-            avoidGoLeft.moveUp();
-            octreeIterator = avoidGoLeft;
-        }
+        do{
+            function(octreeIterator.getCurrentCell(),octreeIterator.getCurrentLeaf());
+        } while(octreeIterator.moveRight());
     }
 };
 
diff --git a/Src/Containers/FSubOctree.hpp b/Src/Containers/FSubOctree.hpp
index 108072fd1..a467e818e 100755
--- a/Src/Containers/FSubOctree.hpp
+++ b/Src/Containers/FSubOctree.hpp
@@ -4,13 +4,13 @@
 // This software is a computer program whose purpose is to compute the FMM.
 //
 // This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
+// abiding by the rules of distribution of free software.
+//
 // This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
+// "http://www.cecill.info".
 // "http://www.gnu.org/licenses".
 // ===================================================================================
 #ifndef FSUBOCTREE_HPP
@@ -32,7 +32,7 @@
  *
  * This class is a sub-octree container.
  * This class is the main component of the octree.
- * 
+ *
  * This class does not have a main root. In fact, the root
  * is contained in the parent sub-octree.
  *
@@ -47,7 +47,7 @@
  * Please refere to testOctree.cpp to see an example
  * @warning Give the particleClass & cellClass
  */
-template< class ParticleClass, class CellClass , class ContainerClass, class LeafClass>
+template< class CellClass , class ContainerClass, class LeafClass>
 class FAbstractSubOctree : protected FAssertable{
 protected:
 
@@ -232,7 +232,10 @@ public:
     * @param inParticle the particle to insert (must inherite from FAbstractParticle)
     * @param inParticle the inTreeHeight the height of the tree
     */
-    virtual void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight) = 0;
+    /*template<typename... Args>
+    void insert(const MortonIndex index, const FTreeCoordinate& host, const int inTreeHeight, const FPoint& inParticlePosition,
+                        Args... args){
+    }*/
 
     /**
       * Remove a leaf and every cells if needed
@@ -331,18 +334,17 @@ public:
  * Please refere to testOctree.cpp to see an example.
  * @warning Give the particleClass & cellClass
  */
-template< class ParticleClass, class CellClass , class ContainerClass, class LeafClass>
-class FSubOctreeWithLeafs : public FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass> {
+template< class CellClass , class ContainerClass, class LeafClass>
+class FSubOctreeWithLeafs : public FAbstractSubOctree<CellClass,ContainerClass,LeafClass> {
 private:
-    typedef FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass> Parent;
+    typedef FAbstractSubOctree<CellClass,ContainerClass,LeafClass> Parent;
 
     LeafClass** leafs;            //< Leafs array
 
-    /** Disable copy */
-    FSubOctreeWithLeafs(const FSubOctreeWithLeafs&){}
-    FSubOctreeWithLeafs& operator=(const FSubOctreeWithLeafs&){return *this;}
+public:
+    FSubOctreeWithLeafs(const FSubOctreeWithLeafs&) = delete;
+    FSubOctreeWithLeafs& operator=(const FSubOctreeWithLeafs&) = delete;
 
-public:     
     /**
     * Constructor
     * Allocate the leafs array
@@ -350,9 +352,9 @@ public:
     * @param inSubOctreeHeight Height of this suboctree
     * @param inSubOctreePosition Level of the current suboctree in the global tree (1 if upper tree)
     */
-    FSubOctreeWithLeafs(FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* const inParent, const int inIndexInParent,
+    FSubOctreeWithLeafs(FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* const inParent, const int inIndexInParent,
                         const int inSubOctreeHeight, const int inSubOctreePosition) :
-                        FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>(inParent, inIndexInParent, inSubOctreeHeight, inSubOctreePosition, true) {
+                        FAbstractSubOctree<CellClass,ContainerClass,LeafClass>(inParent, inIndexInParent, inSubOctreeHeight, inSubOctreePosition, true) {
 
         const int cellsAtLeafLevel = 1 << (3 * inSubOctreeHeight);
 
@@ -377,7 +379,9 @@ public:
     /**
     * Refer to FAbstractSubOctree::insert
     */
-    void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight){
+    template<typename... Args>
+    void insert(const MortonIndex index, const FTreeCoordinate& host, const int inTreeHeight, const FPoint& inParticlePosition,
+                        Args... args){
         // Get the morton index for the leaf level
         const MortonIndex arrayIndex = Parent::getLeafIndex(index,inTreeHeight);
         // is there already a leaf?
@@ -387,7 +391,20 @@ public:
             Parent::newLeafInserted( int(arrayIndex) , index, host);
         }
         // add particle to leaf list
-        this->leafs[arrayIndex]->push(inParticle);
+        this->leafs[arrayIndex]->push(inParticlePosition, args... );
+    }
+
+    LeafClass* createLeaf(const MortonIndex index, const FTreeCoordinate& host, const int inTreeHeight){
+        // Get the morton index for the leaf level
+        const MortonIndex arrayIndex = Parent::getLeafIndex(index,inTreeHeight);
+        // is there already a leaf?
+        if( !this->leafs[arrayIndex] ){
+            this->leafs[arrayIndex] = new LeafClass();
+
+            Parent::newLeafInserted( int(arrayIndex) , index, host);
+        }
+        // add particle to leaf list
+        return this->leafs[arrayIndex];
     }
 
     /**
@@ -462,18 +479,19 @@ public:
  *
  * @warning Give the particleClass & cellClass
  */
-template< class ParticleClass, class CellClass , class ContainerClass, class LeafClass>
-class FSubOctree : public FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass> {
+template< class CellClass , class ContainerClass, class LeafClass>
+class FSubOctree : public FAbstractSubOctree<CellClass,ContainerClass,LeafClass> {
 private:
-    typedef FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass> Parent;
+    typedef FAbstractSubOctree<CellClass,ContainerClass,LeafClass> Parent;
+    typedef FSubOctreeWithLeafs<CellClass,ContainerClass,LeafClass> SubOctreeWithLeaf;
 
     Parent** subleafs;    //< Last levels is composed of suboctree
 
-    /** Disable copy */
-    FSubOctree(const FSubOctree&){}
-    FSubOctree& operator=(const FSubOctree&){return *this;}
+public:
+
+    FSubOctree(const FSubOctree&) = delete;
+    FSubOctree& operator=(const FSubOctree&) = delete;
 
-public:	
     /**
     * Constructor
     * Allocate the subleafs array
@@ -481,9 +499,9 @@ public:
     * @param inSubOctreeHeight Height of this suboctree
     * @param inSubOctreePosition Level of the current suboctree in the global tree (0 if upper tree)
     */
-    FSubOctree(FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* const inParent,  const int inIndexInParent,
+    FSubOctree(FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* const inParent,  const int inIndexInParent,
                const int inSubOctreeHeight, const int inSubOctreePosition) :
-            FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>(inParent, inIndexInParent, inSubOctreeHeight, inSubOctreePosition, false) {
+            FAbstractSubOctree<CellClass,ContainerClass,LeafClass>(inParent, inIndexInParent, inSubOctreeHeight, inSubOctreePosition, false) {
 
         const int cellsAtLeafLevel = 1 << (3 * inSubOctreeHeight);
 
@@ -503,10 +521,46 @@ public:
         delete [] this->subleafs;
     }
 
-    /**
-    * Refer to FAbstractSubOctree::insert
-    */
-    void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight){
+
+    template<typename... Args>
+    void insert(const MortonIndex index, const FTreeCoordinate& host, const int inTreeHeight, const FPoint& inParticlePosition,
+                        Args... args){
+        // We need the morton index at the bottom level of this sub octree
+        // so we remove the right side
+        const MortonIndex arrayIndex = Parent::getLeafIndex(index,inTreeHeight);
+        // Is there already a leaf?
+        if( !this->subleafs[arrayIndex] ){
+            // We need to create leaf sub octree
+            const int nextSubOctreePosition = this->subOctreePosition + this->subOctreeHeight;
+            const int nextSubOctreeHeight = FMath::Min(inTreeHeight - nextSubOctreePosition, this->subOctreeHeight);
+
+            // Next suboctree is a middle suboctree
+            if(inTreeHeight > nextSubOctreeHeight + nextSubOctreePosition){
+                this->subleafs[arrayIndex] = new FSubOctree(this,int(arrayIndex),nextSubOctreeHeight,nextSubOctreePosition);
+            }
+            // Or next suboctree contains the reail leaf!
+            else{
+                this->subleafs[arrayIndex] = new SubOctreeWithLeaf(this,int(arrayIndex),nextSubOctreeHeight,nextSubOctreePosition);
+            }
+
+            const FTreeCoordinate hostAtLevel(
+                        host.getX() >> (inTreeHeight - nextSubOctreePosition ),
+                        host.getY() >> (inTreeHeight - nextSubOctreePosition ),
+                        host.getZ() >> (inTreeHeight - nextSubOctreePosition ));
+
+            // We need to inform parent class
+            Parent::newLeafInserted( int(arrayIndex), index >> (3 * (inTreeHeight-nextSubOctreePosition) ), hostAtLevel);
+        }
+        // Ask next suboctree to insert the particle
+        if(this->subleafs[arrayIndex]->isLeafPart()){
+            ((SubOctreeWithLeaf*)this->subleafs[arrayIndex])->insert( index, host, inTreeHeight, inParticlePosition, args... );
+        }
+        else{
+            ((FSubOctree*)this->subleafs[arrayIndex])->insert( index, host, inTreeHeight, inParticlePosition, args... );
+        }
+    }
+
+    LeafClass* createLeaf(const MortonIndex index, const FTreeCoordinate& host, const int inTreeHeight){
         // We need the morton index at the bottom level of this sub octree
         // so we remove the right side
         const MortonIndex arrayIndex = Parent::getLeafIndex(index,inTreeHeight);
@@ -522,7 +576,7 @@ public:
             }
             // Or next suboctree contains the reail leaf!
             else{
-                this->subleafs[arrayIndex] = new FSubOctreeWithLeafs<ParticleClass,CellClass,ContainerClass,LeafClass>(this,int(arrayIndex),nextSubOctreeHeight,nextSubOctreePosition);
+                this->subleafs[arrayIndex] = new SubOctreeWithLeaf(this,int(arrayIndex),nextSubOctreeHeight,nextSubOctreePosition);
             }
 
             const FTreeCoordinate hostAtLevel(
@@ -534,7 +588,12 @@ public:
             Parent::newLeafInserted( int(arrayIndex), index >> (3 * (inTreeHeight-nextSubOctreePosition) ), hostAtLevel);
         }
         // Ask next suboctree to insert the particle
-        this->subleafs[arrayIndex]->insert( index, host, inParticle, inTreeHeight);
+        if(this->subleafs[arrayIndex]->isLeafPart()){
+            return ((SubOctreeWithLeaf*)this->subleafs[arrayIndex])->createLeaf( index, host, inTreeHeight );
+        }
+        else{
+            return ((FSubOctree*)this->subleafs[arrayIndex])->createLeaf( index, host, inTreeHeight );
+        }
     }
 
     /**
@@ -556,14 +615,14 @@ public:
     /** To get access to leafs elements (child suboctree)
       * @param index the position of the leaf/child suboctree
       * @return child at this index */
-    FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* leafs(const int index) {
+    FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* leafs(const int index) {
         return this->subleafs[index];
     }
 
     /** To get access to leafs elements (child suboctree)
       * @param index the position of the leaf/child suboctree
       * @return child at this index */
-    const FAbstractSubOctree<ParticleClass,CellClass,ContainerClass,LeafClass>* leafs(const int index) const {
+    const FAbstractSubOctree<CellClass,ContainerClass,LeafClass>* leafs(const int index) const {
         return this->subleafs[index];
     }
 };
diff --git a/Src/Containers/FTreeCoordinate.hpp b/Src/Containers/FTreeCoordinate.hpp
index f8eeeb0e6..d3d9eef7d 100755
--- a/Src/Containers/FTreeCoordinate.hpp
+++ b/Src/Containers/FTreeCoordinate.hpp
@@ -42,6 +42,11 @@ public:
         data[0] = data[1] = data[2] = 0;
     }
 
+    /** Default constructor (position = {0,0,0})*/
+    explicit FTreeCoordinate(const MortonIndex mindex, const int indexLevel) {
+        setPositionFromMorton(mindex, indexLevel);
+    }
+
     /**
         * Default constructor
         * @param inX the x
@@ -249,6 +254,23 @@ public:
     void restore(FBufferReader& buffer) {
         buffer >> data[0] >> data[1] >> data[2];
     }
+
+    static std::string MortonToBinary(MortonIndex index, int level){
+        std::string str;
+        int bits = 1 << ((level * 3) - 1);
+        int dim = 0;
+        while(bits){
+            if(index & bits) str.append("1");
+            else str.append("0");
+            bits >>= 1;
+            // we put a dot each 3 values
+            if(++dim == 3){
+                str.append(".");
+                dim = 0;
+            }
+        }
+        return str;
+    }
 };
 
 
diff --git a/Src/Core/FFmmAlgorithm.hpp b/Src/Core/FFmmAlgorithm.hpp
index 356298a98..aa0027ad8 100755
--- a/Src/Core/FFmmAlgorithm.hpp
+++ b/Src/Core/FFmmAlgorithm.hpp
@@ -38,7 +38,7 @@
 *
 * Of course this class does not deallocate pointer given in arguements.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithm : protected FAssertable{
 
     OctreeClass* const tree;       //< The octree to work on
diff --git a/Src/Core/FFmmAlgorithmPeriodic.hpp b/Src/Core/FFmmAlgorithmPeriodic.hpp
index 5e28d5441..0caded4a1 100755
--- a/Src/Core/FFmmAlgorithmPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmPeriodic.hpp
@@ -40,7 +40,7 @@
 *
 * Of course this class does not deallocate pointer given in arguements.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmPeriodic : protected FAssertable{
 
     OctreeClass* const tree;        //< The octree to work on
@@ -294,12 +294,15 @@ public:
                         periodicNeighbors[idxNeig] = neighbors[idxNeig];
                         neighbors[idxNeig] = 0;
                         ++periodicNeighborsCounter;
-                        typename ContainerClass::BasicIterator iter(*periodicNeighbors[idxNeig]);
-                        while( iter.hasNotFinished() ){
-                            iter.data().incPosition(boxWidth * FReal(offsets[idxNeig].getX()),
-                                                    boxWidth * FReal(offsets[idxNeig].getY()),
-                                                    boxWidth * FReal(offsets[idxNeig].getZ()));
-                            iter.gotoNext();
+
+                        FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                        FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                        FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+
+                        for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                            positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX());
+                            positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY());
+                            positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ());
                         }
                     }
                 }
@@ -310,13 +313,15 @@ public:
                 FDEBUG(computationCounterP2P.tac());
 
                 for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
-                    if( periodicNeighbors[idxNeig] ){
-                        typename ContainerClass::BasicIterator iter(*periodicNeighbors[idxNeig]);
-                        while( iter.hasNotFinished() ){
-                            iter.data().incPosition(-boxWidth * FReal(offsets[idxNeig].getX()),
-                                                    -boxWidth * FReal(offsets[idxNeig].getY()),
-                                                    -boxWidth * FReal(offsets[idxNeig].getZ()));
-                            iter.gotoNext();
+                    if( periodicNeighbors[idxNeig] ){                        
+                        FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                        FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                        FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+
+                        for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                            positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
+                            positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
+                            positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
                         }
                     }
                 }
diff --git a/Src/Core/FFmmAlgorithmSectionTask.hpp b/Src/Core/FFmmAlgorithmSectionTask.hpp
index 996c9ea5f..4878ab861 100755
--- a/Src/Core/FFmmAlgorithmSectionTask.hpp
+++ b/Src/Core/FFmmAlgorithmSectionTask.hpp
@@ -38,7 +38,7 @@
 *
 * Of course this class does not deallocate pointer given in arguements.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmSectionTask : protected FAssertable{
 
     OctreeClass* const tree;       //< The octree to work on
diff --git a/Src/Core/FFmmAlgorithmTask.hpp b/Src/Core/FFmmAlgorithmTask.hpp
index f4a3aa351..76e8d322f 100755
--- a/Src/Core/FFmmAlgorithmTask.hpp
+++ b/Src/Core/FFmmAlgorithmTask.hpp
@@ -38,7 +38,7 @@
 *
 * Of course this class does not deallocate pointer given in arguements.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmTask : protected FAssertable{
 
     OctreeClass* const tree;       //< The octree to work on
diff --git a/Src/Core/FFmmAlgorithmThread.hpp b/Src/Core/FFmmAlgorithmThread.hpp
index a3ff19caa..b47ba8b61 100755
--- a/Src/Core/FFmmAlgorithmThread.hpp
+++ b/Src/Core/FFmmAlgorithmThread.hpp
@@ -43,7 +43,7 @@
 *
 * When using this algorithm the P2P is thread safe.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmThread : protected FAssertable{
     OctreeClass* const tree;                  //< The octree to work on
     KernelClass** kernels;                    //< The kernels
diff --git a/Src/Core/FFmmAlgorithmThreadProc.hpp b/Src/Core/FFmmAlgorithmThreadProc.hpp
index 27963b1b1..fc119d77d 100755
--- a/Src/Core/FFmmAlgorithmThreadProc.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProc.hpp
@@ -55,7 +55,7 @@
 * --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes
 * ./Tests/testFmmAlgorithmProc ../Data/testLoaderSmall.fma.tmp
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmThreadProc : protected FAssertable {
 
     static const int MaxSizePerCell = 1024;
diff --git a/Src/Core/FFmmAlgorithmThreadTsm.hpp b/Src/Core/FFmmAlgorithmThreadTsm.hpp
index a992a2c89..d1d68190e 100755
--- a/Src/Core/FFmmAlgorithmThreadTsm.hpp
+++ b/Src/Core/FFmmAlgorithmThreadTsm.hpp
@@ -44,7 +44,7 @@
 * Because this is a Target source model you do not need the P2P to be safe.
 * You should not write on sources in the P2P method!
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmThreadTsm : protected FAssertable{
     OctreeClass* const tree;                  //< The octree to work on
     KernelClass** kernels;                    //< The kernels
@@ -140,11 +140,11 @@ public:
                 // We need the current cell that represent the leaf
                 // and the list of particles
                 ContainerClass* const sources = iterArray[idxLeafs].getCurrentListSrc();
-                if(sources->getSize()){
+                if(sources->getNbParticles()){
                     iterArray[idxLeafs].getCurrentCell()->setSrcChildTrue();
                     myThreadkernels->P2M( iterArray[idxLeafs].getCurrentCell() , sources);
                 }
-                if(iterArray[idxLeafs].getCurrentListTargets()->getSize()){
+                if(iterArray[idxLeafs].getCurrentListTargets()->getNbParticles()){
                     iterArray[idxLeafs].getCurrentCell()->setTargetsChildTrue();
                 }
             }
diff --git a/Src/Core/FFmmAlgorithmTsm.hpp b/Src/Core/FFmmAlgorithmTsm.hpp
index d5b55e7a8..8d4ba360d 100755
--- a/Src/Core/FFmmAlgorithmTsm.hpp
+++ b/Src/Core/FFmmAlgorithmTsm.hpp
@@ -38,7 +38,7 @@
 *
 * The differences with FmmAlgorithm is that it used target source model.
 */
-template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
+template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
 class FFmmAlgorithmTsm : protected FAssertable{
 
     OctreeClass* const tree;                                                     //< The octree to work on
@@ -103,11 +103,11 @@ public:
             // and the list of particles
             FDEBUG(computationCounter.tic());
             ContainerClass* const sources = octreeIterator.getCurrentListSrc();
-            if(sources->getSize()){
+            if(sources->getNbParticles()){
                 octreeIterator.getCurrentCell()->setSrcChildTrue();
                 kernels->P2M( octreeIterator.getCurrentCell() , sources);
             }
-            if(octreeIterator.getCurrentListTargets()->getSize()){
+            if(octreeIterator.getCurrentListTargets()->getNbParticles()){
                 octreeIterator.getCurrentCell()->setTargetsChildTrue();
             }
             FDEBUG(computationCounter.tac());
diff --git a/Src/Extensions/FExtendForces.hpp b/Src/Extensions/FExtendForces.hpp
deleted file mode 100755
index 9604853a6..000000000
--- a/Src/Extensions/FExtendForces.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FEXTENDFORCES_HPP
-#define FEXTENDFORCES_HPP
-
-
-#include "../Utils/FGlobal.hpp"
-#include "../Utils/FPoint.hpp"
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendForces
-* Please read the license
-*
-* This class is an extenssion.
-* It proposes a 3d array as a forces vector.
-*/
-class FExtendForces {
-protected:
-    FPoint forces; //< 3D vector stored in a position object
-
-public:
-    /** Default constructor */
-    FExtendForces() {
-    }
-
-    /** Copy constructor */
-    FExtendForces(const FExtendForces& other) : forces(other.forces) {
-    }
-
-    /** Copy operator */
-    FExtendForces& operator=(const FExtendForces& other) {
-        this->forces = other.forces;
-        return *this;
-    }
-
-    /** Return the forces */
-    const FPoint& getForces() const {
-        return this->forces;
-    }
-
-    /** Set Forces */
-    void incForces(const FPoint& inForces) {
-        this->forces += inForces;
-    }
-
-    /** Set Forces with 3 FReals */
-    void incForces(const FReal inFx, const FReal inFy, const FReal inFz) {
-        this->forces.incX(inFx);
-        this->forces.incY(inFy);
-        this->forces.incZ(inFz);
-    }
-
-    /** set the forces from 3 variables */
-    void setForces(const FReal inFx, const FReal inFy, const FReal inFz) {
-        this->forces.setPosition(inFx , inFy, inFz);
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        forces.save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        forces.restore(buffer);
-    }
-};
-
-
-#endif //FEXTENDFORCES_HPP
-
-
diff --git a/Src/Extensions/FExtendParticleType.hpp b/Src/Extensions/FExtendParticleType.hpp
deleted file mode 100755
index 19c749058..000000000
--- a/Src/Extensions/FExtendParticleType.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FEXTENDPARTICLETYPE_HPP
-#define FEXTENDPARTICLETYPE_HPP
-
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendParticleType
-* Please read the license
-* This class is an extenssion.
-* It proposes a target/source extenssion for particles.
-*/
-class FExtendParticleType {
-protected:
-    /** Particle potential type */
-    enum Type {
-        Source,
-        Target,
-        Undef
-    };
-
-    /** Current type */
-    Type type;
-
-public:
-    /** Default constructor */
-    FExtendParticleType(const Type inType = Undef) : type(inType) {
-    }
-
-    /** Copy constructor */
-    FExtendParticleType(const FExtendParticleType& other) : type(other.type) {
-    }
-
-    /** Copy operator */
-    FExtendParticleType& operator=(const FExtendParticleType& other) {
-        this->type = other.type;
-        return *this;
-    }
-
-    /** To get the type */
-    Type getParticleType() const {
-        return this->type;
-    }
-
-    /** To set the type */
-    void setParticleType(const Type inType) {
-        this->type = inType;
-    }
-
-    /** To know if a particle is a target */
-    bool isTarget() const{
-        return this->type == Target;
-    }
-
-    /** To know if a particle is a source */
-    bool isSource() const{
-        return this->type == Source;
-    }
-
-    /** To know if a particle has an undefined type */
-    bool isUndefinedType() const{
-        return this->type == Undef;
-    }
-
-    /** To know if a particle is a target */
-    void setAsTarget() {
-        this->type = Target;
-    }
-
-    /** To know if a particle is a source */
-    void setAsSource() {
-        this->type = Source;
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        buffer << type;
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        buffer >> type;
-    }
-};
-
-
-#endif //FEXTENDPARTICLETYPE_HPP
-
-
diff --git a/Src/Extensions/FExtendPhysicalValue.hpp b/Src/Extensions/FExtendPhysicalValue.hpp
deleted file mode 100755
index e98aff2be..000000000
--- a/Src/Extensions/FExtendPhysicalValue.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FExtendPhysicalValue_HPP
-#define FExtendPhysicalValue_HPP
-
-
-#include "../Utils/FGlobal.hpp"
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendPhysicalValue
-* Please read the license
-* This class is an extenssion.
-* It proposes a physicalValue (FReal).
-*/
-class FExtendPhysicalValue {
-protected:
-    FReal physicalValue;   //< A simple physicalValue
-
-public:
-    /** Default constructor */
-    FExtendPhysicalValue() : physicalValue(0) {
-    }
-
-    /** Copy constructor */
-    FExtendPhysicalValue(const FExtendPhysicalValue& other) : physicalValue(other.physicalValue) {
-    }
-
-    /** Copy Constructor */
-    FExtendPhysicalValue& operator=(const FExtendPhysicalValue& other) {
-        this->physicalValue = other.physicalValue;
-        return *this;
-    }
-
-    /** To get the physicalValue */
-    FReal getPhysicalValue() const {
-        return this->physicalValue;
-    }
-
-    /** To set the physicalValue */
-    void setPhysicalValue(const FReal inphysicalValue) {
-        this->physicalValue = inphysicalValue;
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        buffer << physicalValue;
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        buffer >> physicalValue;
-    }
-
-};
-
-
-#endif //FExtendPhysicalValue_HPP
-
-
diff --git a/Src/Extensions/FExtendPosition.hpp b/Src/Extensions/FExtendPosition.hpp
deleted file mode 100755
index 5fa3a3231..000000000
--- a/Src/Extensions/FExtendPosition.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FEXTENDPOSITION_HPP
-#define FEXTENDPOSITION_HPP
-
-
-#include "../Utils/FGlobal.hpp"
-#include "../Utils/FPoint.hpp"
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendPosition
-* Please read the license
-* This class is an extenssion.
-* It proposes a position from a FPoint.
-*/
-class FExtendPosition {
-protected:
-    FPoint position; //< The position
-
-public:
-    /** Default constructor */
-    FExtendPosition() {
-    }
-
-    /** Copy constructor */
-    FExtendPosition(const FExtendPosition& other) : position(other.position) {
-    }
-
-    /** Copy operator */
-    FExtendPosition& operator=(const FExtendPosition& other) {
-        this->position = other.position;
-        return *this;
-    }
-
-    /** To get the position */
-    const FPoint& getPosition() const {
-        return this->position;
-    }
-
-    /** To set the position */
-    void setPosition(const FPoint& inPosition) {
-        this->position = inPosition;
-    }
-
-    /** To set the position from 3 FReals */
-    void setPosition(const FReal inX, const FReal inY, const FReal inZ) {
-        this->position.setX(inX);
-        this->position.setY(inY);
-        this->position.setZ(inZ);
-    }
-
-    /** Set Position */
-    void incPosition(const FPoint& inPosition) {
-        this->position += inPosition;
-    }
-
-    /** Set Position with 3 FReals */
-    void incPosition(const FReal inPx, const FReal inPy, const FReal inPz) {
-        this->position.incX(inPx);
-        this->position.incY(inPy);
-        this->position.incZ(inPz);
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        position.save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        position.restore(buffer);
-    }
-};
-
-
-#endif //FEXTENDPOSITION_HPP
-
-
diff --git a/Src/Extensions/FExtendPotential.hpp b/Src/Extensions/FExtendPotential.hpp
deleted file mode 100755
index 8178a3519..000000000
--- a/Src/Extensions/FExtendPotential.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FEXTENDPOTENTIAL_HPP
-#define FEXTENDPOTENTIAL_HPP
-
-
-#include "../Utils/FGlobal.hpp"
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendPotential
-* Please read the license
-* This class is an extenssion.
-* It proposes a Potential (FReal).
-*/
-class FExtendPotential {
-protected:
-    FReal potential;   //< The potential extended
-
-public:
-    /** Default constructor */
-    FExtendPotential() : potential(0) {
-    }
-
-    /** Copy constructor */
-    FExtendPotential(const FExtendPotential& other) : potential(other.potential) {
-    }
-
-    /** Copy operator */
-    FExtendPotential& operator=(const FExtendPotential& other) {
-        this->potential = other.potential;
-        return *this;
-    }
-
-    /** To get the potential */
-    FReal getPotential() const {
-        return this->potential;
-    }
-
-    /** To set the potential */
-    void setPotential(const FReal inPotential) {
-        this->potential = inPotential;
-    }
-
-    /** To inc the potential */
-    void incPotential(const FReal inPotential) {
-        this->potential += inPotential;
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        buffer << potential;
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        buffer >> potential;
-    }
-};
-
-
-#endif //FEXTENDPOTENTIAL_HPP
-
-
diff --git a/Src/Extensions/FExtendVelocity.hpp b/Src/Extensions/FExtendVelocity.hpp
deleted file mode 100755
index 52d5f1313..000000000
--- a/Src/Extensions/FExtendVelocity.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FEXTENDVELOCITY_HPP
-#define FEXTENDVELOCITY_HPP
-
-
-
-#include "../Utils/FGlobal.hpp"
-#include "../Utils/FPoint.hpp"
-#include "../Containers/FBufferReader.hpp"
-#include "../Containers/FBufferWriter.hpp"
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-* @class FExtendVelocity
-* Please read the license
-*
-* This class is an extenssion.
-* It proposes a FPoint as a velocity vector.
-*/
-class FExtendVelocity {
-protected:
-    FPoint velocity; //< 3D vector stored in a position object
-
-public:
-    /** Default constructor */
-    FExtendVelocity() {
-    }
-
-    /** Copy constructor */
-    FExtendVelocity(const FExtendVelocity& other) : velocity(other.velocity) {
-    }
-
-    /** Copy operator */
-    FExtendVelocity& operator=(const FExtendVelocity& other) {
-        this->velocity = other.velocity;
-        return *this;
-    }
-
-    /** Return the velocity */
-    const FPoint& getVelocity() const {
-        return this->velocity;
-    }
-
-    /** Set Velocity */
-    void incVelocity(const FPoint& inVelocity) {
-        this->velocity += inVelocity;
-    }
-
-    /** Set Velocity with 3 FReals */
-    void incVelocity(const FReal inVx, const FReal inVy, const FReal inVz) {
-        this->velocity.incX(inVx);
-        this->velocity.incY(inVy);
-        this->velocity.incZ(inVz);
-    }
-
-    /** set the velocity from 3 variables */
-    void setVelocity(const FReal inVx, const FReal inVy, const FReal inVz) {
-        this->velocity.setPosition(inVx , inVy, inVz);
-    }
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        buffer << velocity;
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        buffer >> velocity;
-    }
-};
-
-
-#endif //FEXTENDVELOCITY_HPP
-
-
diff --git a/Src/Files/FAbstractLoader.hpp b/Src/Files/FAbstractLoader.hpp
index af3a9564f..5f09e6a54 100755
--- a/Src/Files/FAbstractLoader.hpp
+++ b/Src/Files/FAbstractLoader.hpp
@@ -18,6 +18,8 @@
 
 
 #include "../Utils/FGlobal.hpp"
+
+
 class FPoint;
 
 /**
@@ -34,7 +36,6 @@ class FPoint;
 *
 * @warning Inherite from this class when defining a loader class
 */
-template <class ParticleClass>
 class FAbstractLoader {
 public:	
     /** Default destructor */
@@ -64,24 +65,6 @@ public:
         * @return true if file is open
         */
     virtual bool isOpen() const = 0;
-
-    /**
-        * Fill the next particle
-        * @param inParticle the particle to fill
-        */
-    virtual void fillParticle(ParticleClass& inParticle) = 0;
-
-    /** Fill a tree with all the particle of the current loader
-      * @param tree the tree to fill
-      */
-    template <class OctreeClass>
-    void fillTree(OctreeClass& tree){
-        ParticleClass particleToFill;
-        for(int idxPart = 0 ; idxPart < getNumberOfParticles() ; ++idxPart){
-            fillParticle(particleToFill);
-            tree.insert(particleToFill);
-        }
-    }
 };
 
 
diff --git a/Src/Files/FBasicLoader.hpp b/Src/Files/FBasicLoader.hpp
index a0523c676..437704c12 100755
--- a/Src/Files/FBasicLoader.hpp
+++ b/Src/Files/FBasicLoader.hpp
@@ -49,8 +49,7 @@
 *    } <br>
 * @endcode
 */
-template <class ParticleClass>
-class FBasicLoader : public FAbstractLoader<ParticleClass> {
+class FBasicLoader : public FAbstractLoader {
 protected:
     std::ifstream file;         //< The file to read
     FPoint centerOfBox;         //< The center of box read from file
@@ -120,10 +119,10 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePosition){
         FReal x,y,z;
         this->file >> x >> y >> z;
-        inParticle.setPosition(FPoint(x,y,z));
+        inParticlePosition->setPosition(x,y,z);
     }
 
 };
diff --git a/Src/Files/FEwalLoader.hpp b/Src/Files/FEwalLoader.hpp
index da494e5f0..a67620815 100755
--- a/Src/Files/FEwalLoader.hpp
+++ b/Src/Files/FEwalLoader.hpp
@@ -26,61 +26,13 @@
 #include "../Utils/FPoint.hpp"
 
 
-template <class BaseClass>
-class FEwalParticle : public BaseClass {
-public:
-    // Type of particle
-    enum Type{
-        OW,
-        HW,
-        Undefined,
-    };
-
-private:
-    Type type; //< current type
-    int index; //< current index in array
-    int indexInFile; //< current index in array
-
-public:
-    // Basic constructor
-    FEwalParticle() : type(Undefined), index(-1), indexInFile(-1) {
-    }
-
-    Type getType() const{
-        return type;
-    }
-
-    void setType(const Type inType) {
-        type = inType;
-    }
-
-    int getIndex() const{
-        return index;
-    }
-
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
-
-    int getIndexInFile() const{
-        return indexInFile;
-    }
-
-    void setIndexInFile( const int inIndex ){
-        indexInFile = inIndex;
-    }
-};
-
-
-
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * @class FEwalLoader
 * Please read the license
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FEwalLoader : public FAbstractLoader<ParticleClass> {
+class FEwalLoader : public FAbstractLoader {
 protected:
     std::ifstream file;         //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -88,6 +40,12 @@ protected:
     int nbParticles;            //< the number of particles read from file
     int levcfg  ;         //< DL_POLY CONFIG file key. 0,1 or 2
 public:
+    enum Type{
+        OW,
+        HW,
+        Undefined,
+    };
+
     /**
     * The constructor need the file name
     * @param filename the name of the file to open
@@ -177,7 +135,7 @@ public:
            7.64746800518      -1.34490700206      -2.81036521708
           -4406.48579000       6815.52906417       10340.2577024
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FReal inParticle[7], int inIndex [1], Type inType[1]){
         FReal x, y, z, fx, fy, fz, vx, vy, vz;
         int index;
         char type[2];
@@ -198,28 +156,28 @@ public:
             file >> fx >> fy >> fz;
         }
 
-
-        //	std::cout << " x >> y >> z: " << x<< " " <<y<< " " <<z <<std::endl;
-        inParticle.setPosition(x,y,z);
-        inParticle.setForces(fx,fy,fz);
-        //inParticle.setForces(vx,vy,vz);
-        inParticle.setIndexInFile(index);
+        inParticle[0] = x;
+        inParticle[1] = y;
+        inParticle[2] = z;
+        inParticle[3] = fx;
+        inParticle[4] = fy;
+        inParticle[5] = fz;
+        inIndex[0] = index;
 
         if( strncmp(type, "OW", 2) == 0){
-            inParticle.setPhysicalValue(FReal(-0.82));
-            inParticle.setType(ParticleClass::OW);
+            inParticle[6] = FReal(-0.82);
+            inType[0] = OW;
         }
         else{
-            inParticle.setPhysicalValue(FReal(0.41));
-            inParticle.setType(ParticleClass::HW);
+            inParticle[6] = FReal(-0.41);
+            inType[0] = HW;
         }
     }
 
 };
 
 
-template <class ParticleClass>
-class FEwalBinLoader : public FAbstractLoader<ParticleClass> {
+class FEwalBinLoader : public FAbstractLoader {
 protected:
     FILE* const file;         //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -324,7 +282,7 @@ public:
       * @param the particle to fill
         [index charge x y z fx fy fz]
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint* inPosition, FReal inForces[3], FReal* inPhysicalValue, int* inIndex){
         double x, y, z, fx, fy, fz, charge;
         int index;
 
@@ -346,10 +304,12 @@ public:
         removeWarning = fread(&size, sizeof(int), 1, file);
         if(size != 60) printf("Error in loader ewal Size %d should be %d\n", size, 60);
 
-        inParticle.setPosition(x,y,z);
-        inParticle.setForces(fx,fy,fz);
-        inParticle.setIndexInFile(index);
-        inParticle.setPhysicalValue(charge);
+        inPosition->setPosition( x, y ,z);
+        inForces[0] = fx;
+        inForces[1] = fy;
+        inForces[2] = fz;
+        *inPhysicalValue = charge;
+        *inIndex = index;
     }
 
 };
diff --git a/Src/Files/FFmaBinLoader.hpp b/Src/Files/FFmaBinLoader.hpp
index 391d208a5..964fc2184 100755
--- a/Src/Files/FFmaBinLoader.hpp
+++ b/Src/Files/FFmaBinLoader.hpp
@@ -51,8 +51,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FFmaBinLoader : public FAbstractLoader<ParticleClass> {
+class FFmaBinLoader : public FAbstractLoader {
 protected:
     FILE* const file;            //< The file to read
     FPoint centerOfBox;     //< The center of box read from file
@@ -137,7 +136,7 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePosition, FReal*const physicalValue){
         FReal x,y,z,data;
 
         removeWarning += fread(&x, sizeof(FReal), 1, file);
@@ -145,8 +144,8 @@ public:
         removeWarning += fread(&z, sizeof(FReal), 1, file);
         removeWarning += fread(&data, sizeof(FReal), 1, file);
 
-        inParticle.setPosition(x,y,z);
-        inParticle.setPhysicalValue(data);
+        inParticlePosition->setPosition(x,y,z);
+        (*physicalValue) = data;
     }
 
 };
diff --git a/Src/Files/FFmaLoader.hpp b/Src/Files/FFmaLoader.hpp
index b6f289ae8..04dcbcd40 100755
--- a/Src/Files/FFmaLoader.hpp
+++ b/Src/Files/FFmaLoader.hpp
@@ -51,8 +51,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FFmaLoader : public FAbstractLoader<ParticleClass> {
+class FFmaLoader : public FAbstractLoader {
 protected:
     std::ifstream file;         //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -123,11 +122,11 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue){
         FReal x,y,z,data;
         this->file >> x >> y >> z >> data;
-        inParticle.setPosition(x,y,z);
-        inParticle.setPhysicalValue(data);
+        inParticlePositions->setPosition(x,y,z);
+        (*inPhysicalValue) = data;
     }
 
 };
diff --git a/Src/Files/FFmaScanfLoader.hpp b/Src/Files/FFmaScanfLoader.hpp
index e585535bc..1d27a2060 100755
--- a/Src/Files/FFmaScanfLoader.hpp
+++ b/Src/Files/FFmaScanfLoader.hpp
@@ -51,8 +51,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FFmaScanfLoader : public FAbstractLoader<ParticleClass> {
+class FFmaScanfLoader : public FAbstractLoader {
 protected:
     FILE* file;                 //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -130,13 +129,13 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue){
         if(this->file){
             float x,y,z,data;
             const int nbReadElements = fscanf(this->file,"%f %f %f %f",&x,&y,&z,&data);
             if(nbReadElements == 4){
-                inParticle.setPosition(x,y,z);
-                inParticle.setPhysicalValue(data);
+                inParticlePositions->setPosition(x,y,z);
+                (*inPhysicalValue) = data;
             }
             else{
                 fclose(this->file);
diff --git a/Src/Files/FFmaTsmLoader.hpp b/Src/Files/FFmaTsmLoader.hpp
index 84112aee4..e372cdcdc 100755
--- a/Src/Files/FFmaTsmLoader.hpp
+++ b/Src/Files/FFmaTsmLoader.hpp
@@ -51,8 +51,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FFmaTsmLoader : public FAbstractLoader<ParticleClass> {
+class FFmaTsmLoader : public FAbstractLoader {
 protected:
     std::ifstream file;         //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -123,14 +122,14 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue, bool*const inIsTarget){
         FReal x,y,z,data;
         int isTarget;
         this->file >> x >> y >> z >> data >> isTarget;
-        inParticle.setPosition(x,y,z);
-        inParticle.setPhysicalValue(data);
-        if(isTarget) inParticle.setAsTarget();
-        else inParticle.setAsSource();
+
+        inParticlePositions->setPosition(x,y,z);
+        *inPhysicalValue = data;
+        *inIsTarget = isTarget;
     }
 
 };
diff --git a/Src/Files/FHLoader.hpp b/Src/Files/FHLoader.hpp
index ff510b583..5695202cb 100755
--- a/Src/Files/FHLoader.hpp
+++ b/Src/Files/FHLoader.hpp
@@ -51,8 +51,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FHLoader : public FAbstractLoader<ParticleClass> {
+class FHLoader : public FAbstractLoader {
 protected:
     FILE* file;                 //< The file to read
     FPoint centerOfBox;    //< The center of box read from file
@@ -134,14 +133,14 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint*const inParticlePositions, char*const inData){
         if(this->file){
             char buff[128];
             float x,y,z;
             const int nbReadElements = fscanf(this->file,"%s %f %f %f",buff,&x,&y,&z);
             if(nbReadElements == 4){
-                inParticle.setPosition(x,y,z);
-                inParticle.setData(buff[0]);
+                inParticlePositions->setPosition(x,y,z);
+                (*inData) = buff[0];
             }
             else{
                 fclose(this->file);
diff --git a/Src/Files/FMpiFmaLoader.hpp b/Src/Files/FMpiFmaLoader.hpp
index 3afc40d78..849cfa78f 100755
--- a/Src/Files/FMpiFmaLoader.hpp
+++ b/Src/Files/FMpiFmaLoader.hpp
@@ -52,8 +52,7 @@
 *
 * Particle has to extend {FExtendPhysicalValue,FExtendPosition}
 */
-template <class ParticleClass>
-class FMpiFmaLoader : public FAbstractLoader<ParticleClass> {
+class FMpiFmaLoader : public FAbstractLoader {
 protected:
     FPoint centerOfBox;    //< The center of box read from file
     FReal boxWidth;             //< the box width read from file
@@ -226,9 +225,9 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
-        inParticle.setPosition(particles[idxParticles],particles[idxParticles+1],particles[idxParticles+2]);
-        inParticle.setPhysicalValue(particles[idxParticles+3]);
+    void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue){
+        inParticlePositions->setPosition(particles[idxParticles],particles[idxParticles+1],particles[idxParticles+2]);
+        (*inPhysicalValue) = (particles[idxParticles+3]);
         idxParticles += 4;
     }
 
diff --git a/Src/Files/FRandomLoader.hpp b/Src/Files/FRandomLoader.hpp
index 70f302fdb..21fce59d6 100755
--- a/Src/Files/FRandomLoader.hpp
+++ b/Src/Files/FRandomLoader.hpp
@@ -31,8 +31,7 @@
 * @class FRandomLoader
 * Please read the license
 */
-template <class ParticleClass>
-class FRandomLoader : public FAbstractLoader<ParticleClass> {
+class FRandomLoader : public FAbstractLoader {
 protected:
     const size_t nbParticles;            //< the number of particles
     const FReal boxWidth;             //< the box width
@@ -90,8 +89,8 @@ public:
       * @warning to work with the loader, particles has to expose a setPosition method
       * @param the particle to fill
       */
-    void fillParticle(ParticleClass& inParticle){
-        inParticle.setPosition(
+    void fillParticle(FPoint*const inParticlePositions){
+        inParticlePositions->setPosition(
                     (getRandom() * boxWidth) + centerOfBox.getX() - boxWidth/2,
                     (getRandom() * boxWidth) + centerOfBox.getY() - boxWidth/2,
                     (getRandom() * boxWidth) + centerOfBox.getZ() - boxWidth/2);
@@ -107,18 +106,17 @@ public:
 /** This class is a random loader but it also generate
   * randomly the particles type (target or source)
   */
-template <class ParticleClass>
-class FRandomLoaderTsm : public FRandomLoader<ParticleClass> {
+class FRandomLoaderTsm : public FRandomLoader {
 public:
     FRandomLoaderTsm(const size_t inNbParticles, const FReal inBoxWidth = 1.0,
                   const FPoint& inCenterOfBox = FPoint(0,0,0), const unsigned int inSeed = static_cast<unsigned int>(time(NULL)))
-        : FRandomLoader<ParticleClass>(inNbParticles,inBoxWidth,inCenterOfBox,inSeed) {
+        : FRandomLoader(inNbParticles,inBoxWidth,inCenterOfBox,inSeed) {
     }
 
-    void fillParticle(ParticleClass& inParticle){
-        FRandomLoader<ParticleClass>::fillParticle(inParticle);
-        if(FRandomLoader<ParticleClass>::getRandom() > 0.5 ) inParticle.setAsTarget();
-        else inParticle.setAsSource();
+
+    void fillParticle(FPoint*const inParticlePositions, bool*const isTarget){
+        FRandomLoader::fillParticle(inParticlePositions);
+        (*isTarget) = (FRandomLoader::getRandom() > 0.5 );
     }
 };
 
diff --git a/Src/Files/FTreeCsvSaver.hpp b/Src/Files/FTreeCsvSaver.hpp
index e5378176e..b7556760a 100755
--- a/Src/Files/FTreeCsvSaver.hpp
+++ b/Src/Files/FTreeCsvSaver.hpp
@@ -25,7 +25,7 @@
 /** This class is to export a tree in csv file
   *
   */
-template <class OctreeClass, class ContainerClass , class ParticleClass>
+template <class OctreeClass, class ContainerClass >
 class FTreeCsvSaver {
     const bool includeHeader;   //< To include a line of header
     int nbFrames;               //< The current frame
@@ -66,34 +66,29 @@ public:
         typename OctreeClass::Iterator octreeIterator(tree);
         octreeIterator.gotoBottomLeft();
         do{
-            typename ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-
-            while( iter.hasNotFinished() ){
-                file << iter.data().getPosition().getX() << "," << iter.data().getPosition().getY() << "," <<
-                        iter.data().getPosition().getZ() << "," << getValue(&iter.data()) << "\n";
-                iter.gotoNext();
+            FReal values[4];
+            {
+                const ContainerClass* container = octreeIterator.getCurrentListTargets();
+                for(int idxPart = 0 ; idxPart < container->getNbParticles() ; ++idxPart){
+                    container->fillToCsv(idxPart, values);
+                    file << values[0] << "," << values[1] << "," <<
+                            values[2] << "," << values[3] << "\n";
+                }
             }
 
             const bool isUsingTsm = (octreeIterator.getCurrentListTargets() != octreeIterator.getCurrentListSrc());
             if( isUsingTsm ){
-                typename ContainerClass::BasicIterator iterSources(*octreeIterator.getCurrentListSrc());
-
-                while( iterSources.hasNotFinished() ){
-                    file << iterSources.data().getPosition().getX() << "," << iterSources.data().getPosition().getY() << "," <<
-                            iterSources.data().getPosition().getZ() << "," << getValue(&iterSources.data()) << "\n";
-                    iterSources.gotoNext();
+                const ContainerClass* container = octreeIterator.getCurrentListSrc();
+                for(int idxPart = 0 ; idxPart < container->getNbParticles() ; ++idxPart){
+                    container->fillToCsv(idxPart, values);
+                    file << values[0] << "," << values[1] << "," <<
+                            values[2] << "," << values[3] << "\n";
                 }
             }
         } while(octreeIterator.moveRight());
 
         file.close();
     }
-
-    /** Inherit from this class and customize this function if you need it
-      */
-    virtual FReal getValue(ParticleClass*const part){
-        return FReal(0);
-    }
 };
 
 
diff --git a/Src/Files/FTreeIO.hpp b/Src/Files/FTreeIO.hpp
index 9b04e8a73..39f423325 100755
--- a/Src/Files/FTreeIO.hpp
+++ b/Src/Files/FTreeIO.hpp
@@ -35,9 +35,16 @@
   * ...
   */
 class FTreeIO{
+
+    enum TargetSourceDiff{
+        TsmUndef,
+        TsmUsed,
+        TsmUnused
+    };
+
 public:
     /** To save in memory */
-    template <class OctreeClass, class CellClass, class ParticleClass , class ContainerClass >
+    template <class OctreeClass, class CellClass, class LeafClass, class ContainerClass >
     static bool Save(const char filename[], OctreeClass& tree){
         std::ofstream file(filename, std::ofstream::binary | std::ofstream::out );
         FBufferWriter buffer;
@@ -70,22 +77,16 @@ public:
             octreeIterator.gotoBottomLeft();
             const bool useTargetSource = (octreeIterator.getCurrentListSrc() != octreeIterator.getCurrentListTargets());
             if( useTargetSource ){
+                TargetSourceDiff tsm = TsmUsed;
+                file.write((const char*)&tsm,sizeof(tsm));
+
                 do{
-                    const int nbParticlesInLeaf = (octreeIterator.getCurrentListSrc()->getSize() + octreeIterator.getCurrentListTargets()->getSize());
-                    file.write((const char*)&nbParticlesInLeaf,sizeof(int));
+                    const MortonIndex mindex = octreeIterator.getCurrentGlobalIndex();
+                    file.write((const char*)&mindex,sizeof(mindex));
 
                     buffer.reset();
-                    typename ContainerClass::BasicIterator iterSrc(*octreeIterator.getCurrentListSrc());
-                    while( iterSrc.hasNotFinished() ){
-                        iterSrc.data().save(buffer);
-                        iterSrc.gotoNext();
-                    }
-
-                    typename ContainerClass::BasicIterator iterTarget(*octreeIterator.getCurrentListTargets());
-                    while( iterTarget.hasNotFinished() ){
-                        iterTarget.data().save(buffer);
-                        iterTarget.gotoNext();
-                    }
+                    octreeIterator.getCurrentListSrc()->save(buffer);
+                    octreeIterator.getCurrentListTargets()->save(buffer);
 
                     const int sizeOfLeaf = buffer.getSize();
                     file.write((const char*) &sizeOfLeaf, sizeof(int));
@@ -95,16 +96,14 @@ public:
                 } while(octreeIterator.moveRight());
             }
             else{
+                TargetSourceDiff tsm = TsmUnused;
+                file.write((const char*)&tsm,sizeof(tsm));
                 do{
-                    const int nbParticlesInLeaf = octreeIterator.getCurrentListSrc()->getSize();
-                    file.write((const char*)&nbParticlesInLeaf,sizeof(int));
+                    const MortonIndex mindex = octreeIterator.getCurrentGlobalIndex();
+                    file.write((const char*)&mindex,sizeof(mindex));
 
                     buffer.reset();
-                    typename ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListSrc());
-                    while( iter.hasNotFinished() ){
-                        iter.data().save(buffer);
-                        iter.gotoNext();
-                    }
+                    octreeIterator.getCurrentListSrc()->save(buffer);
 
                     const int sizeOfLeaf = buffer.getSize();
                     file.write((const char*) &sizeOfLeaf, sizeof(int));
@@ -163,7 +162,7 @@ public:
 
 
     /** To load from memory */
-    template <class OctreeClass, class CellClass, class ParticleClass , class ContainerClass  >
+    template <class OctreeClass, class CellClass, class LeafClass, class ContainerClass  >
     static bool Load(const char filename[], OctreeClass& tree){
         std::ifstream file(filename, std::ifstream::binary | std::ifstream::in );
         FBufferReader buffer;
@@ -196,11 +195,12 @@ public:
             int nbLeaf = 0;
             file.read((char*)&nbLeaf, sizeof(int));
 
-            ParticleClass particle;
+            TargetSourceDiff tsm = TsmUndef;
+            file.read((char*)&tsm,sizeof(tsm));
 
             for(int idxLeaf = 0 ; idxLeaf < nbLeaf ; ++idxLeaf){
-                int particlesInLeaf = 0;
-                file.read((char*)&particlesInLeaf, sizeof(int));
+                MortonIndex mindex = 0;
+                file.read((char*)&mindex, sizeof(mindex));
 
                 int sizeOfLeaf = 0;
                 file.read((char*)&sizeOfLeaf, sizeof(int));
@@ -208,9 +208,11 @@ public:
                 buffer.reserve(sizeOfLeaf);
                 file.read((char*)buffer.data(), sizeOfLeaf);
 
-                for(int idxParticle = 0 ; idxParticle < particlesInLeaf ; ++idxParticle){
-                    particle.restore(buffer);
-                    tree.insert(particle);
+                LeafClass*const leaf = tree.createLeaf(mindex);
+                leaf->getSrc()->restore(buffer);
+
+                if( tsm == TsmUsed ){
+                    leaf->getTargets()->restore(buffer);
                 }
             }
         }
diff --git a/Src/Kernels/Chebyshev/FAbstractChebKernel.hpp b/Src/Kernels/Chebyshev/FAbstractChebKernel.hpp
index 648f044a6..43c2f00af 100755
--- a/Src/Kernels/Chebyshev/FAbstractChebKernel.hpp
+++ b/Src/Kernels/Chebyshev/FAbstractChebKernel.hpp
@@ -22,6 +22,8 @@
 
 #include "../../Components/FAbstractKernels.hpp"
 
+#include "../P2P/FP2P.hpp"
+
 #include "./FChebInterpolator.hpp"
 
 class FTreeCoordinate;
@@ -35,14 +37,13 @@ template <KERNEL_FUNCCTION_IDENTIFIER Identifier> struct DirectInteactionCompute
  * implements all interfaces (P2P, P2M, M2M, M2L, L2L, L2P) which are required by
  * the FFmmAlgorithm and FFmmAlgorithmThread.
  *
- * @tparam ParticleClass Type of particle
  * @tparam CellClass Type of cell
  * @tparam ContainerClass Type of container to store particles
  * @tparam MatrixKernelClass Type of matrix kernel function
  * @tparam ORDER Chebyshev interpolation order
  */
-template <class ParticleClass, class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
-class FAbstractChebKernel : public FAbstractKernels<ParticleClass, CellClass, ContainerClass>
+template < class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
+class FAbstractChebKernel : public FAbstractKernels< CellClass, ContainerClass>
 {
 protected:
   enum {nnodes = TensorTraits<ORDER>::nnodes};
@@ -127,86 +128,11 @@ public:
 
 	void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
 					 ContainerClass* const FRestrict TargetParticles,
-					 const ContainerClass* const FRestrict SourceParticles,
+                     const ContainerClass* const FRestrict /*SourceParticles*/,
 					 ContainerClass* const NeighborSourceParticles[27],
 					 const int /* size */)
 	{
-		// loop: target particles
-		typename ContainerClass::BasicIterator iTargets(*TargetParticles);
-
-		if (TargetParticles != SourceParticles) {
-
-			while (iTargets.hasNotFinished()) {
-				ParticleClass& Target = iTargets.data();
-				
-				{ // loop: source particles (target leaf cell == source leaf cell)
-					typename ContainerClass::ConstBasicIterator iSources(*SourceParticles);
-					while (iSources.hasNotFinished()) {
-						const ParticleClass& Source = iSources.data();
-						// only if target and source are not identical
-						DirectInteactionComputer<MatrixKernelClass::Identifier>::compute(Target, Source);
-						// progress sources
-						iSources.gotoNext();
-					}
-				}
-				
-				{ // loop: source particles (target leaf cell != source leaf cell)
-					for (unsigned int idx=0; idx<27; ++idx) {
-						if (NeighborSourceParticles[idx]) {
-							typename ContainerClass::ConstBasicIterator	iSources(*NeighborSourceParticles[idx]);
-							while (iSources.hasNotFinished()) {
-								const ParticleClass& Source = iSources.data();
-								// target and source cannot be identical
-								DirectInteactionComputer<MatrixKernelClass::Identifier>::compute(Target, Source);
-								// progress sources
-								iSources.gotoNext();
-							}
-						}
-					}
-				}
-		
-				// progress targets
-				iTargets.gotoNext();
-			}
-
-		} else {
-
-			while (iTargets.hasNotFinished()) {
-				ParticleClass& Target = iTargets.data();
-				
-				{ // loop: source particles  (target leaf cell == source leaf cell)
-					typename ContainerClass::BasicIterator iSources = iTargets;
-					iSources.gotoNext();
-					while (iSources.hasNotFinished()) {
-						ParticleClass& Source = iSources.data();
-						// only if target and source are not identical
-						DirectInteactionComputer<MatrixKernelClass::Identifier>::computeMutual(Target, Source);
-						// progress sources
-						iSources.gotoNext();
-					}
-				}
-				
-				{ // loop: source particles (target leaf cell != source leaf cell)
-					for (unsigned int idx=0; idx<=13; ++idx) {
-						if (NeighborSourceParticles[idx]) {
-							typename ContainerClass::BasicIterator iSources(*NeighborSourceParticles[idx]);
-							while (iSources.hasNotFinished()) {
-								ParticleClass& Source = iSources.data();
-								// target and source cannot be identical
-								DirectInteactionComputer<MatrixKernelClass::Identifier>::computeMutual(Target, Source);
-								// progress sources
-								iSources.gotoNext();
-							}
-						}
-					}
-				}
-		
-				// progress targets
-				iTargets.gotoNext();
-			}
-
-		}
-
+        DirectInteactionComputer<MatrixKernelClass::Identifier>::P2P(TargetParticles,NeighborSourceParticles);
 	}
 
 };
@@ -216,43 +142,11 @@ public:
 template <>
 struct DirectInteactionComputer<ONE_OVER_R>
 {
-	template <typename ParticleClass>
-	static void compute(ParticleClass& Target, const ParticleClass& Source) // 34 overall flops
-	{
-		FPoint xy(Source.getPosition() - Target.getPosition()); // 3 flops
-		const FReal one_over_r = FReal(1.) / FMath::Sqrt(xy.getX()*xy.getX() +
-																										 xy.getY()*xy.getY() +
-																										 xy.getZ()*xy.getZ()); // 1 + 15 + 5 = 21 flops
-		const FReal wt = Target.getPhysicalValue();
-		const FReal ws = Source.getPhysicalValue();
-
-		// laplace potential
-		Target.incPotential(one_over_r * ws); // 2 flops
-
-		// force
-		xy *= ((ws*wt) * (one_over_r*one_over_r*one_over_r)); // 5 flops
-		Target.incForces(xy.getX(), xy.getY(), xy.getZ()); // 3 flops
-	}
-
-	template <typename ParticleClass>
-	static void computeMutual(ParticleClass& Target, ParticleClass& Source) // 39 overall flops
-	{
-		FPoint xy(Source.getPosition() - Target.getPosition()); // 3 flops
-		const FReal one_over_r = FReal(1.) / FMath::Sqrt(xy.getX()*xy.getX() +
-																										 xy.getY()*xy.getY() +
-																										 xy.getZ()*xy.getZ()); // 1 + 15 + 5 = 21 flops
-		const FReal wt = Target.getPhysicalValue();
-		const FReal ws = Source.getPhysicalValue();
-
-		// laplace potential
-		Target.incPotential(one_over_r * ws); // 2 flops
-		Source.incPotential(one_over_r * wt); // 2 flops
-
-		// force
-		xy *= ((ws*wt) * (one_over_r*one_over_r*one_over_r)); // 5 flops
-		Target.incForces(  xy.getX(),    xy.getY(),    xy.getZ());  // 3 flops 
-		Source.incForces((-xy.getX()), (-xy.getY()), (-xy.getZ())); // 3 flops
-	}
+    template <typename ContainerClass>
+    static void P2P(		 ContainerClass* const FRestrict TargetParticles,
+                     ContainerClass* const NeighborSourceParticles[27]){
+        FP2P::FullMutual(TargetParticles,NeighborSourceParticles,14);
+    }
 };
 
 
@@ -260,49 +154,11 @@ struct DirectInteactionComputer<ONE_OVER_R>
 template <>
 struct DirectInteactionComputer<LEONARD_JONES_POTENTIAL>
 {
-	template <typename ParticleClass>
-	static void compute(ParticleClass& Target, const ParticleClass& Source) // 39 overall flops
-	{
-		FPoint xy(Source.getPosition() - Target.getPosition()); // 3 flops
-		const FReal one_over_r = FReal(1.) / FMath::Sqrt(xy.getX()*xy.getX() +
-																										 xy.getY()*xy.getY() +
-																										 xy.getZ()*xy.getZ()); // 1 + 15 + 5 = 21 flops
-		const FReal wt = Target.getPhysicalValue();
-		const FReal ws = Source.getPhysicalValue();
-
-		// lenard-jones potential
-		const FReal one_over_r3 = one_over_r * one_over_r * one_over_r;
-		const FReal one_over_r6 = one_over_r3 * one_over_r3;
-		Target.incPotential((one_over_r6*one_over_r6 - one_over_r6) * ws); // 2 flops
-
-		// force
-		const FReal one_over_r4 = one_over_r3 * one_over_r; // 1 flop
-		xy *= ((ws*wt) * (FReal(12.)*one_over_r6*one_over_r4*one_over_r4 - FReal(6.)*one_over_r4*one_over_r4)); // 9 flops
-		Target.incForces(xy.getX(), xy.getY(), xy.getZ()); // 3 flops
-	}
-
-	template <typename ParticleClass>
-	static void computeMutual(ParticleClass& Target, ParticleClass& Source) // 44 overall flops
-	{
-		FPoint xy(Source.getPosition() - Target.getPosition()); // 3 flops
-		const FReal one_over_r = FReal(1.) / FMath::Sqrt(xy.getX()*xy.getX() +
-																										 xy.getY()*xy.getY() +
-																										 xy.getZ()*xy.getZ()); // 1 + 15 + 5 = 21 flops
-		const FReal wt = Target.getPhysicalValue();
-		const FReal ws = Source.getPhysicalValue();
-
-		// lenard-jones potential
-		const FReal one_over_r3 = one_over_r * one_over_r * one_over_r;
-		const FReal one_over_r6 = one_over_r3 * one_over_r3;
-		Target.incPotential((one_over_r6*one_over_r6 - one_over_r6) * ws); // 2 flops
-		Source.incPotential((one_over_r6*one_over_r6 - one_over_r6) * wt); // 2 flops
-
-		// force
-		const FReal one_over_r4 = one_over_r3 * one_over_r; // 1 flop
-		xy *= ((ws*wt) * (FReal(12.)*one_over_r6*one_over_r4*one_over_r4 - FReal(6.)*one_over_r4*one_over_r4)); // 9 flops
-		Target.incForces(  xy.getX(),    xy.getY(),    xy.getZ());  // 3 flops 
-		Source.incForces((-xy.getX()), (-xy.getY()), (-xy.getZ())); // 3 flops
-	}
+    template <typename ContainerClass>
+    static void P2P(		 ContainerClass* const FRestrict TargetParticles,
+                     ContainerClass* const NeighborSourceParticles[27]){
+        FP2P::FullMutualLJ(TargetParticles,NeighborSourceParticles,14);
+    }
 };
 
 
diff --git a/Src/Kernels/Chebyshev/FChebFlopsSymKernel.hpp b/Src/Kernels/Chebyshev/FChebFlopsSymKernel.hpp
index 51728d129..58dc8d545 100755
--- a/Src/Kernels/Chebyshev/FChebFlopsSymKernel.hpp
+++ b/Src/Kernels/Chebyshev/FChebFlopsSymKernel.hpp
@@ -16,6 +16,8 @@
 #ifndef FCHEBFLOPSSYMKERNEL_HPP
 #define FCHEBFLOPSSYMKERNEL_HPP
 
+#include <stdexcept>
+
 #include "../../Utils/FGlobal.hpp"
 #include "../../Utils/FTrace.hpp"
 #include "../../Utils/FSmartPointer.hpp"
@@ -40,15 +42,14 @@ class FTreeCoordinate;
  * (P2P, P2M, M2M, M2L, L2L, L2P) which are required by the FFmmAlgorithm and
  * FFmmAlgorithmThread.
  *
- * @tparam ParticleClass Type of particle
  * @tparam CellClass Type of cell
  * @tparam ContainerClass Type of container to store particles
  * @tparam MatrixKernelClass Type of matrix kernel function
  * @tparam ORDER Chebyshev interpolation order
  */
-template <class ParticleClass, class CellClass,	class ContainerClass, class MatrixKernelClass, int ORDER>
+template < class CellClass,	class ContainerClass, class MatrixKernelClass, int ORDER>
 class FChebFlopsSymKernel
-	: public FAbstractKernels<ParticleClass, CellClass, ContainerClass>
+    : public FAbstractKernels<CellClass, ContainerClass>
 {
   enum {nnodes = TensorTraits<ORDER>::nnodes};
 public:
@@ -176,7 +177,7 @@ public:
 	
 	void P2M(CellClass* const /* not needed */, const ContainerClass* const SourceParticles)
 	{
-		flopsP2M += countFlopsP2M(SourceParticles->getSize());
+        flopsP2M += countFlopsP2M(SourceParticles->getNbParticles());
 	}
 
 
@@ -231,14 +232,14 @@ public:
 					 ContainerClass* const TargetParticles)
 	{
 		//// 1.a) apply Sx
-		//flopsL2P += countFlopsP2MorL2P(TargetParticlesParticles->getSize()) + TargetParticles->getSize();
+        //flopsL2P += countFlopsP2MorL2P(TargetParticlesParticles->getNbParticles()) + TargetParticles->getNbParticles();
 		//// 1.b) apply Px (grad Sx)
-		//flopsL2P += countFlopsL2PGradient(TargetParticlesParticles->getSize()) + 3 * TargetParticles->getSize();
+        //flopsL2P += countFlopsL2PGradient(TargetParticlesParticles->getNbParticles()) + 3 * TargetParticles->getNbParticles();
 
 		// or
 
 		// 2) apply Sx and Px (grad Sx)
-		flopsL2P += countFlopsL2PTotal(TargetParticles->getSize()) + 4 * TargetParticles->getSize();
+        flopsL2P += countFlopsL2PTotal(TargetParticles->getNbParticles()) + 4 * TargetParticles->getNbParticles();
 	}
 
 
@@ -250,15 +251,15 @@ public:
 					 const int /* size */)
 	{
 		if (TargetParticles != SourceParticles) {
-			flopsP2P += countFlopsP2P() * TargetParticles->getSize() * SourceParticles->getSize();
+            flopsP2P += countFlopsP2P() * TargetParticles->getNbParticles() * SourceParticles->getNbParticles();
 			for (unsigned int idx=0; idx<27; ++idx)
 				if (NeighborSourceParticles[idx])
-					flopsP2P += countFlopsP2P() * TargetParticles->getSize() * NeighborSourceParticles[idx]->getSize();
+                    flopsP2P += countFlopsP2P() * TargetParticles->getNbParticles() * NeighborSourceParticles[idx]->getNbParticles();
 		} else {
-			flopsP2P += countFlopsP2Pmutual() * ((TargetParticles->getSize()*TargetParticles->getSize()+TargetParticles->getSize()) / 2); 
+            flopsP2P += countFlopsP2Pmutual() * ((TargetParticles->getNbParticles()*TargetParticles->getNbParticles()+TargetParticles->getNbParticles()) / 2);
 			for (unsigned int idx=0; idx<=13; ++idx)
 				if (NeighborSourceParticles[idx])
-					flopsP2P += countFlopsP2Pmutual() * TargetParticles->getSize() * NeighborSourceParticles[idx]->getSize();
+                    flopsP2P += countFlopsP2Pmutual() * TargetParticles->getNbParticles() * NeighborSourceParticles[idx]->getNbParticles();
 		}
 	}
 
@@ -278,12 +279,11 @@ public:
  * Handler to deal with all symmetries: Stores permutation indices and vectors
  * to reduce 343 different interactions to 16 only.
  */
-template <class ParticleClass,
-					class CellClass,
+template <			class CellClass,
 					class ContainerClass,
 					class MatrixKernelClass,
 					int ORDER>
-struct FChebFlopsSymKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>
+struct FChebFlopsSymKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER>
 ::SymmetryHandler
 {
 	// M2L operators
@@ -307,7 +307,7 @@ struct FChebFlopsSymKernel<ParticleClass, CellClass, ContainerClass, MatrixKerne
 			nrm2k += singular_values[k-1] * singular_values[k-1];
 			if (nrm2k > eps*eps * nrm2)	return k;
 		}
-		throw std::runtime_error("rank cannot be larger than nnodes");
+        throw std::runtime_error("rank cannot be larger than nnodes");
 		return 0;
 	}
 	
diff --git a/Src/Kernels/Chebyshev/FChebInterpolator.hpp b/Src/Kernels/Chebyshev/FChebInterpolator.hpp
index f2fdda49b..0284f2519 100755
--- a/Src/Kernels/Chebyshev/FChebInterpolator.hpp
+++ b/Src/Kernels/Chebyshev/FChebInterpolator.hpp
@@ -567,9 +567,9 @@ public:
 template <int ORDER>
 template <class ContainerClass>
 inline void FChebInterpolator<ORDER>::applyP2M(const FPoint& center,
-																							 const FReal width,
-																							 FReal *const multipoleExpansion,
-																							 const ContainerClass *const sourceParticles) const
+                                             const FReal width,
+                                             FReal *const multipoleExpansion,
+                                             const ContainerClass *const inParticles) const
 {
 	// set all multipole expansions to zero
 	FBlas::setzero(nnodes, multipoleExpansion);
@@ -587,11 +587,13 @@ inline void FChebInterpolator<ORDER>::applyP2M(const FPoint& center,
 	for(unsigned int i=0; i<(ORDER-1)*(ORDER-1)*(ORDER-1); ++i)	W8[i] = FReal(0.);
 	
 	// loop over source particles
-	typename ContainerClass::ConstBasicIterator iter(*sourceParticles);
-	while(iter.hasNotFinished()){
-		
+    const FReal*const physicalValues = inParticles->getPhysicalValues();
+    const FReal*const positionsX = inParticles->getPositions()[0];
+    const FReal*const positionsY = inParticles->getPositions()[1];
+    const FReal*const positionsZ = inParticles->getPositions()[2];
+    for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++idxPart){
 		// map global position to [-1,1]
-		map(iter.data().getPosition(), localPosition); // 15 flops
+        map(FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]), localPosition); // 15 flops
 		
 		FReal T_of_x[3][ORDER];
 		T_of_x[0][0] = FReal(1.); T_of_x[0][1] = localPosition.getX();
@@ -606,7 +608,7 @@ inline void FChebInterpolator<ORDER>::applyP2M(const FPoint& center,
 			T_of_x[2][j] = z2 * T_of_x[2][j-1] - T_of_x[2][j-2]; // 2 flops
 		}
 		
-		const FReal weight = iter.data().getPhysicalValue();
+        const FReal weight = physicalValues[idxPart];
 		W1 += weight; // 1 flop
 		for (unsigned int i=1; i<ORDER; ++i) {
 			const FReal wx = weight * T_of_x[0][i]; // 1 flop
@@ -628,10 +630,7 @@ inline void FChebInterpolator<ORDER>::applyP2M(const FPoint& center,
 				} // flops: (ORDER-1) * 2
 			} // flops: (ORDER-1) * (6 + (ORDER-1) * 2) 
 		} // flops: (ORDER-1) * (6 + (ORDER-1) * (6 + (ORDER-1) * 2))
-		
-		
-		// increment source iterator
-		iter.gotoNext();
+
 	} // flops: N * (18 + (ORDER-2) * 6 + (ORDER-1) * (6 + (ORDER-1) * (6 + (ORDER-1) * 2)))
 
 	////////////////////////////////////////////////////////////////////
@@ -758,9 +757,9 @@ inline void FChebInterpolator<ORDER>::applyP2M(const FPoint& center,
 template <int ORDER>
 template <class ContainerClass>
 inline void FChebInterpolator<ORDER>::applyL2P(const FPoint& center,
-																							 const FReal width,
-																							 const FReal *const localExpansion,
-																							 ContainerClass *const localParticles) const
+                                             const FReal width,
+                                             const FReal *const localExpansion,
+                                             ContainerClass *const inParticles) const
 {
 	FReal f1;
 	FReal W2[3][ ORDER-1];
@@ -807,11 +806,20 @@ inline void FChebInterpolator<ORDER>::applyL2P(const FPoint& center,
 	// loop over particles
 	const map_glob_loc map(center, width);
 	FPoint localPosition;
-	typename ContainerClass::BasicIterator iter(*localParticles);
-	while(iter.hasNotFinished()){
+
+    //const FReal*const physicalValues = inParticles->getPhysicalValues();
+    const FReal*const positionsX = inParticles->getPositions()[0];
+    const FReal*const positionsY = inParticles->getPositions()[1];
+    const FReal*const positionsZ = inParticles->getPositions()[2];
+    //FReal*const forcesX = inParticles->getForcesX();
+    //FReal*const forcesY = inParticles->getForcesY();
+    //FReal*const forcesZ = inParticles->getForcesZ();
+    FReal*const potentials = inParticles->getPotentials();
+
+    for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++ idxPart){
 			
 		// map global position to [-1,1]
-		map(iter.data().getPosition(), localPosition); // 15 flops
+        map(FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]), localPosition); // 15 flops
 
 		FReal T_of_x[3][ORDER];
 		{
@@ -829,7 +837,7 @@ inline void FChebInterpolator<ORDER>::applyL2P(const FPoint& center,
 		}
 
 		// interpolate and increment target value
-		FReal targetValue = iter.data().getPotential();
+        FReal targetValue = potentials[idxPart];
 		{
 			FReal f2, f4, f8;
 			{
@@ -856,10 +864,7 @@ inline void FChebInterpolator<ORDER>::applyL2P(const FPoint& center,
 		} // 7 + ORDER * (ORDER * (9 + ORDER * 4)) flops
 
 		// set potential
-		iter.data().setPotential(targetValue);
-
-		// increment target iterator
-		iter.gotoNext();
+        potentials[idxPart] += (targetValue);
 	} // N * (7 + ORDER * (ORDER * (9 + ORDER * 4))) flops
 }
 
@@ -959,9 +964,9 @@ inline void FChebInterpolator<ORDER>::applyL2P(const FPoint& center,
 template <int ORDER>
 template <class ContainerClass>
 inline void FChebInterpolator<ORDER>::applyL2PGradient(const FPoint& center,
-																											 const FReal width,
-																											 const FReal *const localExpansion,
-																											 ContainerClass *const localParticles) const
+                                                     const FReal width,
+                                                     const FReal *const localExpansion,
+                                                     ContainerClass *const inParticles) const
 {
 	////////////////////////////////////////////////////////////////////
 	// TENSOR-PRODUCT INTERPOLUTION NOT IMPLEMENTED YET HERE!!! ////////
@@ -977,11 +982,19 @@ inline void FChebInterpolator<ORDER>::applyL2PGradient(const FPoint& center,
 	FReal U_of_x[ORDER][3];
 	FReal P[3];
 
-	typename ContainerClass::BasicIterator iter(*localParticles);
-	while(iter.hasNotFinished()){
+    const FReal*const physicalValues = inParticles->getPhysicalValues();
+    const FReal*const positionsX = inParticles->getPositions()[0];
+    const FReal*const positionsY = inParticles->getPositions()[1];
+    const FReal*const positionsZ = inParticles->getPositions()[2];
+    FReal*const forcesX = inParticles->getForcesX();
+    FReal*const forcesY = inParticles->getForcesY();
+    FReal*const forcesZ = inParticles->getForcesZ();
+    //FReal*const potentials = inParticles->getPotentials();
+
+    for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++ idxPart){
 			
 		// map global position to [-1,1]
-		map(iter.data().getPosition(), localPosition);
+        map(FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]), localPosition);
 			
 		// evaluate chebyshev polynomials of source particle
 		// T_0(x_i) and T_1(x_i)
@@ -1066,12 +1079,9 @@ inline void FChebInterpolator<ORDER>::applyL2PGradient(const FPoint& center,
 		forces[2] *= jacobian[2] / nnodes;
 
 		// set computed forces
-		iter.data().incForces(forces[0] * iter.data().getPhysicalValue(),
-													forces[1] * iter.data().getPhysicalValue(),
-													forces[2] * iter.data().getPhysicalValue());
-
-		// increment iterator
-		iter.gotoNext();
+        forcesX[idxPart] += forces[0] * physicalValues[idxPart];
+        forcesY[idxPart] += forces[1] * physicalValues[idxPart];
+        forcesZ[idxPart] += forces[2] * physicalValues[idxPart];
 	}
 }
 
@@ -1083,9 +1093,9 @@ inline void FChebInterpolator<ORDER>::applyL2PGradient(const FPoint& center,
 template <int ORDER>
 template <class ContainerClass>
 inline void FChebInterpolator<ORDER>::applyL2PTotal(const FPoint& center,
-																										const FReal width,
-																										const FReal *const localExpansion,
-																										ContainerClass *const localParticles) const
+                                                    const FReal width,
+                                                    const FReal *const localExpansion,
+                                                    ContainerClass *const inParticles) const
 {
 	FReal f1;
 	FReal W2[3][ ORDER-1];
@@ -1196,11 +1206,19 @@ inline void FChebInterpolator<ORDER>::applyL2PTotal(const FPoint& center,
 	const FReal jacobian[3] = {Jacobian.getX(), Jacobian.getY(), Jacobian.getZ()}; 
 	FPoint localPosition;
 
-	typename ContainerClass::BasicIterator iter(*localParticles);
-	while(iter.hasNotFinished()){
+    const FReal*const physicalValues = inParticles->getPhysicalValues();
+    const FReal*const positionsX = inParticles->getPositions()[0];
+    const FReal*const positionsY = inParticles->getPositions()[1];
+    const FReal*const positionsZ = inParticles->getPositions()[2];
+    FReal*const forcesX = inParticles->getForcesX();
+    FReal*const forcesY = inParticles->getForcesY();
+    FReal*const forcesZ = inParticles->getForcesZ();
+    FReal*const potentials = inParticles->getPotentials();
+
+    for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++ idxPart){
 			
 		// map global position to [-1,1]
-		map(iter.data().getPosition(), localPosition); // 15 flops
+        map(FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]), localPosition); // 15 flops
 
 		FReal U_of_x[3][ORDER];
 		FReal T_of_x[3][ORDER];
@@ -1270,15 +1288,13 @@ inline void FChebInterpolator<ORDER>::applyL2PTotal(const FPoint& center,
 		} // 28 + (ORDER-1) * ((ORDER-1) * (27 + (ORDER-1) * 16)) flops
 
 		// set computed potential
-		iter.data().incPotential(potential); // 1 flop
+        potentials[idxPart] += (potential); // 1 flop
 
 		// set computed forces
-		iter.data().incForces(forces[0] * iter.data().getPhysicalValue(),
-													forces[1] * iter.data().getPhysicalValue(),
-													forces[2] * iter.data().getPhysicalValue()); // 6 flops
+        forcesX[idxPart] += forces[0] * physicalValues[idxPart];
+        forcesY[idxPart] += forces[1] * physicalValues[idxPart];
+        forcesZ[idxPart] += forces[2] * physicalValues[idxPart]; // 6 flops
 
-		// increment target iterator
-		iter.gotoNext();
 	} // N * (38 + (ORDER-2)*15 + (ORDER-1)*((ORDER-1) * (27 + (ORDER-1) * 16))) + 6 flops
 }
 
diff --git a/Src/Kernels/Chebyshev/FChebKernel.hpp b/Src/Kernels/Chebyshev/FChebKernel.hpp
index 9e38bbbaa..62a984600 100755
--- a/Src/Kernels/Chebyshev/FChebKernel.hpp
+++ b/Src/Kernels/Chebyshev/FChebKernel.hpp
@@ -35,21 +35,20 @@ class FTreeCoordinate;
  * implements all interfaces (P2P, P2M, M2M, M2L, L2L, L2P) which are required by
  * the FFmmAlgorithm and FFmmAlgorithmThread.
  *
- * @tparam ParticleClass Type of particle
  * @tparam CellClass Type of cell
  * @tparam ContainerClass Type of container to store particles
  * @tparam MatrixKernelClass Type of matrix kernel function
  * @tparam ORDER Chebyshev interpolation order
  */
-template <class ParticleClass, class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
+template < class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
 class FChebKernel
-	: public FAbstractChebKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>
+    : public FAbstractChebKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER>
 {
 	// private types
 	typedef FChebM2LHandler<ORDER,MatrixKernelClass> M2LHandlerClass;
 
 	// using from 
-	typedef FAbstractChebKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>
+    typedef FAbstractChebKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER>
 	AbstractBaseClass;
 
 	/// Needed for M2L operator
@@ -65,7 +64,7 @@ public:
 							const FPoint& inBoxCenter,
 							const FReal inBoxWidth,
 							const FReal Epsilon)
-		: FAbstractChebKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>(inTreeHeight,
+        : FAbstractChebKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER>(inTreeHeight,
 																																															inBoxCenter,
 																																															inBoxWidth),
 			M2LHandler(new M2LHandlerClass(Epsilon))
diff --git a/Src/Kernels/Chebyshev/FChebParticle.hpp b/Src/Kernels/Chebyshev/FChebParticle.hpp
deleted file mode 100755
index 7bf207b16..000000000
--- a/Src/Kernels/Chebyshev/FChebParticle.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FCHEBPARTICLE_HPP
-#define FCHEBPARTICLE_HPP
-
-#include <stdexcept>
-#include <cassert>
-
-#include "../../Extensions/FExtendPosition.hpp"
-#include "../../Extensions/FExtendPhysicalValue.hpp"
-#include "../../Extensions/FExtendPotential.hpp"
-#include "../../Extensions/FExtendForces.hpp"
-
-/**
- * @author Matthias Messner (matthias.matthias@inria.fr)
- * @class FChebParticle
- * Please read the license
- *
- * The class @p FChebParticle defines the particle used for the Chebyshev FMM
- * approach.
- */
-class FChebParticle : public FExtendPosition,
-											public FExtendPhysicalValue,
-											public FExtendPotential,
-											public FExtendForces
-{
-public:
-	~FChebParticle() {}
-};
-
-
-#endif
diff --git a/Src/Kernels/Chebyshev/FChebSymKernel.hpp b/Src/Kernels/Chebyshev/FChebSymKernel.hpp
index 79fbb18db..5a63badea 100755
--- a/Src/Kernels/Chebyshev/FChebSymKernel.hpp
+++ b/Src/Kernels/Chebyshev/FChebSymKernel.hpp
@@ -45,17 +45,16 @@ class FTreeCoordinate;
  * (P2P, P2M, M2M, M2L, L2L, L2P) which are required by the FFmmAlgorithm and
  * FFmmAlgorithmThread.
  *
- * @tparam ParticleClass Type of particle
  * @tparam CellClass Type of cell
  * @tparam ContainerClass Type of container to store particles
  * @tparam MatrixKernelClass Type of matrix kernel function
  * @tparam ORDER Chebyshev interpolation order
  */
-template <class ParticleClass, class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
+template < class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER>
 class FChebSymKernel
-	: public FAbstractChebKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>
+    : public FAbstractChebKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER>
 {
-	typedef FAbstractChebKernel<ParticleClass, CellClass, ContainerClass, MatrixKernelClass, ORDER>	AbstractBaseClass;
+    typedef FAbstractChebKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER>	AbstractBaseClass;
 	typedef SymmetryHandler<ORDER, MatrixKernelClass::Type> SymmetryHandlerClass;
   enum {nnodes = AbstractBaseClass::nnodes};
 
diff --git a/Src/Kernels/P2P/FP2P.hpp b/Src/Kernels/P2P/FP2P.hpp
new file mode 100644
index 000000000..59f6bb38b
--- /dev/null
+++ b/Src/Kernels/P2P/FP2P.hpp
@@ -0,0 +1,469 @@
+#ifndef FP2P_HPP
+#define FP2P_HPP
+
+#include "../../Utils/FGlobal.hpp"
+
+/**
+ * @brief The FP2P class
+ */
+class FP2P {
+public:
+    /**
+     *
+     */
+    template <class ContainerClass>
+    static void FullMutual(ContainerClass* const FRestrict inTargets, ContainerClass* const inNeighbors[],
+                    const int limiteNeighbors){
+
+        const int nbParticlesTargets = inTargets->getNbParticles();
+        const FReal*const targetsPhysicalValues = inTargets->getPhysicalValues();
+        const FReal*const targetsX = inTargets->getPositions()[0];
+        const FReal*const targetsY = inTargets->getPositions()[1];
+        const FReal*const targetsZ = inTargets->getPositions()[2];
+        FReal*const targetsForcesX = inTargets->getForcesX();
+        FReal*const targetsForcesY = inTargets->getForcesY();
+        FReal*const targetsForcesZ = inTargets->getForcesZ();
+        FReal*const targetsPotentials = inTargets->getPotentials();
+
+        for(int idxNeighbors = 0 ; idxNeighbors < limiteNeighbors ; ++idxNeighbors){
+            for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+                if( inNeighbors[idxNeighbors] ){
+                    const int nbParticlesSources = inNeighbors[idxNeighbors]->getNbParticles();
+                    const FReal*const sourcesPhysicalValues = inNeighbors[idxNeighbors]->getPhysicalValues();
+                    const FReal*const sourcesX = inNeighbors[idxNeighbors]->getPositions()[0];
+                    const FReal*const sourcesY = inNeighbors[idxNeighbors]->getPositions()[1];
+                    const FReal*const sourcesZ = inNeighbors[idxNeighbors]->getPositions()[2];
+                    FReal*const sourcesForcesX = inNeighbors[idxNeighbors]->getForcesX();
+                    FReal*const sourcesForcesY = inNeighbors[idxNeighbors]->getForcesY();
+                    FReal*const sourcesForcesZ = inNeighbors[idxNeighbors]->getForcesZ();
+                    FReal*const sourcesPotentials = inNeighbors[idxNeighbors]->getPotentials();
+
+                    for(int idxSource = 0 ; idxSource < nbParticlesSources ; ++idxSource){
+                        double dx = sourcesX[idxSource] - targetsX[idxTarget];
+                        double dy = sourcesY[idxSource] - targetsY[idxTarget];
+                        double dz = sourcesZ[idxSource] - targetsZ[idxTarget];
+
+                        double inv_square_distance = 1.0 / (dx*dx + dy*dy + dz*dz);
+                        const double inv_distance = sqrt(inv_square_distance);
+
+                        inv_square_distance *= inv_distance;
+                        inv_square_distance *= targetsPhysicalValues[idxTarget] * sourcesPhysicalValues[idxSource];
+
+                        dx *= inv_square_distance;
+                        dy *= inv_square_distance;
+                        dz *= inv_square_distance;
+
+                        targetsForcesX[idxTarget] += dx;
+                        targetsForcesY[idxTarget] += dy;
+                        targetsForcesZ[idxTarget] += dz;
+                        targetsPotentials[idxTarget] += inv_distance * sourcesPhysicalValues[idxSource];
+
+                        sourcesForcesX[idxSource] -= dx;
+                        sourcesForcesY[idxSource] -= dy;
+                        sourcesForcesZ[idxSource] -= dz;
+                        sourcesPotentials[idxSource] += inv_distance * targetsPhysicalValues[idxTarget];
+                    }
+                }
+            }
+        }
+
+        for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+            for(int idxSource = idxTarget + 1 ; idxSource < nbParticlesTargets ; ++idxSource){
+                double dx = targetsX[idxSource] - targetsX[idxTarget];
+                double dy = targetsY[idxSource] - targetsY[idxTarget];
+                double dz = targetsZ[idxSource] - targetsZ[idxTarget];
+
+                double inv_square_distance = 1.0 / (dx*dx + dy*dy + dz*dz);
+                const double inv_distance = sqrt(inv_square_distance);
+
+                inv_square_distance *= inv_distance;
+                inv_square_distance *= targetsPhysicalValues[idxTarget] * targetsPhysicalValues[idxSource];
+
+                dx *= inv_square_distance;
+                dy *= inv_square_distance;
+                dz *= inv_square_distance;
+
+                targetsForcesX[idxTarget] += dx;
+                targetsForcesY[idxTarget] += dy;
+                targetsForcesZ[idxTarget] += dz;
+                targetsPotentials[idxTarget] += inv_distance * targetsPhysicalValues[idxSource];
+
+                targetsForcesX[idxSource] -= dx;
+                targetsForcesY[idxSource] -= dy;
+                targetsForcesZ[idxSource] -= dz;
+                targetsPotentials[idxSource] += inv_distance * targetsPhysicalValues[idxTarget];
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    template <class ContainerClass>
+    static void FullRemote(ContainerClass* const FRestrict inTargets, ContainerClass* const inNeighbors[],
+                    const int limiteNeighbors){
+        const int nbParticlesTargets = inTargets->getNbParticles();
+        const FReal*const targetsPhysicalValues = inTargets->getPhysicalValues();
+        const FReal*const targetsX = inTargets->getPositions()[0];
+        const FReal*const targetsY = inTargets->getPositions()[1];
+        const FReal*const targetsZ = inTargets->getPositions()[2];
+        FReal*const targetsForcesX = inTargets->getForcesX();
+        FReal*const targetsForcesY = inTargets->getForcesY();
+        FReal*const targetsForcesZ = inTargets->getForcesZ();
+        FReal*const targetsPotentials = inTargets->getPotentials();
+
+        for(int idxNeighbors = 0 ; idxNeighbors < limiteNeighbors ; ++idxNeighbors){
+            for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+                if( inNeighbors[idxNeighbors] ){
+                    const int nbParticlesSources = inNeighbors[idxNeighbors]->getNbParticles();
+                    const FReal*const sourcesPhysicalValues = inNeighbors[idxNeighbors]->getPhysicalValues();
+                    const FReal*const sourcesX = inNeighbors[idxNeighbors]->getPositions()[0];
+                    const FReal*const sourcesY = inNeighbors[idxNeighbors]->getPositions()[1];
+                    const FReal*const sourcesZ = inNeighbors[idxNeighbors]->getPositions()[2];
+
+                    for(int idxSource = 0 ; idxSource < nbParticlesSources ; ++idxSource){
+                        double dx = sourcesX[idxSource] - targetsX[idxTarget];
+                        double dy = sourcesY[idxSource] - targetsY[idxTarget];
+                        double dz = sourcesZ[idxSource] - targetsZ[idxTarget];
+
+                        double inv_square_distance = 1.0 / (dx*dx + dy*dy + dz*dz);
+                        const double inv_distance = sqrt(inv_square_distance);
+
+                        inv_square_distance *= inv_distance;
+                        inv_square_distance *= targetsPhysicalValues[idxTarget] * sourcesPhysicalValues[idxSource];
+
+                        dx *= inv_square_distance;
+                        dy *= inv_square_distance;
+                        dz *= inv_square_distance;
+
+                        targetsForcesX[idxTarget] += dx;
+                        targetsForcesY[idxTarget] += dy;
+                        targetsForcesZ[idxTarget] += dz;
+                        targetsPotentials[idxTarget] += inv_distance * sourcesPhysicalValues[idxSource];
+                    }
+                }
+            }
+        }
+    }
+
+    /** P2P mutual interaction,
+      * this function computes the interaction for 2 particles.
+      *
+      * Formulas are:
+      * \f[
+      * F = q_1 * q_2 / r^2
+      * P_1 = q_2 / r ; P_2 = q_1 / r
+      * \f]
+      * In details :
+      * \f$ F(x) = \frac{ \Delta_x * q_1 * q_2 }{ r^2 } = \Delta_x * F \f$
+      */
+    static void MutualParticles(const FReal sourceX,const FReal sourceY,const FReal sourceZ, const FReal sourcePhysicalValue,
+                         FReal* sourceForceX, FReal* sourceForceY, FReal* sourceForceZ, FReal* sourcePotential,
+                         const FReal targetX,const FReal targetY,const FReal targetZ, const FReal targetPhysicalValue,
+                         FReal* targetForceX, FReal* targetForceY, FReal* targetForceZ, FReal* targetPotential
+                         ){
+        FReal dx = sourceX - targetX;
+        FReal dy = sourceY - targetY;
+        FReal dz = sourceZ - targetZ;
+
+        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+        FReal inv_distance = FMath::Sqrt(inv_square_distance);
+
+        inv_square_distance *= inv_distance;
+        inv_square_distance *= targetPhysicalValue * sourcePhysicalValue;
+
+        dx *= inv_square_distance;
+        dy *= inv_square_distance;
+        dz *= inv_square_distance;
+
+        *targetForceX += dx;
+        *targetForceY += dy;
+        *targetForceZ += dz;
+        *targetPotential += ( inv_distance * sourcePhysicalValue );
+
+        *sourceForceX -= dx;
+        *sourceForceY -= dy;
+        *sourceForceZ -= dz;
+        *sourcePotential += ( inv_distance * targetPhysicalValue );
+    }
+
+    /** P2P mutual interaction,
+      * this function computes the interaction for 2 particles.
+      *
+      * Formulas are:
+      * \f[
+      * F = q_1 * q_2 / r^2
+      * P_1 = q_2 / r ; P_2 = q_1 / r
+      * \f]
+      * In details :
+      * \f$ F(x) = \frac{ \Delta_x * q_1 * q_2 }{ r^2 } = \Delta_x * F \f$
+      */
+    static void NonMutualParticles(const FReal sourceX,const FReal sourceY,const FReal sourceZ, const FReal sourcePhysicalValue,
+                            const FReal targetX,const FReal targetY,const FReal targetZ, const FReal targetPhysicalValue,
+                            FReal* targetForceX, FReal* targetForceY, FReal* targetForceZ, FReal* targetPotential){
+        FReal dx = sourceX - targetX;
+        FReal dy = sourceY - targetY;
+        FReal dz = sourceZ - targetZ;
+
+        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+        FReal inv_distance = FMath::Sqrt(inv_square_distance);
+
+        inv_square_distance *= inv_distance;
+        inv_square_distance *= targetPhysicalValue * sourcePhysicalValue;
+
+        dx *= inv_square_distance;
+        dy *= inv_square_distance;
+        dz *= inv_square_distance;
+
+        *targetForceX += dx;
+        *targetForceY += dy;
+        *targetForceZ += dz;
+        *targetPotential += ( inv_distance * sourcePhysicalValue );
+    }
+
+    template <class ContainerClass>
+    static void FullMutualLJ(ContainerClass* const FRestrict inTargets, ContainerClass* const inNeighbors[],
+                    const int limiteNeighbors){
+
+        const int nbParticlesTargets = inTargets->getNbParticles();
+        const FReal*const targetsPhysicalValues = inTargets->getPhysicalValues();
+        const FReal*const targetsX = inTargets->getPositions()[0];
+        const FReal*const targetsY = inTargets->getPositions()[1];
+        const FReal*const targetsZ = inTargets->getPositions()[2];
+        FReal*const targetsForcesX = inTargets->getForcesX();
+        FReal*const targetsForcesY = inTargets->getForcesY();
+        FReal*const targetsForcesZ = inTargets->getForcesZ();
+        FReal*const targetsPotentials = inTargets->getPotentials();
+
+        for(int idxNeighbors = 0 ; idxNeighbors < limiteNeighbors ; ++idxNeighbors){
+            for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+                if( inNeighbors[idxNeighbors] ){
+                    const int nbParticlesSources = inNeighbors[idxNeighbors]->getNbParticles();
+                    const FReal*const sourcesPhysicalValues = inNeighbors[idxNeighbors]->getPhysicalValues();
+                    const FReal*const sourcesX = inNeighbors[idxNeighbors]->getPositions()[0];
+                    const FReal*const sourcesY = inNeighbors[idxNeighbors]->getPositions()[1];
+                    const FReal*const sourcesZ = inNeighbors[idxNeighbors]->getPositions()[2];
+                    FReal*const sourcesForcesX = inNeighbors[idxNeighbors]->getForcesX();
+                    FReal*const sourcesForcesY = inNeighbors[idxNeighbors]->getForcesY();
+                    FReal*const sourcesForcesZ = inNeighbors[idxNeighbors]->getForcesZ();
+                    FReal*const sourcesPotentials = inNeighbors[idxNeighbors]->getPotentials();
+
+                    for(int idxSource = 0 ; idxSource < nbParticlesSources ; ++idxSource){
+                        FReal dx = sourcesX[idxSource] - targetsX[idxTarget];
+                        FReal dy = sourcesY[idxSource] - targetsY[idxTarget];
+                        FReal dz = sourcesZ[idxSource] - targetsZ[idxTarget];
+
+                        FReal inv_distance_pow2 = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+                        FReal inv_distance = FMath::Sqrt(inv_distance_pow2);
+                        FReal inv_distance_pow3 = inv_distance_pow2 * inv_distance;
+                        FReal inv_distance_pow6 = inv_distance_pow3 * inv_distance_pow3;
+                        FReal inv_distance_pow8 = inv_distance_pow6 * inv_distance_pow2;
+
+                        FReal coef = ((targetsPhysicalValues[idxTarget] * sourcesPhysicalValues[idxSource])
+                                      * (FReal(12.0)*inv_distance_pow6*inv_distance_pow8 - FReal(6.0)*inv_distance_pow8));
+                        FReal potentialCoef = (inv_distance_pow6*inv_distance_pow6-inv_distance_pow6);
+
+                        dx *= coef;
+                        dy *= coef;
+                        dz *= coef;
+
+                        targetsForcesX[idxTarget] += dx;
+                        targetsForcesY[idxTarget] += dy;
+                        targetsForcesZ[idxTarget] += dz;
+                        targetsPotentials[idxTarget] += ( potentialCoef * sourcesPhysicalValues[idxSource] );
+
+                        sourcesForcesX[idxSource] -= dx;
+                        sourcesForcesY[idxSource] -= dy;
+                        sourcesForcesZ[idxSource] -= dz;
+                        sourcesPotentials[idxSource] += potentialCoef * targetsPhysicalValues[idxTarget];
+                    }
+                }
+            }
+        }
+
+        for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+            for(int idxSource = idxTarget + 1 ; idxSource < nbParticlesTargets ; ++idxSource){
+                FReal dx = targetsX[idxSource] - targetsX[idxTarget];
+                FReal dy = targetsY[idxSource] - targetsY[idxTarget];
+                FReal dz = targetsZ[idxSource] - targetsZ[idxTarget];
+
+                FReal inv_distance_pow2 = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+                FReal inv_distance = FMath::Sqrt(inv_distance_pow2);
+                FReal inv_distance_pow3 = inv_distance_pow2 * inv_distance;
+                FReal inv_distance_pow6 = inv_distance_pow3 * inv_distance_pow3;
+                FReal inv_distance_pow8 = inv_distance_pow6 * inv_distance_pow2;
+
+                FReal coef = ((targetsPhysicalValues[idxTarget] * targetsPhysicalValues[idxSource])
+                              * (FReal(12.0)*inv_distance_pow6*inv_distance_pow8 - FReal(6.0)*inv_distance_pow8));
+                FReal potentialCoef = (inv_distance_pow6*inv_distance_pow6-inv_distance_pow6);
+
+                dx *= coef;
+                dy *= coef;
+                dz *= coef;
+
+                targetsForcesX[idxTarget] += dx;
+                targetsForcesY[idxTarget] += dy;
+                targetsForcesZ[idxTarget] += dz;
+                targetsPotentials[idxTarget] += ( potentialCoef * targetsPhysicalValues[idxSource] );
+
+                targetsForcesX[idxSource] -= dx;
+                targetsForcesY[idxSource] -= dy;
+                targetsForcesZ[idxSource] -= dz;
+                targetsPotentials[idxSource] += potentialCoef * targetsPhysicalValues[idxTarget];
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    template <class ContainerClass>
+    static void FullRemoteLJ(ContainerClass* const FRestrict inTargets, ContainerClass* const inNeighbors[],
+                    const int limiteNeighbors){
+        const int nbParticlesTargets = inTargets->getNbParticles();
+        const FReal*const targetsPhysicalValues = inTargets->getPhysicalValues();
+        const FReal*const targetsX = inTargets->getPositions()[0];
+        const FReal*const targetsY = inTargets->getPositions()[1];
+        const FReal*const targetsZ = inTargets->getPositions()[2];
+        FReal*const targetsForcesX = inTargets->getForcesX();
+        FReal*const targetsForcesY = inTargets->getForcesY();
+        FReal*const targetsForcesZ = inTargets->getForcesZ();
+        FReal*const targetsPotentials = inTargets->getPotentials();
+
+        for(int idxNeighbors = 0 ; idxNeighbors < limiteNeighbors ; ++idxNeighbors){
+            for(int idxTarget = 0 ; idxTarget < nbParticlesTargets ; ++idxTarget){
+                if( inNeighbors[idxNeighbors] ){
+                    const int nbParticlesSources = inNeighbors[idxNeighbors]->getNbParticles();
+                    const FReal*const sourcesPhysicalValues = inNeighbors[idxNeighbors]->getPhysicalValues();
+                    const FReal*const sourcesX = inNeighbors[idxNeighbors]->getPositions()[0];
+                    const FReal*const sourcesY = inNeighbors[idxNeighbors]->getPositions()[1];
+                    const FReal*const sourcesZ = inNeighbors[idxNeighbors]->getPositions()[2];
+
+                    for(int idxSource = 0 ; idxSource < nbParticlesSources ; ++idxSource){
+                        // lenard-jones potential
+                        FReal dx = sourcesX[idxSource] - targetsX[idxTarget];
+                        FReal dy = sourcesY[idxSource] - targetsY[idxTarget];
+                        FReal dz = sourcesZ[idxSource] - targetsZ[idxTarget];
+
+                        FReal inv_distance_pow2 = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+                        FReal inv_distance = FMath::Sqrt(inv_distance_pow2);
+                        FReal inv_distance_pow3 = inv_distance_pow2 * inv_distance;
+                        FReal inv_distance_pow6 = inv_distance_pow3 * inv_distance_pow3;
+                        FReal inv_distance_pow8 = inv_distance_pow6 * inv_distance_pow2;
+
+                        FReal coef = ((targetsPhysicalValues[idxTarget] * sourcesPhysicalValues[idxSource])
+                                      * (FReal(12.0)*inv_distance_pow6*inv_distance_pow8 - FReal(6.0)*inv_distance_pow8));
+
+                        dx *= coef;
+                        dy *= coef;
+                        dz *= coef;
+
+                        targetsForcesX[idxTarget] += dx;
+                        targetsForcesY[idxTarget] += dy;
+                        targetsForcesZ[idxTarget] += dz;
+                        targetsPotentials[idxTarget] += ( (inv_distance_pow6*inv_distance_pow6-inv_distance_pow6) * sourcesPhysicalValues[idxSource] );
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @brief NonMutualParticlesLJ
+     * @param sourceX
+     * @param sourceY
+     * @param sourceZ
+     * @param sourcePhysicalValue
+     * @param targetX
+     * @param targetY
+     * @param targetZ
+     * @param targetPhysicalValue
+     * @param targetForceX
+     * @param targetForceY
+     * @param targetForceZ
+     * @param targetPotential
+     */
+    static void NonMutualParticlesLJ(const FReal sourceX,const FReal sourceY,const FReal sourceZ, const FReal sourcePhysicalValue,
+                                     const FReal targetX,const FReal targetY,const FReal targetZ, const FReal targetPhysicalValue,
+                                     FReal* targetForceX, FReal* targetForceY, FReal* targetForceZ, FReal* targetPotential){
+        // lenard-jones potential
+        FReal dx = sourceX - targetX;
+        FReal dy = sourceY - targetY;
+        FReal dz = sourceZ - targetZ;
+
+        FReal inv_distance_pow2 = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+        FReal inv_distance = FMath::Sqrt(inv_distance_pow2);
+        FReal inv_distance_pow3 = inv_distance_pow2 * inv_distance;
+        FReal inv_distance_pow6 = inv_distance_pow3 * inv_distance_pow3;
+        FReal inv_distance_pow8 = inv_distance_pow6 * inv_distance_pow2;
+
+        FReal coef = ((targetPhysicalValue * sourcePhysicalValue) * (FReal(12.0)*inv_distance_pow6*inv_distance_pow8
+                                                                     - FReal(6.0)*inv_distance_pow8));
+
+        dx *= coef;
+        dy *= coef;
+        dz *= coef;
+
+        (*targetForceX) += dx;
+        (*targetForceY) += dy;
+        (*targetForceZ) += dz;
+        (*targetPotential) += ( (inv_distance_pow6*inv_distance_pow6-inv_distance_pow6) * sourcePhysicalValue );
+    }
+
+    /**
+     * @brief MutualParticlesLJ
+     * @param sourceX
+     * @param sourceY
+     * @param sourceZ
+     * @param sourcePhysicalValue
+     * @param sourceForceX
+     * @param sourceForceY
+     * @param sourceForceZ
+     * @param sourcePotential
+     * @param targetX
+     * @param targetY
+     * @param targetZ
+     * @param targetPhysicalValue
+     * @param targetForceX
+     * @param targetForceY
+     * @param targetForceZ
+     * @param targetPotential
+     */
+    static void MutualParticlesLJ(const FReal sourceX,const FReal sourceY,const FReal sourceZ, const FReal sourcePhysicalValue,
+                                  FReal* sourceForceX, FReal* sourceForceY, FReal* sourceForceZ, FReal* sourcePotential,
+                                  const FReal targetX,const FReal targetY,const FReal targetZ, const FReal targetPhysicalValue,
+                                  FReal* targetForceX, FReal* targetForceY, FReal* targetForceZ, FReal* targetPotential
+                                  ){
+        // lenard-jones potential
+        FReal dx = sourceX - targetX;
+        FReal dy = sourceY - targetY;
+        FReal dz = sourceZ - targetZ;
+
+        FReal inv_distance_pow2 = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
+        FReal inv_distance = FMath::Sqrt(inv_distance_pow2);
+        FReal inv_distance_pow3 = inv_distance_pow2 * inv_distance;
+        FReal inv_distance_pow6 = inv_distance_pow3 * inv_distance_pow3;
+        FReal inv_distance_pow8 = inv_distance_pow6 * inv_distance_pow2;
+
+        FReal coef = ((targetPhysicalValue * sourcePhysicalValue) * (FReal(12.0)*inv_distance_pow6*inv_distance_pow8
+                                                                     - FReal(6.0)*inv_distance_pow8));
+        FReal potentialCoef = (inv_distance_pow6*inv_distance_pow6-inv_distance_pow6);
+
+        dx *= coef;
+        dy *= coef;
+        dz *= coef;
+
+        (*targetForceX) += dx;
+        (*targetForceY) += dy;
+        (*targetForceZ) += dz;
+        (*targetPotential) += ( potentialCoef * sourcePhysicalValue );
+
+        (*sourceForceX) -= dx;
+        (*sourceForceY) -= dy;
+        (*sourceForceZ) -= dz;
+        (*sourcePotential) += ( potentialCoef * targetPhysicalValue );
+    }
+};
+
+#endif // FP2P_HPP
diff --git a/Src/Kernels/P2P/FP2PParticleContainer.hpp b/Src/Kernels/P2P/FP2PParticleContainer.hpp
new file mode 100644
index 000000000..0c881bbaa
--- /dev/null
+++ b/Src/Kernels/P2P/FP2PParticleContainer.hpp
@@ -0,0 +1,66 @@
+// ===================================================================================
+// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
+// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
+// This software is a computer program whose purpose is to compute the FMM.
+//
+// This software is governed by the CeCILL-C and LGPL licenses and
+// abiding by the rules of distribution of free software.
+//
+// This program 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 and CeCILL-C Licenses for more details.
+// "http://www.cecill.info".
+// "http://www.gnu.org/licenses".
+// ===================================================================================
+#ifndef FP2PPARTICLECONTAINER_HPP
+#define FP2PPARTICLECONTAINER_HPP
+
+#include "../../Components/FBasicParticleContainer.hpp"
+
+class FP2PParticleContainer : public FBasicParticleContainer<5> {
+    typedef FBasicParticleContainer<5> Parent;
+
+public:
+    FReal* getPhysicalValues(){
+        return Parent::getAttribute<0>();
+    }
+
+    const FReal* getPhysicalValues() const {
+        return Parent::getAttribute<0>();
+    }
+
+    FReal* getPotentials(){
+        return Parent::getAttribute<1>();
+    }
+
+    const FReal* getPotentials() const {
+        return Parent::getAttribute<1>();
+    }
+
+    FReal* getForcesX(){
+        return Parent::getAttribute<2>();
+    }
+
+    const FReal* getForcesX() const {
+        return Parent::getAttribute<2>();
+    }
+
+    FReal* getForcesY(){
+        return Parent::getAttribute<3>();
+    }
+
+    const FReal* getForcesY() const {
+        return Parent::getAttribute<3>();
+    }
+
+    FReal* getForcesZ(){
+        return Parent::getAttribute<4>();
+    }
+
+    const FReal* getForcesZ() const {
+        return Parent::getAttribute<4>();
+    }
+};
+
+#endif // FP2PPARTICLECONTAINER_HPP
diff --git a/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp b/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp
new file mode 100644
index 000000000..e379d6589
--- /dev/null
+++ b/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp
@@ -0,0 +1,25 @@
+#ifndef FP2PPARTICLECONTAINERINDEXED_HPP
+#define FP2PPARTICLECONTAINERINDEXED_HPP
+
+#include "../../Containers/FVector.hpp"
+
+#include "FP2PParticleContainer.hpp"
+
+class FP2PParticleContainerIndexed : public FP2PParticleContainer {
+    typedef FP2PParticleContainer Parent;
+
+    FVector<int> indexes;
+
+public:
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, const int index, Args... args){
+        Parent::push(inParticlePosition, args... );
+        indexes.push(index);
+    }
+
+    const FVector<int>& getIndexes() const{
+        return indexes;
+    }
+};
+
+#endif // FP2PPARTICLECONTAINERINDEXED_HPP
diff --git a/Src/Kernels/Rotation/FRotationKernel.hpp b/Src/Kernels/Rotation/FRotationKernel.hpp
index a59b4894f..1e0404491 100755
--- a/Src/Kernels/Rotation/FRotationKernel.hpp
+++ b/Src/Kernels/Rotation/FRotationKernel.hpp
@@ -22,6 +22,7 @@
 #include "../../Utils/FMemUtils.hpp"
 #include "../../Utils/FSpherical.hpp"
 
+#include "../P2P/FP2P.hpp"
 
 /** This is a recursion to get the minimal size of the matrix dlmk
   */
@@ -43,8 +44,8 @@ template<> struct NumberOfValuesInDlmk<0>{
 * Here is the optimizated kernel, please refer to FRotationOriginalKernel
 * to see the non optimized easy to understand kernel.
 */
-template< class ParticleClass, class CellClass, class ContainerClass, int P>
-class FRotationKernel : public FAbstractKernels<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass, int P>
+class FRotationKernel : public FAbstractKernels<CellClass,ContainerClass> {
 
     //< Size of the data array computed using a suite relation
     static const int SizeArray = ((P+2)*(P+1))/2;
@@ -918,14 +919,18 @@ public:
         FReal angles[P+1][2];
 
         // For all particles in the leaf box
-        typename ContainerClass::ConstBasicIterator iterParticle(*inParticles);
-        while( iterParticle.hasNotFinished()){
+        const FReal*const physicalValues = inParticles->getPhysicalValues();
+        const FReal*const positionsX = inParticles->getPositions()[0];
+        const FReal*const positionsY = inParticles->getPositions()[1];
+        const FReal*const positionsZ = inParticles->getPositions()[2];
+
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++ idxPart){
             // P2M
-            const ParticleClass& particle = iterParticle.data();
-            const FSpherical sph(particle.getPosition() - cellPosition);
+            const FPoint position(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
+            const FSpherical sph(position - cellPosition);
 
             // The physical value (charge, mass)
-            const FReal q = particle.getPhysicalValue();
+            const FReal q = physicalValues[idxPart];
             // The distance between the SH and the particle
             const FReal a = sph.getR();
 
@@ -950,9 +955,6 @@ public:
                 }
                 q_aPowL *= a;
             }
-
-            // Goto next particle
-            iterParticle.gotoNext();
         }
     }
 
@@ -1152,11 +1154,19 @@ public:
         const FPoint cellPosition = getLeafCenter(inLocal->getCoordinate());
 
         // For all particles in the leaf box
-        typename ContainerClass::BasicIterator iterParticle(*inParticles);
-        while( iterParticle.hasNotFinished()){
+        const FReal*const physicalValues = inParticles->getPhysicalValues();
+        const FReal*const positionsX = inParticles->getPositions()[0];
+        const FReal*const positionsY = inParticles->getPositions()[1];
+        const FReal*const positionsZ = inParticles->getPositions()[2];
+        FReal*const forcesX = inParticles->getForcesX();
+        FReal*const forcesY = inParticles->getForcesY();
+        FReal*const forcesZ = inParticles->getForcesZ();
+        FReal*const potentials = inParticles->getPotentials();
+
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++ idxPart){
             // L2P
-            ParticleClass& particle = iterParticle.data();
-            const FSpherical sph(particle.getPosition() - cellPosition);
+            const FPoint position(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
+            const FSpherical sph(position - cellPosition);
 
             // The distance between the SH and the particle
             const FReal r = sph.getR();
@@ -1242,7 +1252,7 @@ public:
                 // copy variable from spherical position
                 const FReal cosPhi     = FMath::Cos(sph.getPhi());
                 const FReal sinPhi     = FMath::Sin(sph.getPhi());
-                const FReal physicalValue = particle.getPhysicalValue();
+                const FReal physicalValue = physicalValues[idxPart];
 
                 // compute forces
                 const FReal forceX = (
@@ -1260,7 +1270,9 @@ public:
                         (-sph.getSinTheta()) * FO) * physicalValue;
 
                 // inc particles forces
-                particle.incForces( forceX, forceY, forceZ );
+                forcesX[idxPart] += forceX;
+                forcesY[idxPart] += forceY;
+                forcesZ[idxPart] += forceZ;
             }
             // compute the potential
             {
@@ -1281,10 +1293,8 @@ public:
                     }
                 }
                 // inc potential
-                particle.incPotential(magnitude);
+                potentials[idxPart] += magnitude;
             }
-            // progress
-            iterParticle.gotoNext();
         }
     }
 
@@ -1298,44 +1308,7 @@ public:
     void P2P(const FTreeCoordinate& /*inPosition*/,
                      ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
                      ContainerClass* const inNeighbors[27], const int /*inSize*/){
-
-        {
-            typename ContainerClass::BasicIterator iterTarget(*inTargets);
-            while( iterTarget.hasNotFinished() ){
-                // We copy the target particle to work with a particle in the heap
-                ParticleClass target( iterTarget.data() );
-
-                // For all particles after the current one
-                typename ContainerClass::BasicIterator iterSameBox = iterTarget;
-                iterSameBox.gotoNext();
-                while( iterSameBox.hasNotFinished() ){
-                    particlesMutualInteraction(&target, &iterSameBox.data());
-                    iterSameBox.gotoNext();
-                }
-                // Set data and progress
-                iterTarget.setData(target);
-                iterTarget.gotoNext();
-            }
-        }
-        // For all the neigbors leaves
-        for(int idxDirectNeighbors = 0 ; idxDirectNeighbors <= 13 ; ++idxDirectNeighbors){
-            if( inNeighbors[idxDirectNeighbors] ){
-                // For all particles in current leaf
-                typename ContainerClass::BasicIterator iterTarget(*inTargets);
-                while( iterTarget.hasNotFinished() ){
-                    ParticleClass target( iterTarget.data() );
-                    // For all the particles in the other leaf
-                    typename ContainerClass::BasicIterator iterSource(*inNeighbors[idxDirectNeighbors]);
-                    while( iterSource.hasNotFinished() ){
-                        particlesMutualInteraction(&target, &iterSource.data());
-                        iterSource.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-        }
+        FP2P::FullMutual(inTargets,inNeighbors,14);
     }
 
 
@@ -1343,91 +1316,7 @@ public:
     void P2PRemote(const FTreeCoordinate& /*inPosition*/,
                    ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
                    ContainerClass* const inNeighbors[27], const int /*inSize*/){
-        for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < 27 ; ++idxDirectNeighbors){
-            if( inNeighbors[idxDirectNeighbors] ){
-                // For all particles in current leaf
-                typename ContainerClass::BasicIterator iterTarget(*inTargets);
-                while( iterTarget.hasNotFinished() ){
-                    ParticleClass target( iterTarget.data() );
-                    // For all the particles in the other leaf
-                    typename ContainerClass::BasicIterator iterSource(*inNeighbors[idxDirectNeighbors]);
-                    while( iterSource.hasNotFinished() ){
-                        particlesInteraction(&target, iterSource.data());
-                        iterSource.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-        }
-    }
-
-public:
-    /** P2P mutual interaction,
-      * this function computes the interaction for 2 particles.
-      *
-      * Formulas are:
-      * \f[
-      * F = q_1 * q_2 / r^2
-      * P_1 = q_2 / r ; P_2 = q_1 / r
-      * \f]
-      * In details :
-      * \f$ F(x) = \frac{ \Delta_x * q_1 * q_2 }{ r^2 } = \Delta_x * F \f$
-      */
-    void particlesMutualInteraction(ParticleClass*const FRestrict target, ParticleClass*const FRestrict source) const {
-
-        FReal dx = source->getPosition().getX() - target->getPosition().getX();
-        FReal dy = source->getPosition().getY() - target->getPosition().getY();
-        FReal dz = source->getPosition().getZ() - target->getPosition().getZ();
-
-        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
-        FReal inv_distance = FMath::Sqrt(inv_square_distance);
-
-        inv_square_distance *= inv_distance;
-        inv_square_distance *= target->getPhysicalValue() * source->getPhysicalValue();
-
-        dx *= inv_square_distance;
-        dy *= inv_square_distance;
-        dz *= inv_square_distance;
-
-        target->incForces( dx, dy, dz);
-        target->incPotential( inv_distance * source->getPhysicalValue() );
-
-        source->incForces( (-dx), (-dy), (-dz));
-        source->incPotential( inv_distance * target->getPhysicalValue() );
-
-    }
-
-    /** P2P mutual interaction,
-      * this function computes the interaction for 2 particles.
-      *
-      * Formulas are:
-      * \f[
-      * F = q_1 * q_2 / r^2
-      * P_1 = q_2 / r ; P_2 = q_1 / r
-      * \f]
-      * In details :
-      * \f$ F(x) = \frac{ \Delta_x * q_1 * q_2 }{ r^2 } = \Delta_x * F \f$
-      */
-    void particlesInteraction(ParticleClass*const FRestrict target, const ParticleClass& source) const {
-
-        FReal dx = source.getPosition().getX() - target->getPosition().getX();
-        FReal dy = source.getPosition().getY() - target->getPosition().getY();
-        FReal dz = source.getPosition().getZ() - target->getPosition().getZ();
-
-        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
-        FReal inv_distance = FMath::Sqrt(inv_square_distance);
-
-        inv_square_distance *= inv_distance;
-        inv_square_distance *= target->getPhysicalValue() * source.getPhysicalValue();
-
-        dx *= inv_square_distance;
-        dy *= inv_square_distance;
-        dz *= inv_square_distance;
-
-        target->incForces( dx, dy, dz);
-        target->incPotential( inv_distance * source.getPhysicalValue() );
+        FP2P::FullRemote(inTargets,inNeighbors,27);
     }
 };
 
diff --git a/Src/Kernels/Rotation/FRotationOriginalKernel.hpp b/Src/Kernels/Rotation/FRotationOriginalKernel.hpp
index c7ec5f06a..d1b77cc43 100755
--- a/Src/Kernels/Rotation/FRotationOriginalKernel.hpp
+++ b/Src/Kernels/Rotation/FRotationOriginalKernel.hpp
@@ -22,6 +22,7 @@
 #include "../../Utils/FMemUtils.hpp"
 #include "../../Utils/FSpherical.hpp"
 
+#include "../P2P/FP2P.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -47,8 +48,8 @@
 * }
 * @endcode
 */
-template< class ParticleClass, class CellClass, class ContainerClass, int P>
-class FRotationOriginalKernel : public FAbstractKernels<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass, int P>
+class FRotationOriginalKernel : public FAbstractKernels<CellClass,ContainerClass> {
     //< Size of the data array computed using a suite relation
     static const int SizeArray = ((P+2)*(P+1))/2;
 
@@ -454,14 +455,18 @@ public:
         FReal legendre[SizeArray];
 
         // For all particles in the leaf box
-        typename ContainerClass::ConstBasicIterator iterParticle(*inParticles);
-        while( iterParticle.hasNotFinished()){
+        const FReal*const physicalValues = inParticles.getPhysicalValues();
+        const FReal*const positionsX = inParticles.getPositions()[0];
+        const FReal*const positionsY = inParticles.getPositions()[1];
+        const FReal*const positionsZ = inParticles.getPositions()[2];
+
+        for(int idxPart = 0 ; idxPart < inParticles.getNbParticles() ; ++ idxPart){
             // P2M
-            const ParticleClass& particle = iterParticle.data();
-            const FSpherical sph(particle.getPosition() - cellPosition);
+            const FPoint position(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
+            const FSpherical sph(position - cellPosition);
 
             // The physical value (charge, mass)
-            const FReal q = particle.getPhysicalValue();
+            const FReal q = physicalValues[idxPart];
             // The distance between the SH and the particle
             const FReal a = sph.getR();
 
@@ -477,9 +482,6 @@ public:
                     w[atLm(l,m)].incImag(magnitude * FMath::Sin(FReal(m) * sph.getPhi() + i_pow_m[m & 0x3]));
                 }
             }
-
-            // Goto next particle
-            iterParticle.gotoNext();
         }
     }
 
@@ -664,11 +666,19 @@ public:
         const FPoint cellPosition = getLeafCenter(inLocal->getCoordinate());
 
         // For all particles in the leaf box
-        typename ContainerClass::BasicIterator iterParticle(*inParticles);
-        while( iterParticle.hasNotFinished()){
+        const FReal*const physicalValues = inParticles.getPhysicalValues();
+        const FReal*const positionsX = inParticles.getPositions()[0];
+        const FReal*const positionsY = inParticles.getPositions()[1];
+        const FReal*const positionsZ = inParticles.getPositions()[2];
+        const FReal*const forcesX = inParticles.getForcesX();
+        const FReal*const forcesY = inParticles.getForcesY();
+        const FReal*const forcesZ = inParticles.getForcesZ();
+        const FReal*const potentials = inParticles.getPotentials();
+
+        for(int idxPart = 0 ; idxPart < inParticles.getNbParticles() ; ++ idxPart){
             // L2P
-            ParticleClass& particle = iterParticle.data();
-            const FSpherical sph(particle.getPosition() - cellPosition);
+            const FPoint position(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
+            const FSpherical sph(position - cellPosition);
 
             // The distance between the SH and the particle
             const FReal r = sph.getR();
@@ -727,7 +737,7 @@ public:
                 // copy variable from spherical position
                 const FReal cosPhi     = FMath::Cos(sph.getPhi());
                 const FReal sinPhi     = FMath::Sin(sph.getPhi());
-                const FReal physicalValue = particle.getPhysicalValue();
+                const FReal physicalValue = physicalValues[idxPart];
 
                 // compute forces
                 const FReal forceX = (
@@ -745,7 +755,9 @@ public:
                         (-sph.getSinTheta()) * FO) * physicalValue;
 
                 // inc particles forces
-                particle.incForces( forceX, forceY, forceZ );
+                forcesX[idxPart] += forceX;
+                forcesY[idxPart] += forceY;
+                forcesZ[idxPart] += forceZ;
             }
 
             { // Result for potential
@@ -767,14 +779,18 @@ public:
                     }
                 }
                 // inc potential
-                particle.incPotential(magnitude);
+                potentials[idxPart] += magnitude;
             }
-            // progress
-            iterParticle.gotoNext();
         }
     }
 
 
+    /** P2P
+      * This function proceed the P2P using particlesMutualInteraction
+      * The computation is done for interactions with an index <= 13.
+      * (13 means current leaf (x;y;z) = (0;0;0)).
+      * Calling this method in multi thread should be done carrefully.
+      */
     /** P2P
       * This function proceed the P2P using particlesMutualInteraction
       * The computation is done for interactions with an index <= 13.
@@ -784,104 +800,15 @@ public:
     void P2P(const FTreeCoordinate& /*inPosition*/,
                      ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
                      ContainerClass* const inNeighbors[27], const int /*inSize*/){
-
-        {
-            typename ContainerClass::BasicIterator iterTarget(*inTargets);
-            while( iterTarget.hasNotFinished() ){
-                // We copy the target particle to work with a particle in the heap
-                ParticleClass target( iterTarget.data() );
-
-                // For all particles after the current one
-                typename ContainerClass::BasicIterator iterSameBox = iterTarget;
-                iterSameBox.gotoNext();
-                while( iterSameBox.hasNotFinished() ){
-                    particlesMutualInteraction(&target, &iterSameBox.data());
-                    iterSameBox.gotoNext();
-                }
-                // Set data and progress
-                iterTarget.setData(target);
-                iterTarget.gotoNext();
-            }
-        }
-        // For all the neigbors leaves
-        for(int idxDirectNeighbors = 0 ; idxDirectNeighbors <= 13 ; ++idxDirectNeighbors){
-            if( inNeighbors[idxDirectNeighbors] ){
-                // For all particles in current leaf
-                typename ContainerClass::BasicIterator iterTarget(*inTargets);
-                while( iterTarget.hasNotFinished() ){
-                    ParticleClass target( iterTarget.data() );
-                    // For all the particles in the other leaf
-                    typename ContainerClass::BasicIterator iterSource(*inNeighbors[idxDirectNeighbors]);
-                    while( iterSource.hasNotFinished() ){
-                        particlesMutualInteraction(&target, &iterSource.data());
-                        iterSource.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-        }
+        FP2P::FullMutual(inTargets,inNeighbors,14);
     }
 
 
     /** Use mutual even if it not useful and call particlesMutualInteraction */
-    void P2PRemote(const FTreeCoordinate& inPosition,
-                   ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict inSources,
-                   ContainerClass* const inNeighbors[27], const int inSize){
-        for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < 27 ; ++idxDirectNeighbors){
-            if( inNeighbors[idxDirectNeighbors] ){
-                // For all particles in current leaf
-                typename ContainerClass::BasicIterator iterTarget(*inTargets);
-                while( iterTarget.hasNotFinished() ){
-                    ParticleClass target( iterTarget.data() );
-                    // For all the particles in the other leaf
-                    typename ContainerClass::BasicIterator iterSource(*inNeighbors[idxDirectNeighbors]);
-                    while( iterSource.hasNotFinished() ){
-                        particlesMutualInteraction(&target, &iterSource.data());
-                        iterSource.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-        }
-    }
-
-    /** P2P mutual interaction,
-      * this function computes the interaction for 2 particles.
-      *
-      * Formulas are:
-      * \f[
-      * F = q_1 * q_2 / r^2
-      * P_1 = q_2 / r ; P_2 = q_1 / r
-      * \f]
-      * In details :
-      * \f$ F(x) = \frac{ \Delta_x * q_1 * q_2 }{ r^2 } = \Delta_x * F \f$
-      */
-    void particlesMutualInteraction(ParticleClass*const FRestrict target, ParticleClass*const FRestrict source) const {
-
-        FReal dx = source->getPosition().getX() - target->getPosition().getX();
-        FReal dy = source->getPosition().getY() - target->getPosition().getY();
-        FReal dz = source->getPosition().getZ() - target->getPosition().getZ();
-
-        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
-        FReal inv_distance = FMath::Sqrt(inv_square_distance);
-
-        inv_square_distance *= inv_distance;
-        inv_square_distance *= target->getPhysicalValue() * source->getPhysicalValue();
-
-        dx *= inv_square_distance;
-        dy *= inv_square_distance;
-        dz *= inv_square_distance;
-
-        target->incForces( dx, dy, dz);
-        target->incPotential( inv_distance * source->getPhysicalValue() );
-
-        source->incForces( (-dx), (-dy), (-dz));
-        source->incPotential( inv_distance * target->getPhysicalValue() );
-
+    void P2PRemote(const FTreeCoordinate& /*inPosition*/,
+                   ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
+                   ContainerClass* const inNeighbors[27], const int /*inSize*/){
+        FP2P::FullRemote(inTargets,inNeighbors,27);
     }
 };
 
diff --git a/Src/Kernels/Rotation/FRotationParticle.hpp b/Src/Kernels/Rotation/FRotationParticle.hpp
deleted file mode 100755
index 0e857d023..000000000
--- a/Src/Kernels/Rotation/FRotationParticle.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FROTATIONLPARTICLE_HPP
-#define FROTATIONLPARTICLE_HPP
-
-#include "../../Extensions/FExtendForces.hpp"
-#include "../../Extensions/FExtendPotential.hpp"
-#include "../../Extensions/FExtendParticleType.hpp"
-#include "../../Components/FFmaParticle.hpp"
-
-#include "../../Components/FAbstractSerializable.hpp"
-
-class FRotationParticle : public FExtendForces, public FFmaParticle, public FExtendPotential {
-public:
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        FExtendForces::save(buffer);
-        FFmaParticle::save(buffer);
-        FExtendPotential::save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        FExtendForces::restore(buffer);
-        FFmaParticle::restore(buffer);
-        FExtendPotential::restore(buffer);
-    }
-};
-
-
-class FTypedRotationParticle : public FRotationParticle, public FExtendParticleType {
-public:
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        FRotationParticle::save(buffer);
-        FExtendParticleType::save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        FRotationParticle::restore(buffer);
-        FExtendParticleType::restore(buffer);
-    }
-};
-
-#endif // FROTATIONLPARTICLE_HPP
diff --git a/Src/Kernels/Rotation/FRotationParticleContainer.hpp b/Src/Kernels/Rotation/FRotationParticleContainer.hpp
new file mode 100755
index 000000000..82f5fc073
--- /dev/null
+++ b/Src/Kernels/Rotation/FRotationParticleContainer.hpp
@@ -0,0 +1,66 @@
+// ===================================================================================
+// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
+// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
+// This software is a computer program whose purpose is to compute the FMM.
+//
+// This software is governed by the CeCILL-C and LGPL licenses and
+// abiding by the rules of distribution of free software.  
+// 
+// This program 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 and CeCILL-C Licenses for more details.
+// "http://www.cecill.info". 
+// "http://www.gnu.org/licenses".
+// ===================================================================================
+#ifndef FROTATIONLPARTICLECONTAINER_HPP
+#define FROTATIONLPARTICLECONTAINER_HPP
+
+
+#include "../../Components/FBasicParticleContainer.hpp"
+
+class FRotationParticleContainer : public FBasicParticleContainer<5> {
+    typedef FBasicParticleContainer<5> Parent;
+public:
+    FReal* getPhysicalValues(){
+        return Parent::getAttribute(0);
+    }
+
+    const FReal* getPhysicalValues() const {
+        return Parent::getAttribute(0);
+    }
+
+    FReal* getPotentials(){
+        return Parent::getAttribute(1);
+    }
+
+    const FReal* getPotentials() const {
+        return Parent::getAttribute(1);
+    }
+
+    FReal* getForcesX(){
+        return Parent::getAttribute(2);
+    }
+
+    const FReal* getForcesX() const {
+        return Parent::getAttribute(2);
+    }
+
+    FReal* getForcesY(){
+        return Parent::getAttribute(3);
+    }
+
+    const FReal* getForcesY() const {
+        return Parent::getAttribute(3);
+    }
+
+    FReal* getForcesZ(){
+        return Parent::getAttribute(4);
+    }
+
+    const FReal* getForcesZ() const {
+        return Parent::getAttribute(4);
+    }
+};
+
+#endif // FROTATIONLPARTICLECONTAINER_HPP
diff --git a/Src/Kernels/Spherical/FAbstractSphericalKernel.hpp b/Src/Kernels/Spherical/FAbstractSphericalKernel.hpp
index 1524597ea..976040193 100755
--- a/Src/Kernels/Spherical/FAbstractSphericalKernel.hpp
+++ b/Src/Kernels/Spherical/FAbstractSphericalKernel.hpp
@@ -22,17 +22,20 @@
 #include "../../Utils/FTrace.hpp"
 #include "../../Utils/FMemUtils.hpp"
 #include "../../Utils/FSmartPointer.hpp"
+#include "../../Utils/FPoint.hpp"
 
 #include "../../Containers/FTreeCoordinate.hpp"
 
+#include "../P2P/FP2P.hpp"
+
 #include "FHarmonic.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * This is the abstract spherical harmonic kernel
 */
-template< class ParticleClass, class CellClass, class ContainerClass>
-class FAbstractSphericalKernel : public FAbstractKernels<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass>
+class FAbstractSphericalKernel : public FAbstractKernels<CellClass,ContainerClass> {
 protected:
     const int   devP;           //< The P
     const FReal boxWidth;       //< the box width at leaf level
@@ -144,11 +147,15 @@ public:
         // Copying the position is faster than using cell position
         const FPoint polePosition = getLeafCenter(inPole->getCoordinate());
         // For all particles in the leaf box
-        typename ContainerClass::ConstBasicIterator iterParticle(*inParticles);
-        while( iterParticle.hasNotFinished()){
+        const FReal*const physicalValues = inParticles->getPhysicalValues();
+        const FReal*const positionsX = inParticles->getPositions()[0];
+        const FReal*const positionsY = inParticles->getPositions()[1];
+        const FReal*const positionsZ = inParticles->getPositions()[2];
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++idxPart){
             // P2M
-            particleToMultiPole(cellMultiPole, polePosition, iterParticle.data());
-            iterParticle.gotoNext();
+            particleToMultiPole(cellMultiPole, polePosition,
+                                FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]),
+                                physicalValues[idxPart]);
         }
     }
 
@@ -163,31 +170,6 @@ public:
             }
         }
     }
-    //  Just for check purpose
-    void ocM2M(CellClass* const FRestrict inPole, const CellClass *const FRestrict *const FRestrict inChild, const int inLevel) {
-        FComplexe* FRestrict const multipole_exp_target = inPole->getMultipole();
-        // iter on each child and process M2M
-        // Reset to zero
-        //
-        std::cout << std::endl<<"Multipole value to found" <<std::endl;
-        for(int idxPole = 0 ; idxPole < inPole->GetPoleSize() ; ++idxPole){
-            std::cout <<  "  "<< multipole_exp_target[idxPole] ;
-            multipole_exp_target[idxPole] = FComplexe(0.0,0.0);
-        }
-        std::cout <<std::endl;
-//
-        const FComplexe* FRestrict const preM2MTransitionsAtLevel = preM2MTransitions[inLevel];
-        for(int idxChild = 0 ; idxChild < 8 ; ++idxChild){
-            if(inChild[idxChild]){
-                multipoleToMultipole(multipole_exp_target, inChild[idxChild]->getMultipole(), &preM2MTransitionsAtLevel[idxChild * harmonic.getExpSize()]);
-                std::cout << "Add multipole from child "<< idxChild << std::endl;
-                for(int idxPole = 0 ; idxPole < inPole->GetPoleSize() ; ++idxPole){
-                    std::cout <<  "  "<< multipole_exp_target[idxPole] ;
-                }
-                std::cout <<std::endl;
-            }
-        }
-    }
 
     /** M2L with a cell and all the existing neighbors */
     virtual void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343],
@@ -205,16 +187,25 @@ public:
     }
 
     /** L2P with a cell and all its particles */
-    void L2P(const CellClass* const local, ContainerClass* const particles){
+    void L2P(const CellClass* const local, ContainerClass* const inParticles){
         const FComplexe* const cellLocal = local->getLocal();
         // Copying the position is faster than using cell position
         const FPoint localPosition = getLeafCenter(local->getCoordinate());
         // For all particles in the leaf box
-        typename ContainerClass::BasicIterator iterTarget(*particles);
-        while( iterTarget.hasNotFinished() ){
+        const FReal*const physicalValues = inParticles->getPhysicalValues();
+        const FReal*const positionsX = inParticles->getPositions()[0];
+        const FReal*const positionsY = inParticles->getPositions()[1];
+        const FReal*const positionsZ = inParticles->getPositions()[2];
+        FReal*const potentials = inParticles->getPotentials();
+        FReal*const forcesX = inParticles->getForcesX();
+        FReal*const forcesY = inParticles->getForcesY();
+        FReal*const forcesZ = inParticles->getForcesZ();
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++idxPart){
             // L2P
-            localToParticle(&iterTarget.data(), localPosition, cellLocal);
-            iterTarget.gotoNext();
+            localToParticle(localPosition, cellLocal,
+                            FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]),
+                            physicalValues[idxPart], &potentials[idxPart],
+                            &forcesX[idxPart],&forcesY[idxPart],&forcesZ[idxPart]);
         }
     }
 
@@ -229,85 +220,7 @@ public:
     void P2P(const FTreeCoordinate& inLeafPosition,
                   ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
                   ContainerClass* const directNeighborsParticles[27], const int /*size*/){
-
-        const bool isNotTsm = (targets != sources);
-        if( isNotTsm ) { // Compute interaction in this leaf
-            {
-                typename ContainerClass::BasicIterator iterTarget(*targets);
-                while( iterTarget.hasNotFinished() ){
-                    // We copy the target particle to work with a particle in the heap
-                    ParticleClass target( iterTarget.data() );
-
-                    // For all the source particles in the same leaf
-                    typename ContainerClass::ConstBasicIterator iterSameBox(*sources);
-                    while( iterSameBox.hasNotFinished() ){
-                        directInteraction(&target, iterSameBox.data());
-                        iterSameBox.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-            // For all the neigbors leaves
-            for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < 27 ; ++idxDirectNeighbors){
-                if( directNeighborsParticles[idxDirectNeighbors] ){
-                    // For all particles in current leaf
-                    typename ContainerClass::BasicIterator iterTarget(*targets);
-                    while( iterTarget.hasNotFinished() ){
-                        ParticleClass target( iterTarget.data() );
-                        // For all the particles in the other leaf
-                        typename ContainerClass::ConstBasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
-                        while( iterSource.hasNotFinished() ){
-                            directInteraction(&target, iterSource.data());
-                            iterSource.gotoNext();
-                        }
-                        // Set data and progress
-                        iterTarget.setData(target);
-                        iterTarget.gotoNext();
-                    }
-                }
-            }
-        }
-        else { // Compute interaction in this leaf
-            {
-                typename ContainerClass::BasicIterator iterTarget(*targets);
-                while( iterTarget.hasNotFinished() ){
-                    // We copy the target particle to work with a particle in the heap
-                    ParticleClass target( iterTarget.data() );
-
-                    // For all particles after the current one
-                    typename ContainerClass::BasicIterator iterSameBox = iterTarget;
-                    iterSameBox.gotoNext();
-                    while( iterSameBox.hasNotFinished() ){
-                        directInteractionMutual(&target, &iterSameBox.data());
-                        iterSameBox.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-            // For all the neigbors leaves
-            for(int idxDirectNeighbors = 0 ; idxDirectNeighbors <= 13 ; ++idxDirectNeighbors){
-                if( directNeighborsParticles[idxDirectNeighbors] ){
-                    // For all particles in current leaf
-                    typename ContainerClass::BasicIterator iterTarget(*targets);
-                    while( iterTarget.hasNotFinished() ){
-                        ParticleClass target( iterTarget.data() );
-                        // For all the particles in the other leaf
-                        typename ContainerClass::BasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
-                        while( iterSource.hasNotFinished() ){
-                            directInteractionMutual(&target, &iterSource.data());
-                            iterSource.gotoNext();
-                        }
-                        // Set data and progress
-                        iterTarget.setData(target);
-                        iterTarget.gotoNext();
-                    }
-                }
-            }
-        }
+        FP2P::FullMutual(targets,directNeighborsParticles,14);
     }
 
     /** This P2P has to be used when target != sources
@@ -321,26 +234,7 @@ public:
     void P2PRemote(const FTreeCoordinate& ,
                   ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict ,
                   ContainerClass* const directNeighborsParticles[27], const int /*size*/){
-        // TODO manage for periodic
-        for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < 27 ; ++idxDirectNeighbors){
-            if( directNeighborsParticles[idxDirectNeighbors] ){
-                // For all particles in current leaf
-                typename ContainerClass::BasicIterator iterTarget(*targets);
-                while( iterTarget.hasNotFinished() ){
-                    ParticleClass target( iterTarget.data() );
-                    // For all the particles in the other leaf
-                    typename ContainerClass::BasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
-                    while( iterSource.hasNotFinished() ){
-                        directInteraction(&target, iterSource.data());
-
-                        iterSource.gotoNext();
-                    }
-                    // Set data and progress
-                    iterTarget.setData(target);
-                    iterTarget.gotoNext();
-                }
-            }
-        }
+        FP2P::FullRemote(targets,directNeighborsParticles,27);
     }
 
 private:
@@ -370,13 +264,13 @@ private:
     *
     */
     void particleToMultiPole(FComplexe* const cellMultiPole, const FPoint& inPolePosition ,
-                             const ParticleClass& particle){
+                             const FPoint& particlePosition, const FReal particlePhysicalValue){
 
         // Inner of Qi - Z0 => harmonic.result
-        harmonic.computeInner( FSpherical(particle.getPosition() - inPolePosition) );
+        harmonic.computeInner( FSpherical(particlePosition - inPolePosition) );
 
         FReal minus_one_pow_j = 1.0;    // (-1)^j => be in turn 1 and -1
-        const FReal qParticle = particle.getPhysicalValue(); // q in the formula
+        const FReal qParticle = particlePhysicalValue; // q in the formula
         int index_j_k = 0; // p_exp_term & p_Y_term
 
         // J from 0 to P
@@ -584,15 +478,17 @@ private:
 
     /** L2P
       */
-    void localToParticle(ParticleClass*const particle, const FPoint& local_position,
-                         const FComplexe*const local_exp){
+    void localToParticle(const FPoint& local_position,const FComplexe*const local_exp,
+                         const FPoint& particlePosition,
+                         const FReal physicalValue, FReal*const potential,
+                         FReal*const forcesX,FReal*const forcesY,FReal*const forcesZ){
         //--------------- Forces ----------------//
 
         FReal force_vector_in_local_base_x = 0;
         FReal force_vector_in_local_base_y = 0;
         FReal force_vector_in_local_base_z = 0;
 
-        const FSpherical spherical(particle->getPosition() - local_position);
+        const FSpherical spherical(particlePosition - local_position);
         harmonic.computeInnerTheta( spherical );
 
         int index_j_k = 1;
@@ -705,12 +601,13 @@ private:
                 cos_theta * force_vector_in_local_base_x +
                 (-sin_theta) * force_vector_in_local_base_y);
 
-        const FReal physicalValue = particle->getPhysicalValue();
         force_vector_tmp_x *= physicalValue;
         force_vector_tmp_y *= physicalValue;
         force_vector_tmp_z *= physicalValue;
 
-        particle->incForces( force_vector_tmp_x, force_vector_tmp_y, force_vector_tmp_z );
+        (*forcesX) += force_vector_tmp_x;
+        (*forcesY) += force_vector_tmp_y;
+        (*forcesZ) += force_vector_tmp_z;
 
         //--------------- Potential ----------------//
 
@@ -731,84 +628,48 @@ private:
             }
         }
 
-        particle->incPotential(result /* * physicalValue*/);
-
+        (*potential) += (result /* * physicalValue*/);
     }
 
 public:
-    /** P2P mutual interaction
-      * F = q * q' / r²
-      */
-    void directInteractionMutual(ParticleClass*const FRestrict target, ParticleClass*const FRestrict source){
-
-        FReal dx = source->getPosition().getX() - target->getPosition().getX();
-        FReal dy = source->getPosition().getY() - target->getPosition().getY();
-        FReal dz = source->getPosition().getZ() - target->getPosition().getZ();
-
-        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
-        FReal inv_distance = FMath::Sqrt(inv_square_distance);
-
-        inv_square_distance *= inv_distance;
-        inv_square_distance *= target->getPhysicalValue() * source->getPhysicalValue();
-
-        dx *= inv_square_distance;
-        dy *= inv_square_distance;
-        dz *= inv_square_distance;
-
-        target->incForces( dx, dy, dz);
-        target->incPotential( inv_distance * source->getPhysicalValue() );
-
-        source->incForces( (-dx), (-dy), (-dz));
-        source->incPotential( inv_distance * target->getPhysicalValue() );
-
-    }
-
-    /** P2P NO mutual interaction
-      * F = q * q' / r²
-      */
-    void directInteraction(ParticleClass*const FRestrict target, const ParticleClass& source){
-
-        FReal dx = source.getPosition().getX() - target->getPosition().getX();
-        FReal dy = source.getPosition().getY() - target->getPosition().getY();
-        FReal dz = source.getPosition().getZ() - target->getPosition().getZ();
-
-        FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
-        FReal inv_distance = FMath::Sqrt(inv_square_distance);
-
-        inv_square_distance *= inv_distance;
-        inv_square_distance *= target->getPhysicalValue() * source.getPhysicalValue();
-
-        dx *= inv_square_distance;
-        dy *= inv_square_distance;
-        dz *= inv_square_distance;
-
-        target->incForces( dx, dy, dz);
-        target->incPotential( inv_distance  * source.getPhysicalValue() );
-
-    }
-
-
     /** Update a velocity of a particle
       *
       */
-    void computeVelocity(ParticleClass*const FRestrict target, const FReal DT){
-        const FReal physicalValue = target->getPhysicalValue();
-        // Coef = 1/m * time/2
-        const FReal coef = (FReal(1.0)/physicalValue) * (DT/FReal(2.0));
-
-        // velocity = velocity + forces * coef
-        FPoint forces_coef(target->getForces());
-        forces_coef *= coef;
-        target->incVelocity(forces_coef);
+    void computeVelocity(ContainerClass*const FRestrict inParticles, const FReal DT){
+        const FReal*const physicalValues = inParticles->getPhysicalValues();
+        FReal*const forcesX = inParticles->getForcesX();
+        FReal*const forcesY = inParticles->getForcesY();
+        FReal*const forcesZ = inParticles->getForcesZ();
+        FVector<FPoint>& velocities = inParticles->getVelocities();
+
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++idxPart){
+            const FReal physicalValue = physicalValues[idxPart];
+            // Coef = 1/m * time/2
+            const FReal coef = (FReal(1.0)/physicalValue) * (DT/FReal(2.0));
+
+            // velocity = velocity + forces * coef
+            FPoint forces_coef(forcesX[idxPart], forcesY[idxPart], forcesZ[idxPart]);
+            forces_coef *= coef;
+            velocities[idxPart] += (forces_coef);
+        }
     }
 
     /** Update a position of a particle
       *
       */
-    void updatePosition(ParticleClass*const FRestrict target, const FReal DT){
-        FPoint velocity_dt( target->getVelocity() );
-        velocity_dt *= DT;
-        target->incPosition( velocity_dt );
+    void updatePosition(ContainerClass*const FRestrict inParticles, const FReal DT){
+        FReal*const positionsX = inParticles->getWPositions()[0];
+        FReal*const positionsY = inParticles->getWPositions()[1];
+        FReal*const positionsZ = inParticles->getWPositions()[2];
+        FVector<FPoint>& velocities = inParticles->getVelocities();
+
+        for(int idxPart = 0 ; idxPart < inParticles->getNbParticles() ; ++idxPart){
+            FPoint velocity_dt( velocities[idxPart] );
+            velocity_dt *= DT;
+            positionsX[idxPart] += velocity_dt.getX();
+            positionsY[idxPart] += velocity_dt.getY();
+            positionsZ[idxPart] += velocity_dt.getZ();
+        }
     }
 };
 
diff --git a/Src/Kernels/Spherical/FSphericalBlasKernel.hpp b/Src/Kernels/Spherical/FSphericalBlasKernel.hpp
index 3249cc01e..3afa3266b 100755
--- a/Src/Kernels/Spherical/FSphericalBlasKernel.hpp
+++ b/Src/Kernels/Spherical/FSphericalBlasKernel.hpp
@@ -25,10 +25,10 @@
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * This class is a spherical harmonic kernels using blas
 */
-template< class ParticleClass, class CellClass, class ContainerClass>
-class FSphericalBlasKernel : public FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass>
+class FSphericalBlasKernel : public FAbstractSphericalKernel<CellClass,ContainerClass> {
 protected:
-    typedef FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> Parent;
+    typedef FAbstractSphericalKernel<CellClass,ContainerClass> Parent;
 
     const int FF_MATRIX_ROW_DIM;     //< The blas matrix number of rows
     const int FF_MATRIX_COLUMN_DIM;  //< The blas matrix number of columns
diff --git a/Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp b/Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp
index d91768e85..c9ed1026f 100755
--- a/Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp
+++ b/Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp
@@ -26,10 +26,10 @@
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * This class is a spherical harmonic kernels using block blas
 */
-template< class ParticleClass, class CellClass, class ContainerClass>
-class FSphericalBlockBlasKernel : public FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass>
+class FSphericalBlockBlasKernel : public FAbstractSphericalKernel<CellClass,ContainerClass> {
 protected:
-    typedef FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> Parent;
+    typedef FAbstractSphericalKernel<CellClass,ContainerClass> Parent;
 
     /** A interaction properties */
     struct ComputationPair {
diff --git a/Src/Kernels/Spherical/FSphericalKernel.hpp b/Src/Kernels/Spherical/FSphericalKernel.hpp
index d8ed3430e..adeb9a1cf 100755
--- a/Src/Kernels/Spherical/FSphericalKernel.hpp
+++ b/Src/Kernels/Spherical/FSphericalKernel.hpp
@@ -23,10 +23,10 @@
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * This class is the basic spherical harmonic kernel
 */
-template< class ParticleClass, class CellClass, class ContainerClass>
-class FSphericalKernel : public FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> {
+template< class CellClass, class ContainerClass>
+class FSphericalKernel : public FAbstractSphericalKernel<CellClass,ContainerClass> {
 protected:
-    typedef FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> Parent;
+    typedef FAbstractSphericalKernel<CellClass,ContainerClass> Parent;
 
     const int devM2lP;               //< A secondary P
 
diff --git a/Src/Kernels/Spherical/FSphericalParticle.hpp b/Src/Kernels/Spherical/FSphericalParticle.hpp
deleted file mode 100755
index 18ac97be6..000000000
--- a/Src/Kernels/Spherical/FSphericalParticle.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-#ifndef FSPHERICALPARTICLE_HPP
-#define FSPHERICALPARTICLE_HPP
-
-#include "../../Extensions/FExtendForces.hpp"
-#include "../../Extensions/FExtendPotential.hpp"
-#include "../../Extensions/FExtendParticleType.hpp"
-#include "../../Components/FFmaParticle.hpp"
-
-#include "../../Components/FAbstractSerializable.hpp"
-
-class FSphericalParticle : public FExtendForces, public FFmaParticle, public FExtendPotential {
-public:
-
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        FExtendForces::save(buffer);
-        FFmaParticle::save(buffer);
-        FExtendPotential::save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        FExtendForces::restore(buffer);
-        FFmaParticle::restore(buffer);
-        FExtendPotential::restore(buffer);
-    }
-};
-
-
-class FTypedSphericalParticle : public FSphericalParticle, public FExtendParticleType {
-public:
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        FSphericalParticle::save(buffer);
-        FExtendParticleType::save(buffer);
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        FSphericalParticle::restore(buffer);
-        FExtendParticleType::restore(buffer);
-    }
-};
-
-#endif // FSPHERICALPARTICLE_HPP
diff --git a/Src/Kernels/Spherical/FSphericalRotationKernel.hpp b/Src/Kernels/Spherical/FSphericalRotationKernel.hpp
index 97781c95c..700f54e73 100755
--- a/Src/Kernels/Spherical/FSphericalRotationKernel.hpp
+++ b/Src/Kernels/Spherical/FSphericalRotationKernel.hpp
@@ -23,10 +23,10 @@
 * @author Berenger Bramas (berenger.bramas@inria.fr)
 * This class is the rotation spherical harmonic kernel
 */
-template< class ParticleClass, class CellClass, class ContainerClass>
-class FSphericalRotationKernel : public FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> {
+template<  class CellClass, class ContainerClass>
+class FSphericalRotationKernel : public FAbstractSphericalKernel<CellClass,ContainerClass> {
 protected:
-    typedef FAbstractSphericalKernel<ParticleClass,CellClass,ContainerClass> Parent;
+    typedef FAbstractSphericalKernel<CellClass,ContainerClass> Parent;
 
     /** This class define some information to use rotation computation
       */
diff --git a/Tests/Kernels/testChebAlgorithm.cpp b/Tests/Kernels/testChebAlgorithm.cpp
index 524e9efa3..7e16983b1 100755
--- a/Tests/Kernels/testChebAlgorithm.cpp
+++ b/Tests/Kernels/testChebAlgorithm.cpp
@@ -26,13 +26,15 @@
 #include "../../Src/Files/FFmaScanfLoader.hpp"
 #include "../../Src/Files/FFmaBinLoader.hpp"
 
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebKernel.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
 
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 #include "../../Src/Utils/FParameters.hpp"
 #include "../../Src/Utils/FMemUtils.hpp"
 
@@ -87,25 +89,24 @@ int main(int argc, char* argv[])
 	FTic time;
 
 
-	// typedefs
-	typedef FChebParticle ParticleClass;
-	typedef FVector<FChebParticle> ContainerClass;
-	typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+    // typedefs
+    typedef FP2PParticleContainer ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >  LeafClass;
 	//typedef FChebMatrixKernelLJ MatrixKernelClass;
 	typedef FChebMatrixKernelR MatrixKernelClass;
 	typedef FChebCell<ORDER> CellClass;
-	typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
+    typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
 	//typedef FChebKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-	typedef FChebSymKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+    typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
 	//typedef FFmmAlgorithm<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
-	typedef FFmmAlgorithmThread<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 
 
 	// What we do //////////////////////////////////////////////////////
 	std::cout << ">> Testing the Chebyshev interpolation base FMM algorithm.\n";
 	
 	// open particle file
-	FFmaScanfLoader<ParticleClass> loader(filename);
+    FFmaScanfLoader loader(filename);
 	//FFmaBinLoader<ParticleClass> loader(filename);
 	if(!loader.isOpen()) throw std::runtime_error("Particle file couldn't be opened!");
 	
@@ -117,7 +118,16 @@ int main(int argc, char* argv[])
 						<< " particles in a octree of height " << TreeHeight
 						<< " ..." << std::endl;
 	time.tic();
-	loader.fillTree(tree);
+
+    {
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition,&physicalValue);
+            tree.insert(particlePosition, physicalValue);
+        }
+    }
+
 	std::cout << "Done  " << "(" << time.tacAndElapsed() << ")." << std::endl;
 	// -----------------------------------------------------
 
@@ -208,7 +218,7 @@ int main(int argc, char* argv[])
 
 	// -----------------------------------------------------
 	// find first non empty leaf cell 
-	if (FParameters::findParameter(argc,argv,"-dont_check_accuracy") == FParameters::NotFound) {
+    /*if (FParameters::findParameter(argc,argv,"-dont_check_accuracy") == FParameters::NotFound) {
 		OctreeClass::Iterator iLeafs(&tree);
 		iLeafs.gotoBottomLeft();
 	
@@ -298,7 +308,7 @@ int main(int argc, char* argv[])
 		delete [] ApproxPotential;
 		delete [] Force;
 		delete [] ApproxForce;
-	}
+    }*/
 
 	/*
 	// Check if particles are strictly within its containing cells
diff --git a/Tests/Kernels/testCompareKernels.cpp b/Tests/Kernels/testCompareKernels.cpp
index 4b050fb59..004dcebbd 100755
--- a/Tests/Kernels/testCompareKernels.cpp
+++ b/Tests/Kernels/testCompareKernels.cpp
@@ -35,7 +35,6 @@
 #include "../../Src/Core/FFmmAlgorithmThread.hpp"
 
 // chebyshev kernel
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
@@ -43,14 +42,14 @@
 #include "../../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
 
 // spherical kernel
-#include "../../Src/Components/FSimpleLeaf.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalBlasKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalRotationKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 /**
  * This program compares two different kernels, eg., the Chebyshev kernel with
@@ -85,86 +84,6 @@ FReal computeINFnorm(const unsigned int N, const FReal *const u, const FReal *co
 }
 
 
-template <class OctreeClass, class MatrixKernelClass, class ContainerClass>
-class DirectInteractionComputer
-{
-
-	const MatrixKernelClass MatrixKernel;
-
-public:
-	DirectInteractionComputer()
-		: MatrixKernel()
-	{}
-	
-	unsigned int operator()(OctreeClass& tree, const unsigned int NumTargetCells,
-													FReal* &p, FReal* &f) const
-	{
-		// begin direct computation of first leaf cell
-		typename OctreeClass::Iterator iLeafs(&tree);
-		iLeafs.gotoBottomLeft();
-
-		const ContainerClass* *const TargetSets = new const ContainerClass* [NumTargetCells];
-
-		unsigned int n = 0;
-		for (unsigned int t=0; t<NumTargetCells; ++t) {
-			TargetSets[t] = iLeafs.getCurrentListTargets();
-			n += TargetSets[t]->getSize();
-			iLeafs.moveRight();
-		}
-		p = new FReal [n];
-		FBlas::setzero(n, p);
-		f = new FReal [n * 3];
-		FBlas::setzero(n * 3, f);
-
-		std::cout << "\nDirect computation of " << n << " target particles ..." << std::endl;
-
-		unsigned int start = 0;
-		for (unsigned int t=0; t<NumTargetCells; ++t) {
-			iLeafs.gotoBottomLeft();
-
-			// retrieve targets
-			const ContainerClass *const Targets = TargetSets[t];
-			
-			do {
-				const ContainerClass *const Sources = iLeafs.getCurrentListSrc();
-				unsigned int counter = start;
-				typename ContainerClass::ConstBasicIterator iTarget(*Targets);
-				while(iTarget.hasNotFinished()) {
-					const FReal wt = iTarget.data().getPhysicalValue();
-					typename ContainerClass::ConstBasicIterator iSource(*Sources);
-					while(iSource.hasNotFinished()) {
-						if (&iTarget.data() != &iSource.data()) {
-							const FReal ws = iSource.data().getPhysicalValue();
-							const FReal one_over_r = MatrixKernel.evaluate(iTarget.data().getPosition(),
-																														 iSource.data().getPosition());
-							// potential
-							p[counter] += one_over_r * ws;
-							// force
-							FPoint force(iSource.data().getPosition() - iTarget.data().getPosition());
-							force *= ((ws*wt) * (one_over_r*one_over_r*one_over_r));
-							f[counter*3 + 0] += force.getX();
-							f[counter*3 + 1] += force.getY();
-							f[counter*3 + 2] += force.getZ();
-						}
-						iSource.gotoNext();
-					}
-					counter++;
-					iTarget.gotoNext();
-				}
-			} while(iLeafs.moveRight());
-
-			start += Targets->getSize();
-		}
-
-		delete [] TargetSets;
-
-		return n;
-	}
-
-};
-
-
-
 // Simply create particles and try the kernels
 int main(int argc, char* argv[])
 {
@@ -172,20 +91,20 @@ int main(int argc, char* argv[])
     const char* const filename       = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     const unsigned int TreeHeight    = FParameters::getValue(argc, argv, "-h", 5);
     const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-sh", 2);
-		const unsigned int NbThreads     = FParameters::getValue(argc, argv, "-t", 1);
-		
-		omp_set_num_threads(NbThreads); 
-		
-		std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
-		
+    const unsigned int NbThreads     = FParameters::getValue(argc, argv, "-t", omp_get_max_threads());
+
+    omp_set_num_threads(NbThreads);
+
+    std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
+
     // init timer
     FTic time;
 
-		// only for direct computation of nt1 target particles
-		unsigned int nt1 = 0;
-		FReal* p10; p10 = NULL;
-		FReal* f10; p10 = NULL;
-		
+    // only for direct computation of nt1 target particles
+    unsigned int nt1 = 0;
+    FReal* p10; p10 = NULL;
+    FReal* f10; p10 = NULL;
+
     ////////////////////////////////////////////////////////////////////
     {	// begin Chebyshef kernel
 
@@ -197,21 +116,20 @@ int main(int argc, char* argv[])
         FReal* f1;  p1  = NULL;
 
         // typedefs
-        typedef FChebParticle ParticleClass;
-        typedef FVector<FChebParticle> ContainerClass;
-        typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+        typedef FP2PParticleContainer ContainerClass;
+        typedef FSimpleLeaf<ContainerClass> LeafClass;
         typedef FChebMatrixKernelR MatrixKernelClass;
         typedef FChebCell<ORDER> CellClass;
-        typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
+        typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
 
-				//typedef FChebKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-				typedef FChebSymKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-				//typedef FFmmAlgorithm<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
-				typedef FFmmAlgorithmThread<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        //typedef FChebKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        //typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        typedef FFmmAlgorithmThread<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 
 
         // open particle file
-        FFmaScanfLoader<ParticleClass> loader(filename);
+        FFmaScanfLoader loader(filename);
         if(!loader.isOpen()) throw std::runtime_error("Particle file couldn't be opened!");
 
         // init oct-tree
@@ -219,13 +137,20 @@ int main(int argc, char* argv[])
 
         { // -----------------------------------------------------
             std::cout << "Creating & Inserting " << loader.getNumberOfParticles()
-											<< " particles ..." << std::endl;
+                      << " particles ..." << std::endl;
             std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
             time.tic();
-            loader.fillTree(tree);
+
+            FPoint particlePosition;
+            FReal physicalValue = 0.0;
+            for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+                loader.fillParticle(&particlePosition,&physicalValue);
+                tree.insert(particlePosition, physicalValue);
+            }
+
             time.tac();
             std::cout << "Done  " << "(@Creating and Inserting Particles = "
-											<< time.elapsed() << "s)." << std::endl;
+                      << time.elapsed() << "s)." << std::endl;
         } // -----------------------------------------------------
 
         { // -----------------------------------------------------
@@ -238,7 +163,7 @@ int main(int argc, char* argv[])
             std::cout << "Done  " << "(@Algorithm = " << time.elapsed() << "s)." << std::endl;
         } // -----------------------------------------------------
 
-        { // -----------------------------------------------------
+        /*{ // -----------------------------------------------------
             // read potential from particles and write to array p1
             p1 = new FReal [loader.getNumberOfParticles()];
             f1 = new FReal [loader.getNumberOfParticles() * 3];
@@ -257,16 +182,12 @@ int main(int argc, char* argv[])
                     iTarget.gotoNext();
                 }
             } while(iLeafs.moveRight());
-        } // -----------------------------------------------------
+        } // -----------------------------------------------------*/
 
-				// compute direct interaction
-				const unsigned int NumTargetCells = 3;
-				DirectInteractionComputer<OctreeClass,MatrixKernelClass,ContainerClass> direct;
-				nt1 = direct(tree, NumTargetCells, p10, f10);
-
-
-        //		for (unsigned int n=0; n<nt1; ++n)
-        //			std::cout << p10[n] << " - " << p1[n] << " = " << p10[n]-p1[n] << std::endl;
+        // compute direct interaction
+        const unsigned int NumTargetCells = 3;
+        //DirectInteractionComputer<OctreeClass,MatrixKernelClass,ContainerClass> direct;
+        //nt1 = direct(tree, NumTargetCells, p10, f10);
 
         std::cout << "\nPotential error:" << std::endl;
         std::cout << "Relative L2 error  = " << computeL2norm( nt1, p10, p1) << std::endl;
@@ -290,21 +211,20 @@ int main(int argc, char* argv[])
         const int DevP = FParameters::getValue(argc, argv, "-p", 5);
 
         // typedefs
-        typedef FSphericalParticle             ParticleClass;
         typedef FSphericalCell                 CellClass;
-        typedef FVector<ParticleClass>         ContainerClass;
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-        //typedef FSphericalBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
-        //typedef FSphericalBlockBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
-        //typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
-        typedef FSphericalBlockBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
-        //typedef FSphericalRotationKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
-        //typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-        typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FP2PParticleContainer         ContainerClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+        //typedef FSphericalBlasKernel< CellClass, ContainerClass > KernelClass;
+        //typedef FSphericalBlockBlasKernel< CellClass, ContainerClass > KernelClass;
+        //typedef FSphericalKernel< CellClass, ContainerClass > KernelClass;
+        typedef FSphericalBlockBlasKernel< CellClass, ContainerClass > KernelClass;
+        //typedef FSphericalRotationKernel< CellClass, ContainerClass > KernelClass;
+        //typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
         // open particle file
-        FFmaScanfLoader<ParticleClass> loader(filename);
+        FFmaScanfLoader loader(filename);
         if(!loader.isOpen()) throw std::runtime_error("Particle file couldn't be opened!");
 
         // init cell class and oct-tree
@@ -314,14 +234,21 @@ int main(int argc, char* argv[])
 
         { // -----------------------------------------------------
             std::cout << "Creating & Inserting " << loader.getNumberOfParticles()
-											<< " particles ..." << std::endl;
+                      << " particles ..." << std::endl;
             std::cout << "\tHeight : " << TreeHeight << " \t sub-height : "
-											<< SubTreeHeight << std::endl;
+                      << SubTreeHeight << std::endl;
             time.tic();
-            loader.fillTree(tree);
+
+            FPoint particlePosition;
+            FReal physicalValue = 0.0;
+            for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+                loader.fillParticle(&particlePosition,&physicalValue);
+                tree.insert(particlePosition, physicalValue);
+            }
+
             time.tac();
             std::cout << "Done  " << "(@Creating and Inserting Particles = "
-											<< time.elapsed() << "s)." << std::endl;
+                      << time.elapsed() << "s)." << std::endl;
         } // -----------------------------------------------------
 
         // -----------------------------------------------------
@@ -336,7 +263,7 @@ int main(int argc, char* argv[])
 
         FReal*const fmmParticlesPotential = new FReal[loader.getNumberOfParticles()];
         FReal*const fmmParticlesForces = new FReal [loader.getNumberOfParticles() * 3];
-        { // -----------------------------------------------------
+        /*{ // -----------------------------------------------------
             // read potential from particles and write to array p2
             OctreeClass::Iterator leavesIterator(&tree);
             leavesIterator.gotoBottomLeft();
@@ -357,19 +284,19 @@ int main(int argc, char* argv[])
                     particlesIterator.gotoNext();
                 }
             } while(leavesIterator.moveRight());
-        } // -----------------------------------------------------
+        } // -----------------------------------------------------*/
 
         std::cout << "\nPotential error:" << std::endl;
         std::cout << "Relative L2 error   = "
-									<< computeL2norm( nt1, p10, fmmParticlesPotential) << std::endl;
+                  << computeL2norm( nt1, p10, fmmParticlesPotential) << std::endl;
         std::cout << "Relative Lmax error = "
-									<< computeINFnorm(nt1, p10, fmmParticlesPotential) << std::endl;
+                  << computeINFnorm(nt1, p10, fmmParticlesPotential) << std::endl;
 
         std::cout << "\nForces error:" << std::endl;
         std::cout << "Relative L2 error   = "
-									<< computeL2norm( nt1*3, f10, fmmParticlesForces) << std::endl;
+                  << computeL2norm( nt1*3, f10, fmmParticlesForces) << std::endl;
         std::cout << "Relative Lmax error = "
-									<< computeINFnorm(nt1*3, f10, fmmParticlesForces) << std::endl;
+                  << computeINFnorm(nt1*3, f10, fmmParticlesForces) << std::endl;
 
 
 
@@ -379,109 +306,9 @@ int main(int argc, char* argv[])
     } // end FFmaBlas kernel
 
 
-		// free memory
-		if (p10!=NULL) delete [] p10;
-		if (f10!=NULL) delete [] f10;
+    // free memory
+    if (p10!=NULL) delete [] p10;
+    if (f10!=NULL) delete [] f10;
 
     return 0;
 }
-
-
-
-
-
-
-
-/*
-// Check if particles are strictly within its containing cells
-const FReal BoxWidthLeaf = BoxWidth / FReal(FMath::pow(2, TreeHeight-1));
-OctreeClass::Iterator octreeIterator(&tree);
-octreeIterator.gotoBottomLeft();
-do{
-const CellClass *const LeafCell = octreeIterator.getCurrentCell();
-const FPoint& LeafCellCenter = LeafCell -> getPosition();
-const ContainerClass *const Particles = octreeIterator.getCurrentListSrc();
-ContainerClass::ConstBasicIterator particleIterator(*Particles);
-while(particleIterator.hasNotFinished()) {
-const FPoint distance(LeafCellCenter-particleIterator.data().getPosition());
-std::cout << "center - particle = " << distance << " < " << BoxWidthLeaf/FReal(2.) << std::endl;
-if (std::abs(distance.getX())>BoxWidthLeaf/FReal(2.) ||
-std::abs(distance.getY())>BoxWidthLeaf/FReal(2.) ||
-std::abs(distance.getZ())>BoxWidthLeaf/FReal(2.)) {
-std::cout << "stop" << std::endl;
-exit(-1);
-}
-particleIterator.gotoNext();
-}
-} while(octreeIterator.moveRight());
-*/
-
-
-
-
-
-
-
-        //unsigned int sizeFirstLeaf = 0;
-        //FReal* firstLeafPotential = 0;
-        //FReal* firstLeafForces = 0;
-        //{ // -----------------------------------------------------
-        //    // begin direct computation of first leaf cell
-        //    OctreeClass::Iterator leavesIterator(&tree);
-        //    leavesIterator.gotoBottomLeft();
-        //    ContainerClass *const firstLeaf = leavesIterator.getCurrentListTargets();
-				//
-        //    { // Compute the first leaf with it self
-        //        ContainerClass::BasicIterator targetParticles(*firstLeaf);
-        //        while(targetParticles.hasNotFinished()) {
-        //            ContainerClass::ConstBasicIterator sourceParticles(*firstLeaf);
-        //            while(sourceParticles.hasNotFinished()) {
-        //                if (&targetParticles.data() != &sourceParticles.data()){
-        //                    kernels.directInteraction( &targetParticles.data(), sourceParticles.data());
-        //                }
-        //                sourceParticles.gotoNext();
-        //            }
-        //            targetParticles.gotoNext();
-        //        }
-        //    }
-				//
-        //    while( leavesIterator.moveRight() ) {
-        //        ContainerClass::ConstBasicIterator sourceParticles(*leavesIterator.getCurrentListSrc());
-        //        while(sourceParticles.hasNotFinished()) {
-        //            ContainerClass::BasicIterator targetParticles(*firstLeaf);
-        //            while(targetParticles.hasNotFinished()) {
-        //                kernels.directInteraction( &targetParticles.data(), sourceParticles.data());
-        //                targetParticles.gotoNext();
-        //            }
-        //            sourceParticles.gotoNext();
-        //        }
-        //    }
-				//
-        //    // Copy data
-        //    sizeFirstLeaf = firstLeaf->getSize();
-				//
-        //    firstLeafPotential = new FReal[sizeFirstLeaf];
-        //    FBlas::setzero(sizeFirstLeaf, firstLeafPotential);
-				//
-        //    firstLeafForces = new FReal[sizeFirstLeaf * 3];
-        //    FBlas::setzero(sizeFirstLeaf * 3, firstLeafForces);
-				//
-        //    unsigned int particlePosition = 0;
-        //    ContainerClass::ConstBasicIterator targetParticles(*firstLeaf);
-        //    while(targetParticles.hasNotFinished()) {
-        //        firstLeafPotential[particlePosition] = targetParticles.data().getPotential();                
-        //        firstLeafForces[particlePosition*3 + 0] = targetParticles.data().getForces().getX();
-        //        firstLeafForces[particlePosition*3 + 1] = targetParticles.data().getForces().getY();
-        //        firstLeafForces[particlePosition*3 + 2] = targetParticles.data().getForces().getZ();
-        //        targetParticles.gotoNext();
-        //        ++particlePosition;
-        //    }
-        //} // -----------------------------------------------------
-
-        //std::cout << "\nPotential error:" << std::endl;
-        //std::cout << "Relative L2 error   = " << computeL2norm( sizeFirstLeaf, firstLeafPotential, fmmParticlesPotential) << std::endl;
-        //std::cout << "Relative Lmax error = " << computeINFnorm(sizeFirstLeaf, firstLeafPotential, fmmParticlesPotential) << std::endl;
-				//
-        //std::cout << "\nForces error:" << std::endl;
-        //std::cout << "Relative L2 error   = " << computeL2norm( sizeFirstLeaf*3, firstLeafForces, fmmParticlesForces) << std::endl;
-        //std::cout << "Relative Lmax error = " << computeINFnorm(sizeFirstLeaf*3, firstLeafForces, fmmParticlesForces) << std::endl;
diff --git a/Tests/Kernels/testFlopsChebAlgorithm.cpp b/Tests/Kernels/testFlopsChebAlgorithm.cpp
index 5c1c7ef9d..420c9d144 100755
--- a/Tests/Kernels/testFlopsChebAlgorithm.cpp
+++ b/Tests/Kernels/testFlopsChebAlgorithm.cpp
@@ -26,8 +26,6 @@
 #include "../../Src/Files/FFmaScanfLoader.hpp"
 #include "../../Src/Files/FFmaBinLoader.hpp"
 
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
-#include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 
@@ -40,8 +38,8 @@
 
 #include "../../Src/Core/FFmmAlgorithm.hpp"
 
-
-
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 
 
@@ -58,15 +56,14 @@ int main(int argc, char* argv[])
 	// init timer
 	FTic time;
 
-	// typedefs
-	typedef FChebParticle ParticleClass;
-	typedef FVector<FChebParticle> ContainerClass;
-	typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+    // typedefs
+    typedef FP2PParticleContainer ContainerClass;
+    typedef FSimpleLeaf<ContainerClass> LeafClass;
 	typedef FChebMatrixKernelR MatrixKernelClass;
 	typedef FChebCell<ORDER> CellClass;
-	typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
-	typedef FChebFlopsSymKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-	typedef FFmmAlgorithm<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+    typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
+    typedef FChebFlopsSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+    typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 
 
 	// What we do //////////////////////////////////////////////////////
@@ -74,7 +71,7 @@ int main(int argc, char* argv[])
 	
 	// open particle file
 	//FFmaScanfLoader<ParticleClass> loader(filename);
-	FFmaBinLoader<ParticleClass> loader(filename);
+    FFmaBinLoader loader(filename);
 	if(!loader.isOpen()) throw std::runtime_error("Particle file couldn't be opened!");
 	
 	// init oct-tree
@@ -84,7 +81,16 @@ int main(int argc, char* argv[])
 	std::cout << "Creating and inserting " << loader.getNumberOfParticles()
 						<< " particles in a octree of height " << TreeHeight << " ..." << std::endl;
 	time.tic();
-	loader.fillTree(tree);
+
+    {
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition,&physicalValue);
+            tree.insert(particlePosition, physicalValue);
+        }
+    }
+
 	std::cout << "Done  " << "(" << time.tacAndElapsed() << ")." << std::endl;
 	// -----------------------------------------------------
 
@@ -98,9 +104,6 @@ int main(int argc, char* argv[])
 	std::cout << "completed in " << time.tacAndElapsed() << "sec." << std::endl;
 	// -----------------------------------------------------
 	
-
-
-
     return 0;
 }
 
diff --git a/Tests/Kernels/testRotationAlgorithm.cpp b/Tests/Kernels/testRotationAlgorithm.cpp
index aae5de691..d32028b53 100755
--- a/Tests/Kernels/testRotationAlgorithm.cpp
+++ b/Tests/Kernels/testRotationAlgorithm.cpp
@@ -25,7 +25,7 @@
 
 #include "../../Src/Core/FFmmAlgorithm.hpp"
 
-#include "../../Src/Kernels/Rotation/FRotationParticle.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 #include "../../Src/Kernels/Rotation/FRotationKernel.hpp"
 #include "../../Src/Kernels/Rotation/FRotationCell.hpp"
@@ -44,17 +44,16 @@
 int main(int argc, char** argv){
     static const int P = 9;
 
-    typedef FRotationParticle                ParticleClass;
     typedef FRotationCell<P>               CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer          ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FRotationKernel<ParticleClass, CellClass, ContainerClass , P>   KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FRotationKernel< CellClass, ContainerClass , P>   KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
-    typedef FFmmAlgorithmTask<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
+    typedef FFmmAlgorithmTask<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical algorithm.\n";
     std::cout << ">> You can pass -sequential or -task (thread by default).\n";
@@ -66,7 +65,7 @@ int main(int argc, char** argv){
 
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaLoader<ParticleClass> loader(filename);
+    FFmaLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -82,7 +81,12 @@ int main(int argc, char** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -122,20 +126,24 @@ int main(int argc, char** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalAlgorithm.cpp b/Tests/Kernels/testSphericalAlgorithm.cpp
index 5c7f99c29..e3367ca20 100755
--- a/Tests/Kernels/testSphericalAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalAlgorithm.cpp
@@ -31,11 +31,10 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
 #include "../../Src/Files/FFmaLoader.hpp"
-
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 /** This program show an example of use of
   * the fmm basic algo
@@ -46,17 +45,16 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >     KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalKernel< CellClass, ContainerClass >     KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
-    typedef FFmmAlgorithmTask<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
+    typedef FFmmAlgorithmTask<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical algorithm.\n";
     std::cout << ">> You can pass -sequential or -task (thread by default).\n";
@@ -69,7 +67,7 @@ int main(int argc, char ** argv){
 
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaLoader<ParticleClass> loader(filename);
+    FFmaLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -85,7 +83,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -125,20 +128,24 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalBench.cpp b/Tests/Kernels/testSphericalBench.cpp
index 46537e8ad..9c0e517f5 100755
--- a/Tests/Kernels/testSphericalBench.cpp
+++ b/Tests/Kernels/testSphericalBench.cpp
@@ -29,13 +29,12 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
 #include "../../Src/Files/FFmaLoader.hpp"
 #include "../../Src/Files/FRandomLoader.hpp"
 
-
+#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 /** This program show an example of use of
   * the fmm basic algo
@@ -43,35 +42,27 @@
   * related that each other
   */
 
-class IndexedParticle : public FSphericalParticle {
-    int index;
-public:
-    IndexedParticle(): index(-1){}
-
-    int getIndex() const{
-        return index;
-    }
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
+struct Particle{
+    FPoint position;
+    FReal physicalValue;
+    FReal forces[3];
+    FReal potential;
 };
 
-
 int restultIndex(const int idxP, const int idxH, const int minP,
                  const int maxP, const int minH){
     return (idxH-minH)*(maxP+1-minP)+(idxP-minP);
 }
 
 
-typedef IndexedParticle                ParticleClass;
 typedef FSphericalCell                 CellClass;
-typedef FVector<ParticleClass>         ContainerClass;
+typedef FP2PParticleContainerIndexed   ContainerClass;
 
-typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >     KernelClass;
+typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+typedef FSphericalKernel< CellClass, ContainerClass >     KernelClass;
 
-typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
 
 void doATest(const int NbParticles, const int minP, const int maxP, const int minH, const int maxH,
@@ -79,28 +70,38 @@ void doATest(const int NbParticles, const int minP, const int maxP, const int mi
              FMath::FAccurater* allPotentialDiff, FReal* allAbsoluteDiff, FReal* timing,
              const int SizeSubLevels = 3, FReal* timeForDirect = 0){
     FTic counter;
-    FRandomLoader<ParticleClass> loader(NbParticles);
-    ParticleClass*const particles = new ParticleClass[loader.getNumberOfParticles()];
+    FRandomLoader loader(NbParticles);
+
+
+
+    Particle*const particles = new Particle[loader.getNumberOfParticles()];
 
     const bool computeDirectAndDiff = timeForDirect || allAbsoluteDiff || allPotentialDiff;
     {
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex( idxPart );
+            loader.fillParticle(&particles[idxPart].position);
             if((idxPart & 1) && neutral){
-                particles[idxPart].setPhysicalValue( -physicalValue );
+                particles[idxPart].physicalValue = -physicalValue;
+            }
+            else{
+                particles[idxPart].physicalValue = physicalValue;
             }
-            else particles[idxPart].setPhysicalValue( physicalValue );
         }
 
         // Compute direct
         if(computeDirectAndDiff){
             printf("Compute direct!\n");
-            KernelClass kernels(minP, minH, loader.getBoxWidth(), loader.getCenterOfBox());
             counter.tic();
             for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
                 for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
-                    kernels.directInteractionMutual(&particles[idxTarget], &particles[idxOther]);
+                    FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                          particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                          &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                          &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                    particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                    particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                    &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                    &particles[idxOther].forces[2],&particles[idxOther].potential);
                 }
             }
             if(timeForDirect) *timeForDirect = counter.tacAndElapsed();
@@ -123,10 +124,7 @@ void doATest(const int NbParticles, const int minP, const int maxP, const int mi
             counter.tic();
 
             for(int idxPart = 0 ; idxPart < NbParticles ; ++idxPart){
-                ParticleClass part = particles[idxPart];
-                part.setPotential(0.0);
-                part.setForces(0.0,0.0,0.0);
-                tree.insert(part);
+                tree.insert(particles[idxPart].position, idxPart, particles[idxPart].physicalValue);
             }
 
             counter.tac();
@@ -160,29 +158,23 @@ void doATest(const int NbParticles, const int minP, const int maxP, const int mi
                 FMath::FAccurater potentialDiff;
                 FMath::FAccurater fx, fy, fz;
                 FReal absoluteDiff = FReal(0.0);
-                { // Check that each particle has been summed with all other
-                    OctreeClass::Iterator octreeIterator(&tree);
-                    octreeIterator.gotoBottomLeft();
 
-                    do{
-                        ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                        while( leafIter.hasNotFinished() ){
-                            const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                            potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-                            absoluteDiff = FMath::Max(absoluteDiff,FMath::Abs(other.getPotential()-leafIter.data().getPotential()));
-
-                            fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                            fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                            fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
-
-                            leafIter.gotoNext();
-                        }
-                    } while(octreeIterator.moveRight());
-                }
+                tree.forEachLeaf([&](LeafClass* leaf){
+                    const FReal*const potentials = leaf->getTargets()->getPotentials();
+                    const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                    const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                    const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                    const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                    const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                    for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                        const int indexPartOrig = indexes[idxPart];
+                        potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                        fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                        fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                        fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
+                    }
+                });
 
                 // Print for information
                 printf("Potential diff is = %e \t %e\n",potentialDiff.getL2Norm(),potentialDiff.getInfNorm());
@@ -289,47 +281,50 @@ int main(int argc, char ** argv){
 
         for(int idxP = 1 ; idxP <= DevP ; ++idxP){
             for(int idxStep = 0 ; idxStep <= nbStep ; ++idxStep){
-                ParticleClass centeredParticle;
-                centeredParticle.setPosition(0.0,0.0,0.5);
-                centeredParticle.setPhysicalValue(physicalValue);
-                centeredParticle.setIndex(0);
+                Particle centeredParticle;
+                centeredParticle.position.setPosition(0.0,0.0,0.5);
+                centeredParticle.physicalValue  = physicalValue;
 
-                ParticleClass otherParticle;
-                otherParticle.setPosition(0.0,0.0,startPosition + (idxStep*stepValue));
-                otherParticle.setPhysicalValue(physicalValue);
-                otherParticle.setIndex(1);
+                Particle otherParticle;
+                otherParticle.position.setPosition(0.0,0.0,startPosition + (idxStep*stepValue));
+                otherParticle.physicalValue = physicalValue;
 
                 CellClass::Init(idxP);
                 OctreeClass tree(NbLevels, 2, boxWidth, boxCenter);
 
-                tree.insert(centeredParticle);
-                tree.insert(otherParticle);
+                tree.insert(centeredParticle.position, 0, centeredParticle.physicalValue);
+                tree.insert(otherParticle.position, 1, otherParticle.physicalValue);
 
                 KernelClass kernels(idxP, NbLevels, boxWidth, boxCenter);
                 FmmClass algo(&tree,&kernels);
                 algo.execute();
 
-                kernels.directInteractionMutual(&centeredParticle, &otherParticle);
+                FP2P::MutualParticles(centeredParticle.position.getX(), centeredParticle.position.getY(),
+                                      centeredParticle.position.getZ(),centeredParticle.physicalValue,
+                                      &centeredParticle.forces[0],&centeredParticle.forces[1],
+                                      &centeredParticle.forces[2],&centeredParticle.potential,
+                                otherParticle.position.getX(), otherParticle.position.getY(),
+                                otherParticle.position.getZ(),otherParticle.physicalValue,
+                                &otherParticle.forces[0],&otherParticle.forces[1],
+                                &otherParticle.forces[2],&otherParticle.potential);
 
                 { // Check that each particle has been summed with all other
-                    OctreeClass::Iterator octreeIterator(&tree);
-                    octreeIterator.gotoBottomLeft();
-
-                    do{
-                        ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                        while( leafIter.hasNotFinished() ){
-                            const ParticleClass& other = (leafIter.data().getIndex()==0?centeredParticle:otherParticle);
 
-                            potentialDiff[idxP].add(other.getPotential(),leafIter.data().getPotential());
+                    tree.forEachLeaf([&](LeafClass* leaf){
+                        const FReal*const potentials = leaf->getTargets()->getPotentials();
+                        const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                        const FVector<int>& indexes = leaf->getTargets()->getIndexes();
 
-                            leafIter.gotoNext();
+                        for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                            const int indexPartOrig = indexes[idxPart];
+                            const Particle& other = (indexPartOrig==0?centeredParticle:otherParticle);
+                            potentialDiff[idxP].add(other.potential,potentials[idxPart]);
                         }
-                    } while(octreeIterator.moveRight());
+                    });
                 }
 
                 // Print for information
-                printf("For P %d, particle pos %lf\n", idxP, otherParticle.getPosition().getZ());
+                printf("For P %d, particle pos %lf\n", idxP, otherParticle.position.getZ());
                 printf("Potential diff is = %e \t %e\n",
                        potentialDiff[idxP].getL2Norm(),
                        potentialDiff[idxP].getInfNorm());
diff --git a/Tests/Kernels/testSphericalBlasAlgorithm.cpp b/Tests/Kernels/testSphericalBlasAlgorithm.cpp
index 9fca7cfc1..5d3ac19eb 100755
--- a/Tests/Kernels/testSphericalBlasAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalBlasAlgorithm.cpp
@@ -38,9 +38,9 @@
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalBlasKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 
 #include "../../Src/Files/FFmaScanfLoader.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 /** This program show an example of use of
   * the fmm blas algo
@@ -51,17 +51,16 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalBlasKernel< CellClass, ContainerClass > KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
-    typedef FFmmAlgorithmTask<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
+    typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
+    typedef FFmmAlgorithmTask<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical Blas algorithm.\n";
     std::cout << ">> You can pass -sequential or -task (thread by default).\n";
@@ -74,7 +73,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaScanfLoader<ParticleClass> loader(filename);
+    FFmaScanfLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -90,7 +89,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -130,20 +134,25 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart] * physicalValues[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalBlockBlasAlgorithm.cpp b/Tests/Kernels/testSphericalBlockBlasAlgorithm.cpp
index c3d0f4922..3f35e8785 100755
--- a/Tests/Kernels/testSphericalBlockBlasAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalBlockBlasAlgorithm.cpp
@@ -37,11 +37,12 @@
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
 
 #include "../../Src/Files/FFmaScanfLoader.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 /** This program show an example of use of
   * the fmm basic algo
   * it also check that eachh particles is little or longer
@@ -52,17 +53,16 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalBlockBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalBlockBlasKernel< CellClass, ContainerClass > KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
-    typedef FFmmAlgorithmTask<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
+    typedef FFmmAlgorithmTask<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical Block Blas algorithm.\n";
     std::cout << ">> You can pass -sequential or -task (thread by default).\n";
@@ -75,7 +75,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaScanfLoader<ParticleClass> loader(filename);
+    FFmaScanfLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -91,7 +91,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -131,20 +136,25 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart] * physicalValues[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalEwalAlgorithm.cpp b/Tests/Kernels/testSphericalEwalAlgorithm.cpp
index be3705d1f..8e13fcc42 100755
--- a/Tests/Kernels/testSphericalEwalAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalEwalAlgorithm.cpp
@@ -31,29 +31,35 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 
 #include "../../Src/Files/FEwalLoader.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
+
 /** Ewal particle is used in the gadget program
   * here we try to make the same simulation
   */
 
-
+struct EwalParticle {
+    FPoint position;
+    FReal forces[3];
+    FReal physicalValue;
+    FReal potential;
+    int index;
+};
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FEwalParticle<FSphericalParticle>    ParticleClass;
     typedef FSphericalCell          CellClass;
-    typedef FVector<ParticleClass>  ContainerClass;
+    typedef FP2PParticleContainerIndexed  ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >   KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalKernel< CellClass, ContainerClass >   KernelClass;
 
-    typedef FFmmAlgorithmPeriodic<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassNoPer;
+    typedef FFmmAlgorithmPeriodic<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClassNoPer;
 
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical algorithm.\n";
@@ -75,8 +81,8 @@ int main(int argc, char ** argv){
     // -----------------------------------------------------
 
     std::cout << "Opening : " << filename << "\n";
-    //FEwalLoader<ParticleClass> loader(filename);
-    FEwalBinLoader<ParticleClass> loader(filename);
+    //FEwalLoader loader(filename);
+    FEwalBinLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -96,16 +102,14 @@ int main(int argc, char ** argv){
 
     counter.tic();
 
-    ParticleClass * const particles = new ParticleClass[loader.getNumberOfParticles()];
+    EwalParticle * const particles = new EwalParticle[loader.getNumberOfParticles()];
+    memset(particles, 0, sizeof(EwalParticle) * loader.getNumberOfParticles());
 
     for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-        loader.fillParticle(particles[idxPart]);
+        loader.fillParticle(&particles[idxPart].position, particles[idxPart].forces,
+                            &particles[idxPart].physicalValue,&particles[idxPart].index);
         // reset forces and insert in the tree
-        particles[idxPart].setIndex(idxPart);
-        ParticleClass part = particles[idxPart];
-        part.setForces(0,0,0);
-        part.setPotential(0);
-        tree.insert(part);
+        tree.insert(particles[idxPart].position, idxPart, particles[idxPart].physicalValue);
     }
 
     counter.tac();
@@ -138,28 +142,33 @@ int main(int argc, char ** argv){
 
     // -----------------------------------------------------
 
-    ParticleClass* particlesDirect = 0;
+    EwalParticle* particlesDirect = 0;
 
     // Do direct
     if(FParameters::existParameter(argc, argv, "-direct")){
         printf("Compute direct:\n");
         printf("Box [%d;%d][%d;%d][%d;%d]\n", min.getX(), max.getX(), min.getY(),
                max.getY(), min.getZ(), max.getZ());
-        KernelClass kernels( DevP, NbLevels, loader.getBoxWidth(), loader.getCenterOfBox());
 
-        particlesDirect = new ParticleClass[loader.getNumberOfParticles()];
+        particlesDirect = new EwalParticle[loader.getNumberOfParticles()];
 
         FReal dpotential = 0.0;
         FMath::FAccurater dfx, dfy, dfz;
 
         for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
-            ParticleClass part = particles[idxTarget];
-            part.setForces(0,0,0);
-            part.setPotential(0);
+            EwalParticle part = particles[idxTarget];
+            part.forces[0] = part.forces[1] = part.forces[2] = 0.0;
+            part.potential = 0.0;
             // compute with all other except itself
             for(int idxOther = 0; idxOther < loader.getNumberOfParticles() ; ++idxOther){
                 if( idxOther != idxTarget ){
-                    kernels.directInteraction(&part, particles[idxOther]);
+                    FP2P::NonMutualParticles(
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                part.position.getX(), part.position.getY(),
+                                part.position.getZ(),part.physicalValue,
+                                &part.forces[0],&part.forces[1],
+                                &part.forces[2],&part.potential);
                 }
             }
             for(int idxX = min.getX() ; idxX <= max.getX() ; ++idxX){
@@ -172,20 +181,26 @@ int main(int argc, char ** argv){
                                             loader.getBoxWidth() * FReal(idxZ));
 
                         for(int idxSource = 0 ; idxSource < loader.getNumberOfParticles() ; ++idxSource){
-                            ParticleClass source = particles[idxSource];
-                            source.incPosition(offset.getX(),offset.getY(),offset.getZ());
-                            kernels.directInteraction(&part, source);
+                            EwalParticle source = particles[idxSource];
+                            source.position += offset;
+                            FP2P::NonMutualParticles(
+                                        source.position.getX(), source.position.getY(),
+                                        source.position.getZ(),source.physicalValue,
+                                        part.position.getX(), part.position.getY(),
+                                                  part.position.getZ(),part.physicalValue,
+                                                  &part.forces[0],&part.forces[1],
+                                                  &part.forces[2],&part.potential
+                                            );
                         }
                     }
                 }
             }
 
+            dfx.add(particles[idxTarget].forces[0],-part.forces[0]*coeff_MD1);
+            dfy.add(particles[idxTarget].forces[1],-part.forces[1]*coeff_MD1);
+            dfz.add(particles[idxTarget].forces[2],-part.forces[2]*coeff_MD1);
 
-            dfx.add(particles[idxTarget].getForces().getX(),-part.getForces().getX()*coeff_MD1);
-            dfy.add(particles[idxTarget].getForces().getY(),-part.getForces().getY()*coeff_MD1);
-            dfz.add(particles[idxTarget].getForces().getZ(),-part.getForces().getZ()*coeff_MD1);
-
-            dpotential += part.getPotential() * part.getPhysicalValue();
+            dpotential += part.potential * part.physicalValue;
 
             particlesDirect[idxTarget] = part;
         }
@@ -209,49 +224,39 @@ int main(int argc, char ** argv){
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
 
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
 
-                const ParticleClass& part = particles[iter.data().getIndex()];
-
-                // Check values ------------------------------------------------------------
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-
-                potentialDiff.add(part.getPotential(),-iter.data().getPotential());
-                fx.add(part.getForces().getX(),-iter.data().getForces().getX()*coeff_MD1);
-                fy.add(part.getForces().getY(),-iter.data().getForces().getY()*coeff_MD1);
-                fz.add(part.getForces().getZ(),-iter.data().getForces().getZ()*coeff_MD1);
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
+            const FReal*const positionsX = leaf->getTargets()->getPositions()[0];
+            const FReal*const positionsY = leaf->getTargets()->getPositions()[1];
+            const FReal*const positionsZ = leaf->getTargets()->getPositions()[2];
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+            const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                const int indexPartOrig = indexes[idxPart];
+                potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
 
                 if(FParameters::existParameter(argc, argv, "-verbose")){
-                    std::cout << ">> index " << iter.data().getIndexInFile() << std::endl;
-                    std::cout << "Good x " << part.getPosition().getX() << " y " << part.getPosition().getY() << " z " << part.getPosition().getZ() << std::endl;
-                    std::cout << "FMM  x " << iter.data().getPosition().getX() << " y " << iter.data().getPosition().getY() << " z " << iter.data().getPosition().getZ() << std::endl;
-                    std::cout << "Good fx " <<part.getForces().getX() << " fy " << part.getForces().getY() << " fz " << part.getForces().getZ() << std::endl;
-                    std::cout << "FMM  fx " << iter.data().getForces().getX()*coeff_MD1 << " fy " << iter.data().getForces().getY()*coeff_MD1 << " fz " << iter.data().getForces().getZ()*coeff_MD1 << std::endl;
-                    std::cout << "GOOD physical value " << part.getPhysicalValue() << " potential " << part.getPotential() << std::endl;
-                    std::cout << "FMM  physical value " << iter.data().getPhysicalValue() << " potential " << iter.data().getPotential() << std::endl;
-
-                    // print result
-                    if(FParameters::existParameter(argc, argv, "-verbose")
-                            && FParameters::existParameter(argc, argv, "-direct")){
-                        const int idxTarget = iter.data().getIndex();
-                        std::cout << ">> index in array " << idxTarget << std::endl;
-                        std::cout << "Direct x " << particlesDirect[idxTarget].getPosition().getX() << " y " << particlesDirect[idxTarget].getPosition().getY() << " z " << particles[idxTarget].getPosition().getZ() << std::endl;
-                        std::cout << "Direct fx " << particlesDirect[idxTarget].getForces().getX()*coeff_MD1 << " fy " << particlesDirect[idxTarget].getForces().getY()*coeff_MD1 << " fz " << particlesDirect[idxTarget].getForces().getZ()*coeff_MD1 << std::endl;
-                        std::cout << "Direct physical value " << particlesDirect[idxTarget].getPhysicalValue() << " potential " << particlesDirect[idxTarget].getPotential() << std::endl;
-                    }
+                    std::cout << ">> index " << particles[indexPartOrig].index << std::endl;
+                    std::cout << "Good x " << particles[indexPartOrig].position.getX() << " y " << particles[indexPartOrig].position.getY() << " z " << particles[indexPartOrig].position.getZ() << std::endl;
+                    std::cout << "FMM  x " << positionsX[idxPart] << " y " << positionsY[idxPart] << " z " << positionsZ[idxPart] << std::endl;
+                    std::cout << "Good fx " <<particles[indexPartOrig].forces[0] << " fy " << particles[indexPartOrig].forces[1] << " fz " << particles[indexPartOrig].forces[2] << std::endl;
+                    std::cout << "FMM  fx " << forcesX[idxPart]*coeff_MD1 << " fy " << forcesY[idxPart]*coeff_MD1 << " fz " << forcesZ[idxPart]*coeff_MD1 << std::endl;
+                    std::cout << "GOOD physical value " << particles[indexPartOrig].physicalValue << " potential " << particles[indexPartOrig].potential << std::endl;
+                    std::cout << "FMM  physical value " << physicalValues[idxPart] << " potential " << potentials[idxPart] << std::endl;
 
                     std::cout << "\n";
                 }
-
-                // Progress ------------------------------------------------------------------
-
-                iter.gotoNext();
             }
-        } while(octreeIterator.moveRight());
+        });
 	
         printf("Difference between FMM and poly:\n");
         printf("Potential diff is = \n");
@@ -274,30 +279,24 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal  potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                if(FParameters::existParameter(argc, argv, "-verbose")){
-                    std::cout << " " << iter.data().getIndex()+1 << " \t "<< iter.data().getType() << "  \t " <<
-                                 std::setprecision(5)<< iter.data().getPosition().getX() << "  \t" <<
-                                 iter.data().getPosition().getY() << "  \t" <<
-                                 iter.data().getPosition().getZ() << "   Forces: \t"<<
-                                 std::setprecision(8) << iter.data().getForces().getX()*coeff_MD1 << "  \t " <<
-                                 iter.data().getForces().getY()*coeff_MD1 << "  \t " <<
-                                 iter.data().getForces().getZ()*coeff_MD1 << std::endl;
-                }
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << std::setprecision(8) << potential*coeff_MD/2 << std::endl;
         std::cout << "Energy from file = " << std::setprecision(8) << loader.getEnergy() << std::endl;
 	//        std::cout << "Constante DL_POLY: " << coeff_MD << std::endl;
diff --git a/Tests/Kernels/testSphericalGalaxyCsv.cpp b/Tests/Kernels/testSphericalGalaxyCsv.cpp
index 00560b72b..4a71f2a14 100755
--- a/Tests/Kernels/testSphericalGalaxyCsv.cpp
+++ b/Tests/Kernels/testSphericalGalaxyCsv.cpp
@@ -30,9 +30,6 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
-
-#include "../../Src/Extensions/FExtendVelocity.hpp"
 
 #include "../../Src/Files/FTreeCsvSaver.hpp"
 #include "../../Src/Files/FFmaLoader.hpp"
@@ -40,48 +37,109 @@
 
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
-class FmmVeloParticle : public FSphericalParticle, public FExtendVelocity {
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
+
+class VelocityContainer : public FP2PParticleContainer {
+    typedef FP2PParticleContainer Parent;
+
+    FVector<FPoint> velocities;
+
+public:
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, const FPoint& velocity, Args... args){
+        Parent::push(inParticlePosition, args... );
+        velocities.push(velocity);
+    }
+
+    const FVector<FPoint>& getVelocities() const{
+        return velocities;
+    }
+
+    FVector<FPoint>& getVelocities() {
+        return velocities;
+    }
+
+    void fillToCsv(const int partIdx, FReal values[4]) const {
+        values[0] = Parent::getPositions()[0][partIdx];
+        values[1] = Parent::getPositions()[1][partIdx];
+        values[2] = Parent::getPositions()[2][partIdx];
+        values[3] = Parent::getPotentials()[partIdx];
+    }
 };
 
-template <class ParticleClass>
-class GalaxyLoader : public FFmaLoader<ParticleClass> {
+
+class GalaxyLoader : public FFmaLoader {
 public:
-    GalaxyLoader(const char* const filename) : FFmaLoader<ParticleClass>(filename) {
+    GalaxyLoader(const char* const filename) : FFmaLoader(filename) {
     }
 
-    void fillParticle(ParticleClass& inParticle){
+    void fillParticle(FPoint* position, FReal* physivalValue, FPoint* velocity){
         FReal x,y,z,data, vx, vy, vz;
         this->file >> x >> y >> z >> data >> vx >> vy >> vz;
-        inParticle.setPosition(x,y,z);
-        inParticle.setPhysicalValue(data);
-        inParticle.setVelocity(vx,vy,vz);
+        position->setPosition(x,y,z);
+        *physivalValue = (data);
+        velocity->setPosition(vx,vy,vz);
     }
 };
 
+template <class ContainerClass>
+class GalaxyExtractor {
+    struct Particle{
+        FPoint position;
+        FReal physicalValue;
+        FReal forces[3];
+        FReal potential;
+        FPoint velocity;
+    };
+
+    FVector<Particle> savedParticles;
 
-template <class OctreeClass, class ContainerClass , class ParticleClass>
-class MassSaver : public FTreeCsvSaver<OctreeClass,ContainerClass, ParticleClass> {
 public:
-    MassSaver(const char inBasefile[], const bool inIncludeHeader = false)
-        : FTreeCsvSaver<OctreeClass,ContainerClass, ParticleClass> (inBasefile,inIncludeHeader) {
+    void extractParticles(const ContainerClass* containers, const int indexesToExtract[], const int nbToExtract){
+        const FReal*const positionsX = containers->getPositions()[0];
+        const FReal*const positionsY = containers->getPositions()[1];
+        const FReal*const positionsZ = containers->getPositions()[2];
+        const FReal*const forcesX = containers->getForcesX();
+        const FReal*const forcesY = containers->getForcesY();
+        const FReal*const forcesZ = containers->getForcesZ();
+        const FReal*const physicalValues = containers->getPhysicalValues();
+        const FReal*const potentials = containers->getPotentials();
+        FVector<FPoint> velocites = containers->getVelocities();
+
+        for(int idxPart = 0 ; idxPart < nbToExtract ; ++ idxPart){
+            const int idxExtract = indexesToExtract[idxPart];
+            Particle part;
+            part.position.setPosition( positionsX[idxExtract],positionsY[idxExtract],positionsZ[idxExtract]);
+            part.physicalValue = physicalValues[idxExtract];
+            part.forces[0] = forcesX[idxExtract];
+            part.forces[1] = forcesY[idxExtract];
+            part.forces[2] = forcesZ[idxExtract];
+            part.potential = potentials[idxExtract];
+            part.velocity  = velocites[idxExtract];
+        }
     }
 
-    virtual FReal getValue(ParticleClass*const part){
-        return part->getPhysicalValue();
+    template <class OctreeClass>
+    void reinsertInTree(OctreeClass* tree){
+        for(int idxPart = 0 ; idxPart < savedParticles.getSize() ; ++idxPart){
+            const Particle part = savedParticles[idxPart];
+            tree->insert(part.position, part.velocity, part.physicalValue, part.forces[0],
+                    part.forces[1],part.forces[2],part.potential);
+        }
     }
 };
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FmmVeloParticle         ParticleClass;
     typedef FSphericalCell          CellClass;
-    typedef FVector<ParticleClass>  ContainerClass;
+    typedef VelocityContainer  ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >   KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalKernel< CellClass, ContainerClass >   KernelClass;
 
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical algorithm.\n";
     //////////////////////////////////////////////////////////////
@@ -93,7 +151,7 @@ int main(int argc, char ** argv){
 
     FSphericalCell::Init(DevP);
 
-    GalaxyLoader<ParticleClass> loader(FParameters::getStr(argc,argv,"-f", "../Data/galaxy.fma.tmp"));
+    GalaxyLoader loader(FParameters::getStr(argc,argv,"-f", "../Data/galaxy.fma.tmp"));
 
     // -----------------------------------------------------
 
@@ -105,12 +163,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
 
     {
-        ParticleClass particleToFill;
-        particleToFill.setPhysicalValue(FReal(0.10));
+        FPoint position, velocity;
+        FReal physicalValue;
 
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particleToFill);
-            tree.insert(particleToFill);
+            loader.fillParticle(&position, &physicalValue, &velocity);
+            tree.insert(position, velocity, physicalValue);
         }
     }
 
@@ -118,8 +176,8 @@ int main(int argc, char ** argv){
 
     KernelClass kernels( DevP, NbLevels, loader.getBoxWidth(), loader.getCenterOfBox());
     FmmClass algo( &tree, &kernels);
-    FOctreeArranger<OctreeClass, ContainerClass, ParticleClass> arranger(&tree);
-    MassSaver<OctreeClass, ContainerClass, ParticleClass> saver("./out/test%d.csv");
+    FOctreeArranger<OctreeClass, ContainerClass, GalaxyExtractor<ContainerClass> > arranger(&tree);
+    FTreeCsvSaver<OctreeClass, ContainerClass> saver("./out/test%d.csv");
 
     for(int idx = 0; idx < 100 ; ++idx){
         algo.execute();
@@ -127,12 +185,8 @@ int main(int argc, char ** argv){
             OctreeClass::Iterator octreeIterator(&tree);
             octreeIterator.gotoBottomLeft();
             do{
-                ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-                while( iter.hasNotFinished() ){
-                    kernels.computeVelocity(&iter.data(), DT);
-                    kernels.updatePosition(&iter.data(), DT);
-                    iter.gotoNext();
-                }
+                kernels.computeVelocity(octreeIterator.getCurrentListTargets(), DT);
+                kernels.updatePosition(octreeIterator.getCurrentListTargets(), DT);
             } while(octreeIterator.moveRight());
         }
         // update tree and vtk
diff --git a/Tests/Kernels/testSphericalRotationAlgorithm.cpp b/Tests/Kernels/testSphericalRotationAlgorithm.cpp
index d83561db9..11c628020 100755
--- a/Tests/Kernels/testSphericalRotationAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalRotationAlgorithm.cpp
@@ -33,10 +33,11 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalRotationKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 
 #include "../../Src/Files/FFmaScanfLoader.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 /** This program show an example of use of
   * the fmm basic algo
   * it also check that eachh particles is little or longer
@@ -46,17 +47,16 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalRotationKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalRotationKernel< CellClass, ContainerClass > KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
-    typedef FFmmAlgorithmTask<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmThread<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;
+    typedef FFmmAlgorithmTask<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassTask;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical Rotation algorithm.\n";
     std::cout << ">> You can pass -sequential or -task (thread by default).\n";
@@ -69,7 +69,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaScanfLoader<ParticleClass> loader(filename);
+    FFmaScanfLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -85,7 +85,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -125,20 +130,24 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalTsmAlgorithm.cpp b/Tests/Kernels/testSphericalTsmAlgorithm.cpp
index 9a9d71c8a..f953cb7dc 100755
--- a/Tests/Kernels/testSphericalTsmAlgorithm.cpp
+++ b/Tests/Kernels/testSphericalTsmAlgorithm.cpp
@@ -31,10 +31,11 @@
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 
 #include "../../Src/Files/FFmaTsmLoader.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 /** This program show an example of use of
   * the fmm basic algo
   * it also check that eachh particles is little or longer
@@ -44,15 +45,14 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FTypedSphericalParticle        ParticleClass;
     typedef FTypedSphericalCell            CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FTypedLeaf<ParticleClass, ContainerClass >                      LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+    typedef FTypedLeaf< ContainerClass >                      LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalKernel< CellClass, ContainerClass >          KernelClass;
 
-    typedef FFmmAlgorithmTsm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithmTsm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical on a Tsm system.\n";
     //////////////////////////////////////////////////////////////
@@ -64,7 +64,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.tsm.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaTsmLoader<ParticleClass> loader(filename);
+    FFmaTsmLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -80,7 +80,13 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        bool isTarget;
+        loader.fillParticle(&particlePosition,&physicalValue,&isTarget);
+        tree.insert(particlePosition, isTarget, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -109,20 +115,24 @@ int main(int argc, char ** argv){
 
     { // get sum forces&potential
         FReal potential = 0;
-        FPoint forces;
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            FVector<ParticleClass>::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                potential += iter.data().getPotential() * iter.data().getPhysicalValue();
-                forces += iter.data().getForces();
-
-                iter.gotoNext();
+        FReal fx = 0.0, fy = 0.0, fz = 0.0;
+
+        tree.forEachLeaf([&](LeafClass* leaf){
+            const FReal*const potentials = leaf->getTargets()->getPotentials();
+            const FReal*const forcesX = leaf->getTargets()->getForcesX();
+            const FReal*const forcesY = leaf->getTargets()->getForcesY();
+            const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+            const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+
+            for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                potential += potentials[idxPart];
+                fx += forcesX[idxPart];
+                fy += forcesY[idxPart];
+                fz += forcesZ[idxPart];
             }
-        } while(octreeIterator.moveRight());
+        });
 
-        std::cout << "Foces Sum  x = " << forces.getX() << " y = " << forces.getY() << " z = " << forces.getZ() << std::endl;
+        std::cout << "Foces Sum  x = " << fx << " y = " << fy << " z = " << fz << std::endl;
         std::cout << "Potential = " << potential << std::endl;
     }
 
diff --git a/Tests/Kernels/testSphericalTsmNoTsm.cpp b/Tests/Kernels/testSphericalTsmNoTsm.cpp
deleted file mode 100755
index fc4dd6e0a..000000000
--- a/Tests/Kernels/testSphericalTsmNoTsm.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-
-#include <iostream>
-
-#include <cstdio>
-#include <cstdlib>
-
-#include "../../Src/Utils/FTic.hpp"
-#include "../../Src/Utils/FParameters.hpp"
-
-#include "../../Src/Containers/FOctree.hpp"
-#include "../../Src/Containers/FVector.hpp"
-
-#include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
-
-#include "../../Src/Core/FFmmAlgorithm.hpp"
-#include "../../Src/Core/FFmmAlgorithmTsm.hpp"
-#include "../../Src/Core/FFmmAlgorithmThread.hpp"
-#include "../../Src/Core/FFmmAlgorithmThreadTsm.hpp"
-
-#include "../../Src/Components/FSimpleLeaf.hpp"
-#include "../../Src/Components/FTypedLeaf.hpp"
-
-
-/** This program show an example of use of
-  * the fmm basic algo
-  * it also check that eachh particles is little or longer
-  * related that each other
-  */
-
-
-// Simply create particles and try the kernels
-int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
-    typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
-
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                      LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
-
-    typedef FFmmAlgorithmThread<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
-
-    typedef FTypedSphericalParticle             ParticleClassTyped;
-    typedef FTypedSphericalCell                 CellClassTyped;
-    typedef FVector<ParticleClassTyped>  ContainerClassTyped;
-
-    typedef FTypedLeaf<ParticleClassTyped, ContainerClassTyped >                      LeafClassTyped;
-    typedef FOctree<ParticleClassTyped, CellClassTyped, ContainerClassTyped , LeafClassTyped >  OctreeClassTyped;
-    typedef FSphericalKernel<ParticleClassTyped, CellClassTyped, ContainerClassTyped >          KernelClassTyped;
-
-    typedef FFmmAlgorithmThreadTsm<OctreeClassTyped, ParticleClassTyped, CellClassTyped, ContainerClassTyped, KernelClassTyped, LeafClassTyped > FmmClassTyped;
-
-    ///////////////////////What we do/////////////////////////////
-    std::cout << ">> This executable has to be used to test Spherical on a Tsm system.\n";
-    std::cout << ">> It compares the results between Tms and no Tms (except P2P & L2P).\n";
-    //////////////////////////////////////////////////////////////
-    const int DevP = FParameters::getValue(argc,argv,"-p", 8);
-    const int NbLevels = FParameters::getValue(argc,argv,"-h", 5);
-    const int SizeSubLevels = FParameters::getValue(argc,argv,"-sh", 3);
-    FTic counter;
-    const int NbPart = 200000;//2000000
-    const double BoxWidth = 1.0;
-    const FPoint CenterOfBox(0.5,0.5,0.5);
-    const FReal FRandMax = FReal(RAND_MAX);
-
-
-    // -----------------------------------------------------
-    CellClass::Init(DevP);
-
-    OctreeClass tree(NbLevels, SizeSubLevels,BoxWidth,CenterOfBox);
-    OctreeClassTyped treeTyped(NbLevels, SizeSubLevels,BoxWidth,CenterOfBox);
-
-
-    std::cout << "Inserting particles ..." << std::endl;
-    counter.tic();
-    for(long idxPart = 0 ; idxPart < NbPart ; ++idxPart){
-        const FReal x = FReal(rand())/FRandMax;
-        const FReal y = FReal(rand())/FRandMax;
-        const FReal z = FReal(rand())/FRandMax;
-
-        ParticleClass particles;
-        ParticleClassTyped particlesTyped;
-        ParticleClassTyped particlesTyped2;
-
-        // Particle for standart model
-        particles.setPosition(x,y,z);
-        particles.setPhysicalValue(1);
-
-        // Create a clone for typed (Tsm) version
-        particlesTyped.setPosition(x,y,z);
-        particlesTyped2.setPosition(x,y,z);
-
-        particlesTyped.setPhysicalValue(1);
-        particlesTyped2.setPhysicalValue(1);
-
-        particlesTyped.setAsSource();
-        particlesTyped2.setAsTarget();
-
-        tree.insert(particles);
-        treeTyped.insert(particlesTyped);
-        treeTyped.insert(particlesTyped2);
-    }
-    counter.tac();
-    std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
-
-    // -----------------------------------------------------
-    std::cout << "Create kernels ..." << std::endl;
-
-    KernelClass kernels(DevP, NbLevels, BoxWidth, CenterOfBox);
-    KernelClassTyped kernelsTyped(DevP, NbLevels, BoxWidth, CenterOfBox);
-
-
-    std::cout << "Working on particles ..." << std::endl;
-
-    FmmClass algo(&tree,&kernels);
-    FmmClassTyped algoTyped(&treeTyped,&kernelsTyped);
-
-    counter.tic();
-    algo.execute();
-    algoTyped.execute();
-
-    counter.tac();
-    std::cout << "Done  " << "(@Algorithm = " << counter.elapsed() << "s)." << std::endl;
-
-    // -----------------------------------------------------
-
-    // Here we compare the cells of the trees that must contains the same values
-
-    std::cout << "Start checking ..." << std::endl;
-    {
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-
-        OctreeClassTyped::Iterator octreeIteratorTyped(&treeTyped);
-        octreeIteratorTyped.gotoBottomLeft();
-
-        for(int idxLevel = NbLevels - 1 ; idxLevel > 1 ; --idxLevel ){
-            std::cout << "\t test level " << idxLevel << "\n";
-
-            do{
-                bool poleDiff = false;
-                bool localDiff = false;
-                for(int idxValues = 0 ; idxValues < FSphericalCell::GetPoleSize() && !(poleDiff && localDiff); ++idxValues){
-                    const FComplexe pole = octreeIterator.getCurrentCell()->getMultipole()[idxValues];
-                    const FComplexe poleTyped = octreeIteratorTyped.getCurrentCell()->getMultipole()[idxValues];
-                    if(!FMath::LookEqual(pole.getImag(),poleTyped.getImag()) || !FMath::LookEqual(pole.getReal(),poleTyped.getReal())){
-                        poleDiff = true;
-                        printf("Pole diff imag( %.15e , %.15e ) real( %.15e , %.15e)\n",
-                               pole.getImag(),poleTyped.getImag(),pole.getReal(),poleTyped.getReal());
-                    }
-                }
-                for(int idxValues = 0 ; idxValues < FSphericalCell::GetPoleSize() && !(poleDiff && localDiff); ++idxValues){
-                    const FComplexe local = octreeIterator.getCurrentCell()->getLocal()[idxValues];
-                    const FComplexe localTyped = octreeIteratorTyped.getCurrentCell()->getLocal()[idxValues];
-                    if(!FMath::LookEqual(local.getImag(),localTyped.getImag()) || !FMath::LookEqual(local.getReal(),localTyped.getReal())){
-                        localDiff = true;
-                        printf("Pole diff imag( %.15e , %.15e ) real( %.15e , %.15e)\n",
-                               local.getImag(),localTyped.getImag(),local.getReal(),localTyped.getReal());
-                    }
-                }
-                if(poleDiff){
-                    std::cout << "Multipole error at level " << idxLevel << "\n";
-                }
-                if(localDiff){
-                    std::cout << "Locale error at level " << idxLevel << "\n";
-                }
-            } while(octreeIterator.moveRight() && octreeIteratorTyped.moveRight());
-
-            octreeIterator.moveUp();
-            octreeIterator.gotoLeft();
-
-            octreeIteratorTyped.moveUp();
-            octreeIteratorTyped.gotoLeft();
-        }
-    }
-
-    std::cout << "Done ..." << std::endl;
-
-    return 0;
-}
-
-
-
diff --git a/Tests/Kernels/testTuneSphericalBlockBlas.cpp b/Tests/Kernels/testTuneSphericalBlockBlas.cpp
index bbfe1ad42..11e19c687 100755
--- a/Tests/Kernels/testTuneSphericalBlockBlas.cpp
+++ b/Tests/Kernels/testTuneSphericalBlockBlas.cpp
@@ -36,11 +36,12 @@
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Kernels/Spherical/FSphericalBlockBlasKernel.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
 
 #include "../../Src/Files/FFmaScanfLoader.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 /** This program find the best block blas size
   */
 
@@ -48,15 +49,14 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FSphericalBlockBlasKernel<ParticleClass, CellClass, ContainerClass > KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSphericalBlockBlasKernel< CellClass, ContainerClass > KernelClass;
 
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test Spherical algorithm.\n";
     //////////////////////////////////////////////////////////////
@@ -69,15 +69,13 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-
-
     // -----------------------------------------------------
     double minTime = 999999999999999999.0;
     int bestSize = -1;
 
     CellClass::Init(DevP, true);
     for(int idxBlockSize = 1 ; idxBlockSize < MaxBlockSize ; idxBlockSize *= 2){
-        FFmaScanfLoader<ParticleClass> loader(filename);
+        FFmaScanfLoader loader(filename);
         if(!loader.isOpen()){
             std::cout << "Loader Error, " << filename << " is missing\n";
             return 1;
@@ -87,7 +85,12 @@ int main(int argc, char ** argv){
 
         // -----------------------------------------------------
 
-        loader.fillTree(tree);
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            FPoint particlePosition;
+            FReal physicalValue = 0.0;
+            loader.fillParticle(&particlePosition,&physicalValue);
+            tree.insert(particlePosition, physicalValue );
+        }
 
         // -----------------------------------------------------
 
diff --git a/Tests/Utils/testChebInterpolator.cpp b/Tests/Utils/testChebInterpolator.cpp
index 9db12aa4a..3310e8636 100755
--- a/Tests/Utils/testChebInterpolator.cpp
+++ b/Tests/Utils/testChebInterpolator.cpp
@@ -33,11 +33,12 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebInterpolator.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+#include "../../Src/Components/FSimpleLeaf.hpp"
 
 
 
@@ -73,11 +74,9 @@ FReal computeINFnorm(unsigned int N, FReal *const u, FReal *const v)
 * In this file we show how to use octree
 */
 
-int main(int, char **){    
-
-	typedef FChebParticle ParticleClass;
-	typedef FVector<FChebParticle> ContainerClass;
-	typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+int main(int, char **){
+    typedef FP2PParticleContainer ContainerClass;
+    typedef FSimpleLeaf<ContainerClass> LeafClass;
 	typedef FChebMatrixKernelR MatrixKernelClass;
 
 
@@ -101,15 +100,12 @@ int main(int, char **){
 	const unsigned long M = 20000;
 	std::cout << "Fill the leaf X of width " << width
 						<< " centered at cx=" << cx << " with M=" << M << " target particles" << std::endl;
-	{
-		FChebParticle particle;
+    {
 		for(unsigned long i=0; i<M; ++i){
 			FReal x = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getX();
 			FReal y = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getY();
 			FReal z = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getZ();
-			particle.setPosition(x, y, z);
-			particle.setPhysicalValue(FReal(rand())/FRandMax);
-			X.push(particle);
+            X.push(FPoint(x, y, z), FReal(rand())/FRandMax);
 		}
 	}
 
@@ -120,15 +116,12 @@ int main(int, char **){
 	const unsigned long N = 20000;
 	std::cout << "Fill the leaf Y of width " << width
 						<< " centered at cy=" << cy	<< " with N=" << N << " target particles" << std::endl;
-	{
-		FChebParticle particle;
+    {
 		for(unsigned long i=0; i<N; ++i){
 			FReal x = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getX();
 			FReal y = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getY();
 			FReal z = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getZ();
-			particle.setPosition(x, y, z);
-			particle.setPhysicalValue(FReal(rand())/FRandMax);
-			Y.push(particle);
+            Y.push(FPoint(x, y, z), FReal(rand())/FRandMax);
 		}
 	}
 
@@ -194,15 +187,18 @@ int main(int, char **){
 	{ // start direct computation
 		unsigned int counter = 0;
 		
-		ContainerClass::ConstBasicIterator iterX(*(X.getSrc()));
-		while(iterX.hasNotFinished()){
-			const FPoint& x = iterX.data().getPosition();
-			const FReal  wx = iterX.data().getPhysicalValue();
+        for(int idxPartX = 0 ; idxPartX < X.getSrc()->getNbParticles() ; ++idxPartX){
+            const FPoint x = FPoint(X.getSrc()->getPositions()[0][idxPartX],
+                                     X.getSrc()->getPositions()[1][idxPartX],
+                                     X.getSrc()->getPositions()[2][idxPartX]);
+            const FReal  wx = X.getSrc()->getPhysicalValues()[idxPartX];
 			
-			ContainerClass::ConstBasicIterator iterY(*(Y.getSrc()));
-			while(iterY.hasNotFinished()){
-				const FPoint& y = iterY.data().getPosition();
-				const FReal  wy = iterY.data().getPhysicalValue();
+            for(int idxPartY = 0 ; idxPartY < Y.getSrc()->getNbParticles() ; ++idxPartY){
+                const FPoint y = FPoint(Y.getSrc()->getPositions()[0][idxPartY],
+                                         Y.getSrc()->getPositions()[1][idxPartY],
+                                         Y.getSrc()->getPositions()[2][idxPartY]);
+                const FReal  wy = Y.getSrc()->getPhysicalValues()[idxPartY];
+
 				const FReal one_over_r = MatrixKernel.evaluate(x, y);
 				// potential
 				p[counter] += one_over_r * wy;
@@ -212,11 +208,9 @@ int main(int, char **){
 				f[counter*3 + 0] += force.getX() * wx * wy;
 				f[counter*3 + 1] += force.getY() * wx * wy;
 				f[counter*3 + 2] += force.getZ() * wx * wy;
-				iterY.gotoNext();
 			}
 			
-			counter++;
-			iterX.gotoNext();
+            counter++;
 		}
 	} // end direct computation
 
@@ -225,18 +219,18 @@ int main(int, char **){
 	std::cout << "Done in " << time.elapsed() << "sec." << std::endl;
 
 
-	////////////////////////////////////////////////////////////////////
-	ContainerClass::ConstBasicIterator iterX(*(X.getSrc()));
+    ////////////////////////////////////////////////////////////////////
 	unsigned int counter = 0;
-	while(iterX.hasNotFinished()) {
-		approx_p[counter] = iterX.data().getPotential();
-		const FPoint& force = iterX.data().getForces();
+    for(int idxPartX = 0 ; idxPartX < X.getSrc()->getNbParticles() ; ++idxPartX){
+        approx_p[counter] = X.getSrc()->getPotentials()[idxPartX];
+        const FPoint force = FPoint(X.getSrc()->getForcesX()[idxPartX],
+                                    X.getSrc()->getForcesY()[idxPartX],
+                                    X.getSrc()->getForcesZ()[idxPartX]);
 		approx_f[counter*3 + 0] = force.getX();
 		approx_f[counter*3 + 1] = force.getY();
 		approx_f[counter*3 + 2] = force.getZ();
 
-		counter++;
-		iterX.gotoNext();
+        counter++;
 	}
 
 	std::cout << "\nPotential error:" << std::endl;
diff --git a/Tests/Utils/testChebOctree.cpp b/Tests/Utils/testChebOctree.cpp
index 551288999..54d501e38 100755
--- a/Tests/Utils/testChebOctree.cpp
+++ b/Tests/Utils/testChebOctree.cpp
@@ -28,10 +28,11 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 /**
 * In this file we show how to use octree
@@ -41,11 +42,10 @@ int main(int, char **){
 
 	const int ORDER = 5;
 
-	typedef FChebParticle ParticleClass;
-	typedef FVector<FChebParticle> ContainerClass;
-	typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+    typedef FP2PParticleContainer ContainerClass;
+    typedef FSimpleLeaf<ContainerClass> LeafClass;
 	typedef FChebCell<ORDER> CellClass;
-	typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
+    typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
 	
 	///////////////////////What we do/////////////////////////////
 	std::cout << ">> This executable is useless to execute.\n";
@@ -67,11 +67,9 @@ int main(int, char **){
 	// -----------------------------------------------------
 	std::cout << "Creating and inserting " << NbPart << " particles ..." << std::endl;
 	counter.tic();
-	{
-		FChebParticle particle;
-		for(long idxPart = 0 ; idxPart < NbPart ; ++idxPart){
-			particle.setPosition(FReal(rand())/FRandMax,FReal(rand())/FRandMax,FReal(rand())/FRandMax);
-			tree.insert(particle);
+    {
+        for(long idxPart = 0 ; idxPart < NbPart ; ++idxPart){
+            tree.insert(FPoint(FReal(rand())/FRandMax,FReal(rand())/FRandMax,FReal(rand())/FRandMax));
 		}
 	}
 	counter.tac();
@@ -83,30 +81,28 @@ int main(int, char **){
 	// Check if particles are strictly within its containing leaf cells
 	{
 		const FReal BoxWidthLeaf = BoxWidth / FReal(FMath::pow(2, TreeHeight-1));
-		OctreeClass::Iterator octreeIterator(&tree);
-		octreeIterator.gotoBottomLeft();
-		do{
-			const CellClass *const LeafCell = octreeIterator.getCurrentCell();
-
+        tree.forEachCellLeaf([&](CellClass* LeafCell, LeafClass* leaf){
 			const FPoint Origin(BoxCenter - BoxWidth / FReal(2.));
 			const FPoint LeafCellCenter(Origin.getX() + (FReal(LeafCell->getCoordinate().getX()) + FReal(.5)) * BoxWidthLeaf,
 																			 Origin.getY() + (FReal(LeafCell->getCoordinate().getY()) + FReal(.5)) * BoxWidthLeaf,
 																			 Origin.getZ() + (FReal(LeafCell->getCoordinate().getZ()) + FReal(.5)) * BoxWidthLeaf);
 
-			const ContainerClass *const Particles = octreeIterator.getCurrentListSrc();
-			ContainerClass::ConstBasicIterator particleIterator(*Particles);
-			while(particleIterator.hasNotFinished()) {
-				const FPoint distance(LeafCellCenter-particleIterator.data().getPosition());
+            const ContainerClass *const Particles = leaf->getSrc();
+            const FReal*const positionsX = Particles->getPositions()[0];
+            const FReal*const positionsY = Particles->getPositions()[1];
+            const FReal*const positionsZ = Particles->getPositions()[2];
+
+            for(int idxPart = 0 ; idxPart < Particles->getNbParticles() ; ++idxPart){
+                const FPoint distance(LeafCellCenter-FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]));
 				if (std::abs(distance.getX())>BoxWidthLeaf/FReal(2.) ||
 						std::abs(distance.getY())>BoxWidthLeaf/FReal(2.) ||
 						std::abs(distance.getZ())>BoxWidthLeaf/FReal(2.)) {
 					std::cout << "Particle (center - particle = " << distance << " < " << BoxWidthLeaf/FReal(2.) << ") is out of cell. STOP"
 										<< std::endl;
 					//exit(-1);
-				}
-				particleIterator.gotoNext();
+                }
 			}
-		} while(octreeIterator.moveRight());
+        });
 	}
 
 	return 0;
diff --git a/Tests/Utils/testChebSxUCBSy.cpp b/Tests/Utils/testChebSxUCBSy.cpp
index a01cd5521..47174b209 100755
--- a/Tests/Utils/testChebSxUCBSy.cpp
+++ b/Tests/Utils/testChebSxUCBSy.cpp
@@ -33,11 +33,12 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebInterpolator.hpp"
 #include "../../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 void applyM2M(FReal *const S,	FReal *const w, const unsigned int n,	FReal *const W, const unsigned int N)
 { FBlas::gemtva(n, N, FReal(1.), S,	w, W); }
@@ -76,9 +77,8 @@ FReal computeINFnorm(unsigned int N, FReal *const u, FReal *const v)
 
 int main(int argc, char* argv[])
 {
-	typedef FChebParticle ParticleClass;
-	typedef FVector<FChebParticle> ContainerClass;
-	typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+    typedef FP2PParticleContainer ContainerClass;
+    typedef FSimpleLeaf<ContainerClass> LeafClass;
 	typedef FChebMatrixKernelR MatrixKernelClass;
 
 	///////////////////////What we do/////////////////////////////
@@ -102,14 +102,12 @@ int main(int argc, char* argv[])
 	std::cout << "Fill the leaf X of width " << width
 						<< " centered at cx=[" << cx.getX() << "," << cx.getY() << "," << cx.getZ()
 						<< "] with M=" << M << " target particles" << std::endl;
-	{
-		FChebParticle particle;
+    {
 		for(long i=0; i<M; ++i){
 			FReal x = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getX();
 			FReal y = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getY();
-			FReal z = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getZ();
-			particle.setPosition(x, y, z);
-			X.push(particle);
+            FReal z = (FReal(rand())/FRandMax - FReal(.5)) * width + cx.getZ();
+            X.push(FPoint(x,y,z));
 		}
 	}
 
@@ -121,15 +119,12 @@ int main(int argc, char* argv[])
 	std::cout << "Fill the leaf Y of width " << width
 						<< " centered at cy=[" << cy.getX() << "," << cy.getY() << "," << cy.getZ()
 						<< "] with N=" << N << " target particles" << std::endl;
-	{
-		FChebParticle particle;
+    {
 		for(long i=0; i<N; ++i){
 			FReal x = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getX();
 			FReal y = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getY();
 			FReal z = (FReal(rand())/FRandMax - FReal(.5)) * width + cy.getZ();
-			particle.setPosition(x, y, z);
-			particle.setPhysicalValue(FReal(rand())/FRandMax);
-			Y.push(particle);
+            Y.push(FPoint(x, y, z),FReal(rand())/FRandMax);
 		}
 	}
 
@@ -197,30 +192,36 @@ int main(int argc, char* argv[])
 
 	FReal* approx_f = new FReal[M];
 	FReal*        f = new FReal[M];
-	for (unsigned int i=0; i<M; ++i) f[i] = FReal(0.);
-	ContainerClass::ConstBasicIterator iterY(*(Y.getSrc()));
-	while(iterY.hasNotFinished()){
-		const FPoint& y = iterY.data().getPosition();
-		const FReal        w = iterY.data().getPhysicalValue();
-		unsigned int counter = 0;
-		ContainerClass::ConstBasicIterator iterX(*(X.getSrc()));
-		while(iterX.hasNotFinished()){
-			const FPoint& x = iterX.data().getPosition();
-			f[counter++] += MatrixKernel.evaluate(x,y) * w;
-			iterX.gotoNext();
-		}
-		iterY.gotoNext();
-	}
+    {
+        for (unsigned int i=0; i<M; ++i) f[i] = FReal(0.);
+
+        const FReal*const positionsX = Y.getSrc()->getPositions()[0];
+        const FReal*const positionsY = Y.getSrc()->getPositions()[1];
+        const FReal*const positionsZ = Y.getSrc()->getPositions()[2];
+        const FReal*const physicalValues = Y.getSrc()->getPhysicalValues();
+
+        for(int idxPart = 0 ; idxPart < Y.getSrc()->getNbParticles() ; ++idxPart){
+            const FPoint y = FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
+            const FReal        w = physicalValues[idxPart];
+
+            const FReal*const xpositionsX = X.getSrc()->getPositions()[0];
+            const FReal*const xpositionsY = X.getSrc()->getPositions()[1];
+            const FReal*const xpositionsZ = X.getSrc()->getPositions()[2];
+
+            for(int idxPartX = 0 ; idxPartX < X.getSrc()->getNbParticles() ; ++idxPartX){
+                const FPoint x = FPoint(xpositionsX[idxPart],xpositionsY[idxPart],xpositionsZ[idxPart]);
+                f[idxPartX] += MatrixKernel.evaluate(x,y) * w;
+            }
+        }
+    }
 	time.tac();
 	std::cout << "Done in " << time.elapsed() << "sec." << std::endl;
 
 
 	////////////////////////////////////////////////////////////////////
-	ContainerClass::ConstBasicIterator iterX(*(X.getSrc()));
-	unsigned int counter = 0;
-	while(iterX.hasNotFinished()) {
-		approx_f[counter++] = iterX.data().getPotential();
-		iterX.gotoNext();
+    const FReal*const potentials = X.getSrc()->getPotentials();
+    for(int idxPart = 0 ; idxPart < X.getSrc()->getNbParticles() ; ++idxPart){
+        approx_f[idxPart] = potentials[idxPart];
 	}
 
 	
diff --git a/Tests/Utils/testCompareIOTree.cpp b/Tests/Utils/testCompareIOTree.cpp
index 324f4aa46..06b385c7f 100755
--- a/Tests/Utils/testCompareIOTree.cpp
+++ b/Tests/Utils/testCompareIOTree.cpp
@@ -30,19 +30,18 @@
 #include "../../Src/Files/FTreeIO.hpp"
 
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
-
+#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to compare two trees.\n";
     //////////////////////////////////////////////////////////////
@@ -58,8 +57,8 @@ int main(int argc, char ** argv){
     const char* const filename2 = FParameters::getStr(argc,argv,"-f1", "dtree.data");
     std::cout << "Compare tree " << filename1 << " and " << filename2 << std::endl;
 
-    FTreeIO::Load<OctreeClass, CellClass, ParticleClass, ContainerClass >(filename1, tree1);
-    FTreeIO::Load<OctreeClass, CellClass, ParticleClass, ContainerClass >(filename2, tree2);
+    FTreeIO::Load<OctreeClass, CellClass, LeafClass, ContainerClass >(filename1, tree1);
+    FTreeIO::Load<OctreeClass, CellClass, LeafClass, ContainerClass >(filename2, tree2);
 
     // -----------------------------------------------------
     std::cout << "Check Result\n";
@@ -78,10 +77,10 @@ int main(int argc, char ** argv){
                 break;
             }
 
-            if( octreeIterator1.getCurrentListSrc()->getSize() != octreeIterator2.getCurrentListSrc()->getSize()){
+            if( octreeIterator1.getCurrentListSrc()->getNbParticles() != octreeIterator2.getCurrentListSrc()->getNbParticles()){
                 std::cout << "Number of particles different on leaf " << octreeIterator1.getCurrentGlobalIndex() <<
-                             " tree1 " << octreeIterator1.getCurrentListSrc()->getSize() <<
-                             " tree2 " << octreeIterator2.getCurrentListSrc()->getSize() << std::endl;
+                             " tree1 " << octreeIterator1.getCurrentListSrc()->getNbParticles() <<
+                             " tree2 " << octreeIterator2.getCurrentListSrc()->getNbParticles() << std::endl;
             }
 
             nbLeaves += 1;
diff --git a/Tests/Utils/testFmmAlgorithm.cpp b/Tests/Utils/testFmmAlgorithm.cpp
index e9f2f3cb0..b33692f78 100755
--- a/Tests/Utils/testFmmAlgorithm.cpp
+++ b/Tests/Utils/testFmmAlgorithm.cpp
@@ -28,7 +28,7 @@
 
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
+#include "../../Src/Components/FTestParticleContainer.hpp"
 #include "../../Src/Components/FTestCell.hpp"
 #include "../../Src/Components/FTestKernels.hpp"
 
@@ -47,16 +47,15 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FTestParticle               ParticleClass;
     typedef FTestCell                   CellClass;
-    typedef FVector<ParticleClass>      ContainerClass;
+    typedef FTestParticleContainer      ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FTestKernels<ParticleClass, CellClass, ContainerClass >         KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FTestKernels< CellClass, ContainerClass >         KernelClass;
 
     // FFmmAlgorithmTask FFmmAlgorithmThread
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
 
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
@@ -70,7 +69,7 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    FRandomLoader<ParticleClass> loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
+    FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
     OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
 
     //////////////////////////////////////////////////////////////////////////////////
@@ -80,7 +79,13 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    {
+        FPoint particlePosition;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition);
+            tree.insert(particlePosition);
+        }
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -101,7 +106,7 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    ValidateFMMAlgo<OctreeClass, ParticleClass, CellClass, ContainerClass, LeafClass>(&tree);
+    ValidateFMMAlgo<OctreeClass, CellClass, ContainerClass, LeafClass>(&tree);
 
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/Utils/testFmmAlgorithmPeriodic.cpp b/Tests/Utils/testFmmAlgorithmPeriodic.cpp
index 60e03b3f8..4fad5a32f 100755
--- a/Tests/Utils/testFmmAlgorithmPeriodic.cpp
+++ b/Tests/Utils/testFmmAlgorithmPeriodic.cpp
@@ -30,9 +30,10 @@
 
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
+#include "../../Src/Components/FTestParticleContainer.hpp"
+
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
 #include "../../Src/Components/FTestCell.hpp"
 #include "../../Src/Components/FTestKernels.hpp"
 
@@ -46,15 +47,14 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FTestParticle               ParticleClass;
     typedef FTestCell                   CellClass;
-    typedef FVector<ParticleClass>      ContainerClass;
+    typedef FTestParticleContainer      ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef FTestKernels<ParticleClass, CellClass, ContainerClass >         KernelClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FTestKernels< CellClass, ContainerClass >         KernelClass;
 
-    typedef FFmmAlgorithmPeriodic<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
+    typedef FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
     //////////////////////////////////////////////////////////////
@@ -81,9 +81,16 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    FRandomLoader<ParticleClass> loader(NbParticles);
+    FRandomLoader loader(NbParticles);
     OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-    loader.fillTree(tree);
+
+    {
+        FPoint particlePosition;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition);
+            tree.insert(particlePosition);
+        }
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -108,17 +115,14 @@ int main(int argc, char ** argv){
     { // Check that each particle has been summed with all other
         long long int counterNbPart = 0;
 
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            // on each leaf we should have the same number of particles
-            if(octreeIterator.getCurrentCell()->getDataUp() != octreeIterator.getCurrentListSrc()->getSize() ){
-                    std::cout << "Problem P2M Data up = " << octreeIterator.getCurrentCell()->getDataUp() <<
-                                 " Size = " << octreeIterator.getCurrentListSrc()->getSize() << "\n";
+        tree.forEachCellLeaf([&](CellClass* cell, LeafClass* leaf){
+            if(cell->getDataUp() != leaf->getSrc()->getNbParticles() ){
+                    std::cout << "Problem P2M Data up = " << cell->getDataUp() <<
+                                 " Size = " << leaf->getSrc()->getNbParticles() << "\n";
             }
             // we also count the number of particles.
-            counterNbPart += octreeIterator.getCurrentListSrc()->getSize();
-        } while(octreeIterator.moveRight());
+            counterNbPart += leaf->getSrc()->getNbParticles();
+        });
 
         if( counterNbPart != NbParticles){
             std::cout << "Problem global nb part, counter = " << counterNbPart << " created = " << NbParticles << std::endl;
@@ -135,20 +139,14 @@ int main(int argc, char ** argv){
         algo.repetitionsIntervals(&min, &max);
         std::cout << "Min is " << min << " Max is " << max << std::endl;
 
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        do{
-            ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-
-            while( iter.hasNotFinished() ){
-                if( NbParticlesEntireSystem - 1 != iter.data().getDataDown()){
+        tree.forEachLeaf([&](LeafClass* leaf){
+            for(int idxPart = 0 ; idxPart < leaf->getSrc()->getNbParticles() ; ++idxPart ){
+                if( NbParticlesEntireSystem - 1 != leaf->getSrc()->getDataDown()[idxPart]){
                     std::cout << "P2P probleme, should be " << NbParticlesEntireSystem - 1 <<
-                                 " iter.data().getDataDown() "<< iter.data().getDataDown() << std::endl;
+                                 " iter.data().getDataDown() "<< leaf->getSrc()->getDataDown()[idxPart] << std::endl;
                 }
-
-                iter.gotoNext();
             }
-        } while(octreeIterator.moveRight());
+        });
     }
 
     //////////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/Utils/testFmmAlgorithmProc.cpp b/Tests/Utils/testFmmAlgorithmProc.cpp
index 56b567b6c..3c7b488d1 100755
--- a/Tests/Utils/testFmmAlgorithmProc.cpp
+++ b/Tests/Utils/testFmmAlgorithmProc.cpp
@@ -290,7 +290,7 @@ void print(OctreeClass* const valideTree){
 
 
 
-/** class has to extend {FExtendForces,FExtendPotential,FExtendPhysicalValue}
+/**
   * Because we use fma loader it needs {FExtendPhysicalValue}
   */
 class TestParticle : public FTestParticle, public FExtendPhysicalValue {
diff --git a/Tests/Utils/testFmmAlgorithmTsm.cpp b/Tests/Utils/testFmmAlgorithmTsm.cpp
index e6140ec7c..1355b4f19 100755
--- a/Tests/Utils/testFmmAlgorithmTsm.cpp
+++ b/Tests/Utils/testFmmAlgorithmTsm.cpp
@@ -29,11 +29,9 @@
 
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
 #include "../../Src/Components/FTestCell.hpp"
 #include "../../Src/Components/FTestKernels.hpp"
 
-#include "../../Src/Extensions/FExtendParticleType.hpp"
 #include "../../Src/Extensions/FExtendCellType.hpp"
 
 #include "../../Src/Core/FFmmAlgorithmTsm.hpp"
@@ -43,29 +41,25 @@
 
 #include "../../Src/Files/FRandomLoader.hpp"
 
+#include "../../Src/Components/FTestParticleContainer.hpp"
+
 /** This program show an example of use of
   * the fmm basic algo
   * it also check that each particles is impacted each other particles
   */
-
-class FTestParticleTsm : public FTestParticle, public FExtendParticleType {
-};
-
 class FTestCellTsm: public FTestCell , public FExtendCellType{
 };
 
-
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FTestParticleTsm             ParticleClassTyped;
     typedef FTestCellTsm                 CellClassTyped;
-    typedef FVector<ParticleClassTyped>  ContainerClassTyped;
+    typedef FTestParticleContainer       ContainerClassTyped;
 
-    typedef FTypedLeaf<ParticleClassTyped, ContainerClassTyped >                      LeafClassTyped;
-    typedef FOctree<ParticleClassTyped, CellClassTyped, ContainerClassTyped , LeafClassTyped >  OctreeClassTyped;
-    typedef FTestKernels<ParticleClassTyped, CellClassTyped, ContainerClassTyped >          KernelClassTyped;
+    typedef FTypedLeaf< ContainerClassTyped >                      LeafClassTyped;
+    typedef FOctree< CellClassTyped, ContainerClassTyped , LeafClassTyped >  OctreeClassTyped;
+    typedef FTestKernels< CellClassTyped, ContainerClassTyped >          KernelClassTyped;
 
-    typedef FFmmAlgorithmThreadTsm<OctreeClassTyped, ParticleClassTyped, CellClassTyped, ContainerClassTyped, KernelClassTyped, LeafClassTyped > FmmClassTyped;
+    typedef FFmmAlgorithmThreadTsm<OctreeClassTyped, CellClassTyped, ContainerClassTyped, KernelClassTyped, LeafClassTyped > FmmClassTyped;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
     //////////////////////////////////////////////////////////////
@@ -78,7 +72,7 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    FRandomLoaderTsm<ParticleClassTyped> loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
+    FRandomLoaderTsm loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
     OctreeClassTyped tree(NbLevels, SizeSubLevels,loader.getBoxWidth(),loader.getCenterOfBox());
 
     //////////////////////////////////////////////////////////////////////////////////
@@ -87,7 +81,14 @@ int main(int argc, char ** argv){
     std::cout << "Creating " << NbPart << " particles ..." << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    {
+        FPoint particlePosition;
+        bool isTarget;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition, &isTarget);
+            tree.insert(particlePosition, isTarget);
+        }
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -110,8 +111,7 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    ValidateFMMAlgo<OctreeClassTyped, ParticleClassTyped, CellClassTyped, ContainerClassTyped, LeafClassTyped>(&tree);
-
+    ValidateFMMAlgo<OctreeClassTyped, CellClassTyped, ContainerClassTyped, LeafClassTyped>(&tree);
 
     return 0;
 }
diff --git a/Tests/Utils/testFmmDemonstration.cpp b/Tests/Utils/testFmmDemonstration.cpp
index 894c09313..c34ea474c 100755
--- a/Tests/Utils/testFmmDemonstration.cpp
+++ b/Tests/Utils/testFmmDemonstration.cpp
@@ -30,7 +30,6 @@
 
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
 #include "../../Src/Components/FTestCell.hpp"
 #include "../../Src/Components/FTestKernels.hpp"
 
@@ -38,6 +37,7 @@
 #include "../../Src/Core/FFmmAlgorithmThread.hpp"
 
 
+#include "../../Src/Components/FAbstractParticleContainer.hpp"
 #include "../../Src/Components/FBasicKernels.hpp"
 
 #include "../../Src/Files/FRandomLoader.hpp"
@@ -46,51 +46,61 @@
 class MyCell : public FBasicCell {
 };
 
-// My fack particle is a basic particle and! a index
-// that correspond to the index in the user particles array
-class MyFackParticle : public FBasicParticle {
-    int myIndex;
+// My fack Container is simply saving the indexes of each
+// particles (nothing more!)
+class MyContainer : public FAbstractParticleContainer {
+    FVector<int> indexes;
 public:
-    MyFackParticle() : myIndex(0) {
+    template<typename... Args>
+    void push(const FPoint& /*inParticlePosition*/, const int newParticleIndex, Args ... /*args*/){
+        indexes.push(newParticleIndex);
     }
-    void setIndex(const int inIndex){
-        this->myIndex = inIndex;
+
+    int getSize() const {
+        return indexes.getSize();
     }
-    int getIndex() const{
-        return this->myIndex;
+
+    const FVector<int>& getIndexes() const{
+        return indexes;
     }
 };
 
-// My leaf store the indexes of the particles it receives
-// in a vector
-class MyLeaf : public FAbstractLeaf<MyFackParticle, FVector<int> > {
-    FVector<int> indexes;
+// My leaf process the particles and save only
+// those where keepIt is true (during the push method)
+class MyLeaf : public FAbstractLeaf< MyContainer > {
+    MyContainer particles;
+
 public:
-    void push(const MyFackParticle& particle){
-        indexes.push( particle.getIndex() );
+    template<typename... Args>
+    void push(const FPoint& inParticlePosition, const bool keepIt, Args ... args){
+        if(keepIt) particles.push(inParticlePosition, args...);
     }
-    FVector<int>* getSrc(){
-        return &indexes;
+    MyContainer* getSrc(){
+        return &particles;
     }
-    FVector<int>* getTargets(){
-        return &indexes;
+    MyContainer* getTargets(){
+        return &particles;
     }
 };
 
 // My kernel actually does nothing except showing how to retreive data from an
 // array from the indexes vector giving by the leaf in the P2M
-template< class ParticleClass, class CellClass, class ContainerClass>
-class MyKernel : public FAbstractKernels<ParticleClass,CellClass,ContainerClass>{
-    FBasicParticle*const realParticles;
+template< class CellClass, class ContainerClass>
+class MyKernel : public FAbstractKernels<CellClass,ContainerClass>{
+    MortonIndex* indexForEachParticle;
 public:
-    MyKernel(FBasicParticle*const inRealParticles): realParticles(inRealParticles) {
+    MyKernel(const int inNbParticles): indexForEachParticle(new MortonIndex[inNbParticles]) {
+        memset(indexForEachParticle,0,sizeof(MortonIndex)*inNbParticles);
     }
 
-    void P2M(CellClass* const , const ContainerClass* const particlesIndexes) {
-        typename ContainerClass::ConstBasicIterator iter(*particlesIndexes);
-        while( iter.hasNotFinished() ){
-            realParticles[iter.data()].getPosition();
-            iter.gotoNext();
+    ~MyKernel(){
+        delete[] indexForEachParticle;
+    }
+
+    void P2M(CellClass* const cell, const ContainerClass* const particles) {
+        for(int idxPart = 0 ; idxPart < particles->getSize() ; ++idxPart){
+            // save the current morton index for each particles
+            indexForEachParticle[ particles->getIndexes()[idxPart] ] = cell->getMortonIndex();
         }
     }
 
@@ -121,14 +131,15 @@ public:
 
 
 int main(int argc, char ** argv){
-    typedef MyFackParticle    ParticleClass;
+    // Custom data structure here
     typedef MyCell            CellClass;
-    typedef FVector<int>      ContainerClass;
+    typedef MyContainer       ContainerClass;
     typedef MyLeaf            LeafClass;
 
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-    typedef MyKernel<ParticleClass, CellClass, ContainerClass >         KernelClass;
-    typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
+    // Standard things here
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef MyKernel< CellClass, ContainerClass >         KernelClass;
+    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
 
     //////////////////////////////////////////////////////////////
     ///////////////////////What we do/////////////////////////////
@@ -146,9 +157,8 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    FRandomLoader<ParticleClass> loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
+    FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
     OctreeClass tree(NbLevels, SizeSubLevels,loader.getBoxWidth(),loader.getCenterOfBox());
-    FBasicParticle*const realsParticles = new FBasicParticle[NbPart];
 
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
@@ -157,17 +167,19 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
+    FPoint*const realsParticlesPositions = new FPoint[NbPart];
     {
-        ParticleClass particleToFill;
+        FPoint particlePosition;
+        bool keepIt;
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
             // get a random position
-            loader.fillParticle(particleToFill);
-            // put the index inside
-            particleToFill.setIndex(idxPart);
+            loader.fillParticle(&particlePosition);
+            // let say we remove 1/5 particles
+            keepIt = (idxPart%5);
             // insert in the tree
-            tree.insert(particleToFill);
-            // copy in the array
-            realsParticles[idxPart].setPosition(particleToFill.getPosition());
+            tree.insert(particlePosition, keepIt, idxPart);
+            // save the position
+            realsParticlesPositions[idxPart] = particlePosition;
         }
     }
 
@@ -183,15 +195,13 @@ int main(int argc, char ** argv){
     OctreeClass::Iterator octreeIterator(&tree);
     octreeIterator.gotoBottomLeft();
     do{
-        ContainerClass::ConstBasicIterator iter(*octreeIterator.getCurrentListTargets());
+        FVector<int>::ConstBasicIterator iter(octreeIterator.getCurrentListTargets()->getIndexes());
         const MortonIndex indexAtThisLeaf = octreeIterator.getCurrentGlobalIndex();
 
         while( iter.hasNotFinished() ){
-            std::cout << "Particles with index " << iter.data() << " has a morton index of " << indexAtThisLeaf << std::endl;
-
-            const FPoint& particlePosition = realsParticles[iter.data()].getPosition();
-            std::cout << "\t The real position of this particle is (" << particlePosition.getX() << ";" << particlePosition.getY() << ";" << particlePosition.getZ() << ")" << std::endl;
-
+            std::cout << "Particles with index " << iter.data() <<
+                         " has a morton index of " << indexAtThisLeaf << std::endl;
+            std::cout << " it real position was " << realsParticlesPositions[iter.data()] << std::endl;
             iter.gotoNext();
         }
     } while(octreeIterator.moveRight());
@@ -205,7 +215,7 @@ int main(int argc, char ** argv){
     std::cout << "Working on particles ..." << std::endl;
     counter.tic();
 
-    KernelClass kernels(realsParticles);
+    KernelClass kernels(NbPart);
     FmmClass algo(&tree,&kernels);
     algo.execute();
 
@@ -215,7 +225,7 @@ int main(int argc, char ** argv){
     //////////////////////////////////////////////////////////////////////////////////
     //////////////////////////////////////////////////////////////////////////////////
 
-    delete [] realsParticles;
+    delete [] realsParticlesPositions;
 
     return 0;
 }
diff --git a/Tests/Utils/testLoader.cpp b/Tests/Utils/testLoader.cpp
index d35e95ee7..d80126edc 100755
--- a/Tests/Utils/testLoader.cpp
+++ b/Tests/Utils/testLoader.cpp
@@ -29,13 +29,14 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FBasicParticle.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
 #include "../../Src/Files/FBasicLoader.hpp"
 
+#include "../../Src/Components/FBasicParticleContainer.hpp"
+
 /**
   * In this file we show an example of FBasicLoader use
 * Inserting 2000000 particles ...
@@ -45,9 +46,9 @@
   */
 
 int main(int argc, char ** argv){
-    typedef FVector<FBasicParticle>      ContainerClass;
-    typedef FSimpleLeaf<FBasicParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FBasicParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -61,7 +62,7 @@ int main(int argc, char ** argv){
     std::cout << "Opening : " << filename << "\n";
 
     // open basic particles loader
-    FBasicLoader<FBasicParticle> loader(filename);
+    FBasicLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << "is missing\n";
         return 1;
@@ -76,7 +77,11 @@ int main(int argc, char ** argv){
         std::cout << "Inserting " << loader.getNumberOfParticles() << " particles ..." << std::endl;
         counter.tic();
 
-        loader.fillTree(tree);
+        FPoint particlePosition;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition);
+            tree.insert(particlePosition);
+        }
 
         counter.tac();
         std::cout << "Done  " << "(" << counter.elapsed() << ")." << std::endl;
diff --git a/Tests/Utils/testLoaderFMA.cpp b/Tests/Utils/testLoaderFMA.cpp
index 5f39cf62a..fad2028df 100755
--- a/Tests/Utils/testLoaderFMA.cpp
+++ b/Tests/Utils/testLoaderFMA.cpp
@@ -29,14 +29,13 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FFmaParticle.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
 #include "../../Src/Files/FFmaLoader.hpp"
 
-// Compile by : g++ testLoaderFMA.cpp ../../Src/Utils/FDebug.cpp ../../Src/Utils/FTrace.cpp -O2 -o testLoaderFMA.exe
+#include "../../Src/Components/FBasicParticleContainer.hpp"
 
 
 /**
@@ -48,9 +47,9 @@
   */
 
 int main(int argc, char ** argv ){
-    typedef FVector<FFmaParticle>      ContainerClass;
-    typedef FSimpleLeaf<FFmaParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FFmaParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<1>      ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -63,7 +62,7 @@ int main(int argc, char ** argv ){
     std::cout << "Opening : " << filename << "\n";
 
     // open basic particles loader
-    FFmaLoader<FFmaParticle> loader(filename);
+    FFmaLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << "is missing\n";
         return 1;
@@ -78,7 +77,12 @@ int main(int argc, char ** argv ){
         std::cout << "Inserting " << loader.getNumberOfParticles() << " particles ..." << std::endl;
         counter.tic();
 
-        loader.fillTree(tree);
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition,&physicalValue);
+            tree.insert(particlePosition,physicalValue);
+        }
 
         counter.tac();
         std::cout << "Done  " << "(" << counter.elapsed() << ")." << std::endl;
diff --git a/Tests/Utils/testLoaderFMATsm.cpp b/Tests/Utils/testLoaderFMATsm.cpp
index 4288c7e21..747150d33 100755
--- a/Tests/Utils/testLoaderFMATsm.cpp
+++ b/Tests/Utils/testLoaderFMATsm.cpp
@@ -28,31 +28,22 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FFmaParticle.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 
-#include "../../Src/Extensions/FExtendParticleType.hpp"
-
-#include "../../Src/Components/FSimpleLeaf.hpp"
+#include "../../Src/Components/FTypedLeaf.hpp"
 
 #include "../../Src/Files/FFmaTsmLoader.hpp"
 
+#include "../../Src/Components/FBasicParticleContainer.hpp"
 
 #include "../../Src/Utils/FParameters.hpp"
 
-/**
-  * In this file we show an example of FFmaLoader use
-  */
-
-class ParticleTsm : public FFmaParticle, public FExtendParticleType {
-};
-
 
 
 int main(int argc, char ** argv ){
-    typedef FVector<ParticleTsm>      ContainerClass;
-    typedef FSimpleLeaf<ParticleTsm, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleTsm, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<1>     ContainerClass;
+    typedef FTypedLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -65,7 +56,7 @@ int main(int argc, char ** argv ){
     std::cout << "Opening : " << filename << "\n";
 
     // open basic particles loader
-    FFmaTsmLoader<ParticleTsm> loader(filename);
+    FFmaTsmLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << "is missing\n";
         return 1;
@@ -79,7 +70,13 @@ int main(int argc, char ** argv ){
         std::cout << "Inserting " << loader.getNumberOfParticles() << " particles ..." << std::endl;
         counter.tic();
 
-        loader.fillTree(tree);
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        bool isTarget;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition,&physicalValue, &isTarget);
+            tree.insert(particlePosition, isTarget, physicalValue);
+        }
 
         counter.tac();
         std::cout << "Done  " << "(" << counter.elapsed() << ")." << std::endl;
diff --git a/Tests/Utils/testMemStats.cpp b/Tests/Utils/testMemStats.cpp
index ccaa1aade..b794ab08f 100755
--- a/Tests/Utils/testMemStats.cpp
+++ b/Tests/Utils/testMemStats.cpp
@@ -29,17 +29,17 @@
 
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
 #include "../../Src/Components/FTestCell.hpp"
 #include "../../Src/Components/FTestKernels.hpp"
 
 #include "../../Src/Kernels/Spherical/FSphericalKernel.hpp"
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
 #include "../../Src/Core/FFmmAlgorithm.hpp"
 
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
+
 /** This program show an example of use of
   * the fmm basic algo
   * it also check that each particles is impacted each other particles
@@ -48,19 +48,16 @@
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
     {
-        //typedef FTestParticle               ParticleClass;
-        //typedef FTestCell                   CellClass;
-        typedef FSphericalParticle             ParticleClass;
         typedef FSphericalCell                 CellClass;
 
-        typedef FVector<ParticleClass>      ContainerClass;
+        typedef FP2PParticleContainer      ContainerClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
-        //typedef FTestKernels<ParticleClass, CellClass, ContainerClass >         KernelClass;
-        typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
+        //typedef FTestKernels< CellClass, ContainerClass >         KernelClass;
+        typedef FSphericalKernel< CellClass, ContainerClass >          KernelClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
+        typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
         ///////////////////////What we do/////////////////////////////
         std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
         //////////////////////////////////////////////////////////////
@@ -90,10 +87,11 @@ int main(int argc, char ** argv){
         counter.tic();
 
         {
-            ParticleClass particleToFill;
+            FPoint particlePosition;
+            FReal physicalValue = 0.10;
             for(int idxPart = 0 ; idxPart < NbPart ; ++idxPart){
-                particleToFill.setPosition(FReal(rand())/FRandMax,FReal(rand())/FRandMax,FReal(rand())/FRandMax);
-                tree.insert(particleToFill);
+                particlePosition.setPosition(FReal(rand())/FRandMax,FReal(rand())/FRandMax,FReal(rand())/FRandMax);
+                tree.insert(particlePosition, physicalValue);
             }
         }
 
diff --git a/Tests/Utils/testMortonIndex.cpp b/Tests/Utils/testMortonIndex.cpp
deleted file mode 100755
index 14bf6464a..000000000
--- a/Tests/Utils/testMortonIndex.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-// ===================================================================================
-// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
-// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
-// This software is a computer program whose purpose is to compute the FMM.
-//
-// This software is governed by the CeCILL-C and LGPL licenses and
-// abiding by the rules of distribution of free software.  
-// 
-// This program 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 and CeCILL-C Licenses for more details.
-// "http://www.cecill.info". 
-// "http://www.gnu.org/licenses".
-// ===================================================================================
-
-#include <iostream>
-
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-#include <iostream>
-#include <iomanip>
-#include <vector>
-#include <algorithm>
-
-#include "../../Src/Utils/FTic.hpp"
-
-#include "../../Src/Containers/FOctree.hpp"
-#include "../../Src/Containers/FVector.hpp"
-
-#include "../../Src/Components/FBasicParticle.hpp"
-
-#include "../../Src/Components/FBasicCell.hpp"
-
-#include "../../Src/Core/FFmmAlgorithm.hpp"
-#include "../../Src/Core/FFmmAlgorithmThread.hpp"
-
-#include "../../Src/Components/FSimpleLeaf.hpp"
-
-#include "../../Src/Utils/FGlobal.hpp"
-#include "../../Src/Utils/FParameters.hpp"
-
-#include "../../Src/Files/FHLoader.hpp"
-
-static const int PrintPrecision = 6;
-
-/** Basic function to convert a morton index in decimal string */
-std::string MortonToBinary(MortonIndex index, int level){
-    std::string str;
-    int bits = 1 << ((level * 3) - 1);
-    int dim = 0;
-    while(bits){
-        if(index & bits) str.append("1");
-        else str.append("0");
-        bits >>= 1;
-        // we put a dot each 3 values
-        if(++dim == 3){
-            str.append(".");
-            dim = 0;
-        }
-    }
-    return str;
-}
-/** This program show an example of use of
-  * the moront indexing from a file
-  */
-struct AtomIndex  {
-    int          globalIndex ;
-    MortonIndex  indexMorton;
-};
-
-bool compareIndex(const AtomIndex& a, const AtomIndex& b){
-    return (a.indexMorton < b.indexMorton);
-}
-
-class Particle : public FBasicParticle {
-    char         data   ;
-    AtomIndex    index ;
-    //
-public:
-    char getData() const{
-        return data;
-    }
-    void setData(const char inData){
-        this->data = inData;
-    }
-
-    MortonIndex mortonIndex() const{
-        return index.indexMorton;
-    }
-    void setMortonIndex(const MortonIndex inIndex) {
-        index.indexMorton = inIndex;
-    }
-
-    int globalIndex() const{
-        return index.globalIndex;
-    }
-    void setGlobalIndex(const int inIndex) {
-        index.globalIndex = inIndex;
-    }
-
-};
-
-
-// Simply create particles and try the kernels
-int main(int argc, char ** argv){
-    typedef FVector<Particle>      ContainerClass;
-    typedef FSimpleLeaf<Particle, ContainerClass >                     LeafClass;
-    typedef FOctree<Particle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
-    ///////////////////////What we do/////////////////////////////
-    std::cout << ">> This executable has to be used to know the box used.\n";
-    //////////////////////////////////////////////////////////////
-
-    const int NbLevels = FParameters::getValue(argc,argv,"-h", 5);
-    const int SizeSubLevels = FParameters::getValue(argc,argv,"-sh", 3);
-    FTic counter;
-    const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/testMortonIndex.txt");
-    std::cout << "Opening : " << filename << "\n";
-
-    FHLoader<Particle> loader(filename);
-    if(!loader.isOpen() ){
-        std::cout << "Loader Error, " << filename << " is missing\n";
-        return 1;
-    }
-
-    // -----------------------------------------------------
-
-    OctreeClass tree(NbLevels, SizeSubLevels,loader.getBoxWidth(),loader.getCenterOfBox());
-
-    // -----------------------------------------------------
-
-    std::cout << "Creating and inserting " << loader.getNumberOfParticles() << " particles ..." << std::endl;
-    std::cout << "Width of box is " << loader.getBoxWidth() << std::endl;
-    std::cout << "Center of box is x " << loader.getCenterOfBox().getX()  << " y " << loader.getCenterOfBox().getY() << " z " << loader.getCenterOfBox().getZ()<< std::endl;
-    counter.tic();
-    {
-        Particle particle;
-        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particle);
-            particle.setGlobalIndex( idxPart+1 );
-            particle.setMortonIndex( -1 );
-            tree.insert(particle);
-        }
-    }
-    counter.tac();
-    std::cout << "Done  " << "(" << counter.elapsed() << "s)." << std::endl;
-
-    // -----------------------------------------------------
-
-    counter.tic();
-    int idx = 1 ;
-    std::vector<AtomIndex> permutation( int(loader.getNumberOfParticles()) ) ;
-
-    { // print indexes
-
-        // -----------------------------------------------------
-
-        OctreeClass::Iterator octreeIterator(&tree);
-        octreeIterator.gotoBottomLeft();
-        idx = 0;
-        do{
-            const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
-            // std::cout << "Current Morton Index : " << currentIndex << " or in binary " << MortonToBinary(currentIndex,NbLevels-1) << std::endl;
-            // std::cout << "Particles :" << std::endl;
-
-            ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-            while( iter.hasNotFinished() ){
-                iter.data().setMortonIndex(currentIndex);
-                //	  iter.data().mortonIndex()       = currentIndex ;
-                permutation[idx].indexMorton   = currentIndex ;
-                permutation[idx].globalIndex   = idx + 1;
-                ++idx;
-                //	  printf("\tx = %e y = %e z = %e data = %c\n",iter.value()->getPosition().getX(),iter.value()->getPosition().getY(),iter.value()->getPosition().getZ(),iter.value()->getData());
-                //	  std::cout << "  " <<iter.value()->globalIndex()  << "   " << (int) iter.value()->mortonIndex() << std::endl;
-                std::cout << "  "  << iter.data().getData()
-                          << std::setprecision(PrintPrecision)
-                          << std::setw(15) << iter.data().getPosition().getX()
-                          << std::setw(15) << iter.data().getPosition().getY()
-                          << std::setw(15) <<iter.data().getPosition().getZ()
-                          << std::endl;
-                iter.gotoNext();
-            }
-
-        } while(octreeIterator.moveRight());
-    }
-    
-
-
-    return 0;
-}
-
-
-
diff --git a/Tests/Utils/testOctree.cpp b/Tests/Utils/testOctree.cpp
index be7093fb2..b2c6e5271 100755
--- a/Tests/Utils/testOctree.cpp
+++ b/Tests/Utils/testOctree.cpp
@@ -29,7 +29,7 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FBasicParticle.hpp"
+#include "../../Src/Components/FBasicParticleContainer.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
@@ -40,9 +40,9 @@
 */
 
 int main(int argc, char ** argv){
-    typedef FVector<FBasicParticle>      ContainerClass;
-    typedef FSimpleLeaf<FBasicParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FBasicParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -51,14 +51,18 @@ int main(int argc, char ** argv){
     const int NbPart = FParameters::getValue(argc,argv,"-nb", 2000000);
     FTic counter;
 
-    FRandomLoader<FBasicParticle> loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
+    FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
     OctreeClass tree(10, 3, loader.getBoxWidth(), loader.getCenterOfBox());
 
     // -----------------------------------------------------
     std::cout << "Creating and inserting " << NbPart << " particles ..." << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    FPoint particlePosition;
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        loader.fillParticle(&particlePosition);
+        tree.insert(particlePosition);
+    }
 
     counter.tac();
     std::cout << "Done  " << "(" << counter.elapsed() << ")." << std::endl;
diff --git a/Tests/Utils/testOctreeFuncteur.cpp b/Tests/Utils/testOctreeFuncteur.cpp
index 7455db6d1..07f6909bc 100644
--- a/Tests/Utils/testOctreeFuncteur.cpp
+++ b/Tests/Utils/testOctreeFuncteur.cpp
@@ -29,7 +29,7 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FBasicParticle.hpp"
+#include "../../Src/Components/FBasicParticleContainer.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
@@ -40,9 +40,10 @@
 */
 
 int main(int argc, char ** argv){
-    typedef FVector<FBasicParticle>      ContainerClass;
-    typedef FSimpleLeaf<FBasicParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FBasicParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicCell CellClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree<CellClass, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -51,14 +52,20 @@ int main(int argc, char ** argv){
     const int NbPart = FParameters::getValue(argc,argv,"-nb", 2000);
     FTic counter;
 
-    FRandomLoader<FBasicParticle> loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
+    FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
     OctreeClass tree(10, 3, loader.getBoxWidth(), loader.getCenterOfBox());
 
     // -----------------------------------------------------
     std::cout << "Creating and inserting " << NbPart << " particles ..." << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    {
+        FPoint particlePosition;
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            loader.fillParticle(&particlePosition);
+            tree.insert(particlePosition);
+        }
+    }
 
     counter.tac();
     std::cout << "Done  " << "(" << counter.elapsed() << ")." << std::endl;
@@ -67,19 +74,19 @@ int main(int argc, char ** argv){
     // Call a function on each leaf
     long nbParticles = 0;
     tree.forEachLeaf([&](LeafClass* leaf){
-        nbParticles += leaf->getSrc()->getSize();
+        nbParticles += leaf->getSrc()->getNbParticles();
     });
     std::cout << "There are " << nbParticles << " particles " << std::endl;
 
     // Call a function on each cell
     long nbCells = 0;
-    tree.forEachCell([&nbCells](FBasicCell* /*cell*/){
+    tree.forEachCell([&nbCells](CellClass* /*cell*/){
         nbCells += 1;
     });
     std::cout << "There are " << nbCells << " cells " << std::endl;
 
     // To get cell and particles at leaf level
-    tree.forEachCellLeaf([&](FBasicCell* /*cell*/, LeafClass* /*leaf*/){
+    tree.forEachCellLeaf([&](CellClass* /*cell*/, LeafClass* /*leaf*/){
     });
 
     return 0;
diff --git a/Tests/Utils/testOctreeIter.cpp b/Tests/Utils/testOctreeIter.cpp
index 4ae66fbef..6c6fc6f41 100755
--- a/Tests/Utils/testOctreeIter.cpp
+++ b/Tests/Utils/testOctreeIter.cpp
@@ -30,7 +30,7 @@
 #include "../../Src/Utils/FAssertable.hpp"
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FBasicParticle.hpp"
+#include "../../Src/Components/FBasicParticleContainer.hpp"
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Utils/FTic.hpp"
@@ -41,9 +41,9 @@
 */
 
 int main(int argc, char ** argv){
-    typedef FVector<FBasicParticle>      ContainerClass;
-    typedef FSimpleLeaf<FBasicParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FBasicParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<0>     ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable is useless to execute.\n";
     std::cout << ">> It is only interesting to wath the code to understand\n";
@@ -66,7 +66,7 @@ int main(int argc, char ** argv){
     std::cout << "Creating and inserting " << NbPart << " particles ..." << std::endl;
     counterTime.tic();
     {
-        FBasicParticle particle;
+        FPoint particle;
         for(long idxPart = 0 ; idxPart < NbPart ; ++idxPart){
             particle.setPosition(FReal(rand())/FRandMax,FReal(rand())/FRandMax,FReal(rand())/FRandMax);
             tree.insert(particle);
@@ -77,7 +77,7 @@ int main(int argc, char ** argv){
 
     // -----------------------------------------------------
     {
-        std::cout << "Itering on particles ..." << std::endl;
+        std::cout << "Itering on Cells ..." << std::endl;
         counterTime.tic();
 
         OctreeClass::Iterator octreeIterator(&tree);
@@ -87,7 +87,7 @@ int main(int argc, char ** argv){
             do{
                 ++counter;
                 //counter += octreeIterator.getCurrentList()->getSize();
-            } while(octreeIterator.moveRight());
+            } while(octreeIterator.moveRight());           
             octreeIterator.moveUp();
             octreeIterator.gotoLeft();
             std::cout << "Cells at this level " << counter << " ...\n";
diff --git a/Tests/Utils/testOctreeRearrange.cpp b/Tests/Utils/testOctreeRearrange.cpp
index 0bef5d1ee..3123d8195 100755
--- a/Tests/Utils/testOctreeRearrange.cpp
+++ b/Tests/Utils/testOctreeRearrange.cpp
@@ -29,20 +29,62 @@
 
 #include "../../Src/Utils/FPoint.hpp"
 
-#include "../../Src/Components/FTestParticle.hpp"
-#include "../../Src/Components/FTestCell.hpp"
+#include "../../Src/Components/FBasicParticleContainer.hpp"
+#include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Arranger/FOctreeArranger.hpp"
 
+template <class ContainerClass>
+class Extractor {
+    struct Particle{
+        FPoint position;
+        FReal physicalValue;
+        FReal forces[3];
+        FReal potential;
+    };
+
+    FVector<Particle> savedParticles;
+
+public:
+    void extractParticles(const ContainerClass* containers, const int indexesToExtract[], const int nbToExtract){
+        //const FReal*const physicalValues = containers->getPhysicalValues();
+        const FReal*const positionsX = containers->getPositions()[0];
+        const FReal*const positionsY = containers->getPositions()[1];
+        const FReal*const positionsZ = containers->getPositions()[2];
+        //const FReal*const forcesX = containers->getForcesX();
+        //const FReal*const forcesY = containers->getForcesY();
+        //const FReal*const forcesZ = containers->getForcesZ();
+        //const FReal*const potentials = containers->getPotentials();
+
+        for(int idxPart = 0 ; idxPart < nbToExtract ; ++ idxPart){
+            const int idxExtract = indexesToExtract[idxPart];
+            Particle part;
+            part.position.setPosition( positionsX[idxExtract],positionsY[idxExtract],positionsZ[idxExtract]);
+            //part.physicalValue = physicalValues[idxExtract];
+            //part.forces[0] = forcesX[idxExtract];
+            //part.forces[1] = forcesY[idxExtract];
+            //part.forces[2] = forcesZ[idxExtract];
+            //part.potential = potentials[idxExtract];
+        }
+    }
+
+    template <class OctreeClass>
+    void reinsertInTree(OctreeClass* tree){
+        for(int idxPart = 0 ; idxPart < savedParticles.getSize() ; ++idxPart){
+            const Particle part = savedParticles[idxPart];
+            tree->insert(part.position/*, part.physicalValue, part.forces[0],
+                    part.forces[1],part.forces[2],part.potential*/);
+        }
+    }
+};
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FTestParticle               ParticleClass;
-    typedef FTestCell                   CellClass;
-    typedef FVector<ParticleClass>      ContainerClass;
+    typedef FBasicCell                      CellClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
@@ -75,7 +117,7 @@ int main(int argc, char ** argv){
 
     {
 
-        FTestParticle particleToFill;
+        FPoint particleToFill;
         for(int idxPart = 0 ; idxPart < NbPart ; ++idxPart){
             particleToFill.setPosition(
                         (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2)),
@@ -94,19 +136,15 @@ int main(int argc, char ** argv){
     std::cout << "Working on particles ..." << std::endl;
     counter.tic();
 
-    { // Check that each particle has been summed with all other
+    { // Create new position for each particles
         OctreeClass::Iterator octreeIterator(&tree);
         octreeIterator.gotoBottomLeft();
         do{
-            ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-
-            while( iter.hasNotFinished() ){
-                iter.data().setPosition(
-                            (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2)),
-                            (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2)),
-                            (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2)));
-
-                iter.gotoNext();
+            ContainerClass* particles = octreeIterator.getCurrentListTargets();
+            for(int idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
+                particles->getWPositions()[0][idxPart] = (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2));
+                particles->getWPositions()[1][idxPart] = (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2));
+                particles->getWPositions()[2][idxPart] = (BoxWidth*FReal(rand())/FRandMax) + (BoxCenter-(BoxWidth/2));
             }
         } while(octreeIterator.moveRight());
     }
@@ -121,7 +159,7 @@ int main(int argc, char ** argv){
     std::cout << "Arrange ..." << std::endl;
     counter.tic();
 
-    FOctreeArranger<OctreeClass, ContainerClass, ParticleClass> arrange(&tree);
+    FOctreeArranger<OctreeClass, ContainerClass, Extractor<ContainerClass> > arrange(&tree);
     arrange.rearrange();
 
     counter.tac();
@@ -139,21 +177,24 @@ int main(int argc, char ** argv){
         OctreeClass::Iterator octreeIterator(&tree);
         octreeIterator.gotoBottomLeft();
         do{
-            ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListTargets());
-
             const MortonIndex leafIndex = octreeIterator.getCurrentGlobalIndex();
 
-            while( iter.hasNotFinished() ){
-                const MortonIndex particleIndex = tree.getMortonFromPosition( iter.data().getPosition() );
+            ContainerClass* particles = octreeIterator.getCurrentListTargets();
+            for(int idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
+                const FPoint particlePosition( particles->getWPositions()[0][idxPart],
+                                               particles->getWPositions()[1][idxPart],
+                                               particles->getWPositions()[2][idxPart]);
+
+                const MortonIndex particleIndex = tree.getMortonFromPosition( particlePosition );
                 if( leafIndex != particleIndex){
                     std::cout << "Index problem, should be " << leafIndex <<
                                  " particleIndex "<< particleIndex << std::endl;
                 }
 
-                iter.gotoNext();
             }
-            counterPart += octreeIterator.getCurrentListTargets()->getSize();
-            if(octreeIterator.getCurrentListTargets()->getSize() == 0){
+
+            counterPart += octreeIterator.getCurrentListTargets()->getNbParticles();
+            if(octreeIterator.getCurrentListTargets()->getNbParticles() == 0){
                 std::cout << "Problem, leaf is empty at index " << leafIndex << std::endl;
             }
         } while(octreeIterator.moveRight());
diff --git a/Tests/Utils/testStatsTree.cpp b/Tests/Utils/testStatsTree.cpp
index 470f7b86f..7f0893737 100755
--- a/Tests/Utils/testStatsTree.cpp
+++ b/Tests/Utils/testStatsTree.cpp
@@ -25,10 +25,6 @@
 #include "../../Src/Containers/FOctree.hpp"
 #include "../../Src/Containers/FVector.hpp"
 
-#include "../../Src/Components/FFmaParticle.hpp"
-#include "../../Src/Extensions/FExtendForces.hpp"
-#include "../../Src/Extensions/FExtendPotential.hpp"
-
 #include "../../Src/Components/FBasicCell.hpp"
 
 #include "../../Src/Core/FFmmAlgorithm.hpp"
@@ -41,6 +37,8 @@
 
 #include "../../Src/Files/FFmaLoader.hpp"
 
+#include "../../Src/Components/FBasicParticleContainer.hpp"
+
 
 /** This program show an example of use of
   * the fmm basic algo
@@ -51,9 +49,9 @@
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FVector<FFmaParticle>      ContainerClass;
-    typedef FSimpleLeaf<FFmaParticle, ContainerClass >                     LeafClass;
-    typedef FOctree<FFmaParticle, FBasicCell, ContainerClass , LeafClass >  OctreeClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< FBasicCell, ContainerClass , LeafClass >  OctreeClass;
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to show some stat about the tree.\n";
     //////////////////////////////////////////////////////////////
@@ -65,7 +63,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaLoader<FFmaParticle> loader(filename);
+    FFmaLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -81,8 +79,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -101,7 +103,7 @@ int main(int argc, char ** argv){
                 OctreeClass::Iterator octreeIterator(&tree);
                 octreeIterator.gotoBottomLeft();
                 do{
-                    averageParticles += FReal(octreeIterator.getCurrentListTargets()->getSize());
+                    averageParticles += FReal(octreeIterator.getCurrentListTargets()->getNbParticles());
                     ++nbLeafs;
                 } while(octreeIterator.moveRight());
                 averageParticles /= FReal(nbLeafs);
@@ -116,7 +118,7 @@ int main(int argc, char ** argv){
                 OctreeClass::Iterator octreeIterator(&tree);
                 octreeIterator.gotoBottomLeft();
                 do{
-                    varianceParticles += FReal(octreeIterator.getCurrentListTargets()->getSize() * octreeIterator.getCurrentListTargets()->getSize());
+                    varianceParticles += FReal(octreeIterator.getCurrentListTargets()->getNbParticles() * octreeIterator.getCurrentListTargets()->getNbParticles());
                     ++nbLeafs;
                 } while(octreeIterator.moveRight());
                 varianceParticles /= FReal(nbLeafs);
diff --git a/Tests/Utils/testTreeIO.cpp b/Tests/Utils/testTreeIO.cpp
index 87f821d80..ff18fa449 100755
--- a/Tests/Utils/testTreeIO.cpp
+++ b/Tests/Utils/testTreeIO.cpp
@@ -30,20 +30,18 @@
 #include "../../Src/Files/FTreeIO.hpp"
 
 #include "../../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../../Src/Components/FSimpleLeaf.hpp"
 
-
+#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
 
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
     typedef FSphericalCell                 CellClass;
-    typedef FVector<ParticleClass>         ContainerClass;
+    typedef FP2PParticleContainer         ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
     ///////////////////////What we do/////////////////////////////
     std::cout << ">> This executable has to be used to load or retrieve an entier tree.\n";
@@ -55,7 +53,7 @@ int main(int argc, char ** argv){
     const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
     std::cout << "Opening : " << filename << "\n";
 
-    FFmaLoader<ParticleClass> loader(filename);
+    FFmaLoader loader(filename);
     if(!loader.isOpen()){
         std::cout << "Loader Error, " << filename << " is missing\n";
         return 1;
@@ -71,7 +69,12 @@ int main(int argc, char ** argv){
     std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
     counter.tic();
 
-    loader.fillTree(tree);
+    for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+        FPoint particlePosition;
+        FReal physicalValue = 0.0;
+        loader.fillParticle(&particlePosition,&physicalValue);
+        tree.insert(particlePosition, physicalValue );
+    }
 
     counter.tac();
     std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;
@@ -80,13 +83,13 @@ int main(int argc, char ** argv){
 
     std::cout << "Save tree ..." << std::endl;
 
-    FTreeIO::Save<OctreeClass, CellClass, ParticleClass, ContainerClass >("/tmp/tree.data", tree);
+    FTreeIO::Save<OctreeClass, CellClass, LeafClass, ContainerClass >("/tmp/tree.data", tree);
 
     // -----------------------------------------------------
 
     std::cout << "Load tree ..." << std::endl;
 
-    FTreeIO::Load<OctreeClass, CellClass, ParticleClass, ContainerClass >("/tmp/tree.data", tree);
+    FTreeIO::Load<OctreeClass, CellClass, LeafClass, ContainerClass >("/tmp/tree.data", tree);
 
     return 0;
 }
diff --git a/UTests/utestChebyshevDirect.cpp b/UTests/utestChebyshevDirect.cpp
index 73d850dfb..566547be4 100755
--- a/UTests/utestChebyshevDirect.cpp
+++ b/UTests/utestChebyshevDirect.cpp
@@ -31,30 +31,19 @@
 
 #include "FUTester.hpp"
 
-#include "../Src/Kernels/Chebyshev/FChebParticle.hpp"
+#include "../Src/Components/FSimpleLeaf.hpp"
+
 #include "../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 #include "../Src/Kernels/Chebyshev/FChebKernel.hpp"
 #include "../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
 
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 /*
   In this test we compare the spherical fmm results and the direct results.
 */
 
-/** We need to know the position of the particle in the array */
-class IndexedParticle : public FChebParticle {
-	int index;
-public:
-	IndexedParticle(): index(-1){}
-
-	int getIndex() const{
-		return index;
-	}
-	void setIndex( const int inIndex ){
-		index = inIndex;
-	}
-};
 
 /** the test class
  *
@@ -65,7 +54,7 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 	// The tests!
 	///////////////////////////////////////////////////////////
 	
-	template <class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class MatrixKernelClass,
+    template <class CellClass, class ContainerClass, class KernelClass, class MatrixKernelClass,
 						class LeafClass, class OctreeClass, class FmmClass>
 	void RunTest(const FReal epsilon)	{
 		// Warning in make test the exec dir it Build/UTests
@@ -73,7 +62,7 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
         const char* const filename = (sizeof(FReal) == sizeof(float))?
                                         "../../Data/utestDirect.bin.fma.single":
                                         "../../Data/utestDirect.bin.fma.double";
-        FFmaBinLoader<ParticleClass> loader(filename);
+        FFmaBinLoader loader(filename);
 		if(!loader.isOpen()){
 			Print("Cannot open particles file.");
 			uassert(false);
@@ -87,13 +76,31 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 		//const FReal epsilon = FReal(1e-5);
 
 		// Create octree
-		OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-		ParticleClass* const particles = new ParticleClass[loader.getNumberOfParticles()];
-		for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-			loader.fillParticle(particles[idxPart]);
-			particles[idxPart].setIndex( idxPart );
-			tree.insert(particles[idxPart]);
-		}
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
+
+        // Create octree
+        OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            FPoint position;
+            FReal physicalValue;
+            loader.fillParticle(&position,&physicalValue);
+            // put in tree
+            tree.insert(position, idxPart, physicalValue);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = physicalValue;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
+        }
 
 
 		// Run FMM
@@ -105,50 +112,42 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 		// Run direct computation
 		const MatrixKernelClass MatrixKernel;
 		Print("Direct...");
-		for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
-			for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
-				//kernels.directInteractionMutual(&particles[idxTarget], &particles[idxOther]);
-				const FReal wt = particles[idxTarget].getPhysicalValue();
-				const FReal ws = particles[idxOther ].getPhysicalValue();
-				const FReal one_over_r = MatrixKernel.evaluate(particles[idxTarget].getPosition(),
-																											 particles[idxOther].getPosition());
-				// potential
-				particles[idxTarget].incPotential(one_over_r * ws);
-				particles[idxOther ].incPotential(one_over_r * wt);
-				// force
-				FPoint force(particles[idxOther].getPosition() - particles[idxTarget].getPosition());
-				force *= ((ws*wt) * (one_over_r*one_over_r*one_over_r));
-				particles[idxTarget].incForces(  force.getX(),  force.getY(),  force.getZ());
-				particles[idxOther ].incForces( -force.getX(), -force.getY(), -force.getZ());
-			}
-		}
+        for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
+            for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
+            }
+        }
 
 		// Compare
-		Print("Compute Diff...");
-		FMath::FAccurater potentialDiff;
-		FMath::FAccurater fx, fy, fz;
-		{ // Check that each particle has been summed with all other
-			typename OctreeClass::Iterator octreeIterator(&tree);
-			octreeIterator.gotoBottomLeft();
-
-			do{
-				typename ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-				while( leafIter.hasNotFinished() ){
-					const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-					potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-					fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-					fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-					fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
-
-					leafIter.gotoNext();
-				}
-			} while(octreeIterator.moveRight());
-		}
+        Print("Compute Diff...");
+        FMath::FAccurater potentialDiff;
+        FMath::FAccurater fx, fy, fz;
+        { // Check that each particle has been summed with all other
+
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
+                }
+            });
+        }
 
 		delete[] particles;
 
@@ -201,33 +200,31 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 	/** TestChebKernel */
 	void TestChebKernel(){
 		const unsigned int ORDER = 5;
-		const FReal epsilon = FReal(1e-5);
-		typedef IndexedParticle ParticleClass;
-		typedef FVector<ParticleClass> ContainerClass;
-		typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+        const FReal epsilon = FReal(1e-5);
+        typedef FP2PParticleContainerIndexed ContainerClass;
+        typedef FSimpleLeaf<ContainerClass> LeafClass;
 		typedef FChebMatrixKernelR MatrixKernelClass;
 		typedef FChebCell<ORDER> CellClass;
-		typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
-		typedef FChebKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-		typedef FFmmAlgorithm<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
+        typedef FChebKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 		// run test
-		RunTest<ParticleClass,CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
+        RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
 	}
 
 	/** TestChebSymKernel */
 	void TestChebSymKernel(){
 		const unsigned int ORDER = 5;
-		const FReal epsilon = FReal(1e-5);
-		typedef IndexedParticle ParticleClass;
-		typedef FVector<ParticleClass> ContainerClass;
-		typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+        const FReal epsilon = FReal(1e-5);
+        typedef FP2PParticleContainerIndexed ContainerClass;
+        typedef FSimpleLeaf<ContainerClass> LeafClass;
 		typedef FChebMatrixKernelR MatrixKernelClass;
 		typedef FChebCell<ORDER> CellClass;
-		typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
-		typedef FChebSymKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-		typedef FFmmAlgorithm<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
+        typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 		// run test
-		RunTest<ParticleClass,CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
+        RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
 	}
 
 
diff --git a/UTests/utestChebyshevDirectPeriodic.cpp b/UTests/utestChebyshevDirectPeriodic.cpp
index 6e1c9d912..af11773ec 100755
--- a/UTests/utestChebyshevDirectPeriodic.cpp
+++ b/UTests/utestChebyshevDirectPeriodic.cpp
@@ -30,30 +30,19 @@
 
 #include "FUTester.hpp"
 
-#include "../Src/Kernels/Chebyshev/FChebParticle.hpp"
 #include "../Src/Kernels/Chebyshev/FChebLeaf.hpp"
 #include "../Src/Kernels/Chebyshev/FChebCell.hpp"
 #include "../Src/Kernels/Chebyshev/FChebMatrixKernel.hpp"
 #include "../Src/Kernels/Chebyshev/FChebKernel.hpp"
 #include "../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
 
+#include "../Src/Components/FSimpleLeaf.hpp"
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
+
 /*
   In this test we compare the spherical fmm results and the direct results.
 */
 
-/** We need to know the position of the particle in the array */
-class IndexedParticle : public FChebParticle {
-	int index;
-public:
-	IndexedParticle(): index(-1){}
-
-	int getIndex() const{
-		return index;
-	}
-	void setIndex( const int inIndex ){
-		index = inIndex;
-	}
-};
 
 /** the test class
  *
@@ -64,7 +53,7 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 	// The tests!
 	///////////////////////////////////////////////////////////
 	
-	template <class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class MatrixKernelClass,
+    template <class CellClass, class ContainerClass, class KernelClass, class MatrixKernelClass,
 						class LeafClass, class OctreeClass, class FmmClass>
 	void RunTest(const FReal epsilon)	{
 		// Warning in make test the exec dir it Build/UTests
@@ -75,19 +64,33 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
         const int PeriodicDeep  = 2;
         const int NbParticles   = 1;
 
-        FRandomLoader<ParticleClass> loader(NbParticles);
+        FRandomLoader loader(NbParticles);
 
         Print("Number of particles:");
         Print(loader.getNumberOfParticles());
 
         // Create octree
         OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        ParticleClass* const particles = new ParticleClass[loader.getNumberOfParticles()];
+
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex( idxPart );
-            particles[idxPart].setPhysicalValue(FReal(0.10));
-            tree.insert(particles[idxPart]);
+            FPoint position;
+            loader.fillParticle(&position);
+            // put in tree
+            tree.insert(position, idxPart, 0.10);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = 0.10;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
         }
 
         // Run FMM
@@ -107,19 +110,14 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 
         for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
             for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
-                //kernels.directInteractionMutual(&particles[idxTarget], &particles[idxOther]);
-                const FReal wt = particles[idxTarget].getPhysicalValue();
-                const FReal ws = particles[idxOther ].getPhysicalValue();
-                const FReal one_over_r = MatrixKernel.evaluate(particles[idxTarget].getPosition(),
-                            particles[idxOther].getPosition());
-                // potential
-                particles[idxTarget].incPotential(one_over_r * ws);
-                particles[idxOther ].incPotential(one_over_r * wt);
-                // force
-                FPoint force(particles[idxOther].getPosition() - particles[idxTarget].getPosition());
-                force *= ((ws*wt) * (one_over_r*one_over_r*one_over_r));
-                particles[idxTarget].incForces(  force.getX(),  force.getY(),  force.getZ());
-                particles[idxOther ].incForces( -force.getX(), -force.getY(), -force.getZ());
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
             }
             for(int idxX = min.getX() ; idxX <= max.getX() ; ++idxX){
                 for(int idxY = min.getY() ; idxY <= max.getY() ; ++idxY){
@@ -132,20 +130,16 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
                                             loader.getBoxWidth() * FReal(idxZ));
 
                         for(int idxSource = 0 ; idxSource < NbParticles ; ++idxSource){
-                            ParticleClass source = particles[idxSource];
-                            source.incPosition(offset.getX(),offset.getY(),offset.getZ());
-
-                            const FReal wt = particles[idxTarget].getPhysicalValue();
-                            const FReal ws = source.getPhysicalValue();
-                            const FReal one_over_r = MatrixKernel.evaluate(particles[idxTarget].getPosition(),
-                                        source.getPosition());
-                            // potential
-                            particles[idxTarget].incPotential(one_over_r * ws);
-                            source.incPotential(one_over_r * wt);
-                            // force
-                            FPoint force(source.getPosition() - particles[idxTarget].getPosition());
-                            force *= ((ws*wt) * (one_over_r*one_over_r*one_over_r));
-                            particles[idxTarget].incForces(  force.getX(),  force.getY(),  force.getZ());
+                            TestParticle source = particles[idxSource];
+                            source.position += offset;
+
+                            FP2P::NonMutualParticles(
+                                        source.position.getX(), source.position.getY(),
+                                        source.position.getZ(),source.physicalValue,
+                                        particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                          particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                          &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                          &particles[idxTarget].forces[2],&particles[idxTarget].potential);
                         }
                     }
                 }
@@ -157,26 +151,23 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
         { // Check that each particle has been summed with all other
-            typename OctreeClass::Iterator octreeIterator(&tree);
-            octreeIterator.gotoBottomLeft();
-
-            do{
-                typename ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                while( leafIter.hasNotFinished() ){
-                    const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                    potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-                    fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                    fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                    fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
 
-                    leafIter.gotoNext();
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
                 }
-            } while(octreeIterator.moveRight());
+            });
         }
 
         delete[] particles;
@@ -231,33 +222,31 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
 	/** TestChebKernel */
 	void TestChebKernel(){
 		const unsigned int ORDER = 5;
-		const FReal epsilon = FReal(1e-5);
-		typedef IndexedParticle ParticleClass;
-		typedef FVector<ParticleClass> ContainerClass;
-		typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+        const FReal epsilon = FReal(1e-5);
+        typedef FP2PParticleContainerIndexed ContainerClass;
+        typedef FSimpleLeaf<ContainerClass> LeafClass;
 		typedef FChebMatrixKernelR MatrixKernelClass;
 		typedef FChebCell<ORDER> CellClass;
-		typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
-		typedef FChebKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-        typedef FFmmAlgorithmPeriodic<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
+        typedef FChebKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        typedef FFmmAlgorithmPeriodic<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 		// run test
-		RunTest<ParticleClass,CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
+        RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
 	}
 
 	/** TestChebSymKernel */
 	void TestChebSymKernel(){
 		const unsigned int ORDER = 5;
-		const FReal epsilon = FReal(1e-5);
-		typedef IndexedParticle ParticleClass;
-		typedef FVector<ParticleClass> ContainerClass;
-		typedef FChebLeaf<ParticleClass,ContainerClass> LeafClass;
+        const FReal epsilon = FReal(1e-5);
+        typedef FP2PParticleContainerIndexed ContainerClass;
+        typedef FSimpleLeaf<ContainerClass> LeafClass;
 		typedef FChebMatrixKernelR MatrixKernelClass;
 		typedef FChebCell<ORDER> CellClass;
-		typedef FOctree<ParticleClass,CellClass,ContainerClass,LeafClass> OctreeClass;
-		typedef FChebSymKernel<ParticleClass,CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
-        typedef FFmmAlgorithmPeriodic<OctreeClass,ParticleClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
+        typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
+        typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
+        typedef FFmmAlgorithmPeriodic<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
 		// run test
-		RunTest<ParticleClass,CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
+        RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass>(epsilon);
 	}
 
 
diff --git a/UTests/utestOctree.cpp b/UTests/utestOctree.cpp
index 5950f45bf..c9c259fe2 100755
--- a/UTests/utestOctree.cpp
+++ b/UTests/utestOctree.cpp
@@ -22,7 +22,7 @@
 #include "../Src/Utils/FAssertable.hpp"
 #include "../Src/Utils/FPoint.hpp"
 
-#include "../Src/Components/FBasicParticle.hpp"
+#include "../Src/Components/FBasicParticleContainer.hpp"
 #include "../Src/Components/FBasicCell.hpp"
 
 #include "../Src/Utils/FTic.hpp"
@@ -36,12 +36,11 @@
 
 /** this class test the octree container */
 class TestOctree : public FUTester<TestOctree> {
-    typedef FBasicParticle               ParticleClass;
     typedef FBasicCell                   CellClass;
-    typedef FVector<ParticleClass>      ContainerClass;
+    typedef FBasicParticleContainer<0>      ContainerClass;
 
-    typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-    typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+    typedef FOctree<CellClass, ContainerClass , LeafClass >  OctreeClass;
 
     // test size
     void TestAll(){
@@ -64,14 +63,13 @@ class TestOctree : public FUTester<TestOctree> {
                 OctreeClass tree(idxHeight, idxSub, BoxWidth, FPoint(BoxCenter,BoxCenter,BoxCenter));
 
                 // fill the tree
-                ParticleClass particleToFill;
                 for(int idxX = 0 ; idxX < NbSmallBoxesPerSide ; ++idxX){
                     for(int idxY = 0 ; idxY < NbSmallBoxesPerSide ; ++idxY){
                         for(int idxZ = 0 ; idxZ < NbSmallBoxesPerSide ; ++idxZ){
-                            particleToFill.setPosition(FReal(idxX)*SmallBoxWidth + SmallBoxWidthDiv2,
+                            const FPoint pos(FReal(idxX)*SmallBoxWidth + SmallBoxWidthDiv2,
                                                        FReal(idxY)*SmallBoxWidth + SmallBoxWidthDiv2,
                                                        FReal(idxZ)*SmallBoxWidth + SmallBoxWidthDiv2);
-                            tree.insert(particleToFill);
+                            tree.insert(pos);
                         }
                     }
                 }
diff --git a/UTests/utestRotationDirect.cpp b/UTests/utestRotationDirect.cpp
index b35bf64b2..4773d15a9 100755
--- a/UTests/utestRotationDirect.cpp
+++ b/UTests/utestRotationDirect.cpp
@@ -20,7 +20,7 @@
 #include "../Src/Containers/FVector.hpp"
 
 #include "../Src/Kernels/Rotation/FRotationCell.hpp"
-#include "../Src/Kernels/Rotation/FRotationParticle.hpp"
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 #include "../Src/Components/FSimpleLeaf.hpp"
 #include "../Src/Kernels/Rotation/FRotationKernel.hpp"
@@ -33,30 +33,13 @@
 
 #include "FUTester.hpp"
 
-/*
-  In this test we compare the spherical fmm results and the direct results.
-  */
-
-/** We need to know the position of the particle in the array */
-class IndexedParticle : public FRotationParticle {
-    int index;
-public:
-    IndexedParticle(): index(-1){}
-
-    int getIndex() const{
-        return index;
-    }
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
-};
 
 /** the test class
   *
   */
 class TestRotationDirect : public FUTester<TestRotationDirect> {
     /** The test method to factorize all the test based on different kernels */
-    template <class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass,
+    template <class CellClass, class ContainerClass, class KernelClass, class LeafClass,
               class OctreeClass, class FmmClass>
     void RunTest(){
         // Warning in make test the exec dir it Build/UTests
@@ -64,7 +47,7 @@ class TestRotationDirect : public FUTester<TestRotationDirect> {
         const char* const filename = (sizeof(FReal) == sizeof(float))?
                                         "../../Data/utestDirect.bin.fma.single":
                                         "../../Data/utestDirect.bin.fma.double";
-        FFmaBinLoader<ParticleClass> loader(filename);
+        FFmaBinLoader loader(filename);
         if(!loader.isOpen()){
             Print("Cannot open particles file.");
             uassert(false);
@@ -76,13 +59,31 @@ class TestRotationDirect : public FUTester<TestRotationDirect> {
         const int NbLevels      = 4;
         const int SizeSubLevels = 2;
 
+
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
+
         // Create octree
         OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        ParticleClass* const particles = new ParticleClass[loader.getNumberOfParticles()];
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex( idxPart );
-            tree.insert(particles[idxPart]);
+            FPoint position;
+            FReal physicalValue;
+            loader.fillParticle(&position,&physicalValue);
+            // put in tree
+            tree.insert(position, idxPart, physicalValue);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = physicalValue;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
         }
 
 
@@ -97,7 +98,14 @@ class TestRotationDirect : public FUTester<TestRotationDirect> {
         Print("Direct...");
         for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
             for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
-                kernels.particlesMutualInteraction(&particles[idxTarget], &particles[idxOther]);
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
             }
         }
 
@@ -106,26 +114,23 @@ class TestRotationDirect : public FUTester<TestRotationDirect> {
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
         { // Check that each particle has been summed with all other
-            typename OctreeClass::Iterator octreeIterator(&tree);
-            octreeIterator.gotoBottomLeft();
-
-            do{
-                typename ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                while( leafIter.hasNotFinished() ){
-                    const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                    potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-                    fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                    fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                    fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
 
-                    leafIter.gotoNext();
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
                 }
-            } while(octreeIterator.moveRight());
+            });
         }
 
         delete[] particles;
@@ -173,19 +178,17 @@ class TestRotationDirect : public FUTester<TestRotationDirect> {
 
     /** Rotation */
     void TestRotation(){
-        typedef IndexedParticle         ParticleClass;
-        typedef FRotationCell<P>            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FRotationCell<P>              CellClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FRotationKernel<ParticleClass, CellClass, ContainerClass, P >          KernelClass;
+        typedef FRotationKernel<CellClass, ContainerClass, P >          KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf<ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
-        RunTest<ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass,
-                OctreeClass, FmmClass>();
+        RunTest<CellClass, ContainerClass, KernelClass, LeafClass, OctreeClass, FmmClass>();
     }
 
     ///////////////////////////////////////////////////////////
diff --git a/UTests/utestRotationDirectPeriodic.cpp b/UTests/utestRotationDirectPeriodic.cpp
index 30ab1a604..d230fb42d 100755
--- a/UTests/utestRotationDirectPeriodic.cpp
+++ b/UTests/utestRotationDirectPeriodic.cpp
@@ -18,7 +18,7 @@
 
 #include "../Src/Kernels/Rotation/FRotationCell.hpp"
 #include "../Src/Kernels/Rotation/FRotationKernel.hpp"
-#include "../Src/Kernels/Rotation/FRotationParticle.hpp"
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 #include "../Src/Components/FSimpleLeaf.hpp"
 #include "../Src/Core/FFmmAlgorithmPeriodic.hpp"
@@ -28,54 +28,49 @@
 
 #include "../Src/Components/FTestCell.hpp"
 #include "../Src/Components/FTestKernels.hpp"
-#include "../Src/Components/FTestParticle.hpp"
-
-/*
-  In this test we compare the fmm results and the direct results.
-  */
-class IndexedParticle : public FRotationParticle {
-    int index;
-public:
-    IndexedParticle(): index(-1){}
-
-    int getIndex() const{
-        return index;
-    }
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
-};
 
 /** The class to run the test */
 class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
     /** Here we test only the P2P */
     void TestPeriodicFmm(){
         static const int P = 9;
-        typedef IndexedParticle         ParticleClass;
         typedef FRotationCell<P>            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FRotationKernel<ParticleClass, CellClass, ContainerClass, P >   KernelClass;
+        typedef FRotationKernel< CellClass, ContainerClass, P >   KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithmPeriodic<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
         // Parameters
         const int NbLevels      = 4;
         const int SizeSubLevels = 2;
         const int PeriodicDeep  = -1;
         const int NbParticles   = 100;
-        ParticleClass* const particles = new ParticleClass[NbParticles];
 
-        FRandomLoader<ParticleClass> loader(NbParticles);
+        FRandomLoader loader(NbParticles);
         OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        for( int idxPart = 0 ; idxPart < NbParticles ; ++idxPart ){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex(idxPart);
-            particles[idxPart].setPhysicalValue(FReal(0.80));
-            tree.insert(particles[idxPart]);
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            FPoint position;
+            loader.fillParticle(&position);
+            // put in tree
+            tree.insert(position, idxPart, 0.10);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = 0.10;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
         }
 
         // Run FMM
@@ -90,23 +85,38 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
         FTreeCoordinate min, max;
         algo.repetitionsIntervals(&min, &max);
 
-        for(int idxTarget = 0 ; idxTarget < NbParticles ; ++idxTarget){
-            for(int idxSource = idxTarget + 1 ; idxSource < NbParticles ; ++idxSource){
-                kernels.particlesMutualInteraction(&particles[idxTarget], &particles[idxSource]);
+        for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
+            for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
             }
             for(int idxX = min.getX() ; idxX <= max.getX() ; ++idxX){
                 for(int idxY = min.getY() ; idxY <= max.getY() ; ++idxY){
                     for(int idxZ = min.getZ() ; idxZ <= max.getZ() ; ++idxZ){
-                        if(idxX == 0 && idxY == 0 && idxZ == 0) continue;
+                        if(idxX ==0 && idxY == 0 && idxZ == 0) continue;
+                        // next lines for test
 
                         const FPoint offset(loader.getBoxWidth() * FReal(idxX),
                                             loader.getBoxWidth() * FReal(idxY),
                                             loader.getBoxWidth() * FReal(idxZ));
 
                         for(int idxSource = 0 ; idxSource < NbParticles ; ++idxSource){
-                            ParticleClass source = particles[idxSource];
-                            source.incPosition(offset.getX(),offset.getY(),offset.getZ());
-                            kernels.particlesInteraction(&particles[idxTarget], source);
+                            TestParticle source = particles[idxSource];
+                            source.position += offset;
+
+                            FP2P::NonMutualParticles(
+                                        source.position.getX(), source.position.getY(),
+                                        source.position.getZ(),source.physicalValue,
+                                        particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                          particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                          &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                          &particles[idxTarget].forces[2],&particles[idxTarget].potential);
                         }
                     }
                 }
@@ -118,35 +128,23 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
         { // Check that each particle has been summed with all other
-            OctreeClass::Iterator octreeIterator(&tree);
-            octreeIterator.gotoBottomLeft();
-
-            do{
-                ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                while( leafIter.hasNotFinished() ){
-                    const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                    /*printf("Tree x %e y %e z %e physical %e potential %e fx %e fy %e fz %e\n",
-                           leafIter.data().getPosition().getX(),leafIter.data().getPosition().getY(),leafIter.data().getPosition().getZ(),
-                           leafIter.data().getPhysicalValue(),leafIter.data().getPotential(),
-                           leafIter.data().getForces().getX(),leafIter.data().getForces().getY(),leafIter.data().getForces().getZ());// todo delete
-                    printf("Direct x %e y %e z %e physical %e potential %e fx %e fy %e fz %e\n",
-                           other.getPosition().getX(),other.getPosition().getY(),other.getPosition().getZ(),
-                           other.getPhysicalValue(),other.getPotential(),
-                           other.getForces().getX(),other.getForces().getY(),other.getForces().getZ());//*/
-
-                    potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-                    fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                    fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                    fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
 
-                    leafIter.gotoNext();
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
                 }
-            } while(octreeIterator.moveRight());
+            });
         }
 
         Print("Potential diff is = ");
diff --git a/UTests/utestSphericalDirect.cpp b/UTests/utestSphericalDirect.cpp
index b1d49e705..b8b4d5f9f 100755
--- a/UTests/utestSphericalDirect.cpp
+++ b/UTests/utestSphericalDirect.cpp
@@ -20,7 +20,7 @@
 #include "../Src/Containers/FVector.hpp"
 
 #include "../Src/Kernels/Spherical/FSphericalCell.hpp"
-#include "../Src/Kernels/Spherical/FSphericalParticle.hpp"
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 #include "../Src/Components/FSimpleLeaf.hpp"
 #include "../Src/Kernels/Spherical/FSphericalKernel.hpp"
@@ -40,26 +40,12 @@
   In this test we compare the spherical fmm results and the direct results.
   */
 
-/** We need to know the position of the particle in the array */
-class IndexedParticle : public FSphericalParticle {
-    int index;
-public:
-    IndexedParticle(): index(-1){}
-
-    int getIndex() const{
-        return index;
-    }
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
-};
-
 /** the test class
   *
   */
 class TestSphericalDirect : public FUTester<TestSphericalDirect> {
     /** The test method to factorize all the test based on different kernels */
-    template <class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass,
+    template < class CellClass, class ContainerClass, class KernelClass, class LeafClass,
               class OctreeClass, class FmmClass>
     void RunTest(const bool isBlasKernel){
         // Warning in make test the exec dir it Build/UTests
@@ -67,7 +53,7 @@ class TestSphericalDirect : public FUTester<TestSphericalDirect> {
         const char* const filename = (sizeof(FReal) == sizeof(float))?
                                         "../../Data/utestDirect.bin.fma.single":
                                         "../../Data/utestDirect.bin.fma.double";
-        FFmaBinLoader<ParticleClass> loader(filename);
+        FFmaBinLoader loader(filename);
         if(!loader.isOpen()){
             Print("Cannot open particles file.");
             uassert(false);
@@ -81,13 +67,31 @@ class TestSphericalDirect : public FUTester<TestSphericalDirect> {
         const int DevP = 9;
         FSphericalCell::Init(DevP, isBlasKernel);
 
+        // Create octree
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
+
         // Create octree
         OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        ParticleClass* const particles = new ParticleClass[loader.getNumberOfParticles()];
         for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex( idxPart );
-            tree.insert(particles[idxPart]);
+            FPoint position;
+            FReal physicalValue;
+            loader.fillParticle(&position,&physicalValue);
+            // put in tree
+            tree.insert(position, idxPart, physicalValue);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = physicalValue;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
         }
 
 
@@ -102,7 +106,14 @@ class TestSphericalDirect : public FUTester<TestSphericalDirect> {
         Print("Direct...");
         for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
             for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
-                kernels.directInteractionMutual(&particles[idxTarget], &particles[idxOther]);
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
             }
         }
 
@@ -111,26 +122,23 @@ class TestSphericalDirect : public FUTester<TestSphericalDirect> {
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
         { // Check that each particle has been summed with all other
-            typename OctreeClass::Iterator octreeIterator(&tree);
-            octreeIterator.gotoBottomLeft();
-
-            do{
-                typename ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                while( leafIter.hasNotFinished() ){
-                    const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                    potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-                    fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                    fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                    fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
 
-                    leafIter.gotoNext();
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
                 }
-            } while(octreeIterator.moveRight());
+            });
         }
 
         delete[] particles;
@@ -176,70 +184,66 @@ class TestSphericalDirect : public FUTester<TestSphericalDirect> {
 
     /** Classic */
     void TestSpherical(){
-        typedef IndexedParticle         ParticleClass;
         typedef FSphericalCell            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+        typedef FSphericalKernel< CellClass, ContainerClass >          KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
-        RunTest<ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass,
+        RunTest< CellClass, ContainerClass, KernelClass, LeafClass,
                 OctreeClass, FmmClass>(false);
     }
 
     /** Rotation */
     void TestRotation(){
-        typedef IndexedParticle         ParticleClass;
         typedef FSphericalCell            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FSphericalRotationKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+        typedef FSphericalRotationKernel< CellClass, ContainerClass >          KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
-        RunTest<ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass,
+        RunTest< CellClass, ContainerClass, KernelClass, LeafClass,
                 OctreeClass, FmmClass>(false);
     }
 
 #ifdef SCALFMM_USE_BLAS
     /** Blas */
     void TestSphericalBlas(){
-        typedef IndexedParticle         ParticleClass;
         typedef FSphericalCell            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FSphericalBlasKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+        typedef FSphericalBlasKernel< CellClass, ContainerClass >          KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
-        RunTest<ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass,
+        RunTest< CellClass, ContainerClass, KernelClass, LeafClass,
                 OctreeClass, FmmClass>(true);
     }
 
     /** Block blas */
     void TestSphericalBlockBlas(){
-        typedef IndexedParticle         ParticleClass;
         typedef FSphericalCell            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed ContainerClass;
 
-        typedef FSphericalBlockBlasKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+        typedef FSphericalBlockBlasKernel< CellClass, ContainerClass >          KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithm<OctreeClass,  CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
-        RunTest<ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass,
+        RunTest< CellClass, ContainerClass, KernelClass, LeafClass,
                 OctreeClass, FmmClass>(true);
     }
 #endif
diff --git a/UTests/utestSphericalDirectPeriodic.cpp b/UTests/utestSphericalDirectPeriodic.cpp
index be0af8912..f9c9a6c36 100755
--- a/UTests/utestSphericalDirectPeriodic.cpp
+++ b/UTests/utestSphericalDirectPeriodic.cpp
@@ -18,7 +18,7 @@
 
 #include "../Src/Kernels/Spherical/FSphericalCell.hpp"
 #include "../Src/Kernels/Spherical/FSphericalKernel.hpp"
-#include "../Src/Kernels/Spherical/FSphericalParticle.hpp"
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 #include "../Src/Components/FSimpleLeaf.hpp"
 #include "../Src/Core/FFmmAlgorithmPeriodic.hpp"
@@ -28,38 +28,22 @@
 
 #include "../Src/Components/FTestCell.hpp"
 #include "../Src/Components/FTestKernels.hpp"
-#include "../Src/Components/FTestParticle.hpp"
-
-/*
-  In this test we compare the fmm results and the direct results.
-  */
-class IndexedParticle : public FSphericalParticle {
-    int index;
-public:
-    IndexedParticle(): index(-1){}
-
-    int getIndex() const{
-        return index;
-    }
-    void setIndex( const int inIndex ){
-        index = inIndex;
-    }
-};
+
+
 
 /** The class to run the test */
 class TestSphericalDirectPeriodic : public FUTester<TestSphericalDirectPeriodic> {
     /** Here we test only the P2P */
     void TestPeriodicFmm(){
-        typedef IndexedParticle         ParticleClass;
         typedef FSphericalCell            CellClass;
-        typedef FVector<ParticleClass>  ContainerClass;
+        typedef FP2PParticleContainerIndexed  ContainerClass;
 
-        typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >   KernelClass;
+        typedef FSphericalKernel<CellClass, ContainerClass >   KernelClass;
 
-        typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-        typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+        typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+        typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-        typedef FFmmAlgorithmPeriodic<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+        typedef FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
         // Parameters
         const int NbLevels      = 3;
@@ -67,17 +51,30 @@ class TestSphericalDirectPeriodic : public FUTester<TestSphericalDirectPeriodic>
         const int PeriodicDeep  = 3;
         const int DevP = 9;
         const int NbParticles = 1;
-        ParticleClass* const particles = new ParticleClass[NbParticles];
 
         FSphericalCell::Init(DevP);
 
-        FRandomLoader<ParticleClass> loader(NbParticles);
+        FRandomLoader loader(NbParticles);
         OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        for( int idxPart = 0 ; idxPart < NbParticles ; ++idxPart ){
-            loader.fillParticle(particles[idxPart]);
-            particles[idxPart].setIndex(idxPart);
-            particles[idxPart].setPhysicalValue(FReal(0.10));
-            tree.insert(particles[idxPart]);
+        struct TestParticle{
+            FPoint position;
+            FReal forces[3];
+            FReal physicalValue;
+            FReal potential;
+        };
+        TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            FPoint position;
+            loader.fillParticle(&position);
+            // put in tree
+            tree.insert(position, idxPart, 0.10);
+            // get copy
+            particles[idxPart].position = position;
+            particles[idxPart].physicalValue = 0.10;
+            particles[idxPart].potential = 0.0;
+            particles[idxPart].forces[0] = 0.0;
+            particles[idxPart].forces[1] = 0.0;
+            particles[idxPart].forces[2] = 0.0;
         }
 
         // Run FMM
@@ -92,23 +89,38 @@ class TestSphericalDirectPeriodic : public FUTester<TestSphericalDirectPeriodic>
         FTreeCoordinate min, max;
         algo.repetitionsIntervals(&min, &max);
 
-        for(int idxTarget = 0 ; idxTarget < NbParticles ; ++idxTarget){
-            for(int idxSource = idxTarget + 1 ; idxSource < NbParticles ; ++idxSource){
-                kernels.directInteractionMutual(&particles[idxTarget], &particles[idxSource]);
+        for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
+            for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
+                FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                      particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                      &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                      &particles[idxTarget].forces[2],&particles[idxTarget].potential,
+                                particles[idxOther].position.getX(), particles[idxOther].position.getY(),
+                                particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
+                                &particles[idxOther].forces[0],&particles[idxOther].forces[1],
+                                &particles[idxOther].forces[2],&particles[idxOther].potential);
             }
             for(int idxX = min.getX() ; idxX <= max.getX() ; ++idxX){
                 for(int idxY = min.getY() ; idxY <= max.getY() ; ++idxY){
                     for(int idxZ = min.getZ() ; idxZ <= max.getZ() ; ++idxZ){
-                        if(idxX == 0 && idxY == 0 && idxZ == 0) continue;
+                        if(idxX ==0 && idxY == 0 && idxZ == 0) continue;
+                        // next lines for test
 
                         const FPoint offset(loader.getBoxWidth() * FReal(idxX),
                                             loader.getBoxWidth() * FReal(idxY),
                                             loader.getBoxWidth() * FReal(idxZ));
 
                         for(int idxSource = 0 ; idxSource < NbParticles ; ++idxSource){
-                            ParticleClass source = particles[idxSource];
-                            source.incPosition(offset.getX(),offset.getY(),offset.getZ());
-                            kernels.directInteraction(&particles[idxTarget], source);
+                            TestParticle source = particles[idxSource];
+                            source.position += offset;
+
+                            FP2P::NonMutualParticles(
+                                        source.position.getX(), source.position.getY(),
+                                        source.position.getZ(),source.physicalValue,
+                                        particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
+                                          particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
+                                          &particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
+                                          &particles[idxTarget].forces[2],&particles[idxTarget].potential);
                         }
                     }
                 }
@@ -120,26 +132,23 @@ class TestSphericalDirectPeriodic : public FUTester<TestSphericalDirectPeriodic>
         FMath::FAccurater potentialDiff;
         FMath::FAccurater fx, fy, fz;
         { // Check that each particle has been summed with all other
-            OctreeClass::Iterator octreeIterator(&tree);
-            octreeIterator.gotoBottomLeft();
-
-            do{
-                ContainerClass::BasicIterator leafIter(*octreeIterator.getCurrentListTargets());
-
-                while( leafIter.hasNotFinished() ){
-                    const ParticleClass& other = particles[leafIter.data().getIndex()];
-
-                    potentialDiff.add(other.getPotential(),leafIter.data().getPotential());
-
-                    fx.add(other.getForces().getX(),leafIter.data().getForces().getX());
-
-                    fy.add(other.getForces().getY(),leafIter.data().getForces().getY());
-
-                    fz.add(other.getForces().getZ(),leafIter.data().getForces().getZ());
 
-                    leafIter.gotoNext();
+            tree.forEachLeaf([&](LeafClass* leaf){
+                const FReal*const potentials = leaf->getTargets()->getPotentials();
+                const FReal*const forcesX = leaf->getTargets()->getForcesX();
+                const FReal*const forcesY = leaf->getTargets()->getForcesY();
+                const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
+                const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
+                const FVector<int>& indexes = leaf->getTargets()->getIndexes();
+
+                for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
+                    const int indexPartOrig = indexes[idxPart];
+                    potentialDiff.add(particles[indexPartOrig].potential,potentials[idxPart]);
+                    fx.add(particles[indexPartOrig].forces[0],forcesX[idxPart]);
+                    fy.add(particles[indexPartOrig].forces[1],forcesY[idxPart]);
+                    fz.add(particles[indexPartOrig].forces[2],forcesZ[idxPart]);
                 }
-            } while(octreeIterator.moveRight());
+            });
         }
 
         Print("Potential diff is = ");
diff --git a/UTests/utestSphericalWithPrevious.cpp b/UTests/utestSphericalWithPrevious.cpp
index 03ca57fd8..481828d4e 100755
--- a/UTests/utestSphericalWithPrevious.cpp
+++ b/UTests/utestSphericalWithPrevious.cpp
@@ -18,7 +18,6 @@
 
 #include "../Src/Kernels/Spherical/FSphericalCell.hpp"
 #include "../Src/Kernels/Spherical/FSphericalKernel.hpp"
-#include "../Src/Kernels/Spherical/FSphericalParticle.hpp"
 #include "../Src/Components/FSimpleLeaf.hpp"
 
 #include "../Src/Files/FFmaBinLoader.hpp"
@@ -27,23 +26,22 @@
 #include "../Src/Core/FFmmAlgorithm.hpp"
 
 #include "FUTester.hpp"
-
+#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
 /**
   * This test compare a previous FMM result with a previous simulation result.
   */
 
 
-typedef FSphericalParticle       ParticleClass;
 typedef FSphericalCell           CellClass;
-typedef FVector<ParticleClass>  ContainerClass;
+typedef FP2PParticleContainerIndexed  ContainerClass;
 
-typedef FSphericalKernel<ParticleClass, CellClass, ContainerClass >          KernelClass;
+typedef FSphericalKernel< CellClass, ContainerClass >          KernelClass;
 
-typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
-typedef FOctree<ParticleClass, CellClass, ContainerClass , LeafClass >  OctreeClass;
+typedef FSimpleLeaf< ContainerClass >                     LeafClass;
+typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
 
-typedef FFmmAlgorithm<OctreeClass, ParticleClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
+typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
 
 /** To check if a value is correct */
 bool IsSimilar(const FReal good, const FReal other){
@@ -68,7 +66,7 @@ class TestSphericalWithPrevious : public FUTester<TestSphericalWithPrevious> {
         const int DevP = 9;
 
         // Load the particles file
-        FFmaBinLoader<ParticleClass> loader(ParticleFile);
+        FFmaBinLoader loader(ParticleFile);
         if(!loader.isOpen()){
             Print("Cannot open particles file.");
             uassert(false);
@@ -78,7 +76,13 @@ class TestSphericalWithPrevious : public FUTester<TestSphericalWithPrevious> {
         // Create octree
         FSphericalCell::Init(DevP);
         OctreeClass testTree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        loader.fillTree(testTree);
+        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
+            FPoint position;
+            FReal physicalValue = 0.0;
+            loader.fillParticle(&position,&physicalValue);
+            // put in tree
+            testTree.insert(position, idxPart, physicalValue);
+        }
 
         // Run simulation
         KernelClass kernels(DevP, NbLevels, loader.getBoxWidth(), loader.getCenterOfBox());
@@ -86,11 +90,11 @@ class TestSphericalWithPrevious : public FUTester<TestSphericalWithPrevious> {
         algo.execute();
 
         // If needed save the result
-        // FTreeIO::Save<OctreeClass, CellClass, ParticleClass, ContainerClass >(DataFile, testTree);
+        // FTreeIO::Save<OctreeClass, CellClass, LeafClass, ContainerClass >(DataFile, testTree);
 
         // Load previous result
         OctreeClass goodTree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
-        FTreeIO::Load<OctreeClass, CellClass, ParticleClass, ContainerClass >(DataFile, goodTree);
+        FTreeIO::Load<OctreeClass, CellClass, LeafClass, ContainerClass >(DataFile, goodTree);
 
         // Compare the two simulations
         Print("Check the particles...");
@@ -107,25 +111,21 @@ class TestSphericalWithPrevious : public FUTester<TestSphericalWithPrevious> {
                     break;
                 }
 
-                if(testOctreeIterator.getCurrentListSrc()->getSize() != goodOctreeIterator.getCurrentListSrc()->getSize()){
+                if(testOctreeIterator.getCurrentListSrc()->getNbParticles() != goodOctreeIterator.getCurrentListSrc()->getNbParticles()){
                     uassert(false);
                     break;
                 }
 
-                ContainerClass::BasicIterator goodIter(*goodOctreeIterator.getCurrentListTargets());
-                ContainerClass::BasicIterator testIter(*testOctreeIterator.getCurrentListTargets());
+                const ContainerClass* testLeaf = testOctreeIterator.getCurrentListSrc();
+                const ContainerClass* goodLeaf = goodOctreeIterator.getCurrentListSrc();
 
-                while( goodIter.hasNotFinished() ){
-                    uassert( IsSimilar(goodIter.data().getPotential(), testIter.data().getPotential()) );
-                    uassert( IsSimilar(goodIter.data().getPosition().getX(), testIter.data().getPosition().getX()) );
-                    uassert( IsSimilar(goodIter.data().getPosition().getY(), testIter.data().getPosition().getY()) );
-                    uassert( IsSimilar(goodIter.data().getPosition().getZ(), testIter.data().getPosition().getZ()) );
-
-                    goodIter.gotoNext();
-                    testIter.gotoNext();
+                for(int idxPart = 0 ; idxPart < testLeaf->getNbParticles() ; ++idxPart ){
+                    uassert( IsSimilar(goodLeaf->getPotentials()[idxPart], testLeaf->getPotentials()[idxPart]) );
+                    uassert( IsSimilar(goodLeaf->getForcesX()[idxPart], testLeaf->getForcesX()[idxPart]) );
+                    uassert( IsSimilar(goodLeaf->getForcesY()[idxPart], testLeaf->getForcesY()[idxPart]) );
+                    uassert( IsSimilar(goodLeaf->getForcesZ()[idxPart], testLeaf->getForcesZ()[idxPart]) );
                 }
 
-
                 if(!testOctreeIterator.moveRight()){
                     if(goodOctreeIterator.moveRight()){
                         uassert(false);
-- 
GitLab