diff --git a/src/cell.c b/src/cell.c
index 67d72bf6205bafdddcdd7db7b53f5e41311a13e0..4c5064e2036d2682be7f0ec52845935ae6b5d4c9 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -3864,11 +3864,12 @@ void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset) {
   }
 }
 
-void cell_reorder_extra_gparts(struct cell *c, const ptrdiff_t sparts_offset) {
+void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
+                               struct spart *sparts) {
 
   struct gpart *gparts = c->grav.parts;
   const int count_real = c->grav.count;
-  const int count_total = count_real + space_extra_parts;
+  const int count_total = count_real + space_extra_gparts;
 
   if (c->depth != 0)
     error("This function should only be called on top-level cells!");
@@ -3891,11 +3892,11 @@ void cell_reorder_extra_gparts(struct cell *c, const ptrdiff_t sparts_offset) {
 #endif
 
       /* Swap everything (including pointers) */
-      memswap(&gparts[i], &gparts[first_not_extra], sizeof(struct spart));
+      memswap(&gparts[i], &gparts[first_not_extra], sizeof(struct gpart));
       if (gparts[i].type == swift_type_gas) {
-        error("Need to handle this.");
+        parts[-gparts[i].id_or_neg_offset].gpart = &gparts[i];
       } else if (gparts[i].type == swift_type_stars) {
-        error("Need to handle this.");
+        sparts[-gparts[i].id_or_neg_offset].gpart = &gparts[i];
       }
     }
   }
diff --git a/src/cell.h b/src/cell.h
index cf286f02f11179c62e4f7e6fb6afab74324da609..b6bdf1561bcc46a0aef09bd82ba019cfe3455087 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -664,7 +664,8 @@ void cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
 void cell_convert_spart_to_gpart(const struct engine *e, struct cell *c,
                                  struct spart *sp);
 void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset);
-void cell_reorder_extra_gparts(struct cell *c, const ptrdiff_t gparts_offset);
+void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
+                               struct spart *sparts);
 void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset);
 int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
                          const struct engine *e, const struct space *s);
diff --git a/src/engine.c b/src/engine.c
index 9239d00c27a4e29faecf730227741d284ef8d468..0530ae3fb9e48baaa8bd3645563e2c3b95a4d2c1 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1992,9 +1992,10 @@ void engine_rebuild(struct engine *e, int repartitioned,
   space_rebuild(e->s, repartitioned, e->verbose);
 
   /* Update the global counters of particles */
-  long long num_particles[3] = {(long long)e->s->nr_parts,
-                                (long long)e->s->nr_gparts,
-                                (long long)e->s->nr_sparts};
+  long long num_particles[3] = {
+      (long long)(e->s->nr_parts - e->s->nr_extra_parts),
+      (long long)(e->s->nr_gparts - e->s->nr_extra_gparts),
+      (long long)(e->s->nr_sparts - e->s->nr_extra_sparts)};
 #ifdef WITH_MPI
   MPI_Allreduce(MPI_IN_PLACE, num_particles, 3, MPI_LONG_LONG, MPI_SUM,
                 MPI_COMM_WORLD);
diff --git a/src/part.c b/src/part.c
index 3a626e652cf28f0376cadc1d9a40ab85b752e6c1..ec3627d728f69f469cc7d75eb2beb9ae39ed107e 100644
--- a/src/part.c
+++ b/src/part.c
@@ -139,8 +139,9 @@ void part_verify_links(struct part *parts, struct gpart *gparts,
 
   for (size_t k = 0; k < nr_gparts; ++k) {
 
-    /* We have a DM particle */
-    if (gparts[k].type == swift_type_dark_matter) {
+    /* We have a real DM particle */
+    if (gparts[k].type == swift_type_dark_matter &&
+        gparts[k].time_bin != time_bin_not_created) {
 
       /* Check that it's not linked */
       if (gparts[k].id_or_neg_offset <= 0)
diff --git a/src/space.c b/src/space.c
index 98f93d0d0d6810e600de33690a08662547519677..88da0b5fed5511b1151d3ce7e9810c336e7bf5b2 100644
--- a/src/space.c
+++ b/src/space.c
@@ -669,10 +669,103 @@ void space_allocate_extras(struct space *s, int verbose) {
   if (expected_num_extra_sparts < s->nr_extra_sparts)
     error("Reduction in top-level cells number not handled.");
 
+  /* Do we have enough space for the extra gparts (i.e. we haven't used up any)
+   * ? */
+  if (nr_gparts + expected_num_extra_gparts > size_gparts) {
+
+    /* Ok... need to put some more in the game */
+
+    /* Do we need to reallocate? */
+    if (nr_actual_gparts + expected_num_extra_gparts > size_gparts) {
+
+      size_gparts = (nr_actual_gparts + expected_num_extra_gparts) *
+                    engine_redistribute_alloc_margin;
+
+      if (verbose)
+        message("Re-allocating gparts array from %zd to %zd", s->size_gparts,
+                size_gparts);
+
+      /* Create more space for parts */
+      struct gpart *gparts_new = NULL;
+      if (posix_memalign((void **)&gparts_new, gpart_align,
+                         sizeof(struct gpart) * size_gparts) != 0)
+        error("Failed to allocate new gpart data");
+      const ptrdiff_t delta = gparts_new - s->gparts;
+      memcpy(gparts_new, s->gparts, sizeof(struct gpart) * s->size_gparts);
+      free(s->gparts);
+      s->gparts = gparts_new;
+
+      /* Update the counter */
+      s->size_gparts = size_gparts;
+
+      /* We now need to reset all the part and spart pointers */
+      for (size_t i = 0; i < nr_parts; ++i) {
+        if (s->parts[i].time_bin != time_bin_not_created)
+          s->parts[i].gpart += delta;
+      }
+      for (size_t i = 0; i < nr_sparts; ++i) {
+        if (s->sparts[i].time_bin != time_bin_not_created)
+          s->sparts[i].gpart += delta;
+      }
+    }
+
+    /* Turn some of the allocated spares into particles we can use */
+    for (size_t i = nr_gparts; i < nr_actual_gparts + expected_num_extra_gparts;
+         ++i) {
+      bzero(&s->gparts[i], sizeof(struct gpart));
+      s->gparts[i].time_bin = time_bin_not_created;
+      s->gparts[i].type = swift_type_dark_matter;
+      s->gparts[i].id_or_neg_offset = -1;
+    }
+
+      /* Put the spare particles in their correct cell */
+#ifdef WITH_MPI
+    error("Need to do this correctly over MPI for only the local cells.");
+#endif
+    int count_in_cell = 0, current_cell = 0;
+    size_t count_extra_gparts = 0;
+    for (size_t i = 0; i < nr_actual_gparts + expected_num_extra_gparts; ++i) {
+
+#ifdef SWIFT_DEBUG_CHECKS
+      if (current_cell == s->nr_cells)
+        error("Cell counter beyond the maximal nr. cells.");
+#endif
+
+      if (s->gparts[i].time_bin == time_bin_not_created) {
+
+        /* We want the extra particles to be at the centre of their cell */
+        s->gparts[i].x[0] = cells[current_cell].loc[0] + half_cell_width[0];
+        s->gparts[i].x[1] = cells[current_cell].loc[1] + half_cell_width[1];
+        s->gparts[i].x[2] = cells[current_cell].loc[2] + half_cell_width[2];
+        ++count_in_cell;
+        count_extra_gparts++;
+      }
+
+      /* Once we have reached the number of extra gpart per cell, we move to the
+       * next */
+      if (count_in_cell == space_extra_gparts) {
+        ++current_cell;
+        count_in_cell = 0;
+      }
+    }
+
+#ifdef SWIFT_DEBUG_CHECKS
+    if (count_extra_gparts != expected_num_extra_gparts)
+      error("Constructed the wrong number of extra gparts (%zd vs. %zd)",
+            count_extra_gparts, expected_num_extra_gparts);
+#endif
+
+    /* Update the counters */
+    s->nr_gparts = nr_actual_gparts + expected_num_extra_gparts;
+    s->nr_extra_gparts = expected_num_extra_gparts;
+  }
+
   /* Do we have enough space for the extra parts (i.e. we haven't used up any) ?
    */
   if (expected_num_extra_parts > s->nr_extra_parts) {
 
+    /* Ok... need to put some more in the game */
+
     /* Do we need to reallocate? */
     if (nr_actual_parts + expected_num_extra_parts > size_parts) {
 
@@ -711,6 +804,7 @@ void space_allocate_extras(struct space *s, int verbose) {
       bzero(&s->parts[i], sizeof(struct part));
       bzero(&s->xparts[i], sizeof(struct xpart));
       s->parts[i].time_bin = time_bin_not_created;
+      s->parts[i].id = -1;
     }
 
       /* Put the spare particles in their correct cell */
@@ -755,13 +849,12 @@ void space_allocate_extras(struct space *s, int verbose) {
     s->nr_extra_parts = expected_num_extra_parts;
   }
 
-  if (nr_gparts + expected_num_extra_gparts > size_gparts) {
-  }
-
   /* Do we have enough space for the extra sparts (i.e. we haven't used up any)
    * ? */
   if (nr_sparts + expected_num_extra_sparts > size_sparts) {
 
+    /* Ok... need to put some more in the game */
+
     /* Do we need to reallocate? */
     if (nr_actual_sparts + expected_num_extra_sparts > size_sparts) {
 
@@ -790,6 +883,7 @@ void space_allocate_extras(struct space *s, int verbose) {
          ++i) {
       bzero(&s->sparts[i], sizeof(struct spart));
       s->sparts[i].time_bin = time_bin_not_created;
+      s->sparts[i].id = -1;
     }
 
       /* Put the spare particles in their correct cell */
@@ -833,6 +927,13 @@ void space_allocate_extras(struct space *s, int verbose) {
     s->nr_sparts = nr_actual_sparts + expected_num_extra_sparts;
     s->nr_extra_sparts = expected_num_extra_sparts;
   }
+
+#ifdef SWIFT_DEBUG_CHECKS
+  /* Verify that the links are correct */
+  if ((nr_gparts > 0 && nr_parts > 0) || (nr_gparts > 0 && nr_sparts > 0))
+    part_verify_links(s->parts, s->gparts, s->sparts, nr_parts, nr_gparts,
+                      nr_sparts, verbose);
+#endif
 }
 
 /**
@@ -1504,7 +1605,7 @@ void space_reorder_extra_gparts_mapper(void *map_data, int num_cells,
 
   for (int ind = 0; ind < num_cells; ind++) {
     struct cell *c = &cells_top[ind];
-    cell_reorder_extra_gparts(c, c->grav.parts - s->gparts);
+    cell_reorder_extra_gparts(c, s->parts, s->sparts);
   }
 }
 
diff --git a/src/space.h b/src/space.h
index 4f1a39c287b491a727f0775e2812a2475887cee3..efb3ce407f23463bc72c82eaf39e750683c63c9b 100644
--- a/src/space.h
+++ b/src/space.h
@@ -45,8 +45,8 @@ struct cosmology;
 #define space_splitsize_default 400
 #define space_maxsize_default 8000000
 #define space_extra_parts_default 10
-#define space_extra_gparts_default 0
-#define space_extra_sparts_default 0
+#define space_extra_gparts_default 30
+#define space_extra_sparts_default 20
 #define space_expected_max_nr_strays_default 100
 #define space_subsize_pair_hydro_default 256000000
 #define space_subsize_self_hydro_default 32000