diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp
index 2ea88a1234e956a855dc043891e384de3e2d2e3f..f1c0ffba37597121cf22bcd1737ad7088d172eb6 100755
--- a/src/Decomposition/CartDecomposition.hpp
+++ b/src/Decomposition/CartDecomposition.hpp
@@ -1013,6 +1013,7 @@ public:
 		calculateGhostBoxes();
 
 		domain_nn_calculator_cart<dim>::reset();
+		domain_nn_calculator_cart<dim>::setParameters(proc_box);
 	}
 
 	/*! \brief Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call
@@ -1034,6 +1035,7 @@ public:
 		calculateGhostBoxes();
 
 		domain_nn_calculator_cart<dim>::reset();
+		domain_nn_calculator_cart<dim>::setParameters(proc_box);
 	}
 
 	/*! \brief Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call
@@ -1055,6 +1057,7 @@ public:
 		calculateGhostBoxes();
 
 		domain_nn_calculator_cart<dim>::reset();
+		domain_nn_calculator_cart<dim>::setParameters(proc_box);
 	}
 
 	/*! \brief Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call
@@ -1283,9 +1286,9 @@ public:
 	 * \param gs grid extension
 	 *
 	 */
-	openfpm::vector<size_t> & getDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs)
+	openfpm::vector<size_t> & getDomainCells()
 	{
-		return domain_nn_calculator_cart<dim>::getDomainCells(shift,cell_shift,gs,proc_box,loc_box);
+		return domain_nn_calculator_cart<dim>::getDomainCells();
 	}
 
 	/*! \brief Get the CRS domain Cells
@@ -1296,11 +1299,23 @@ public:
 	 * \param shift Cell padding
 	 * \param cell_shift where the domain cell start
 	 * \param gs grid extension
+	 * \param loc_box processor sub-domains
 	 *
 	 */
-	openfpm::vector<size_t> & getCRSDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs)
+	openfpm::vector<size_t> & getCRSDomainCells()
 	{
-		return domain_nn_calculator_cart<dim>::getCRSDomainCells(shift,cell_shift,gs,proc_box,loc_box);
+		return domain_nn_calculator_cart<dim>::getCRSDomainCells();
+	}
+
+	/*! \brief set NN parameters to calculate cell-list neighborhood
+	 *
+	 * \param shift to apply in cell linearization
+	 * \param gs cell grid
+	 *
+	 */
+	void setNNParameters(grid_key_dx<dim> & shift, grid_sm<dim,void> & gs)
+	{
+		domain_nn_calculator_cart<dim>::setNNParameters(loc_box, shift, gs);
 	}
 
 	/*! \brief Get the CRS anomalous cells
@@ -1316,9 +1331,9 @@ public:
 	 * \return the anomalous cells with neighborhood
 	 *
 	 */
-	openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs)
+	openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells()
 	{
-		return domain_nn_calculator_cart<dim>::getCRSAnomDomainCells(shift,cell_shift,gs,proc_box,loc_box);
+		return domain_nn_calculator_cart<dim>::getCRSAnomDomainCells();
 	}
 
 	/*! \brief Check if the particle is local considering boundary conditions
diff --git a/src/Decomposition/Domain_NN_calculator_cart.hpp b/src/Decomposition/Domain_NN_calculator_cart.hpp
index e0889bc25ffe0f236c6d81530ca51ed6334db061..e32d2215ce4d7d48718b9ad48cca9558a95bc088 100644
--- a/src/Decomposition/Domain_NN_calculator_cart.hpp
+++ b/src/Decomposition/Domain_NN_calculator_cart.hpp
@@ -8,6 +8,9 @@
 #ifndef SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_
 #define SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_
 
+#include <Vector/map_vector.hpp>
+#include "NN/CellList/ParticleItCRS_Cells.hpp"
+
 /*! \brief This class calculate processor domains and neighborhood
  *  of each processor domain
  *
@@ -20,49 +23,39 @@ class domain_nn_calculator_cart
 	//! True if domain and anomalous domain cells are computed
 	bool are_domain_anom_computed;
 
-	//! Are linearized the domain cells
-    bool are_dom_cells_lin;
-
-	//! Are linearized the CRS domain cell
-    bool are_dom_lin;
-
-    //! are linearized the CRS anomalous cells
-    bool are_anom_lin;
+    /////////////////////////////// CRS //////////////////////
 
 	//! anomalous cell neighborhood for CRS
 	openfpm::vector<subsub<dim>> anom;
 
+	//! Set of anomalous CRS domain cells linearized
+	openfpm::vector<subsub_lin<dim>> anom_lin;
+
 	//! Set of normal domain cells for CRS
 	openfpm::vector<grid_key_dx<dim>> dom;
 
-	//! Set of domain cells
-	openfpm::vector<grid_key_dx<dim>> dom_cells;
-
-	//! Linearization is calculated out of a shift and grid dimension this is the shift
-	grid_key_dx<dim> shift_calc_dom;
-
-	//! Linearization is calculated out of a grid dimensions this is the grid dimension
-	grid_sm<dim,void> gs_calc_dom;
-
-	//! Linearization is calculated out of a shift and grid dimension this is the shift
-	grid_key_dx<dim> shift_calc_anom;
-
-	//! Linearization is calculated out of a grid dimensions this is the grid dimension
-	grid_sm<dim,void> gs_calc_anom;
-
-
 	//! Set of normal CRS domain cells linearized
 	openfpm::vector<size_t> dom_lin;
 
-	//! Set of anomalous CRS domain cells linearized
-	openfpm::vector<subsub_lin<dim>> anom_lin;
+	////////////////////////////////// DOMAIN CELLS ///////////////////////
+
+	//! Set of domain cells
+	openfpm::vector<grid_key_dx<dim>> dom_cells;
 
 	//! Set of linearized domain cells
 	openfpm::vector<size_t> dom_cells_lin;
 
+	//////////////////////////////////////////////////////////////
+
 	//! Processor box
 	Box<dim,long int> proc_box;
 
+	//! Processor cells-grid
+	grid_sm<dim,void> gs;
+
+	//! key with all coordinates set to one
+	grid_key_dx<dim> one;
+
 	/*! \brief Calculate the subdomain that are in the skin part of the domain
 	 *
        \verbatim
@@ -114,7 +107,6 @@ class domain_nn_calculator_cart
 			                      openfpm::vector<grid_key_dx<dim>> & dom_subsub,
 								  openfpm::vector<grid_key_dx<dim>> & dom_cells,
 								  const ::Box<dim,long int> & proc_box,
-								  grid_key_dx<dim> & shift,
 								  const openfpm::vector<::Box<dim, size_t>> & loc_box)
 	{
 		// Reset dom and dom_subsub
@@ -123,13 +115,21 @@ class domain_nn_calculator_cart
 
 		size_t sz[dim];
 
+		// ----Grid size = proc_box.getHigh(j) - proc_box.getLow(j)
+		// +2 is padding
+
 		for (size_t j = 0 ; j < dim ; j++)
-			sz[j] = proc_box.getHigh(j) - proc_box.getLow(j) + 2;
+			sz[j] = proc_box.getHigh(j) - proc_box.getLow(j) + 2 + 1;
+
+		gs.setDimensions(sz);
 
 		// Set the grid
-		grid_cpu<dim, aggregate<openfpm::vector<grid_key_dx<dim>>> > g(sz);
+		grid_cpu<dim, aggregate<openfpm::vector<grid_key_dx<dim>> >> g(sz);
 		g.setMemory();
 
+		for (size_t i = 0 ; i < dim ; i++)
+			one.set_d(i,1);
+
 		// Calculate the csr neighborhood
 		openfpm::vector<std::pair<grid_key_dx<dim>,grid_key_dx<dim>>> csr;
 		NNcalc_csr(csr);
@@ -142,8 +142,8 @@ class domain_nn_calculator_cart
 
 			for (size_t j = 0 ; j < dim ; j++)
 			{
-				start.set_d(j,loc_box.template get<0>(i)[j] - proc_box.getLow(j));
-				stop.set_d(j,loc_box.template get<1>(i)[j] - proc_box.getLow(j));
+				start.set_d(j,loc_box.template get<0>(i)[j] - proc_box.getLow(j) + 1);
+				stop.set_d(j,loc_box.template get<1>(i)[j] - proc_box.getLow(j) + 1);
 			}
 
 			grid_key_dx_iterator_sub<dim> sub(g.getGrid(),start,stop);
@@ -156,10 +156,10 @@ class domain_nn_calculator_cart
 				{
 					grid_key_dx<dim> src = key + csr.get(j).first;
 					grid_key_dx<dim> dst = key + csr.get(j).second;
-					g.template get<0>(src).add(dst + shift);
+					g.template get<0>(src).add(dst);
 				}
 
-				dom_cells.add(key + shift);
+				dom_cells.add(key - one);
 
 				++sub;
 			}
@@ -178,152 +178,154 @@ class domain_nn_calculator_cart
 			if (g.template get<0>(key).size() == openfpm::math::pow(3,dim)/2+1)
 			{
 				// Add in the list of the normal neighborhood list
-				dom_subsub.add(key + shift);
+				dom_subsub.add(key - one);
 			}
 			else if (g.template get<0>(key).size() != 0)
 			{
 				sub_keys.add();
-				sub_keys.last().subsub = key + shift;
+				sub_keys.last().subsub = key - one;
 				// Adding the neighborhood of the cell
-				sub_keys.last().NN_subsub = g.template get<0>(key);
+
+				sub_keys.last().NN_subsub.resize(g.template get<0>(key).size());
+
+				for (size_t i = 0 ; i < g.template get<0>(key).size() ; i++)
+					sub_keys.last().NN_subsub.get(i) = g.template get<0>(key).get(i) - one;
 			}
 
 			++it;
 		}
 	}
 
+	/*! \brief Linearize the sub-sub-domains
+	 *
+	 * \param anon set of grid keys to linearize
+	 * \param anom_lin linearized output
+	 * \param shift shifting
+	 *
+	 */
+	void linearize_subsub(const openfpm::vector<subsub<dim>> & anom,
+			              openfpm::vector<subsub_lin<dim>> & anom_lin,
+						  const grid_key_dx<dim> & shift,
+						  const grid_sm<dim,void> & gs)
+	{
+		anom_lin.clear();
+		for (size_t i = 0 ; i < anom.size() ; i++)
+		{
+			anom_lin.add();
+			anom_lin.last().subsub = gs.LinId(anom.get(i).subsub + shift);
+
+			long int self_cell = -1;
+
+			for (size_t j = 0 ; j < anom.get(i).NN_subsub.size() ; j++)
+			{
+				anom_lin.get(i).NN_subsub.add((long int)gs.LinId(anom.get(i).NN_subsub.get(j) + shift) - anom_lin.get(i).subsub);
+
+				// This indicate that for example in the neighborhood of one cell it-self is included in the list
+				// For example the cell 100 is in the neighborhood of the cell 100
+				if (anom_lin.get(i).NN_subsub.last() == 0)
+					self_cell = anom_lin.get(i).NN_subsub.size() - 1;
+			}
+
+			// if exist the self interacting cell (Example cell 100 neighborhood of cell 100), this cell MUST BE ALWAYS at the beginning
+			if (self_cell != -1)
+			{
+				// bring the self-cell into the beginning
+				size_t tmp = anom_lin.get(i).NN_subsub.get(0);
+				anom_lin.get(i).NN_subsub.get(0) = 0;
+				anom_lin.get(i).NN_subsub.get(self_cell) = tmp;
+			}
+		}
+	}
+
 public:
 
 	domain_nn_calculator_cart()
-	:are_domain_anom_computed(false),are_dom_cells_lin(false),are_dom_lin(false),are_anom_lin(false)
-	{}
+	:are_domain_anom_computed(false)
+	{
+	}
 
-	/*! \brief Get the domain Cells
+	/*! \brief Set parameters to calculate the cell neighborhood
 	 *
-	 * \param shift Shifting point
-	 * \param gs grid extension
-	 * \param proc_box processor bounding box
-	 * \param loc_box set of local sub-domains
+	 * \param proc_box processor cells box
 	 *
-	 * \return The set of domain cells
+	 */
+	void setParameters(const Box<dim,long int> & proc_box)
+	{
+		this->proc_box = proc_box;
+	}
+
+	/*! \brief Set parameters to calculate the cell neighborhood
+	 *
+	 * \param shift to apply in the linearization
+	 * \param loc_box set of local sub-domains
 	 *
 	 */
-	openfpm::vector<size_t> & getDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
+	void setNNParameters(openfpm::vector<::Box<dim, size_t>> & loc_box,
+			             const grid_key_dx<dim> & shift,
+						 const grid_sm<dim,void> & gs)
 	{
 		if (are_domain_anom_computed == false)
 		{
-			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
+			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,loc_box);
 			are_domain_anom_computed = true;
-		}
 
-		if (are_dom_cells_lin == false)
-		{
 			dom_cells_lin.clear();
-			shift_calc_dom = shift;
-			gs_calc_dom = gs;
 			for (size_t i = 0 ; i < dom_cells.size() ; i++)
-				dom_cells_lin.add(gs.LinId(dom_cells.get(i) - cell_shift));
+				dom_cells_lin.add(gs.LinId(dom_cells.get(i) + shift));
 
-			are_dom_cells_lin = true;
+
+			dom_lin.clear();
+			for (size_t i = 0 ; i < dom.size() ; i++)
+				dom_lin.add(gs.LinId(dom.get(i) + shift));
+
+			linearize_subsub(anom,anom_lin,shift,gs);
 		}
+	}
 
+	/*! \brief Get the domain Cells
+	 *
+	 * \param loc_box set of local sub-domains
+	 *
+	 * \return The set of domain cells
+	 *
+	 */
+	openfpm::vector<size_t> & getDomainCells()
+	{
 		return dom_cells_lin;
 	}
 
 	/*! \brief Get the domain Cells
 	 *
-	 * \param shift Shifting point
-	 * \param gs grid extension
-	 * \param proc_box processor bounding box
 	 * \param loc_box set of local sub-domains
 	 *
 	 * \return The set of domain cells
 	 *
 	 */
-	openfpm::vector<size_t> & getCRSDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
+	openfpm::vector<size_t> & getCRSDomainCells()
 	{
-		if (are_domain_anom_computed == false)
-		{
-			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
-			are_domain_anom_computed = true;
-		}
-
-		if (are_dom_lin == false)
-		{
-			dom_lin.clear();
-			shift_calc_dom = shift;
-			gs_calc_dom = gs;
-			for (size_t i = 0 ; i < dom.size() ; i++)
-				dom_lin.add(gs.LinId(dom.get(i) - cell_shift));
-
-			are_dom_lin = true;
-		}
-
 		return dom_lin;
 	}
 
 	/*! \brief Get the domain anomalous cells
 	 *
-	 * \param shift Shifting point
-	 * \param gs grid extension
-	 * \param proc_box processor bounding box
 	 * \param loc_box set of local sub-domains
 	 *
 	 * \return The set of anomalous cells
 	 *
 	 */
-	openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
+	openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells()
 	{
-		// if the neighborhood of each sub-sub-domains has not been calculated, calculate it
-		if (are_domain_anom_computed == false)
-		{
-			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
-			are_domain_anom_computed = true;
-		}
-
-		if (are_anom_lin == false)
-		{
-			anom_lin.clear();
-			shift_calc_anom = shift;
-			gs_calc_anom = gs;
-			for (size_t i = 0 ; i < anom.size() ; i++)
-			{
-				anom_lin.add();
-				anom_lin.last().subsub = gs.LinId(anom.get(i).subsub - cell_shift);
-
-				long int self_cell = -1;
-
-				for (size_t j = 0 ; j < anom.get(i).NN_subsub.size() ; j++)
-				{
-					anom_lin.get(i).NN_subsub.add((long int)gs.LinId(anom.get(i).NN_subsub.get(j) - cell_shift) - anom_lin.get(i).subsub);
-
-					// This indicate that for example in the neighborhood of one cell it-self is included in the list
-					// For example the cell 100 is in the neighborhood of the cell 100
-					if (anom_lin.get(i).NN_subsub.last() == 0)
-						self_cell = anom_lin.get(i).NN_subsub.size() - 1;
-				}
-
-				// if exist the self interacting cell (Example cell 100 neighborhood of cell 100), this cell MUST BE ALWAYS at the beginning
-				if (self_cell != -1)
-				{
-					// bring the self-cell into the beginning
-					size_t tmp = anom_lin.get(i).NN_subsub.get(0);
-					anom_lin.get(i).NN_subsub.get(0) = 0;
-					anom_lin.get(i).NN_subsub.get(self_cell) = tmp;
-				}
-			}
-
-			are_anom_lin = true;
-		}
-
 		return anom_lin;
 	}
 
+
+	/*! \brief In case you have to recompute the indexes
+	 *
+	 *
+	 */
 	void reset()
 	{
 		are_domain_anom_computed = false;
-		are_dom_lin = false;
-		are_anom_lin = false;
 	}
 };
 
diff --git a/src/Grid/Iterators/grid_dist_id_iterators_unit_tests.hpp b/src/Grid/Iterators/grid_dist_id_iterators_unit_tests.hpp
index 0ac518ac6fae53d52d43e2eff6a26579324ec00d..e71ccad3708b52fd14ed1bb4d70024889f62a32c 100644
--- a/src/Grid/Iterators/grid_dist_id_iterators_unit_tests.hpp
+++ b/src/Grid/Iterators/grid_dist_id_iterators_unit_tests.hpp
@@ -260,7 +260,7 @@ void Test3D_decit(const Box<3,float> & domain, long int k)
 
 			// create a grid iterator from the decomposition
 
-			grid_dist_id_iterator_dec<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),sz,{0,0,0},{sz[0]-2,sz[1]-2,sz[2]-2});
+			grid_dist_id_iterator_dec<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),sz,{0,0,0},{(long int)sz[0]-2,(long int)sz[1]-2,(long int)sz[2]-2});
 
 			while (dom.isNext())
 			{
diff --git a/src/Makefile.am b/src/Makefile.am
index b45481df14f0bbd0c5acce6759aa7a00f84c2fc2..e9529878fa45d601418730e250914d6d9a096431 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,6 @@
 LINKLIBS = $(OPENMP_LDFLAGS) $(LIBHILBERT_LIB)  $(METIS_LIB) $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_IOSTREAMS_LIB) $(CUDA_LIBS) $(PETSC_LIB) $(HDF5_LDFLAGS)  $(HDF5_LIBS) $(PARMETIS_LIB) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(BOOST_CHRONO_LIB) $(BOOST_TIMER_LIB) $(BOOST_SYSTEM_LIB) $(LIBIFCORE)
 
+
 noinst_PROGRAMS = pdata
 pdata_SOURCES = main.cpp pdata_performance.cpp Grid/grid_dist_id_unit_test.cpp  lib/pdata.cpp test_multiple_o.cpp ../openfpm_devices/src/memory/HeapMemory.cpp ../openfpm_devices/src/memory/PtrMemory.cpp ../openfpm_vcluster/src/VCluster/VCluster.cpp ../openfpm_devices/src/Memleak_check.cpp
 pdata_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(PETSC_INCLUDE) $(HDF5_CPPFLAGS) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(PARMETIS_INCLUDE) $(METIS_INCLUDE) $(BOOST_CPPFLAGS) $(H5PART_INCLUDE) -DPARALLEL_IO  -Wno-unused-local-typedefs
@@ -16,6 +17,10 @@ nobase_include_HEADERS = Decomposition/CartDecomposition.hpp Decomposition/CartD
          Graph/ids.hpp Graph/dist_map_graph.hpp Graph/DistGraphFactory.hpp \
          DLB/DLB.hpp DLB/LB_Model.hpp
 
+#testa_SOURCES = Decomposition/Domain_NN_calculator_cart_unit_test.cpp ../openfpm_devices/src/memory/HeapMemory.cpp ../openfpm_vcluster/src/VCluster/VCluster.cpp
+#testa_LDADD = $(LINKLIBS)
+#testa_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(LIBHILBERT_INCLUDE) $(PETSC_INCLUDE) $(HDF5_CPPFLAGS) $(CUDA_CFLAGS) $(INCLUDES_PATH) $(PARMETIS_INCLUDE) $(METIS_INCLUDE) $(BOOST_CPPFLAGS) $(H5PART_INCLUDE) -DPARALLEL_IO  -Wno-unused-local-typedefs
+
 lib_LIBRARIES = libofpm_pdata.a
 libofpm_pdata_a_SOURCES = lib/pdata.cpp
 libofpm_pdata_a_CXXFLAGS = $(OPENMP_CFLAGS) $(AM_CXXFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include -Wno-unused-local-typedefs
diff --git a/src/Vector/Iterators/vector_dist_iterator.hpp b/src/Vector/Iterators/vector_dist_iterator.hpp
index 17bd344695a3ae3f91776ae2fc16f3c5e87fc40a..4deac8ebe834599d0ee3561e9af183c61b848d04 100644
--- a/src/Vector/Iterators/vector_dist_iterator.hpp
+++ b/src/Vector/Iterators/vector_dist_iterator.hpp
@@ -72,9 +72,11 @@ class vector_dist_iterator
 	 * \return the actual key
 	 *
 	 */
-	vect_dist_key_dx get()
+	inline vect_dist_key_dx get()
 	{
-		return vect_dist_key_dx(v_it);
+		vect_dist_key_dx v;
+		v.setKey(v_it);
+		return v;
 	}
 
 	/*! \brief Reset the iterator
diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp
index 8a715c74c2988d8a8bb6825947604ecebf78ffa4..057070eb816d6c2aa554d5356ff07d5874022925 100644
--- a/src/Vector/vector_dist.hpp
+++ b/src/Vector/vector_dist.hpp
@@ -416,6 +416,20 @@ public:
 		return v_pos.template get<0>(vec_key.getKey());
 	}
 
+	/*! \brief Get the position of an element
+	 *
+	 * see the vector_dist iterator usage to get an element key
+	 *
+	 * \param vec_key element
+	 *
+	 * \return the position of the element in space
+	 *
+	 */
+	inline auto getPos(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
+	{
+		return v_pos.template get<0>(vec_key);
+	}
+
 	/*! \brief Get the property of an element
 	 *
 	 * see the vector_dist iterator usage to get an element key
@@ -446,6 +460,21 @@ public:
 		return v_prp.template get<id>(vec_key.getKey());
 	}
 
+	/*! \brief Get the property of an element
+	 *
+	 * see the vector_dist iterator usage to get an element key
+	 *
+	 * \tparam id property id
+	 * \param vec_key vector element
+	 *
+	 * \return return the selected property of the vector element
+	 *
+	 */
+	template<unsigned int id> inline auto getProp(size_t vec_key) const -> const decltype(v_prp.template get<id>(vec_key))
+	{
+		return v_prp.template get<id>(vec_key);
+	}
+
 #endif
 
 ///////////////////// Read and Write function
@@ -673,6 +702,34 @@ public:
 		return cell_list;
 	}
 
+	/*! \brief return the neighborhood cells of a cells to do symmetric interactions
+	 *
+	 * \warning Used in in combination of getNNIteratorSym in a Cell-list
+	 *
+	 * \return the neighborhood cells of a cell
+	 *
+	 *
+	 */
+/*	const openfpm::vector<subsub_lin<dim>> & getNNCells(size_t cell) const
+	{
+		return getDecomposition().getDomainCellNNSym();
+	}*/
+
+	/*! \brief Construct a cell list symmetric based on a cut of radius
+	 *
+	 * \tparam CellL CellList type to construct
+	 *
+	 * \param r_cut interation radius, or size of each cell
+	 *
+	 * \return the Cell list
+	 *
+	 */
+	template<typename CellL = CellList<dim, St, FAST, shift<dim, St> > > CellL getCellListSymNoBind(St r_cut)
+	{
+		return getCellList(r_cut);
+	}
+
+
 	/*! \brief Construct a cell list starting from the stored particles
 	 *
 	 * \tparam CellL CellList type to construct
@@ -927,20 +984,19 @@ public:
 		auto & NN = ver.getInternalCellList();
 
 		// Shift
-		grid_key_dx<dim> cell_shift = NN.getShift();
-
-		// Shift
-		grid_key_dx<dim> shift = NN.getShift();
+		grid_key_dx<dim> shift;
 
 		// Add padding
 		for (size_t i = 0 ; i < dim ; i++)
-			shift.set_d(i,shift.get(i) + NN.getPadding(i));
+			shift.set_d(i,NN.getPadding(i));
 
 		grid_sm<dim,void> gs = NN.getInternalGrid();
 
+		getDecomposition().setNNParameters(shift,gs);
+
 		ver.createVerletCrs(r_cut,g_m,v_pos,
-				            getDecomposition().getCRSDomainCells(shift,cell_shift,gs),
-							getDecomposition().getCRSAnomDomainCells(shift,cell_shift,gs));
+				            getDecomposition().getCRSDomainCells(),
+							getDecomposition().getCRSAnomDomainCells());
 
 		ver.set_ndec(getDecomposition().get_ndec());
 
@@ -1022,20 +1078,19 @@ public:
 			if (to_reconstruct == false)
 			{
 				// Shift
-				grid_key_dx<dim> cell_shift = NN.getShift();
-
-				// Shift
-				grid_key_dx<dim> shift = NN.getShift();
+				grid_key_dx<dim> shift;
 
 				// Add padding
 				for (size_t i = 0 ; i < dim ; i++)
-					shift.set_d(i,shift.get(i) + NN.getPadding(i));
+					shift.set_d(i,NN.getPadding(i));
 
 				grid_sm<dim,void> gs = NN.getInternalGrid();
 
+				getDecomposition().setNNParameters(shift,gs);
+
 				ver.updateCrs(getDecomposition().getDomain(),r_cut,v_pos,g_m,
-						      getDecomposition().getCRSDomainCells(shift,cell_shift,gs),
-							  getDecomposition().getCRSAnomDomainCells(shift,cell_shift,gs));
+						      getDecomposition().getCRSDomainCells(),
+							  getDecomposition().getCRSAnomDomainCells());
 			}
 			else
 			{
@@ -1284,18 +1339,17 @@ public:
 #endif
 
 		// Shift
-		grid_key_dx<dim> cell_shift = NN.getShift();
-
-		// Shift
-		grid_key_dx<dim> shift = NN.getShift();
+		grid_key_dx<dim> shift;
 
 		// Add padding
 		for (size_t i = 0 ; i < dim ; i++)
-			shift.set_d(i,shift.get(i) + NN.getPadding(i));
+			shift.set_d(i,NN.getPadding(i));
 
 		grid_sm<dim,void> gs = NN.getInternalGrid();
 
-		return ParticleIt_Cells<dim,CellList>(NN,getDecomposition().getDomainCells(shift,cell_shift,gs));
+		getDecomposition().setNNParameters(shift,gs);
+
+		return ParticleIt_Cells<dim,CellList>(NN,getDecomposition().getDomainCells());
 	}
 
 	/*! \brief Get an iterator that traverse the particles in the domain
@@ -1732,20 +1786,19 @@ public:
 	template<typename cli> ParticleItCRS_Cells<dim,cli> getParticleIteratorCRS(cli & NN)
 	{
 		// Shift
-		grid_key_dx<dim> cell_shift = NN.getShift();
-
-		// Shift
-		grid_key_dx<dim> shift = NN.getShift();
+		grid_key_dx<dim> shift;
 
 		// Add padding
 		for (size_t i = 0 ; i < dim ; i++)
-			shift.set_d(i,shift.get(i) + NN.getPadding(i));
+			shift.set_d(i,NN.getPadding(i));
 
 		grid_sm<dim,void> gs = NN.getInternalGrid();
 
+		getDecomposition().setNNParameters(shift,gs);
+
 		// First we check that
-		return ParticleItCRS_Cells<dim,cli>(NN,getDecomposition().getCRSDomainCells(shift,cell_shift,gs),
-				                               getDecomposition().getCRSAnomDomainCells(shift,cell_shift,gs),
+		return ParticleItCRS_Cells<dim,cli>(NN,getDecomposition().getCRSDomainCells(),
+				                               getDecomposition().getCRSAnomDomainCells(),
 											   NN.getNNc_sym());
 	}
 
diff --git a/src/Vector/vector_dist_NN_tests.hpp b/src/Vector/vector_dist_NN_tests.hpp
index c893c741e2dba2bf097e70dce8fd722cb232dae9..06c0c3954326544367dc22c9c147a5f5287df8cf 100644
--- a/src/Vector/vector_dist_NN_tests.hpp
+++ b/src/Vector/vector_dist_NN_tests.hpp
@@ -295,11 +295,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_particle_iteration )
 	v_cl.sum(count);
 	v_cl.execute();
 
-	for (size_t i = 0 ; i < ids.size() ; i++)
-	{
-		std::cout << "OUTPUT: " << i << "    " << ids.get(i) <<  create_vcluster().getProcessUnitID() << std::endl;
-	}
-
 	BOOST_REQUIRE_EQUAL((long int)count,k);
 }
 
diff --git a/src/Vector/vector_dist_cell_list_tests.hpp b/src/Vector/vector_dist_cell_list_tests.hpp
index a6a1144e24af3daf36661c342a0eb9689d3c10e0..b7a517f93203aa0e845dc1f913291a70ee06faaa 100644
--- a/src/Vector/vector_dist_cell_list_tests.hpp
+++ b/src/Vector/vector_dist_cell_list_tests.hpp
@@ -1385,7 +1385,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list )
 
 		ret &= vd2.getProp<1>(p) == vd.getProp<0>(p);
 
-
 		vd.getProp<3>(p).sort();
 		vd2.getProp<4>(p).sort();
 
@@ -1403,4 +1402,5 @@ BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list )
 	BOOST_REQUIRE_EQUAL(ret,true);
 }
 
+
 #endif /* SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_ */
diff --git a/src/Vector/vector_dist_comm.hpp b/src/Vector/vector_dist_comm.hpp
index 41ed6c0251313640f8d0cccc8939541536cfdac3..24ba62e51f2429e58399468eb61ec631796e60e5 100644
--- a/src/Vector/vector_dist_comm.hpp
+++ b/src/Vector/vector_dist_comm.hpp
@@ -78,9 +78,6 @@ class vector_dist_comm
 	//! processor rank list of g_opart
 	openfpm::vector<size_t> prc_g_opart;
 
-	//! Sending buffer for the ghost particles position
-	openfpm::vector<send_pos_vector> g_pos_send;
-
 	//! It store the list of processor that communicate with us (local processor)
 	//! from the last ghost get
 	openfpm::vector<size_t> prc_recv_get;
@@ -108,6 +105,12 @@ class vector_dist_comm
 	//! replicated ghost particles that are local
 	size_t lg_m;
 
+	//! Sending buffer
+	openfpm::vector<HeapMemory> hsmem;
+
+	//! Receiving buffer
+	openfpm::vector<HeapMemory> hrmem;
+
 	//! process the particle without properties
 	struct proc_without_prp
 	{
@@ -419,8 +422,19 @@ class vector_dist_comm
 
 		// create a number of send buffers equal to the near processors
 		g_pos_send.resize(g_opart.size());
+
+		resize_retained_buffer(hsmem,g_pos_send.size());
+
 		for (size_t i = 0; i < g_pos_send.size(); i++)
 		{
+			// Buffer must retained and survive the destruction of the
+			// vector
+			if (hsmem.get(i).ref() == 0)
+				hsmem.get(i).incRef();
+
+			// Set the memory for retain the send buffer
+			g_pos_send.get(i).setMemory(hsmem.get(i));
+
 			// resize the sending vector (No allocation is produced)
 			g_pos_send.get(i).resize(g_opart.get(i).size());
 		}
@@ -453,8 +467,19 @@ class vector_dist_comm
 		// create a number of send buffers equal to the near processors
 		// from which we received
 		g_send_prp.resize(prc_recv_get.size());
+
+		resize_retained_buffer(hsmem,g_send_prp.size());
+
 		for (size_t i = 0; i < g_send_prp.size(); i++)
 		{
+			// Buffer must retained and survive the destruction of the
+			// vector
+			if (hsmem.get(i).ref() == 0)
+				hsmem.get(i).incRef();
+
+			// Set the memory for retain the send buffer
+			g_send_prp.get(i).setMemory(hsmem.get(i));
+
 			// resize the sending vector (No allocation is produced)
 			g_send_prp.get(i).resize(recv_sz_get.get(i));
 		}
@@ -482,6 +507,21 @@ class vector_dist_comm
 		}
 	}
 
+	/*! \brief resize the retained buffer by nbf
+	 *
+	 *
+	 */
+	void resize_retained_buffer(openfpm::vector<HeapMemory> & rt_buf, size_t nbf)
+	{
+		// Release all the buffer that are going to be deleted
+		for (size_t i = nbf ; i < rt_buf.size() ; i++)
+		{
+			rt_buf.get(i).decRef();
+		}
+
+		hsmem.resize(nbf);
+	}
+
 	/*! \brief This function fill the send buffer for properties after the particles has been label with labelParticles
 	 *
 	 * \tparam send_vector type used to send data
@@ -496,8 +536,19 @@ class vector_dist_comm
 	{
 		// create a number of send buffers equal to the near processors
 		g_send_prp.resize(g_opart.size());
+
+		resize_retained_buffer(hsmem,g_send_prp.size());
+
 		for (size_t i = 0; i < g_send_prp.size(); i++)
 		{
+			// Buffer must retained and survive the destruction of the
+			// vector
+			if (hsmem.get(i).ref() == 0)
+				hsmem.get(i).incRef();
+
+			// Set the memory for retain the send buffer
+			g_send_prp.get(i).setMemory(hsmem.get(i));
+
 			// resize the sending vector (No allocation is produced)
 			g_send_prp.get(i).resize(g_opart.get(i).size());
 		}
@@ -785,6 +836,23 @@ public:
 	{
 	}
 
+	/*! \brief Destructor
+	 *
+	 * Release the retained buffer
+	 *
+	 */
+	~vector_dist_comm()
+	{
+		for (size_t i = 0 ; i < hsmem.size() ; i++)
+		{
+			if (hsmem.get(i).ref() == 1)
+				hsmem.get(i).decRef();
+			else
+				std::cout << __FILE__ << ":" << __LINE__ << " internal error memory is in an invalid state " << std::endl;
+		}
+
+	}
+
 	/*! \brief Get the number of minimum sub-domain per processor
 	 *
 	 * \return minimum number
@@ -884,18 +952,15 @@ public:
 			labelParticlesGhost(v_pos,v_prp,prc_g_opart,g_m);
 
 		// Send and receive ghost particle information
-		openfpm::vector<send_vector> g_send_prp;
-		fill_send_ghost_prp_buf<send_vector, prp_object, prp...>(v_prp,g_send_prp);
-
-		// Create and fill the send buffer for the particle position
-		if (!(opt & NO_POSITION))
-			fill_send_ghost_pos_buf(v_pos,g_pos_send);
+		{
+			openfpm::vector<send_vector> g_send_prp;
+			fill_send_ghost_prp_buf<send_vector, prp_object, prp...>(v_prp,g_send_prp);
 
-		// if there are no properties skip
-		// SSendRecvP send everything when we do not give properties
+			// if there are no properties skip
+			// SSendRecvP send everything when we do not give properties
 
-        if (sizeof...(prp) != 0)
-        {
+			if (sizeof...(prp) != 0)
+			{
                 if (opt & SKIP_LABELLING)
                 {
                 	size_t opt_ = compute_options(opt);
@@ -910,10 +975,16 @@ public:
 
 				for (size_t i = 0 ; i < prc_g_opart.size() ; i++)
 					g_opart_sz.get(i) = g_send_prp.get(i).size();
-        }
+			}
+		}
 
 		if (!(opt & NO_POSITION))
 		{
+			// Sending buffer for the ghost particles position
+			openfpm::vector<send_pos_vector> g_pos_send;
+
+			fill_send_ghost_pos_buf(v_pos,g_pos_send);
+
 			if (opt & SKIP_LABELLING)
 			{
             	size_t opt_ = compute_options(opt);
diff --git a/src/Vector/vector_dist_key.hpp b/src/Vector/vector_dist_key.hpp
index 97bfac2e16d74bb13a6a8561eaab50ac6b682920..c5c7a8781283612bf40556ca1f0bc974af7793a2 100644
--- a/src/Vector/vector_dist_key.hpp
+++ b/src/Vector/vector_dist_key.hpp
@@ -59,10 +59,10 @@ public:
 	}
 
 	//! constructor from a key
-	inline vect_dist_key_dx(size_t key)
+/*	inline vect_dist_key_dx(size_t key)
 	:key(key)
 	{
-	}
+	}*/
 
 	//! Default constructor
 	inline vect_dist_key_dx()
diff --git a/src/main.cpp b/src/main.cpp
index f33bd63d8f07a050c8c7d3028a7b89c47d958bfe..38e281838cccc35b3937f7b02a370ba7f7a2051d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,4 +56,5 @@ int main(int argc, char* argv[])
 #include "Vector/vector_dist_MP_unit_tests.hpp"
 #include "Vector/se_class3_vector_unit_tests.hpp"
 #include "Vector/vector_dist_dlb_test.hpp"
+#include "Decomposition/Domain_NN_calculator_cart_unit_test.hpp"
 //#include "antoniol_test_isolation.hpp"