+
+static void clean_references (THREAD * brk, THREAD * cur)
+{
+ THREAD *p;
+ LIST *ref = NULL;
+ int done = 0;
+
+ for (; cur; cur = cur->next, done = 0) {
+ /* parse subthread recursively */
+ clean_references (brk, cur->child);
+
+ if (!cur->message)
+ break; /* skip pseudo-message */
+
+ /* Looking for the first bad reference according to the new threading.
+ * Optimal since Mutt stores the references in reverse order, and the
+ * first loop should match immediatly for mails respecting RFC2822. */
+ for (p = brk; !done && p; p = p->parent)
+ for (ref = cur->message->env->references; p->message && ref;
+ ref = ref->next)
+ if (!str_casecmp (ref->data, p->message->env->message_id)) {
+ done = 1;
+ break;
+ }
+
+ if (done) {
+ HEADER *h = cur->message;
+
+ /* clearing the References: header from obsolete Message-Id(s) */
+ mutt_free_list (&ref->next);
+
+ h->env->refs_changed = h->changed = 1;
+ }
+ }
+}
+
+void mutt_break_thread (HEADER * hdr)
+{
+ mutt_free_list (&hdr->env->in_reply_to);
+ mutt_free_list (&hdr->env->references);
+ hdr->env->irt_changed = hdr->env->refs_changed = 1;
+ clean_references (hdr->thread, hdr->thread->child);
+}
+
+static int link_threads (HEADER * parent, HEADER * child, CONTEXT * ctx)
+{
+ if (child == parent)
+ return 0;
+
+ mutt_break_thread (child);
+
+ child->env->in_reply_to = mutt_new_list ();
+ child->env->in_reply_to->data = str_dup (parent->env->message_id);
+
+ mutt_set_flag (ctx, child, M_TAG, 0);
+
+ child->env->irt_changed = child->changed = 1;
+ return 1;
+}
+
+int mutt_link_threads (HEADER * cur, HEADER * last, CONTEXT * ctx)
+{
+ int i, changed = 0;
+
+ if (!last) {
+ for (i = 0; i < ctx->vcount; i++)
+ if (ctx->hdrs[Context->v2r[i]]->tagged)
+ changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx);
+ }
+ else
+ changed = link_threads (cur, last, ctx);
+
+ return changed;
+}
+
+void mutt_adjust_subject (ENVELOPE* e) {
+ regmatch_t pmatch[1];
+
+ if (e && e->subject) {
+ if (regexec (ReplyRegexp.rx, e->subject, 1, pmatch, 0) == 0)
+ e->real_subj = e->subject + pmatch[0].rm_eo;
+ else
+ e->real_subj = e->subject;
+ }
+}
+
+void mutt_adjust_all_subjects (void) {
+ int i = 0;
+
+ if (!Context || !Context->msgcount)
+ return;
+
+ for (i = 0; i < Context->msgcount; i++)
+ mutt_adjust_subject (Context->hdrs[i]->env);
+}