diff --git a/src/cell.c b/src/cell.c
index 05143497fb7e6d80b5445286b341f35640dc5cf1..848176b1370df0c14435dae44b4867211ce34f0a 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -69,11 +69,6 @@
 /* Global variables. */
 int cell_next_tag = 0;
 
-int depth_0_counter = 0;
-int depth_1_counter = 0;
-int depth_2_counter = 0;
-int depth_3_counter = 0;
-
 /**
  * @brief Get the size of the cell subtree.
  *
@@ -104,6 +99,9 @@ int cell_getsize(struct cell *c) {
 int cell_link_parts(struct cell *c, struct part *parts) {
 
 #ifdef SWIFT_DEBUG_CHECKS
+  if (c->nodeID == engine_rank)
+    error("Linking foreign particles in a local cell!");
+
   if(c->hydro.parts != NULL)
     error("Linking parts into a cell that was already linked");
 #endif
@@ -123,57 +121,23 @@ int cell_link_parts(struct cell *c, struct part *parts) {
   return c->hydro.count;
 }
 
-
 /**
- * @brief Link the cells recursively to the given #part array.
+ * @brief Link the cells recursively to the given #gpart array.
  *
  * @param c The #cell.
- * @param parts The #part array.
+ * @param gparts The #gpart array.
  *
  * @return The number of particles linked.
  */
-int cell_link_foreign_parts(struct cell *c, struct part *parts) {
+int cell_link_gparts(struct cell *c, struct gpart *gparts) {
 
 #ifdef SWIFT_DEBUG_CHECKS
   if (c->nodeID == engine_rank)
     error("Linking foreign particles in a local cell!");
-#endif
-
-  /* Do we have a hydro task at this level? */
-  if (c->hydro.density != NULL) {
 
-    /* Recursively attach the parts */
-    const int counts = cell_link_parts(c, parts);
-#ifdef SWIFT_DEBUG_CHECKS
-    if (counts != c->hydro.count)
-      error("Something is wrong with the foreign counts");
+  if(c->grav.parts != NULL)
+    error("Linking gparts into a cell that was already linked");
 #endif
-    return counts;
-  }
-
-  /* Go deeper to find the level where the tasks are */
-  if (c->split) {
-    int count = 0;
-    for (int k = 0; k < 8; k++) {
-      if (c->progeny[k] != NULL) {
-        count += cell_link_foreign_parts(c->progeny[k], &parts[count]);
-      }
-    }
-    return count;
-  } else {
-    return 0;
-  }
-}
-
-/**
- * @brief Link the cells recursively to the given #gpart array.
- *
- * @param c The #cell.
- * @param gparts The #gpart array.
- *
- * @return The number of particles linked.
- */
-int cell_link_gparts(struct cell *c, struct gpart *gparts) {
 
   c->grav.parts = gparts;
 
@@ -200,6 +164,14 @@ int cell_link_gparts(struct cell *c, struct gpart *gparts) {
  */
 int cell_link_sparts(struct cell *c, struct spart *sparts) {
 
+#ifdef SWIFT_DEBUG_CHECKS
+  if (c->nodeID == engine_rank)
+    error("Linking foreign particles in a local cell!");
+
+  if(c->stars.parts != NULL)
+    error("Linking sparts into a cell that was already linked");
+#endif
+
   c->stars.parts = sparts;
 
   /* Fill the progeny recursively, depth-first. */
@@ -215,6 +187,72 @@ int cell_link_sparts(struct cell *c, struct spart *sparts) {
   return c->stars.count;
 }
 
+int cell_link_foreign_parts(struct cell *c, struct part *parts) {
+
+#ifdef SWIFT_DEBUG_CHECKS
+  if (c->nodeID == engine_rank)
+    error("Linking foreign particles in a local cell!");
+#endif
+
+  /* Do we have a hydro task at this level? */
+  if (c->hydro.density != NULL) {
+
+    /* Recursively attach the parts */
+    const int counts = cell_link_parts(c, parts);
+#ifdef SWIFT_DEBUG_CHECKS
+    if (counts != c->hydro.count)
+      error("Something is wrong with the foreign counts");
+#endif
+    return counts;
+  }
+
+  /* Go deeper to find the level where the tasks are */
+  if (c->split) {
+    int count = 0;
+    for (int k = 0; k < 8; k++) {
+      if (c->progeny[k] != NULL) {
+        count += cell_link_foreign_parts(c->progeny[k], &parts[count]);
+      }
+    }
+    return count;
+  } else {
+    return 0;
+  }
+}
+
+int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts) {
+
+#ifdef SWIFT_DEBUG_CHECKS
+  if (c->nodeID == engine_rank)
+    error("Linking foreign particles in a local cell!");
+#endif
+
+  /* Do we have a hydro task at this level? */
+  if (c->grav.grav != NULL) {
+
+    /* Recursively attach the parts */
+    const int counts = cell_link_gparts(c, gparts);
+#ifdef SWIFT_DEBUG_CHECKS
+    if (counts != c->grav.count)
+      error("Something is wrong with the foreign counts");
+#endif
+    return counts;
+  }
+
+  /* Go deeper to find the level where the tasks are */
+  if (c->split) {
+    int count = 0;
+    for (int k = 0; k < 8; k++) {
+      if (c->progeny[k] != NULL) {
+        count += cell_link_foreign_gparts(c->progeny[k], &gparts[count]);
+      }
+    }
+    return count;
+  } else {
+    return 0;
+  }
+}
+
 int cell_count_parts_for_tasks(const struct cell *c) {
 
 #ifdef SWIFT_DEBUG_CHECKS
@@ -224,10 +262,6 @@ int cell_count_parts_for_tasks(const struct cell *c) {
 
   /* Do we have a hydro task at this level? */
   if (c->hydro.density != NULL) {
-    if (c->depth == 0) ++depth_0_counter;
-    if (c->depth == 1) ++depth_1_counter;
-    if (c->depth == 2) ++depth_2_counter;
-    if (c->depth == 3) ++depth_3_counter;
     return c->hydro.count;
   }
 
@@ -244,6 +278,32 @@ int cell_count_parts_for_tasks(const struct cell *c) {
   }
 }
 
+int cell_count_gparts_for_tasks(const struct cell *c) {
+
+#ifdef SWIFT_DEBUG_CHECKS
+  if (c->nodeID == engine_rank)
+    error("Counting foreign particles in a local cell!");
+#endif
+
+  /* Do we have a hydro task at this level? */
+  if (c->grav.grav != NULL) {
+    return c->grav.count;
+  }
+
+  if (c->split) {
+    int count = 0;
+    for (int k = 0; k < 8; ++k) {
+      if (c->progeny[k] != NULL) {
+        count += cell_count_gparts_for_tasks(c->progeny[k]);
+      }
+    }
+    return count;
+  } else {
+    return 0;
+  }
+}
+
+
 /**
  * @brief Pack the data of the given cell and all it's sub-cells.
  *
diff --git a/src/cell.h b/src/cell.h
index 45b42ec4dcd0cbc849f0512e2b257d09fe244280..c5fbc9b8c02b0e008d337189fdbf582faf4fa600 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -689,10 +689,12 @@ int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m);
 int cell_unpack_multipoles(struct cell *c, struct gravity_tensors *m);
 int cell_getsize(struct cell *c);
 int cell_link_parts(struct cell *c, struct part *parts);
-int cell_link_foreign_parts(struct cell *c, struct part *parts);
 int cell_link_gparts(struct cell *c, struct gpart *gparts);
 int cell_link_sparts(struct cell *c, struct spart *sparts);
+int cell_link_foreign_parts(struct cell *c, struct part *parts);
+int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts);
 int cell_count_parts_for_tasks(const struct cell *c);
+int cell_count_gparts_for_tasks(const struct cell *c);
 void cell_clean_links(struct cell *c, void *data);
 void cell_make_multipoles(struct cell *c, integertime_t ti_current);
 void cell_check_multipole(struct cell *c);
diff --git a/src/engine.c b/src/engine.c
index 1382d090d54e7d5d067220ade21d59bb20e9c59b..d89dd6a74fd933657727dba87da84016044bc76b 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1750,11 +1750,6 @@ void engine_exchange_proxy_multipoles(struct engine *e) {
 #endif
 }
 
-extern int depth_0_counter;
-extern int depth_1_counter;
-extern int depth_2_counter;
-extern int depth_3_counter;
-
 void engine_allocate_foreign_particles(struct engine *e) {
 
 #ifdef WITH_MPI
@@ -1765,23 +1760,26 @@ void engine_allocate_foreign_particles(struct engine *e) {
 
   /* Count the number of particles we need to import and re-allocate
      the buffer if needed. */
-  size_t count_parts_in_old = 0;
-  size_t count_parts_in = 0;
+  size_t count_parts_in_old = 0, count_gparts_in_old = 0;
+  size_t count_parts_in = 0, count_gparts_in = 0;
   for (int k = 0; k < nr_proxies; k++) {
     for (int j = 0; j < e->proxies[k].nr_cells_in; j++) {
 
       if (e->proxies[k].cells_in_type[j] & proxy_cell_type_hydro) {
         count_parts_in_old += e->proxies[k].cells_in[j]->hydro.count;
-
         count_parts_in += cell_count_parts_for_tasks(e->proxies[k].cells_in[j]);
       }
+
+      if (e->proxies[k].cells_in_type[j] & proxy_cell_type_gravity) {
+        count_gparts_in_old += e->proxies[k].cells_in[j]->grav.count;
+        count_gparts_in += cell_count_gparts_for_tasks(e->proxies[k].cells_in[j]);
+      }
+
     }
   }
 
-  message("New count: %zd old count: %zd", count_parts_in, count_parts_in_old);
-
-  message("counters: %d %d %d %d", depth_0_counter, depth_1_counter,
-          depth_2_counter, depth_3_counter);
+  message("New parts count: %zd old parts count: %zd", count_parts_in, count_parts_in_old);
+  message("New gparts count: %zd old gparts count: %zd", count_gparts_in, count_gparts_in_old);
 
   /* Allocate space for the foreign particles we will receive */
   if (count_parts_in > s->size_parts_foreign) {
@@ -1791,9 +1789,19 @@ void engine_allocate_foreign_particles(struct engine *e) {
                        sizeof(struct part) * s->size_parts_foreign) != 0)
       error("Failed to allocate foreign part data.");
   }
+  /* Allocate space for the foreign particles we will receive */
+  if (count_gparts_in > s->size_gparts_foreign) {
+    if (s->gparts_foreign != NULL) free(s->gparts_foreign);
+    s->size_gparts_foreign = 1.1 * count_gparts_in;
+    if (posix_memalign((void **)&s->gparts_foreign, part_align,
+                       sizeof(struct gpart) * s->size_gparts_foreign) != 0)
+      error("Failed to allocate foreign gpart data.");
+  }
 
   struct part *parts = s->parts_foreign;
+  struct gpart *gparts = s->gparts_foreign;
   size_t total_count_parts = 0;
+  size_t total_count_gparts = 0;
   for (int k = 0; k < nr_proxies; k++) {
     for (int j = 0; j < e->proxies[k].nr_cells_in; j++) {
 
@@ -1803,11 +1811,19 @@ void engine_allocate_foreign_particles(struct engine *e) {
         parts = &parts[count_parts];
 	total_count_parts += count_parts;
       }
+
+      if (e->proxies[k].cells_in_type[j] & proxy_cell_type_gravity) {
+
+        const size_t count_gparts = cell_link_foreign_gparts(e->proxies[k].cells_in[j], gparts);
+        gparts = &gparts[count_gparts];
+	total_count_gparts += count_gparts;
+      }
     }
   }
 
   /* Update the counters */
   s->nr_parts_foreign = parts - s->parts_foreign;
+  s->nr_gparts_foreign = gparts - s->gparts_foreign;
 
   
   message("count_parts: %zd %zd", count_parts_in, total_count_parts);