+/**
+ * \brief This function is called periodically. It checks the immediate
+ * successor of the current node.
+ * \param node the current node
+ */
+static void stabilize(node_t node) {
+
+ int x = find_predecessor(node, node->fingers[0].id);
+ if (is_in_interval(x, node->id + 1, node->fingers[0].id)) {
+ node->fingers[0].id = x;
+ node->fingers[0].mailbox = get_mailbox(x);
+ }
+ remote_notify(node, node->fingers[0].id, node->id);
+}
+
+/**
+ * \brief Notifies the current node that its predecessor may have changed.
+ * \param node the current node
+ * \param candidate_id the possible new predecessor
+ */
+static void notify(node_t node, int predecessor_candidate_id) {
+
+ if (node->pred_id == node->id
+ || is_in_interval(predecessor_candidate_id, node->pred_id, node->id)) {
+
+ node->pred_id = predecessor_candidate_id;
+ node->pred_mailbox = get_mailbox(predecessor_candidate_id);
+
+ INFO1("My new predecessor is %d", predecessor_candidate_id);
+ print_finger_table(node);
+ }
+ else {
+ INFO1("I don't have to change my predecessor to %d", predecessor_candidate_id);
+ }
+}
+
+/**
+ * \brief Notifies a remote node that its predecessor may have changed.
+ * \param node the current node
+ * \param notify_id id of the node to notify
+ * \param candidate_id the possible new predecessor
+ */
+static void remote_notify(node_t node, int notify_id, int predecessor_candidate_id) {
+
+ task_data_t req_data = xbt_new0(s_task_data_t, 1);
+ req_data->request_id = predecessor_candidate_id;
+ req_data->issuer_host_name = MSG_host_get_name(MSG_host_self());
+
+ // send a "Notify" request to notify_id
+ INFO1("Sending a 'Notify' request to %d", notify_id);
+ m_task_t task = MSG_task_create("Notify", 1000, 5000, req_data);
+ msg_comm_t comm = MSG_task_isend(task, get_mailbox(notify_id));
+ xbt_dynar_push(node->comms, &comm);
+}
+