Index: messaging.mail.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/messaging/Attic/messaging.mail.inc,v
retrieving revision 1.1.2.1.2.1
diff -u -p -r1.1.2.1.2.1 messaging.mail.inc
--- messaging.mail.inc	13 Jun 2009 14:49:13 -0000	1.1.2.1.2.1
+++ messaging.mail.inc	30 Nov 2009 10:59:34 -0000
@@ -91,5 +91,74 @@ function messaging_mail_headers($message
     $headers += $more_headers;
   }  
 
+  // For non-digested Notifications emails, get nid & cid for list headers.
+  if (!empty($message->notifications) && ($account = $message->account) 
+    && empty($message->notifications['digest'])) {
+    $event = current($message->notifications['events']);
+    // uid is also in $account->uid.
+    $uid = $event->uid;
+    $nid = $cid = 0;
+    if ($event->type == 'node' && !empty($event->objects['node'])) {
+      $nid = $event->objects['node']->nid;
+      if ($event->action == 'comment' && !empty($event->objects['comment'])) {
+        $cid = $event->objects['comment']->cid;
+      }
+    }
+  }
+  
+  // Only events with node info get more headers.
+  if ($nid) {
+    $list_headers['Message-ID'] = messaging_mail_messageid($nid, $cid);
+
+    // Only comments may have ancestors, so only comments have these headers.
+    if ($cid) {
+      $ancestor_msg_ids = messaging_mail_comment_ancestor_message_ids($nid, $cid);
+      $list_headers['In-Reply-To'] = end($ancestor_msg_ids);
+      $list_headers['References'] = implode(' ', $ancestor_msg_ids);
+    }
+    // Notifications are enabled, so the best place to "unsubscribe" is here.
+    // See <http://drupal.org/node/622440?no_cache=1257283281>.
+    $list_headers['List-Unsubscribe'] = url('user/'. $uid .'/notifications', array('absolute' => TRUE));
+    $headers += $list_headers;
+  }
   return $headers;
 }
+
+/**
+ * Return array of Message-ID values for the ancestors of a comment starting with the earliest. 
+ *
+ * The parent node is considered an ancestor with a cid value of zero. 
+ * Exploits the encoded sorting field 'thread'.
+ *
+ * @param $cid
+ *   Primary key of comment for which ancestors are sought.
+ */
+function messaging_mail_comment_ancestor_message_ids($nid, $cid) {
+  $msg_ids = array();
+  if ($cid != 0) {
+    // Every comment has a node ancestor.
+    $msg_ids[] = messaging_mail_messageid($nid, 0);
+     $thread = db_result(db_query("SELECT thread from {comments} WHERE cid = %d", $cid));
+    if ($thread) {
+      // Thread value of ancestors matches front of child thread if trailing slash removed.
+      $query = "SELECT cid FROM {comments} WHERE nid = %d AND cid <> %d AND LOCATE(TRIM(TRAILING '/' FROM thread), '%s') = 1 ORDER BY thread DESC";
+      $result = db_query($query, $nid, $cid, $thread);
+      while ($row = db_fetch_object($result)) {
+        $msg_ids[] = messaging_mail_messageid($nid, $row->cid);
+      }
+    }
+  }
+  return ($msg_ids);
+}
+
+/**
+ * Build a proper value for a Message-ID header.
+ * 
+ * Exploit nid and cid to create a (probably) unique message header.
+ *
+ * @TODO: is there something better than $_SERVER['HTTP_HOST']?
+ * @TODO: could gaurantee uniqueness if a safe site-specific item could be inserted, such as md5 of the site_key?
+ */
+function messaging_mail_messageid($nid, $cid) {
+  return '<'. $nid .'.'. $cid .'@'. $_SERVER['HTTP_HOST'] .'>';
+}
