diff --git a/src/Decomposition/ie_ghost.hpp b/src/Decomposition/ie_ghost.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..76e9eb508d08967a3516a6407253ce49f0069f0c
--- /dev/null
+++ b/src/Decomposition/ie_ghost.hpp
@@ -0,0 +1,244 @@
+/*
+ * ie_ghost.hpp
+ *
+ *  Created on: Aug 8, 2015
+ *      Author: i-bird
+ */
+
+#ifndef SRC_DECOMPOSITION_IE_GHOST_HPP_
+#define SRC_DECOMPOSITION_IE_GHOST_HPP_
+
+#include "common.hpp"
+
+/*! \brief structure that store and compute the internal and external local ghost box
+ *
+ * \tparam dim is the dimensionality of the physical domain we are going to decompose.
+ * \tparam T type of the space we decompose, Real, Integer, Complex ...
+ *
+ * \see CartDecomposition
+ *
+ */
+template<unsigned int dim, typename T>
+class ie_ghost
+{
+	//! for each sub-domain (first vector), contain the list (nested vector) of the neighborhood processors
+	//! 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;
+
+	//! It store the same information of box_nn_processor_int organized by processor id
+	openfpm::vector< Box_dom<dim,T> > proc_int_box;
+
+	/*! \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
+	 *  come from the intersection with the near processors sub-domains (External ghost box)
+	 *
+	 * \param ghost margins
+	 *
+	 * \note Are the G8_0 G9_0 G9_1 G5_0 boxes in calculateGhostBoxes
+	 * \see calculateGhostBoxes
+	 *
+	 */
+	void create_box_nn_processor_ext(Ghost<dim,T> & ghost, openfpm::vector<SpaceBox<dim,T>> & sub_domains)
+	{
+/*		box_nn_processor_int.resize(sub_domains.size());
+		proc_int_box.resize(getNNProcessors());
+
+		// For each sub-domain
+		for (size_t i = 0 ; i < sub_domains.size() ; i++)
+		{
+			SpaceBox<dim,T> sub_with_ghost = sub_domains.get(i);
+
+			// enlarge the sub-domain with the ghost
+			sub_with_ghost.enlarge(ghost);
+
+			// resize based on the number of adjacent processors
+			box_nn_processor_int.get(i).resize(box_nn_processor.get(i).size());
+
+			// For each processor adjacent to this sub-domain
+			for (size_t j = 0 ; j < box_nn_processor.get(i).size() ; j++)
+			{
+				// Contiguous processor
+				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));
+
+				// 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;
+
+				// near processor sub-domain intersections
+				openfpm::vector< ::Box<dim,T> > & box_nn_processor_int_gg = box_nn_processor_int.get(i).get(j).bx;
+
+				// for each near processor sub-domain intersect with the enlarged local sub-domain and store it
+				for (size_t b = 0 ; b < nn_processor_subdomains_g.size() ; b++)
+				{
+					::Box<dim,T> bi;
+
+					bool intersect = sub_with_ghost.Intersect(::Box<dim,T>(nn_processor_subdomains_g.get(b)),bi);
+
+					if (intersect == true)
+					{
+						struct p_box pb;
+
+						pb.box = bi;
+						pb.proc = p_id;
+						pb.lc_proc = ProctoID(p_id);
+
+						//
+						// Updating
+						//
+						// vb_ext
+						// box_nn_processor_int
+						// proc_int_box
+						//
+						// They all store the same information but organized in different ways
+						// read the description of each for more information
+						//
+						vb_ext.add(pb);
+						box_nn_processor_int_gg.add(bi);
+						proc_int_box_g.ebx.add();
+						proc_int_box_g.ebx.last() = bi;
+						proc_int_box_g.ebx.last().sub = i;
+
+						// 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++)
+						{
+							if (proc_adj_box.get(p_idp).get(k) == i)
+								break;
+						}
+						if (k == proc_adj_box.get(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
+	 *
+	 * This structure store for each sub-domain of this processors the boxes that come from the intersection
+	 * 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 ghost margins
+	 *
+	 * \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 )
+	{
+		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++)
+		{
+			// For each processor contiguous to this sub-domain
+			for (size_t j = 0 ; j < box_nn_processor.get(i).size() ; j++)
+			{
+				// Contiguous processor
+				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;
+
+				// get the local processor id
+				size_t lc_proc = nn_processor_subdomains[p_id].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++)
+				{
+
+					// enlarge the near-processor sub-domain
+					::Box<dim,T> n_sub = nn_p_box.get(k);
+
+					// local sub-domain
+					::SpaceBox<dim,T> l_sub = sub_domains.get(i);
+
+					// Create a margin of ghost size around the near processor sub-domain
+					n_sub.enlarge(ghost);
+
+					// Intersect with the local sub-domain
+					p_box b_int;
+					bool intersect = n_sub.Intersect(l_sub,b_int.box);
+
+					// store if it intersect
+					if (intersect == true)
+					{
+						// the box fill with the processor id
+						b_int.proc = p_id;
+
+						// fill the local processor id
+						b_int.lc_proc = lc_proc;
+
+						//
+						// Updating
+						//
+						// vb_int
+						// box_nn_processor_int
+						// proc_int_box
+						//
+						// They all store the same information but organized in different ways
+						// read the description of each for more information
+						//
+
+						// add the box to the near processor sub-domain intersections
+						openfpm::vector< ::Box<dim,T> > & p_box_int = box_nn_processor_int.get(i).get(j).nbx;
+						p_box_int.add(b_int.box);
+						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_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++)
+						{
+							if (proc_adj_box.get(p_idp).get(s) == i)
+								break;
+						}
+						if (s == proc_adj_box.get(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();
+
+						pr_box_int.ibx.add(sb);
+
+						// update the geo_cell list
+
+						// get the cells this box span
+						const grid_key_dx<dim> p1 = geo_cell.getCellGrid(b_int.box.getP1());
+						const grid_key_dx<dim> p2 = geo_cell.getCellGrid(b_int.box.getP2());
+
+						// Get the grid and the sub-iterator
+						auto & gi = geo_cell.getGrid();
+						grid_key_dx_iterator_sub<dim> g_sub(gi,p1,p2);
+
+						// add the box-id to the cell list
+						while (g_sub.isNext())
+						{
+							auto key = g_sub.get();
+							geo_cell.addCell(gi.LinId(key),vb_int.size()-1);
+							++g_sub;
+						}
+					}
+				}
+			}
+		}
+	}
+};
+
+
+#endif /* SRC_DECOMPOSITION_IE_GHOST_HPP_ */
diff --git a/src/Decomposition/nn_processor.hpp b/src/Decomposition/nn_processor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b432881744e0c410e6522bc66a9e5129ab0e4511
--- /dev/null
+++ b/src/Decomposition/nn_processor.hpp
@@ -0,0 +1,226 @@
+/*
+ * nn_processor.hpp
+ *
+ *  Created on: Aug 9, 2015
+ *      Author: i-bird
+ */
+
+#ifndef SRC_DECOMPOSITION_NN_PROCESSOR_HPP_
+#define SRC_DECOMPOSITION_NN_PROCESSOR_HPP_
+
+#include "common.hpp"
+
+/*! \brief This class store the adjacent processors and the adjacent sub_domains
+ *
+ * \tparam dim is the dimensionality of the physical domain we are going to decompose.
+ * \tparam T type of the space we decompose, Real, Integer, Complex ...
+ *
+ * \see CartDecomposition
+ *
+ */
+template<unsigned int dim, typename T>
+class nn_prcs
+{
+	//! Virtual cluster
+	Vcluster & v_cl;
+
+	//! List of adjacent processors
+	openfpm::vector<size_t> nn_processors;
+
+	// for each near-processor store the sub-domain of the near processor
+	std::unordered_map<size_t, N_box<dim,T>> nn_processor_subdomains;
+
+	// for each processor store the set of the sub-domains sent to the adjacent processors
+	openfpm::vector<openfpm::vector<size_t>> proc_adj_box;
+
+	//! contain the internal adjacent sub-domains sent to the other processors
+	openfpm::vector< openfpm::vector< ::SpaceBox<dim,T>> > boxes;
+
+	// Receive counter
+	size_t recv_cnt;
+
+	/*! \brief Message allocation
+	 *
+	 * \param message size required to receive from i
+	 * \param total message size to receive from all the processors
+	 * \param the total number of processor want to communicate with you
+	 * \param i processor id
+	 * \param ri request id (it is an id that goes from 0 to total_p, and is unique
+	 *           every time message_alloc is called)
+	 * \param ptr a pointer to the vector_dist structure
+	 *
+	 * \return the pointer where to store the message
+	 *
+	 */
+	static void * message_alloc(size_t msg_i ,size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr)
+	{
+		// cast the pointer
+		nn_prcs<dim,T> * cd = static_cast< nn_prcs<dim,T> *>(ptr);
+
+		// Resize the memory
+		cd->nn_processor_subdomains[i].bx.resize(msg_i / sizeof(::Box<dim,T>) );
+
+		// Return the receive pointer
+		return cd->nn_processor_subdomains[i].bx.getPointer();
+	}
+
+public:
+
+	nn_prcs(Vcluster & v_cl)
+	:v_cl(v_cl){}
+
+	/*! \brief Create the list of adjacent processors and the list of adjacent sub-domains
+	 *
+	 * \param box_nn_processors
+	 *
+	 */
+	void create(const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor, const openfpm::vector<SpaceBox<dim,T>> & sub_domains)
+	{
+		// produce the list of the contiguous processor (nn_processors) and link nn_processor_subdomains to the
+		// processor list
+		for (size_t i = 0 ;  i < box_nn_processor.size() ; i++)
+		{
+			for (size_t j = 0 ; j < box_nn_processor.get(i).size() ; j++)
+			{
+				nn_processors.add(box_nn_processor.get(i).get(j));
+			}
+		}
+
+		// make the list sorted and unique
+	    std::sort(nn_processors.begin(), nn_processors.end());
+	    auto last = std::unique(nn_processors.begin(), nn_processors.end());
+	    nn_processors.erase(last, nn_processors.end());
+
+		// create a buffer with the sub-domains of this processor, the informations ( the boxes )
+		// of the sub-domains contiguous to the processor A are sent to the processor A and
+		// the information of the contiguous sub-domains in the near processors are received
+		//
+		proc_adj_box.resize(getNNProcessors());
+		boxes.resize(nn_processors.size());
+
+		for (size_t b = 0 ; b < box_nn_processor.size() ; b++)
+		{
+			for (size_t p = 0 ; p < box_nn_processor.get(b).size() ; p++)
+			{
+				size_t prc = box_nn_processor.get(b).get(p);
+
+				// id of the processor in the processor list
+				// [value between 0 and the number of the near processors]
+				size_t id = nn_processor_subdomains[prc].id;
+
+				boxes.get(id).add(sub_domains.get(b));
+				proc_adj_box.get(id).add(b);
+			}
+		}
+
+		// Intersect all the local sub-domains with the sub-domains of the contiguous processors
+
+		// Get the sub-domains of the near processors
+		v_cl.sendrecvMultipleMessagesNBX(nn_processors,boxes,nn_prcs<dim,T>::message_alloc, this ,NEED_ALL_SIZE);
+
+
+	}
+
+	/*! \brief Get the number of Near processors
+	 *
+	 * \return the number of near processors
+	 *
+	 */
+	inline size_t getNNProcessors() const
+	{
+		return nn_processors.size();
+	}
+
+	/*! \brief Return the processor id of the near processor list at place id
+	 *
+	 * \param id
+	 *
+	 * \return return the processor rank
+	 *
+	 */
+	inline size_t IDtoProc(size_t id)
+	{
+		return nn_processors.get(id);
+	}
+
+	/*! \brief Get the sub-domain pf an adjacent processor
+	 *
+	 * \param p_id adjacent processor (id from 0 to getNNProcessors())
+	 *
+	 * \return the sub-domains
+	 *
+	 */
+	inline const openfpm::vector< ::Box<dim,T> > & getAdjacentSubdomain(size_t p_id)
+	{
+		return nn_processor_subdomains[p_id].bx;
+	}
+
+	/*! \brief Get the adjacent processor id
+	 *
+	 * \param p_id adjacent processor (id from 0 to getNNProcessors())
+	 *
+	 * \return the processor rank
+	 *
+	 */
+	inline size_t getAdjacentProcessor(size_t p_id)
+	{
+		return nn_processor_subdomains[p_id].id;
+	}
+
+
+	/*! \brief Get the local sub-domains adjacent to a processor p_id
+	 *
+	 * \param p_id adjacent processor (id from 0 to getNNProcessors())
+	 *
+	 * \return the sub-domains
+	 *
+	 */
+	inline const openfpm::vector<size_t> & getInternalAdjSubdomain(size_t p_id)
+	{
+		return proc_adj_box.get(p_id);
+	}
+
+	/*! \brief Convert the processor rank to the id in the list
+	 *
+	 * \param p processor rank
+	 *
+	 * \return the id
+	 *
+	 */
+	inline size_t ProctoID(size_t p)
+	{
+		return nn_processor_subdomains[p].id;
+	}
+
+	/*! \brief Write the decomposition as VTK file
+	 *
+	 * The function generate several files
+	 *
+	 * 1) subdomains_adjacent_X.vtk sub-domains adjacent to the local processor (X)
+	 *
+	 * where X is the local processor rank
+	 *
+	 * \param output directory where to write the files
+	 * \param p_id id of the local processor
+	 *
+	 */
+	bool write(std::string output) const
+	{
+		//! subdomains_adjacent_X.vtk sub-domains adjacent to the local processor (X)
+		VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box2;
+		for (size_t p = 0 ; p < nn_processors.size() ; p++)
+		{
+			size_t prc = nn_processors.get(p);
+			auto it = nn_processor_subdomains.find(prc);
+			if (it != nn_processor_subdomains.end())
+				vtk_box2.add(nn_processor_subdomains.at(prc).bx);
+		}
+		vtk_box2.write(output + std::string("subdomains_adjacent_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));
+
+		return true;
+	}
+
+};
+
+
+#endif /* SRC_DECOMPOSITION_NN_PROCESSOR_HPP_ */