diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp
index 45dfb9f1624cbeb6473b19ca65dcbe9e1f704f5c..dab7b09b6f8163a833241092e9f81377fc620876 100644
--- a/src/Decomposition/CartDecomposition.hpp
+++ b/src/Decomposition/CartDecomposition.hpp
@@ -66,7 +66,7 @@
  */
 
 template<unsigned int dim, typename T, template<typename> class device_l=openfpm::device_cpu, typename Memory=HeapMemory, template<unsigned int, typename> class Domain=Box>
-class CartDecomposition : public ie_loc_ghost<dim,T>, public nn_prcs<dim,T>
+class CartDecomposition : public ie_loc_ghost<dim,T>, public nn_prcs<dim,T> , public ie_ghost<dim,T>
 {
 
 public:
@@ -90,10 +90,10 @@ private:
 	//! and for each processor contain the boxes calculated from the intersection
 	//! of the sub-domains + ghost with the near-by processor sub-domain () and the other way around
 	//! \see calculateGhostBoxes
-	openfpm::vector< openfpm::vector< Box_proc<dim,T> > > box_nn_processor_int;
+//	openfpm::vector< openfpm::vector< Box_proc<dim,T> > > box_nn_processor_int;
 
 	//! It store the same information of box_nn_processor_int organized by processor id
-	openfpm::vector< Box_dom<dim,T> > proc_int_box;
+//	openfpm::vector< Box_dom<dim,T> > proc_int_box;
 
 	//! for each sub-domain, contain the list of the neighborhood processors
 	openfpm::vector<openfpm::vector<long unsigned int> > box_nn_processor;
@@ -119,7 +119,7 @@ private:
 	Vcluster & v_cl;
 
 	//! Cell-list that store the geometrical information of the internal ghost boxes
-	CellList<dim,T,FAST> geo_cell;
+//	CellList<dim,T,FAST> geo_cell;
 
 	//! Cell-list that store the geometrical information of the local internal ghost boxes
 	CellList<dim,T,FAST> lgeo_cell;
@@ -273,7 +273,7 @@ private:
 			orig.get(i) = bound.getLow(i);
 
 		// Initialize the geo_cell structure
-		geo_cell.Initialize(domain,div,orig);
+		ie_ghost<dim,T>::Initialize_geo_cell(domain,div,orig);
 		lgeo_cell.Initialize(domain,div,orig);
 	}
 
@@ -330,7 +330,7 @@ private:
 	 * \see calculateGhostBoxes
 	 *
 	 */
-	void create_box_nn_processor_ext(Ghost<dim,T> & ghost)
+/*	void create_box_nn_processor_ext(Ghost<dim,T> & ghost)
 	{
 		box_nn_processor_int.resize(sub_domains.size());
 		proc_int_box.resize(nn_prcs<dim,T>::getNNProcessors());
@@ -370,7 +370,7 @@ private:
 
 					if (intersect == true)
 					{
-						struct p_box pb;
+						struct p_box<dim,T> pb;
 
 						pb.box = bi;
 						pb.proc = p_id;
@@ -409,7 +409,7 @@ private:
 				}
 			}
 		}
-	}
+	}*/
 
 	/*! \brief Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box
 	 *
@@ -423,7 +423,7 @@ private:
 	 * \see calculateGhostBoxes
 	 *
 	 */
-	void create_box_nn_processor_int(Ghost<dim,T> & ghost)
+/*	void create_box_nn_processor_int(Ghost<dim,T> & ghost)
 	{
 		box_nn_processor_int.resize(sub_domains.size());
 		proc_int_box.resize(nn_prcs<dim,T>::getNNProcessors());
@@ -441,7 +441,7 @@ private:
 				const openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_prcs<dim,T>::getAdjacentSubdomain(p_id);
 
 				// get the local processor id
-				size_t lc_proc = nn_prcs<dim,T>::getAdjacentProcessor(p_id)/*nn_processor_subdomains[p_id].id*/;
+				size_t lc_proc = nn_prcs<dim,T>::getAdjacentProcessor(p_id);
 
 				// For each near processor sub-domains enlarge and intersect with the local sub-domain and store the result
 				for (size_t k = 0 ; k < nn_p_box.size() ; k++)
@@ -457,7 +457,7 @@ private:
 					n_sub.enlarge(ghost);
 
 					// Intersect with the local sub-domain
-					p_box b_int;
+					p_box<dim,T> b_int;
 					bool intersect = n_sub.Intersect(l_sub,b_int.box);
 
 					// store if it intersect
@@ -527,7 +527,7 @@ private:
 				}
 			}
 		}
-	}
+	}*/
 
 	// Heap memory receiver
 	HeapMemory hp_recv;
@@ -581,29 +581,7 @@ public:
 	~CartDecomposition()
 	{}
 
-	// It store all the boxes of the near processors in a linear array
-	struct p_box
-	{
-		//! Box that identify the intersection of the ghost of the near processor with the
-		//! processor sub-domain
-		::Box<dim,T> box;
-		//! local processor id
-		size_t lc_proc;
-		//! processor id
-		size_t proc;
-
-		/*! \brief Check if two p_box are the same
-		 *
-		 * \param pb box to check
-		 *
-		 */
-		bool operator==(const p_box & pb)
-		{
-			return pb.lc_proc == lc_proc;
-		}
-	};
-
-	openfpm::vector<size_t> ids;
+//	openfpm::vector<size_t> ids;
 
 	/*! \brief class to select the returned id by ghost_processorID
 	 *
@@ -619,7 +597,7 @@ public:
 		 * \return box id
 		 *
 		 */
-		inline static size_t id(p_box & p, size_t b_id)
+		inline static size_t id(p_box<dim,T> & p, size_t b_id)
 		{
 			return b_id;
 		}
@@ -639,7 +617,7 @@ public:
 		 * \return processor id
 		 *
 		 */
-		inline static size_t id(p_box & p, size_t b_id)
+		inline static size_t id(p_box<dim,T> & p, size_t b_id)
 		{
 			return p.proc;
 		}
@@ -659,7 +637,7 @@ public:
 		 * \return local processor id
 		 *
 		 */
-		inline static size_t id(p_box & p, size_t b_id)
+		inline static size_t id(p_box<dim,T> & p, size_t b_id)
 		{
 			return p.lc_proc;
 		}
@@ -671,14 +649,11 @@ public:
 	 * \return An iterator with the id's of the internal boxes in which the point fall
 	 *
 	 */
-	auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
+/*	auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
 	{
 		return geo_cell.getIterator(geo_cell.getCell(p));
-	}
-
+	}*/
 
-#define UNIQUE 1
-#define MULTIPLE 2
 
 	/*! \brief Given a position it return if the position belong to any neighborhood processor ghost
 	 * (Internal ghost)
@@ -692,7 +667,7 @@ public:
 	 * \param return the processor ids
 	 *
 	 */
-	template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE)
+/*	template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE)
 	{
 		ids.clear();
 
@@ -719,7 +694,7 @@ public:
 			ids.unique();
 
 		return ids;
-	}
+	}*/
 
 	/*! \brief Given a position it return if the position belong to any neighborhood processor ghost
 	 * (Internal ghost)
@@ -730,7 +705,7 @@ public:
 	 * \param return the processor ids
 	 *
 	 */
-	template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE)
+/*	template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE)
 	{
 		ids.clear();
 
@@ -757,14 +732,14 @@ public:
 			ids.unique();
 
 		return ids;
-	}
+	}*/
 
 	// External ghost boxes for this processor, indicated with G8_0 G9_0 ...
-	openfpm::vector<p_box> vb_ext;
+//	openfpm::vector<p_box<dim,T>> vb_ext;
 
 	// Internal ghost boxes for this processor domain, indicated with B8_0 B9_0 ..... in the figure
 	// below as a linear vector
-	openfpm::vector<p_box> vb_int;
+//	openfpm::vector<p_box<dim,T>> vb_int;
 
 	/*! It calculate the internal ghost boxes
 	 *
@@ -865,8 +840,8 @@ p1[0]<-----+         +----> p2[0]
 		// Intersect all the local sub-domains with the sub-domains of the contiguous processors
 
 		// create the internal structures that store ghost information
-		create_box_nn_processor_ext(ghost);
-		create_box_nn_processor_int(ghost);
+		ie_ghost<dim,T>::create_box_nn_processor_ext(v_cl,ghost,sub_domains,box_nn_processor,*this);
+		ie_ghost<dim,T>::create_box_nn_processor_int(v_cl,ghost,sub_domains,box_nn_processor,*this);
 
 		// ebox must come after ibox (in this case)
 
@@ -1101,10 +1076,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return iterator of the processors id's
 	 *
 	 */
-	inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
+/*	inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
 	{
 		return geo_cell.getIterator(geo_cell.getCell(p));
-	}
+	}*/
 
 
 	////////////// Functions to get decomposition information ///////////////
@@ -1116,10 +1091,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the number of internal ghost
 	 *
 	 */
-	inline size_t getProcessorNIGhost(size_t id) const
+/*	inline size_t getProcessorNIGhost(size_t id) const
 	{
 		return proc_int_box.get(id).ibx.size();
-	}
+	}*/
 
 	/*! \brief Get the number of External ghost boxes for one processor id
 	 *
@@ -1127,10 +1102,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the number of external ghost
 	 *
 	 */
-	inline size_t getProcessorNEGhost(size_t id) const
+/*	inline size_t getProcessorNEGhost(size_t id) const
 	{
 		return proc_int_box.get(id).ebx.size();
-	}
+	}*/
 
 	/*! \brief Get the j Internal ghost box for one processor
 	 *
@@ -1139,10 +1114,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the box
 	 *
 	 */
-	inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const
+/*	inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ibx.get(j);
-	}
+	}*/
 
 	/*! \brief Get the j External ghost box
 	 *
@@ -1151,10 +1126,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the box
 	 *
 	 */
-	inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const
+/*	inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ebx.get(j);
-	}
+	}*/
 
 	/*! \brief Get the j Internal ghost box id
 	 *
@@ -1163,10 +1138,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the box
 	 *
 	 */
-	inline size_t getProcessorIGhostId(size_t id, size_t j) const
+/*	inline size_t getProcessorIGhostId(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ibx.get(j).id;
-	}
+	}*/
 
 	/*! \brief Get the j External ghost box id
 	 *
@@ -1175,10 +1150,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the box
 	 *
 	 */
-	inline size_t getProcessorEGhostId(size_t id, size_t j) const
+/*	inline size_t getProcessorEGhostId(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ebx.get(j).id;
-	}
+	}*/
 
 
 	/*! \brief Get the local sub-domain at witch belong the internal ghost box
@@ -1188,10 +1163,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return sub-domain at which belong the internal ghost box
 	 *
 	 */
-	inline const size_t getProcessorIGhostSub(size_t id, size_t j) const
+/*	inline const size_t getProcessorIGhostSub(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ibx.get(j).sub;
-	}
+	}*/
 
 	/*! \brief Get the local sub-domain at witch belong the external ghost box
 	 *
@@ -1200,30 +1175,30 @@ p1[0]<-----+         +----> p2[0]
 	 * \return sub-domain at which belong the external ghost box
 	 *
 	 */
-	inline const size_t getProcessorEGhostSub(size_t id, size_t j) const
+/*	inline const size_t getProcessorEGhostSub(size_t id, size_t j) const
 	{
 		return proc_int_box.get(id).ebx.get(j).sub;
-	}
+	}*/
 
 	/*! \brief Return the total number of the calculated internal ghost boxes
 	 *
 	 * \return the number of internal ghost boxes
 	 *
 	 */
-	inline size_t getNIGhostBox() const
+/*	inline size_t getNIGhostBox() const
 	{
 		return vb_int.size();
-	}
+	}*/
 
 	/*! \brief Given the internal ghost box id, it return the internal ghost box
 	 *
 	 * \return the internal ghost box
 	 *
 	 */
-	inline ::Box<dim,T> getIGhostBox(size_t b_id) const
+/*	inline ::Box<dim,T> getIGhostBox(size_t b_id) const
 	{
 		return vb_int.get(b_id).box;
-	}
+	}*/
 
 	/*! \brief Given the internal ghost box id, it return the near processor at witch belong
 	 *         or the near processor that produced this internal ghost box
@@ -1231,30 +1206,30 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the processor id of the ghost box
 	 *
 	 */
-	inline size_t getIGhostBoxProcessor(size_t b_id) const
+/*	inline size_t getIGhostBoxProcessor(size_t b_id) const
 	{
 		return vb_int.get(b_id).proc;
-	}
+	}*/
 
 	/*! \brief Get the number of the calculated external ghost boxes
 	 *
 	 * \return the number of external ghost boxes
 	 *
 	 */
-	inline size_t getNEGhostBox() const
+/*	inline size_t getNEGhostBox() const
 	{
 		return vb_ext.size();
-	}
+	}*/
 
 	/*! \brief Given the external ghost box id, it return the external ghost box
 	 *
 	 * \return the external ghost box
 	 *
 	 */
-	inline ::Box<dim,T> getEGhostBox(size_t b_id) const
+/*	inline ::Box<dim,T> getEGhostBox(size_t b_id) const
 	{
 		return vb_ext.get(b_id).box;
-	}
+	}*/
 
 	/*! \brief Given the external ghost box id, it return the near processor at witch belong
 	 *         or the near processor that produced this external ghost box
@@ -1262,10 +1237,10 @@ p1[0]<-----+         +----> p2[0]
 	 * \return the processor id of the external ghost box
 	 *
 	 */
-	inline size_t getEGhostBoxProcessor(size_t b_id) const
+/*	inline size_t getEGhostBoxProcessor(size_t b_id) const
 	{
 		return vb_ext.get(b_id).proc;
-	}
+	}*/
 
 	/*! \brief Write the decomposition as VTK file
 	 *
@@ -1293,7 +1268,7 @@ p1[0]<-----+         +----> p2[0]
 		nn_prcs<dim,T>::write(output);
 
 		//! internal_ghost_X.vtk Internal ghost boxes for the local processor (X)
-		VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3;
+/*		VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3;
 		for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
 		{
 			for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
@@ -1312,8 +1287,9 @@ p1[0]<-----+         +----> p2[0]
 				vtk_box4.add(box_nn_processor_int.get(p).get(s).bx);
 			}
 		}
-		vtk_box4.write(output + std::string("external_ghost_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));
+		vtk_box4.write(output + std::string("external_ghost_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));*/
 
+		ie_ghost<dim,T>::write(output,v_cl.getProcessUnitID());
 		ie_loc_ghost<dim,T>::write(output,v_cl.getProcessUnitID());
 
 		return true;
@@ -1338,9 +1314,9 @@ p1[0]<-----+         +----> p2[0]
 
 		for (size_t p = 0 ; p < nn_prcs<dim,T>::getNNProcessors() ; p++)
 		{
-			for (size_t i = 0 ; i < getProcessorNEGhost(p) ; i++)
+			for (size_t i = 0 ; i < ie_ghost<dim,T>::getProcessorNEGhost(p) ; i++)
 			{
-				std::cout << getProcessorEGhostBox(p,i).toString() << "   prc=" << nn_prcs<dim,T>::IDtoProc(p) << "   id=" << getProcessorEGhostId(p,i) << "\n";
+				std::cout << ie_ghost<dim,T>::getProcessorEGhostBox(p,i).toString() << "   prc=" << nn_prcs<dim,T>::IDtoProc(p) << "   id=" << ie_ghost<dim,T>::getProcessorEGhostId(p,i) << "\n";
 			}
 		}
 
@@ -1348,9 +1324,9 @@ p1[0]<-----+         +----> p2[0]
 
 		for (size_t p = 0 ; p < nn_prcs<dim,T>::getNNProcessors() ; p++)
 		{
-			for (size_t i = 0 ; i < getProcessorNIGhost(p) ; i++)
+			for (size_t i = 0 ; i < ie_ghost<dim,T>::getProcessorNIGhost(p) ; i++)
 			{
-				std::cout << getProcessorIGhostBox(p,i).toString() << "   prc=" << nn_prcs<dim,T>::IDtoProc(p)  << "   id=" << getProcessorIGhostId(p,i) <<  "\n";
+				std::cout << ie_ghost<dim,T>::getProcessorIGhostBox(p,i).toString() << "   prc=" << nn_prcs<dim,T>::IDtoProc(p)  << "   id=" << ie_ghost<dim,T>::getProcessorIGhostId(p,i) <<  "\n";
 			}
 		}
 	}
diff --git a/src/Decomposition/common.hpp b/src/Decomposition/common.hpp
index 6387226a42fa41bca2a6021bda9eeab4d6c183bd..403820e7d5fc64b2b3fbdadc7d7d39d8acf8de5a 100644
--- a/src/Decomposition/common.hpp
+++ b/src/Decomposition/common.hpp
@@ -130,4 +130,27 @@ struct N_box
 	typename openfpm::vector<::Box<dim,T>> bx;
 };
 
+// It store all the boxes of the near processors in a linear array
+template<unsigned int dim, typename T>
+struct p_box
+{
+	//! Box that identify the intersection of the ghost of the near processor with the
+	//! processor sub-domain
+	::Box<dim,T> box;
+	//! local processor id
+	size_t lc_proc;
+	//! processor id
+	size_t proc;
+
+	/*! \brief Check if two p_box are the same
+	 *
+	 * \param pb box to check
+	 *
+	 */
+	bool operator==(const p_box & pb)
+	{
+		return pb.lc_proc == lc_proc;
+	}
+};
+
 #endif /* SRC_DECOMPOSITION_COMMON_HPP_ */
diff --git a/src/Decomposition/ie_ghost.hpp b/src/Decomposition/ie_ghost.hpp
index 76e9eb508d08967a3516a6407253ce49f0069f0c..deced3bb54cabdb80122cf995a8a30dbdcbf425b 100644
--- a/src/Decomposition/ie_ghost.hpp
+++ b/src/Decomposition/ie_ghost.hpp
@@ -9,6 +9,10 @@
 #define SRC_DECOMPOSITION_IE_GHOST_HPP_
 
 #include "common.hpp"
+#include "nn_processor.hpp"
+
+#define UNIQUE 1
+#define MULTIPLE 2
 
 /*! \brief structure that store and compute the internal and external local ghost box
  *
@@ -30,6 +34,30 @@ class ie_ghost
 	//! It store the same information of box_nn_processor_int organized by processor id
 	openfpm::vector< Box_dom<dim,T> > proc_int_box;
 
+	// External ghost boxes for this processor, indicated with G8_0 G9_0 ...
+	openfpm::vector<p_box<dim,T> > vb_ext;
+
+	// Internal ghost boxes for this processor domain, indicated with B8_0 B9_0 ..... in the figure
+	// below as a linear vector
+	openfpm::vector<p_box<dim,T> > vb_int;
+
+	//! Cell-list that store the geometrical information of the internal ghost boxes
+	CellList<dim,T,FAST> geo_cell;
+
+protected:
+
+	/*! \brief Initialize the geo cell list structure
+	 *
+	 * The geo cell list structure exist to speed up the labelling the points if they fall on some
+	 * internal ghost
+	 *
+	 */
+	void Initialize_geo_cell(const Box<dim,T> & domain, const size_t (&div)[dim] ,const Point<dim,T> & orig)
+	{
+		// Initialize the geo_cell structure
+		geo_cell.Initialize(domain,div,orig);
+	}
+
 	/*! \brief Create the box_nn_processor_int (bx part)  structure
 	 *
 	 * This structure store for each sub-domain of this processors enlarged by the ghost size the boxes that
@@ -41,10 +69,10 @@ class ie_ghost
 	 * \see calculateGhostBoxes
 	 *
 	 */
-	void create_box_nn_processor_ext(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains)
+	void create_box_nn_processor_ext(Vcluster & v_cl, Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor, const nn_prcs<dim,T> & nn_p)
 	{
-/*		box_nn_processor_int.resize(sub_domains.size());
-		proc_int_box.resize(getNNProcessors());
+		box_nn_processor_int.resize(sub_domains.size());
+		proc_int_box.resize(nn_p.getNNProcessors());
 
 		// For each sub-domain
 		for (size_t i = 0 ; i < sub_domains.size() ; i++)
@@ -64,10 +92,10 @@ class ie_ghost
 				size_t p_id = box_nn_processor.get(i).get(j);
 
 				// store the box in proc_int_box storing from which sub-domain they come from
-				Box_dom & proc_int_box_g = proc_int_box.get(ProctoID(p_id));
+				Box_dom<dim,T> & proc_int_box_g = proc_int_box.get(nn_p.ProctoID(p_id));
 
 				// get the set of sub-domains of the adjacent processor p_id
-				openfpm::vector< ::Box<dim,T> > & nn_processor_subdomains_g = nn_processor_subdomains[p_id].bx;
+				const openfpm::vector< ::Box<dim,T> > & nn_processor_subdomains_g = nn_p.getExternalAdjSubdomain(p_id).bx;
 
 				// near processor sub-domain intersections
 				openfpm::vector< ::Box<dim,T> > & box_nn_processor_int_gg = box_nn_processor_int.get(i).get(j).bx;
@@ -81,11 +109,11 @@ class ie_ghost
 
 					if (intersect == true)
 					{
-						struct p_box pb;
+						struct p_box<dim,T> pb;
 
 						pb.box = bi;
 						pb.proc = p_id;
-						pb.lc_proc = ProctoID(p_id);
+						pb.lc_proc = nn_p.ProctoID(p_id);
 
 						//
 						// Updating
@@ -105,20 +133,20 @@ class ie_ghost
 
 						// Search for the correct id
 						size_t k = 0;
-						size_t p_idp = ProctoID(p_id);
-						for (k = 0 ; k < proc_adj_box.get(p_idp).size() ; k++)
+						size_t p_idp = nn_p.ProctoID(p_id);
+						for (k = 0 ; k < nn_p.getInternalAdjSubdomain(p_idp).size() ; k++)
 						{
-							if (proc_adj_box.get(p_idp).get(k) == i)
+							if (nn_p.getInternalAdjSubdomain(p_idp).get(k) == i)
 								break;
 						}
-						if (k == proc_adj_box.get(p_idp).size())
+						if (k == nn_p.getInternalAdjSubdomain(p_idp).size())
 							std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n";
 
 						proc_int_box_g.ebx.last().id = (k * nn_processor_subdomains_g.size() + b) * v_cl.getProcessingUnits() + p_id;
 					}
 				}
 			}
-		}*/
+		}
 	}
 
 	/*! \brief Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box
@@ -127,13 +155,18 @@ class ie_ghost
 	 * of the near processors sub-domains enlarged by the ghost size (Internal ghost box). These boxes
 	 * fill a geometrical cell list. The proc_int_box store the same information ordered by near processors
 	 *
+	 * \param v_cl Virtual cluster
 	 * \param ghost margins
+	 * \param sub_domains
+	 * \param box_nn_processors sub-domains of the adjacent processors
+	 * \param nn_prcs structure that store the adjacent processor information
+	 * \param geo_cell Cell list that store the subdomain information
 	 *
 	 * \note Are the B8_0 B9_0 B9_1 B5_0 boxes in calculateGhostBoxes
 	 * \see calculateGhostBoxes
 	 *
 	 */
-	void create_box_nn_processor_int(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processors, const nn_prcs<dim,T> & nn_p )
+	void create_box_nn_processor_int(Vcluster & v_cl, Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains, const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor, const nn_prcs<dim,T> & nn_p)
 	{
 		box_nn_processor_int.resize(sub_domains.size());
 		proc_int_box.resize(nn_p.getNNProcessors());
@@ -148,10 +181,10 @@ class ie_ghost
 				size_t p_id = box_nn_processor.get(i).get(j);
 
 				// get the set of sub-domains of the contiguous processor p_id
-				openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_p.get nn_processor_subdomains[p_id].bx;
+				const openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_p.getExternalAdjSubdomain(p_id).bx;
 
 				// get the local processor id
-				size_t lc_proc = nn_processor_subdomains[p_id].id;
+				size_t lc_proc = nn_p.getAdjacentProcessor(p_id);
 
 				// For each near processor sub-domains enlarge and intersect with the local sub-domain and store the result
 				for (size_t k = 0 ; k < nn_p_box.size() ; k++)
@@ -167,7 +200,7 @@ class ie_ghost
 					n_sub.enlarge(ghost);
 
 					// Intersect with the local sub-domain
-					p_box b_int;
+					p_box<dim,T> b_int;
 					bool intersect = n_sub.Intersect(l_sub,b_int.box);
 
 					// store if it intersect
@@ -196,23 +229,23 @@ class ie_ghost
 						vb_int.add(b_int);
 
 						// store the box in proc_int_box storing from which sub-domain they come from
-						Box_dom & pr_box_int = proc_int_box.get(ProctoID(p_id));
+						Box_dom<dim,T> & pr_box_int = proc_int_box.get(nn_p.ProctoID(p_id));
 						Box_sub<dim,T> sb;
 						sb = b_int.box;
 						sb.sub = i;
 
 						// Search for the correct id
 						size_t s = 0;
-						size_t p_idp = ProctoID(p_id);
-						for (s = 0 ; s < proc_adj_box.get(p_idp).size() ; s++)
+						size_t p_idp = nn_p.ProctoID(p_id);
+						for (s = 0 ; s < nn_p.getInternalAdjSubdomain(p_idp).size() ; s++)
 						{
-							if (proc_adj_box.get(p_idp).get(s) == i)
+							if (nn_p.getInternalAdjSubdomain(p_idp).get(s) == i)
 								break;
 						}
-						if (s == proc_adj_box.get(p_idp).size())
+						if (s == nn_p.getInternalAdjSubdomain(p_idp).size())
 							std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n";
 
-						sb.id = (k * proc_adj_box.get(p_idp).size() + s) * v_cl.getProcessingUnits() + v_cl.getProcessUnitID();
+						sb.id = (k * nn_p.getInternalAdjSubdomain(p_idp).size() + s) * v_cl.getProcessingUnits() + v_cl.getProcessUnitID();
 
 						pr_box_int.ibx.add(sb);
 
@@ -238,6 +271,305 @@ class ie_ghost
 			}
 		}
 	}
+
+public:
+
+	/*! \brief Get the number of Internal ghost boxes for one processor
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \return the number of internal ghost
+	 *
+	 */
+	inline size_t getProcessorNIGhost(size_t id) const
+	{
+		return proc_int_box.get(id).ibx.size();
+	}
+
+	/*! \brief Get the number of External ghost boxes for one processor id
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \return the number of external ghost
+	 *
+	 */
+	inline size_t getProcessorNEGhost(size_t id) const
+	{
+		return proc_int_box.get(id).ebx.size();
+	}
+
+	/*! \brief Get the j Internal ghost box for one processor
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one internal ghost box)
+	 * \return the box
+	 *
+	 */
+	inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ibx.get(j);
+	}
+
+	/*! \brief Get the j External ghost box
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one external ghost box)
+	 * \return the box
+	 *
+	 */
+	inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ebx.get(j);
+	}
+
+	/*! \brief Get the j Internal ghost box id
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one internal ghost box)
+	 * \return the box
+	 *
+	 */
+	inline size_t getProcessorIGhostId(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ibx.get(j).id;
+	}
+
+	/*! \brief Get the j External ghost box id
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one external ghost box)
+	 * \return the box
+	 *
+	 */
+	inline size_t getProcessorEGhostId(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ebx.get(j).id;
+	}
+
+
+	/*! \brief Get the local sub-domain at witch belong the internal ghost box
+	 *
+	 * \param id adjacent processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one internal ghost box)
+	 * \return sub-domain at which belong the internal ghost box
+	 *
+	 */
+	inline const size_t getProcessorIGhostSub(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ibx.get(j).sub;
+	}
+
+	/*! \brief Get the local sub-domain at witch belong the external ghost box
+	 *
+	 * \param id near processor list id (the id go from 0 to getNNProcessor())
+	 * \param j box (each near processor can produce more than one external ghost box)
+	 * \return sub-domain at which belong the external ghost box
+	 *
+	 */
+	inline const size_t getProcessorEGhostSub(size_t id, size_t j) const
+	{
+		return proc_int_box.get(id).ebx.get(j).sub;
+	}
+
+	/*! \brief Return the total number of the calculated internal ghost boxes
+	 *
+	 * \return the number of internal ghost boxes
+	 *
+	 */
+	inline size_t getNIGhostBox() const
+	{
+		return vb_int.size();
+	}
+
+	/*! \brief Given the internal ghost box id, it return the internal ghost box
+	 *
+	 * \return the internal ghost box
+	 *
+	 */
+	inline ::Box<dim,T> getIGhostBox(size_t b_id) const
+	{
+		return vb_int.get(b_id).box;
+	}
+
+	/*! \brief Given the internal ghost box id, it return the near processor at witch belong
+	 *         or the near processor that produced this internal ghost box
+	 *
+	 * \return the processor id of the ghost box
+	 *
+	 */
+	inline size_t getIGhostBoxProcessor(size_t b_id) const
+	{
+		return vb_int.get(b_id).proc;
+	}
+
+	/*! \brief Get the number of the calculated external ghost boxes
+	 *
+	 * \return the number of external ghost boxes
+	 *
+	 */
+	inline size_t getNEGhostBox() const
+	{
+		return vb_ext.size();
+	}
+
+	/*! \brief Given the external ghost box id, it return the external ghost box
+	 *
+	 * \return the external ghost box
+	 *
+	 */
+	inline ::Box<dim,T> getEGhostBox(size_t b_id) const
+	{
+		return vb_ext.get(b_id).box;
+	}
+
+	/*! \brief Given the external ghost box id, it return the near processor at witch belong
+	 *         or the near processor that produced this external ghost box
+	 *
+	 * \return the processor id of the external ghost box
+	 *
+	 */
+	inline size_t getEGhostBoxProcessor(size_t b_id) const
+	{
+		return vb_ext.get(b_id).proc;
+	}
+
+	/*! /brief Given a point it return the set of boxes in which the point fall
+	 *
+	 * \param p Point to check
+	 * \return An iterator with the id's of the internal boxes in which the point fall
+	 *
+	 */
+	auto getInternalIDBoxes(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
+	{
+		return geo_cell.getIterator(geo_cell.getCell(p));
+	}
+
+	/*! \brief if the point fall into the ghost of some near processor it return the processors id's in which
+	 *  it fall
+	 *
+	 * \param p Point
+	 * \return iterator of the processors id's
+	 *
+	 */
+	inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getIterator(geo_cell.getCell(p)))
+	{
+		return geo_cell.getIterator(geo_cell.getCell(p));
+	}
+
+	openfpm::vector<size_t> ids;
+
+	/*! \brief Given a position it return if the position belong to any neighborhood processor ghost
+	 * (Internal ghost)
+	 *
+	 * \tparam id type of if to get box_id processor_id lc_processor_id
+	 * \param p Particle position
+	 * \param opt intersection boxes of the same processor can overlap, so in general the function
+	 *        can produce more entry with the same processor, the UNIQUE option eliminate double entries
+	 *        (UNIQUE) is for particle data (MULTIPLE) is for grid data [default MULTIPLE]
+	 *
+	 * \param return the processor ids
+	 *
+	 */
+	template <typename id> inline const openfpm::vector<size_t> ghost_processorID(Point<dim,T> & p, const int opt = MULTIPLE)
+	{
+		ids.clear();
+
+		// Check with geo-cell if a particle is inside one Cell containing boxes
+
+		auto cell_it = geo_cell.getIterator(geo_cell.getCell(p));
+
+		// For each element in the cell, check if the point is inside the box
+		// if it is, store the processor id
+		while (cell_it.isNext())
+		{
+			size_t bid = cell_it.get();
+
+			if (vb_int.get(bid).box.isInside(p) == true)
+			{
+				ids.add(id::id(vb_int.get(bid),bid));
+			}
+
+			++cell_it;
+		}
+
+		// Make the id unique
+		if (opt == UNIQUE)
+			ids.unique();
+
+		return ids;
+	}
+
+	/*! \brief Given a position it return if the position belong to any neighborhood processor ghost
+	 * (Internal ghost)
+	 *
+	 * \tparam id type of if to get box_id processor_id lc_processor_id
+	 * \param p Particle position
+	 *
+	 * \param return the processor ids
+	 *
+	 */
+	template<typename id, typename Mem> inline const openfpm::vector<size_t> ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE)
+	{
+		ids.clear();
+
+		// Check with geo-cell if a particle is inside one Cell containing boxes
+
+		auto cell_it = geo_cell.getIterator(geo_cell.getCell(p));
+
+		// For each element in the cell, check if the point is inside the box
+		// if it is, store the processor id
+		while (cell_it.isNext())
+		{
+			size_t bid = cell_it.get();
+
+			if (vb_int.get(bid).box.isInside(p) == true)
+			{
+				ids.add(id::id(vb_int.get(bid),bid));
+			}
+
+			++cell_it;
+		}
+
+		// Make the id unique
+		if (opt == UNIQUE)
+			ids.unique();
+
+		return ids;
+	}
+
+	/*! \brief write the information about the ghost in vtk format
+	 *
+	 * 1) internal_ghost_X.vtk Internal ghost boxes for the local processor (X)
+	 * 2) external_ghost_X.vtk External ghost boxes for the local processor (X)
+	 *
+	 * \param output directory
+	 * \param p_id processor rank
+	 *
+	 */
+	bool write(std::string output, size_t p_id) const
+	{
+		//! internal_ghost_X.vtk Internal ghost boxes for the local processor (X)
+		VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3;
+		for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
+		{
+			for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
+			{
+				vtk_box3.add(box_nn_processor_int.get(p).get(s).nbx);
+			}
+		}
+		vtk_box3.write(output + std::string("internal_ghost_") + std::to_string(p_id) + std::string(".vtk"));
+
+		//! external_ghost_X.vtk External ghost boxes for the local processor (X)
+		VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box4;
+		for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
+		{
+			for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
+			{
+				vtk_box4.add(box_nn_processor_int.get(p).get(s).bx);
+			}
+		}
+		vtk_box4.write(output + std::string("external_ghost_") + std::to_string(p_id) + std::string(".vtk"));
+
+		return true;
+	}
 };
 
 
diff --git a/src/Decomposition/nn_processor.hpp b/src/Decomposition/nn_processor.hpp
index b432881744e0c410e6522bc66a9e5129ab0e4511..b11a758196ffe9f51d03c1d03f8fc427e6b0a5b3 100644
--- a/src/Decomposition/nn_processor.hpp
+++ b/src/Decomposition/nn_processor.hpp
@@ -138,7 +138,7 @@ public:
 	 * \return return the processor rank
 	 *
 	 */
-	inline size_t IDtoProc(size_t id)
+	inline size_t IDtoProc(size_t id) const
 	{
 		return nn_processors.get(id);
 	}
@@ -150,9 +150,16 @@ public:
 	 * \return the sub-domains
 	 *
 	 */
-	inline const openfpm::vector< ::Box<dim,T> > & getAdjacentSubdomain(size_t p_id)
+	inline const openfpm::vector< ::Box<dim,T> > & getAdjacentSubdomain(size_t p_id) const
 	{
-		return nn_processor_subdomains[p_id].bx;
+		auto key = nn_processor_subdomains.find(p_id);
+#ifdef DEBUG
+		if (key == nn_processor_subdomains.end())
+		{
+			std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor";
+		}
+#endif
+		return key->second.bx;
 	}
 
 	/*! \brief Get the adjacent processor id
@@ -162,9 +169,16 @@ public:
 	 * \return the processor rank
 	 *
 	 */
-	inline size_t getAdjacentProcessor(size_t p_id)
+	inline size_t getAdjacentProcessor(size_t p_id) const
 	{
-		return nn_processor_subdomains[p_id].id;
+		auto key = nn_processor_subdomains.find(p_id);
+#ifdef DEBUG
+		if (key == nn_processor_subdomains.end())
+		{
+			std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor";
+		}
+#endif
+		return key->second.id;
 	}
 
 
@@ -175,11 +189,29 @@ public:
 	 * \return the sub-domains
 	 *
 	 */
-	inline const openfpm::vector<size_t> & getInternalAdjSubdomain(size_t p_id)
+	inline const openfpm::vector<size_t> & getInternalAdjSubdomain(size_t p_id) const
 	{
 		return proc_adj_box.get(p_id);
 	}
 
+	/*! \brief Get the external sub-domain adjacent to a processor p_id
+	 *
+	 * \param p_id processor rank
+	 * \return the set of adjacent sub-domain comming from the processor p_id
+	 *
+	 */
+	inline const N_box<dim,T> getExternalAdjSubdomain(size_t p_id) const
+	{
+		auto key = nn_processor_subdomains.find(p_id);
+#ifdef DEBUG
+		if (key == nn_processor_subdomains.end())
+		{
+			std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor";
+		}
+#endif
+		return key->second;
+	}
+
 	/*! \brief Convert the processor rank to the id in the list
 	 *
 	 * \param p processor rank
@@ -187,9 +219,17 @@ public:
 	 * \return the id
 	 *
 	 */
-	inline size_t ProctoID(size_t p)
+	inline size_t ProctoID(size_t p) const
 	{
-		return nn_processor_subdomains[p].id;
+		auto key = nn_processor_subdomains.find(p);
+#ifdef DEBUG
+		if (key == nn_processor_subdomains.end())
+		{
+			std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " error this process rank is not adjacent to the local processor";
+		}
+#endif
+
+		return key->second.id;
 	}
 
 	/*! \brief Write the decomposition as VTK file