diff --git a/examples/main_fof.c b/examples/main_fof.c
index b743d7311045af73a40ba367dc0842e9d7e80301..39c91d29cc673a7ec6f9028205e84a2c45a49e84 100644
--- a/examples/main_fof.c
+++ b/examples/main_fof.c
@@ -1002,7 +1002,8 @@ int main(int argc, char *argv[]) {
 #endif
 
     /* Initialise the FOF parameters. */
-    fof_init(&s);
+    // MATTHIEU
+    // fof_init(&s);
 
     /* Initialise the particles */
     engine_init_particles(&e, flag_entropy_ICs, clean_smoothing_length_values,
diff --git a/src/fof.c b/src/fof.c
index 4f99a7913f5c58fd84585695f3103a4ad9b3fecd..38c23109a5c92cecba31814395a39d873e8e739f 100644
--- a/src/fof.c
+++ b/src/fof.c
@@ -677,19 +677,22 @@ void fof_search_pair_cells(const struct fof_props *props, const struct space *s,
 
 /* Perform a FOF search between a local and foreign cell using the Union-Find
  * algorithm. Store any links found between particles.*/
-void fof_search_pair_cells_foreign(struct space *s, struct cell *ci,
-                                   struct cell *cj, int *link_count,
+void fof_search_pair_cells_foreign(const struct fof_props *props,
+                                   const struct space *s, const double dim[3],
+                                   const double l_x2, struct cell *restrict ci,
+                                   struct cell *restrict cj,
+                                   int *restrict link_count,
                                    struct fof_mpi **group_links,
-                                   int *group_links_size) {
+                                   int *restrict group_links_size) {
 #ifdef WITH_MPI
   const size_t count_i = ci->grav.count;
   const size_t count_j = cj->grav.count;
   struct gpart *gparts_i = ci->grav.parts;
   struct gpart *gparts_j = cj->grav.parts;
-  const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
-  const double l_x2 = s->fof_data.l_x2;
-  size_t *group_index = s->fof_data.group_index;
-  size_t *group_size = s->fof_data.group_size;
+
+  /* Get local pointers */
+  size_t *group_index = props->group_index;
+  size_t *group_size = props->group_size;
 
   /* Make a list of particle offsets into the global gparts array. */
   size_t *const offset_i = group_index + (ptrdiff_t)(gparts_i - s->gparts);
@@ -701,10 +704,12 @@ void fof_search_pair_cells_foreign(struct space *s, struct cell *ci,
   const int ci_local = (ci->nodeID == engine_rank);
   const int cj_local = (cj->nodeID == engine_rank);
 
+#ifdef SWIFT_DEBUG_CHECKS
   if ((ci_local && cj_local) || (!ci_local && !cj_local))
     error(
         "FOF search of foreign cells called on two local cells or two foreign "
         "cells.");
+#endif
 
   /* Get the relative distance between the pairs, wrapping. */
   const int periodic = s->periodic;
@@ -854,15 +859,14 @@ void rec_fof_search_pair(const struct fof_props *props, const struct space *s,
     fof_search_pair_cells(props, s, dim, search_r2, ci, cj);
   }
 }
-
 #ifdef WITH_MPI
+
 /* Recurse on a pair of cells (one local, one foreign) and perform a FOF search
  * between cells that are within range. */
-static void rec_fof_search_pair_foreign(struct cell *ci, struct cell *cj,
-                                        struct space *s, const double *dim,
-                                        const double search_r2, int *link_count,
-                                        struct fof_mpi **group_links,
-                                        int *group_links_size) {
+static void rec_fof_search_pair_foreign(
+    const struct fof_props *props, const struct space *s, const double dim[3],
+    const double search_r2, struct cell *ci, struct cell *cj, int *link_count,
+    struct fof_mpi **group_links, int *group_links_size) {
 
   /* Find the shortest distance between cells, remembering to account for
    * boundary conditions. */
@@ -880,31 +884,34 @@ static void rec_fof_search_pair_foreign(struct cell *ci, struct cell *cj,
 
         for (int l = 0; l < 8; l++)
           if (cj->progeny[l] != NULL)
-            rec_fof_search_pair_foreign(ci->progeny[k], cj->progeny[l], s, dim,
-                                        search_r2, link_count, group_links,
-                                        group_links_size);
+            rec_fof_search_pair_foreign(
+                props, s, dim, search_r2, ci->progeny[k], cj->progeny[l],
+                link_count, group_links, group_links_size);
       }
     }
   } else if (ci->split) {
 
     for (int k = 0; k < 8; k++) {
       if (ci->progeny[k] != NULL)
-        rec_fof_search_pair_foreign(ci->progeny[k], cj, s, dim, search_r2,
-                                    link_count, group_links, group_links_size);
+        rec_fof_search_pair_foreign(props, s, dim, search_r2, ci->progeny[k],
+                                    cj, link_count, group_links,
+                                    group_links_size);
     }
   } else if (cj->split) {
     for (int k = 0; k < 8; k++) {
       if (cj->progeny[k] != NULL)
-        rec_fof_search_pair_foreign(ci, cj->progeny[k], s, dim, search_r2,
-                                    link_count, group_links, group_links_size);
+        rec_fof_search_pair_foreign(props, s, dim, search_r2, ci,
+                                    cj->progeny[k], link_count, group_links,
+                                    group_links_size);
     }
   } else {
     /* Perform FOF search between pairs of cells that are within the linking
      * length and not the same cell. */
-    fof_search_pair_cells_foreign(s, ci, cj, link_count, group_links,
-                                  group_links_size);
+    fof_search_pair_cells_foreign(props, s, dim, search_r2, ci, cj, link_count,
+                                  group_links, group_links_size);
   }
 }
+
 #endif
 
 /**
@@ -1080,41 +1087,46 @@ void fof_unpack_group_mass_mapper(hashmap_key_t key, hashmap_value_t *value,
  * @brief Calculates the total mass of each group above min_group_size and finds
  * the densest particle for black hole seeding.
  */
-void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
+void fof_calc_group_mass(struct fof_props *props, const struct space *s,
+                         const size_t num_groups_local,
                          const size_t num_groups_prev, size_t *num_on_node,
                          size_t *first_on_node, double *group_mass) {
 
   const size_t nr_gparts = s->nr_gparts;
   struct gpart *gparts = s->gparts;
-  struct fof_props *props = s->e->fof_properties;
+  const struct part *parts = s->parts;
   const size_t group_id_offset = props->group_id_offset;
   const size_t group_id_default = props->group_id_default;
   const double seed_halo_mass = props->seed_halo_mass;
 
 #ifdef WITH_MPI
-  size_t *group_index = s->fof_data.group_index;
-  int nr_nodes = s->e->nr_nodes;
-  struct part *parts = s->parts;
-  long long *max_part_density_index = NULL;
-  float *max_part_density = NULL;
+  size_t *group_index = props->group_index;
+  const int nr_nodes = s->e->nr_nodes;
+
   /* Allocate and initialise the densest particle array. */
   if (swift_memalign("max_part_density_index",
-                     (void **)&s->fof_data.max_part_density_index, 32,
+                     (void **)&props->max_part_density_index, 32,
                      num_groups_local * sizeof(long long)) != 0)
     error(
         "Failed to allocate list of max group density indices for FOF search.");
 
-  if (swift_memalign("max_part_density", (void **)&s->fof_data.max_part_density,
-                     32, num_groups_local * sizeof(float)) != 0)
+  if (swift_memalign("max_part_density", (void **)&props->max_part_density, 32,
+                     num_groups_local * sizeof(float)) != 0)
     error("Failed to allocate list of max group densities for FOF search.");
 
-  for (size_t i = 0; i < num_groups_local; i++)
-    s->fof_data.max_part_density_index[i] = FOF_NO_GAS;
-  bzero(s->fof_data.max_part_density, num_groups_local * sizeof(float));
+  /* Direct pointers to the arrays */
+  long long *max_part_density_index = props->max_part_density_index;
+  float *max_part_density = props->max_part_density;
 
-  max_part_density_index = s->fof_data.max_part_density_index;
-  max_part_density = s->fof_data.max_part_density;
+  /* No densest particle found so far */
+  bzero(&max_part_density, num_groups_local * sizeof(float));
+
+  /* Start by assuming that the haloes have no gas */
+  for (size_t i = 0; i < num_groups_local; i++) {
+    max_part_density_index[i] = fof_halo_has_no_gas;
+  }
 
+  /* Start the hash map */
   hashmap_t map;
   hashmap_init(&map);
 
@@ -1124,12 +1136,13 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
     /* Check if the particle is in a group above the threshold. */
     if (gparts[i].group_id != group_id_default) {
 
-      size_t root = fof_find_global(i, group_index, nr_gparts);
+      const size_t root = fof_find_global(i, group_index, nr_gparts);
 
       /* Increment the mass of groups that are local */
       if (is_local(root, nr_gparts)) {
 
-        size_t index = gparts[i].group_id - group_id_offset - num_groups_prev;
+        const size_t index =
+            gparts[i].group_id - group_id_offset - num_groups_prev;
 
         /* Update group mass */
         group_mass[index] += gparts[i].mass;
@@ -1142,25 +1155,25 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
         hashmap_value_t *data = hashmap_get(&map, (hashmap_key_t)root);
 
         if (data != NULL) {
-          (*data).value_dbl += gparts[i].mass;
+          data->value_dbl += gparts[i].mass;
 
           /* Find the densest gas particle.
            * Account for groups that already have a black hole and groups that
            * contain no gas. */
           if (gparts[i].type == swift_type_gas &&
-              (*data).value_st != FOF_BLACK_HOLE) {
+              data->value_st != fof_halo_has_black_hole) {
 
             /* Update index if a denser gas particle is found. */
-            if (parts[-gparts[i].id_or_neg_offset].rho > (*data).value_flt) {
-              (*data).value_flt = parts[-gparts[i].id_or_neg_offset].rho;
-              (*data).value_st = -gparts[i].id_or_neg_offset;
+            if (parts[-gparts[i].id_or_neg_offset].rho > data->value_flt) {
+              data->value_flt = parts[-gparts[i].id_or_neg_offset].rho;
+              data->value_st = -gparts[i].id_or_neg_offset;
             }
           }
           /* If there is already a black hole in the group we don't need to
              create a new one. */
           else if (gparts[i].type == swift_type_black_hole) {
-            (*data).value_st = FOF_BLACK_HOLE;
-            (*data).value_flt = 0.f;
+            data->value_st = fof_halo_has_black_hole;
+            data->value_flt = 0.f;
           }
         } else
           error("Couldn't find key (%zu) or create new one.", root);
@@ -1189,7 +1202,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
            * Account for groups that already have a black hole and groups that
            * contain no gas. */
           if (gparts[i].type == swift_type_gas &&
-              max_part_density_index[index] != FOF_BLACK_HOLE) {
+              max_part_density_index[index] != fof_halo_has_black_hole) {
 
             /* Update index if a denser gas particle is found. */
             if (parts[-gparts[i].id_or_neg_offset].rho >
@@ -1201,7 +1214,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
           /* If there is already a black hole in the group we don't need to
              create a new one. */
           else if (gparts[i].type == swift_type_black_hole) {
-            max_part_density_index[index] = FOF_BLACK_HOLE;
+            max_part_density_index[index] = fof_halo_has_black_hole;
           }
         }
       }
@@ -1287,7 +1300,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
     if (group_mass[offset] > seed_halo_mass) {
 
       /* Only check groups that don't already contain a black hole. */
-      if (max_part_density_index[offset] != FOF_BLACK_HOLE) {
+      if (max_part_density_index[offset] != fof_halo_has_black_hole) {
 
         /* Find the densest particle in each group using the densest particle
          * from each group fragment. */
@@ -1299,11 +1312,12 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
       }
       /* If there is already a black hole in the group we don't need to create a
          new one. */
-      else if (fof_mass_recv[i].max_part_density_index == FOF_BLACK_HOLE) {
-        max_part_density_index[offset] = FOF_BLACK_HOLE;
+      else if (fof_mass_recv[i].max_part_density_index ==
+               fof_halo_has_black_hole) {
+        max_part_density_index[offset] = fof_halo_has_black_hole;
       }
     } else {
-      max_part_density_index[offset] = FOF_NO_GAS;
+      max_part_density_index[offset] = fof_halo_has_no_gas;
     }
   }
 
@@ -1325,12 +1339,12 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
      * seed a black hole locally. */
     if (max_part_density_index[offset] ==
         fof_mass_recv[i].max_part_density_index) {
-      max_part_density_index[offset] = FOF_BLACK_HOLE;
+      max_part_density_index[offset] = fof_halo_has_black_hole;
     }
     /* The densest particle is on the same node as the global root so we don't
        need to seed a black hole on the other node. */
     else {
-      fof_mass_recv[i].max_part_density_index = FOF_BLACK_HOLE;
+      fof_mass_recv[i].max_part_density_index = fof_halo_has_black_hole;
     }
   }
 
@@ -1346,8 +1360,10 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
    * is not on this node. */
   for (size_t i = 0; i < nsend; i++) {
 
-    /* Only add the index if: 1) there is not already a black hole in the group
-     * and 2) there is gas in the group. */
+    /* Only add the index if:
+     * 1) there is not already a black hole in the group
+     * AND
+     * 2) there is gas in the group. */
     if (fof_mass_send[i].max_part_density_index >= 0) {
 
       /* Re-allocate the list if it's needed. */
@@ -1363,7 +1379,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
 
         density_index_size = new_size;
 
-        s->fof_data.max_part_density_index = max_part_density_index;
+        props->max_part_density_index = max_part_density_index;
       }
 
       /* Add particle index onto the end of the array. */
@@ -1373,7 +1389,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
     }
   }
 
-  s->fof_data.extra_bh_seed_count = extra_seed_count;
+  props->extra_bh_seed_count = extra_seed_count;
 
   free(sendcount);
   free(recvcount);
@@ -1383,10 +1399,6 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
   free(fof_mass_recv);
 #else
 
-  struct part *parts = s->parts;
-  long long *max_part_density_index = NULL;
-  float *max_part_density = NULL;
-
   /* Allocate and initialise the densest particle array. */
   if (swift_memalign("max_part_density_index",
                      (void **)&props->max_part_density_index, 32,
@@ -1399,8 +1411,8 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
     error("Failed to allocate list of max group densities for FOF search.");
 
   /* Direct pointers to the arrays */
-  max_part_density_index = props->max_part_density_index;
-  max_part_density = props->max_part_density;
+  long long *max_part_density_index = props->max_part_density_index;
+  float *max_part_density = props->max_part_density;
 
   /* No densest particle found so far */
   bzero(&max_part_density, num_groups_local * sizeof(float));
@@ -1412,7 +1424,7 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
 
   /* Increment the group mass for groups above min_group_size. */
   threadpool_map(&s->e->threadpool, fof_calc_group_mass_mapper, gparts,
-                 nr_gparts, sizeof(struct gpart), 0, s);
+                 nr_gparts, sizeof(struct gpart), 0, (struct space *)s);
 
   /* Loop over particles and find the densest particle in each group. */
   /* JSW TODO: Parallelise with threadpool*/
@@ -1448,7 +1460,6 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
 #endif
 }
 
-#ifdef WITH_MPI
 /**
  * @brief Mapper function to perform FOF search.
  *
@@ -1459,16 +1470,20 @@ void fof_calc_group_mass(struct space *s, const size_t num_groups_local,
 void fof_find_foreign_links_mapper(void *map_data, int num_elements,
                                    void *extra_data) {
 
+#ifdef WITH_MPI
+
   /* Retrieve mapped data. */
   struct space *s = (struct space *)extra_data;
+  const struct engine *e = s->e;
+  struct fof_props *props = e->fof_properties;
   struct cell_pair_indices *cell_pairs = (struct cell_pair_indices *)map_data;
 
   const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
-  const double search_r2 = s->fof_data.l_x2;
+  const double search_r2 = props->l_x2;
 
   /* Store links in an array local to this thread. */
   int local_link_count = 0;
-  int local_group_links_size = s->fof_data.group_links_size / s->e->nr_threads;
+  int local_group_links_size = props->group_links_size / e->nr_threads;
 
   /* Init the local group links buffer. */
   struct fof_mpi *local_group_links = (struct fof_mpi *)swift_calloc(
@@ -1484,9 +1499,9 @@ void fof_find_foreign_links_mapper(void *map_data, int num_elements,
     struct cell *restrict local_cell = cell_pairs[ind].local;
     struct cell *restrict foreign_cell = cell_pairs[ind].foreign;
 
-    rec_fof_search_pair_foreign(local_cell, foreign_cell, s, dim, search_r2,
-                                &local_link_count, &local_group_links,
-                                &local_group_links_size);
+    rec_fof_search_pair_foreign(props, s, dim, search_r2, local_cell,
+                                foreign_cell, &local_link_count,
+                                &local_group_links, &local_group_links_size);
   }
 
   /* Add links found by this thread to the global link list. */
@@ -1494,9 +1509,9 @@ void fof_find_foreign_links_mapper(void *map_data, int num_elements,
   if (lock_lock(&s->lock) == 0) {
 
     /* Get pointers to global arrays. */
-    int *group_links_size = &s->fof_data.group_links_size;
-    int *group_link_count = &s->fof_data.group_link_count;
-    struct fof_mpi **group_links = &s->fof_data.group_links;
+    int *group_links_size = &props->group_links_size;
+    int *group_link_count = &props->group_link_count;
+    struct fof_mpi **group_links = &props->group_links;
 
     /* If the global group_links array is not big enough re-allocate it. */
     if (*group_link_count + local_link_count > *group_links_size) {
@@ -1550,8 +1565,8 @@ void fof_find_foreign_links_mapper(void *map_data, int num_elements,
   if (lock_unlock(&s->lock) != 0) error("Failed to unlock the space");
 
   swift_free("fof_local_group_links", local_group_links);
-}
 #endif
+}
 
 /* Dump FOF group data. */
 void fof_dump_group_data(const struct fof_props *props,
@@ -1623,17 +1638,17 @@ void fof_dump_group_data(const struct fof_props *props,
  *
  * @param s Pointer to a #space.
  */
-void fof_search_foreign_cells(struct space *s) {
+void fof_search_foreign_cells(struct fof_props *props, const struct space *s) {
 
 #ifdef WITH_MPI
 
   struct engine *e = s->e;
   int verbose = e->verbose;
-  size_t *group_index = s->fof_data.group_index;
-  size_t *group_size = s->fof_data.group_size;
+  size_t *group_index = props->group_index;
+  size_t *group_size = props->group_size;
   const size_t nr_gparts = s->nr_gparts;
   const double dim[3] = {s->dim[0], s->dim[1], s->dim[2]};
-  const double search_r2 = s->fof_data.l_x2;
+  const double search_r2 = props->l_x2;
 
   ticks tic = getticks();
 
@@ -1644,8 +1659,8 @@ void fof_search_foreign_cells(struct space *s) {
   int group_link_count = 0;
   int cell_pair_count = 0;
 
-  s->fof_data.group_links_size = s->fof_data.group_links_size_default;
-  s->fof_data.group_link_count = 0;
+  props->group_links_size = props->group_links_size_default;
+  props->group_link_count = 0;
 
   int num_cells_out = 0;
   int num_cells_in = 0;
@@ -1670,10 +1685,9 @@ void fof_search_foreign_cells(struct space *s) {
 
   const int cell_pair_size = num_cells_in * num_cells_out;
 
-  if (swift_memalign("fof_group_links", (void **)&s->fof_data.group_links,
+  if (swift_memalign("fof_group_links", (void **)&props->group_links,
                      SWIFT_STRUCT_ALIGNMENT,
-                     s->fof_data.group_links_size * sizeof(struct fof_mpi)) !=
-      0)
+                     props->group_links_size * sizeof(struct fof_mpi)) != 0)
     error("Error while allocating memory for FOF links over an MPI domain");
 
   if (swift_memalign("fof_cell_pairs", (void **)&cell_pairs,
@@ -1794,9 +1808,10 @@ void fof_search_foreign_cells(struct space *s) {
   /* Perform search of group links between local and foreign cells with the
    * threadpool. */
   threadpool_map(&s->e->threadpool, fof_find_foreign_links_mapper, cell_pairs,
-                 cell_pair_count, sizeof(struct cell_pair_indices), 1, s);
+                 cell_pair_count, sizeof(struct cell_pair_indices), 1,
+                 (struct space *)s);
 
-  group_link_count = s->fof_data.group_link_count;
+  group_link_count = props->group_link_count;
 
   /* Clean up memory. */
   swift_free("fof_cell_pairs", cell_pairs);
@@ -1855,13 +1870,13 @@ void fof_search_foreign_cells(struct space *s) {
     displ[i] = displ[i - 1] + group_link_counts[i - 1];
 
   /* Gather the global link list on all ranks. */
-  MPI_Allgatherv(s->fof_data.group_links, group_link_count, fof_mpi_type,
+  MPI_Allgatherv(props->group_links, group_link_count, fof_mpi_type,
                  global_group_links, group_link_counts, displ, fof_mpi_type,
                  MPI_COMM_WORLD);
 
   /* Clean up memory. */
   free(displ);
-  swift_free("fof_group_links", s->fof_data.group_links);
+  swift_free("fof_group_links", props->group_links);
 
   if (verbose) {
     message("Communication took: %.3f %s.",
@@ -2096,7 +2111,7 @@ void fof_search_tree(struct fof_props *props, struct space *s) {
     ticks tic_mpi = getticks();
 
     /* Search for group links across MPI domains. */
-    fof_search_foreign_cells(s);
+    fof_search_foreign_cells(props, s);
 
     if (verbose)
       message("fof_search_foreign_cells() took: %.3f %s.",
@@ -2318,12 +2333,12 @@ void fof_search_tree(struct fof_props *props, struct space *s) {
 
   double *group_mass = props->group_mass;
 #ifdef WITH_MPI
-  fof_calc_group_mass(s, num_groups_local, num_groups_prev, num_on_node,
+  fof_calc_group_mass(props, s, num_groups_local, num_groups_prev, num_on_node,
                       first_on_node, group_mass);
   free(num_on_node);
   free(first_on_node);
 #else
-  fof_calc_group_mass(s, num_groups_local, num_groups_prev, NULL, NULL,
+  fof_calc_group_mass(props, s, num_groups_local, num_groups_prev, NULL, NULL,
                       group_mass);
 #endif