--- privatemsg.list_messages15.patch	2009-03-13 16:33:38.000000000 +0100
+++ privatemsg.list_messages16.patch	2009-03-17 11:30:26.000000000 +0100
@@ -5,7 +5,7 @@ RCS file: /cvs/drupal/contributions/modu
 retrieving revision 1.70.2.30.2.91.2.25
 diff -u -p -r1.70.2.30.2.91.2.25 privatemsg.module
 --- privatemsg.module	22 Feb 2009 21:21:08 -0000	1.70.2.30.2.91.2.25
-+++ privatemsg.module	11 Mar 2009 07:05:24 -0000
++++ privatemsg.module	17 Mar 2009 10:30:25 -0000
 @@ -6,7 +6,8 @@
   * Allows users to send private messages to other users.
   */
@@ -16,17 +16,15 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  
  /**
   * Implementation of hook_perm().
-@@ -25,6 +26,9 @@ function _privatemsg_generate_user_array
+@@ -23,6 +24,7 @@ function privatemsg_perm() {
+ function _privatemsg_generate_user_array($userstring) {
+   static $user_cache = array();
  
++  // convert user uid list (uid1,uid2,uid3) into an array and only load the last 4 uids.
    $users = array_slice(explode(',', $userstring), -4);
    $participants = array();
-+  if (empty($users[0])) {
-+    return array();
-+  }
    foreach ($users as $user) {
-     if (isset($user_cache[$user])) {
-       $participants[$user] = $user_cache[$user];
-@@ -77,28 +81,23 @@ function privatemsg_menu() {
+@@ -77,28 +79,23 @@ function privatemsg_menu() {
    $items['messages'] = array(
      'title'            => 'Messages',
      'title callback'  => 'privatemsg_title_callback',
@@ -61,7 +59,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
      'access callback'  => 'privatemsg_user_access',
      'type'             => MENU_LOCAL_TASK,
      'weight'           => -5,
-@@ -153,6 +152,13 @@ function privatemsg_menu() {
+@@ -153,6 +150,13 @@ function privatemsg_menu() {
      'type'             => MENU_DEFAULT_LOCAL_TASK,
      'weight'           => -10,
    );
@@ -75,7 +73,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
    return $items;
  }
  
-@@ -256,6 +262,26 @@ function private_message_settings() {
+@@ -256,6 +260,25 @@ function private_message_settings() {
      '#default_value' => variable_get('privatemsg_display_loginmessage', TRUE),
      '#description' => t('This option can safely be disabled if the "New message indication" block is used instead.'),
    );
@@ -86,23 +84,22 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +    '#collapsed' => TRUE,
 +  );
 +
-+  $fields = array(
-+    'author' => t('Author'),
-+    'thread_started' => t('Started'),
-+    'count' => t('Answers'),
-+  );
 +  $form['privatemsg_listing']['privatemsg_display_fields'] = array(
 +    '#type' => 'checkboxes',
 +    '#title' => t('Configure fields'),
 +    '#description' => t('Select which columns/fields should be displayed in the message listings. Subject and Last updated cannot be disabled.'),
-+    '#options' => $fields,
-+    '#default_value' => variable_get('privatemsg_display_fields', array('author', 'last_updated')),
++    '#options' => array(
++      'author'          => t('Author'),
++      'thread_started'  => t('Started'),
++      'count'           => t('Answers'),
++    ),
++    '#default_value' => variable_get('privatemsg_display_fields', array('author')),
 +  );
 +
    $form['#submit'][] = 'private_message_settings_submit';
    return system_settings_form($form);
  }
-@@ -282,10 +308,26 @@ function privatemsg_theme() {
+@@ -282,10 +305,26 @@ function privatemsg_theme() {
        'arguments'        => array('recipients' => NULL),
        'template'         => 'privatemsg-between',
      ),
@@ -110,28 +107,28 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 -      'arguments'             => array('row'),
 +    'privatemsg_list'    => array(
 +      'file'                  => 'privatemsg.theme.inc',
-+      'path'                  => drupal_get_path('module', 'privatemsg') .'/',
++      'path'                  => drupal_get_path('module', 'privatemsg'),
 +      'arguments'        => array('form'),
 +    ),
 +    'privatemsg_list_header'  => array(
 +      'file'                  => 'privatemsg.theme.inc',
-+      'path'                  => drupal_get_path('module', 'privatemsg') .'/',
++      'path'                  => drupal_get_path('module', 'privatemsg'),
 +      'pattern'               => 'privatemsg_list_header__',
 +      'arguments'             => array(),
 +    ),
 +    'privatemsg_list_field'   => array(
 +      'file'                  => 'privatemsg.theme.inc',
-+      'path'                  => drupal_get_path('module', 'privatemsg') .'/',
++      'path'                  => drupal_get_path('module', 'privatemsg'),
 +      'pattern'               => 'privatemsg_list_field__',
 +      'arguments'             => array('thread'),
      ),
      'privatemsg_new_block'  => array(
 +      'file'                  => 'privatemsg.theme.inc',
-+      'path'                  => drupal_get_path('module', 'privatemsg') .'/',
++      'path'                  => drupal_get_path('module', 'privatemsg'),
        'arguments'             => array('count'),
      ),
    );
-@@ -325,12 +367,12 @@ function privatemsg_preprocess_privatems
+@@ -325,12 +364,12 @@ function privatemsg_preprocess_privatems
   *
   * @param $uid - user id for whom to load messages.
   */
@@ -146,7 +143,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
      // Trying to view someone else's messages...
      if (!privatemsg_user_access('read all private messages')) {
        drupal_set_message(t("You do not have sufficient rights to view someone else's messages"), 'warning');
-@@ -341,26 +383,6 @@ function privatemsg_list($uid = NULL) {
+@@ -341,26 +380,6 @@ function privatemsg_list($uid = NULL) {
      }
    }
    // By this point we have figured out for which user we are listing messages and now it is safe to use $account->uid in the listing query.
@@ -173,7 +170,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
    switch (arg(1)) {
      case 'sent':
        $query = _privatemsg_assemble_query('list_sent', $account);
-@@ -371,78 +393,44 @@ function privatemsg_list_messages($accou
+@@ -371,78 +390,44 @@ function privatemsg_list_messages($accou
    }
    $result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']);
  
@@ -279,7 +276,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  }
  
  /**
-@@ -463,45 +451,6 @@ function privatemsg_unread_count($accoun
+@@ -463,45 +448,6 @@ function privatemsg_unread_count($accoun
    return $counts[$account->uid];
  }
  
@@ -325,7 +322,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  function privatemsg_view($thread_id) {
    global $user;
    $output = '';
-@@ -516,13 +465,13 @@ function privatemsg_view($thread_id) {
+@@ -516,13 +462,13 @@ function privatemsg_view($thread_id) {
    $content['participants']['#weight'] = -5;
  
    // Load the messages.
@@ -341,7 +338,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
      $message['author'] = user_load($message['author']);
      // Some tasks only need to be done once - on the first message of a thread.
      if ($message_count == 0) {
-@@ -776,37 +725,38 @@ function privatemsg_sql_list_sent(&$frag
+@@ -776,57 +722,48 @@ function privatemsg_sql_list_sent(&$frag
    $fragments['group_by'][]  = 'pmi.thread_id';
    $fragments['group_by'][]  = 'pm.subject';
  
@@ -364,7 +361,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  function privatemsg_sql_list(&$fragments, $account) {
    $fragments['primary_table'] = '{pm_message} pm';
  
-+  $fields = array_filter(variable_get('privatemsg_display_fields', array('author', 'last_updated')));
++  $fields = array_filter(variable_get('privatemsg_display_fields', array('author')));
 +
    $fragments['select'][]      = 'pmi.thread_id';
    $fragments['select'][]      = 'MIN(pm.subject) as subject';
@@ -375,12 +372,17 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 -                                                         FROM {pm_message} pma
 -                                                         INNER JOIN pm_index pmia ON pma.mid = pmia.mid
 -                                                         WHERE pmia.thread_id = pmi.thread_id),',') AS author";
-+  if (in_array('count', $fields)) {
-+    $fragments['select'][]      = 'COUNT(pmi.thread_id) as count';
-   }
+-  }
 -  else {
 -    $fragments['select'][]      = 'GROUP_CONCAT(DISTINCT author SEPARATOR ",") as author';
-+
+-  }
+   $fragments['select'][]      = 'MAX(pm.timestamp) as last_updated';
+-  $fragments['select'][]      = 'MIN(pm.timestamp) as thread_started';
+   $fragments['select'][]      = 'MAX(pmi.is_new) as is_new';
++  
++  if (in_array('count', $fields)) {
++    $fragments['select'][]      = 'COUNT(pmi.thread_id) as count';
++  }
 +  if (in_array('author', $fields)) {
 +    if ($GLOBALS['db_type'] == 'pgsql') {
 +      $fragments['select'][]      = "array_to_string(array(SELECT DISTINCT textin(int4out(pma.author))
@@ -391,17 +393,13 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +    else {
 +      $fragments['select'][]      = 'GROUP_CONCAT(DISTINCT author SEPARATOR ",") as author';
 +    }
-   }
-   $fragments['select'][]      = 'MAX(pm.timestamp) as last_updated';
--  $fragments['select'][]      = 'MIN(pm.timestamp) as thread_started';
-+
++  }
 +  if (in_array('thread_started', $fields)) {
 +    $fragments['select'][]      = 'MIN(pm.timestamp) as thread_started';
 +  }
-   $fragments['select'][]      = 'MAX(pmi.is_new) as is_new';
    // pm_index needs to be the first join.
    $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
-@@ -814,19 +764,10 @@ function privatemsg_sql_list(&$fragments
+   $fragments['where'][]       = 'pmi.uid = %d';
    $fragments['query_args'][]  = $account->uid;
    $fragments['where'][]       = 'pmi.deleted = 0';
    $fragments['group_by'][]    = 'pmi.thread_id';
@@ -424,7 +422,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  }
  
  function privatemsg_sql_load(&$fragments, $pmid, $account) {
-@@ -847,15 +788,17 @@ function privatemsg_sql_load(&$fragments
+@@ -847,15 +784,17 @@ function privatemsg_sql_load(&$fragments
    $fragments['query_args'][]  = $account->uid;
  }
  
@@ -446,7 +444,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
    $fragments['order_by'][]    = 'pmi.mid ASC';
  }
  
-@@ -1103,14 +1046,14 @@ function privatemsg_delete($form_state, 
+@@ -1103,14 +1042,14 @@ function privatemsg_delete($form_state, 
    );
  }
  
@@ -463,7 +461,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
  
    $result = db_query("SELECT MIN(deleted) AS deleted_by_all FROM {pm_index} WHERE mid = %d", $pmid);
    $deleted = db_fetch_array($result);
-@@ -1124,10 +1067,8 @@ function privatemsg_message_delete($pmid
+@@ -1124,10 +1063,8 @@ function privatemsg_message_delete($pmid
  }
  
  function privatemsg_delete_submit($form, &$form_state) {
@@ -475,7 +473,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
      drupal_set_message(t('Message has been deleted'));
    }
    $form_state['redirect'] = 'messages';
-@@ -1453,3 +1394,226 @@ function _privatemsg_assemble_query($que
+@@ -1453,3 +1390,251 @@ function _privatemsg_assemble_query($que
    }
    return FALSE;
  }
@@ -521,9 +519,12 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +/**
 + * Marks one or multiple threads as (un)read
 + *
-+ * @param array|int $threads Array with id's, a single int value will be converted to int
-+ * @param int       $status  Either PRIVATEMSG_READ or PRIVATEMSG_UNREAD, sets the new status
-+ * @param object    $account User object for which the threads should be deleted, defaults to the current user
++ * @param $threads
++ *   Array with id's, a single int value will be converted to int
++ * @param $status
++ *   Either PRIVATEMSG_READ or PRIVATEMSG_UNREAD, sets the new status
++ * @param $account
++ *   User object for which the threads should be deleted, defaults to the current user
 + */
 +function privatemsg_thread_change_status($threads, $status, $account = NULL) {
 +  if (!is_array($threads)) {
@@ -534,8 +535,8 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +    global $user;
 +    $account = drupal_clone($user);
 +  }
-+
-+  $params = array($status, $account->uid) + $threads;
++  // merge status and uid with the threads list. array_merge() will not overwrite/ignore thread_id 1
++  $params = array_merge(array($status, $account->uid), $threads);
 +  db_query('UPDATE {pm_index} SET is_new = %d WHERE uid = %d AND thread_id IN ('. db_placeholders($threads) .')', $params);
 +
 +  if ($status == PRIVATEMSG_UNREAD) {
@@ -545,7 +546,16 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +    drupal_set_message(t('Marked %count threads as read.', array('%count' => count($threads))));
 +  }
 +}
-+
++/**
++ * Returns a table header definition based on the submitted keys.
++ *
++ * @param $has_posts
++ *   TRUE when there is atleast one row. decides if the select all checkbox should be displayed.
++ * @param
++ *   Array with the keys which are present in the query/should be displayed.
++ * @return
++ *   Array with header defintions for tablesort_sql and theme('table').
++ */
 +function _privatemsg_list_headers($has_posts, $keys) {
 +  $select_header = $has_posts ? theme('table_select_header_cell') : '';
 +  $select_header['#weight'] = -50;
@@ -562,6 +572,16 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +  return $header;
 +}
 +
++/**
++ * Formats a row in the message list.
++ *
++ * Does use theme patterns to display the single fields.
++ * 
++ * @param $thread
++ *   Array with the row data returned by the database.
++ * @return
++ *   Row definition for use with theme('table')
++ */
 +function _privatemsg_list_thread($thread) {
 +  $row = array('data' => array());
 +
@@ -595,7 +615,7 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 + * Process privatemsg_list form submissions.
 + *
 + * Execute the chosen action on the selected messages. This function is
-+ * a copy of node_admin_nodes_submit
++ * based on node_admin_nodes_submit().
 + */
 +function privatemsg_list_submit($form, &$form_state) {
 +  $operations = module_invoke_all('privatemsg_thread_operations');
@@ -643,9 +663,12 @@ diff -u -p -r1.70.2.30.2.91.2.25 private
 +/**
 + * Delete or restore one or multiple threads
 + *
-+ * @param array|int $threads Array with id's, a single int value will be converted to int
-+ * @param int       $delete  Indiciates if the threads should be deleted or restored. 1 = delete, 0 => restore
-+ * @param object    $account User object for which the threads should be deleted, defaults to the current user
++ * @param $threads
++ *   Array with id's, a single int value will be converted to int
++ * @param $delete
++ *   Indiciates if the threads should be deleted or restored. 1 = delete, 0 => restore.
++ * @param $account
++ *   User object for which the threads should be deleted, defaults to the current user.
 + */
 +function privatemsg_thread_change_delete($threads, $delete, $account = NULL) {
 +  if (!is_array($threads)) {
@@ -707,8 +730,8 @@ Index: privatemsg.theme.inc
 RCS file: privatemsg.theme.inc
 diff -N privatemsg.theme.inc
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ privatemsg.theme.inc	11 Mar 2009 07:05:24 -0000
-@@ -0,0 +1,169 @@
++++ privatemsg.theme.inc	17 Mar 2009 10:30:25 -0000
+@@ -0,0 +1,175 @@
 +<?php
 +// $Id$
 +
@@ -721,6 +744,9 @@ diff -N privatemsg.theme.inc
 +}
 +
 +function phptemplate_privatemsg_list_field__author($thread) {
++  if (empty($thread['author'])) {
++    return;
++  }
 +  $authors = _privatemsg_generate_user_array($thread['author']);
 +  $field = array();
 +  $field['data'] = _privatemsg_format_participants($authors, 3, TRUE);
@@ -729,6 +755,9 @@ diff -N privatemsg.theme.inc
 +}
 +
 +function phptemplate_privatemsg_list_field__recipient($thread) {
++  if (empty($thread['recipient'])) {
++    return;
++  }
 +  $recipients = _privatemsg_generate_user_array($thread['recipient']);
 +  $field = array();
 +  $field['data'] = _privatemsg_format_participants($recipients, 3, TRUE);
@@ -884,7 +913,7 @@ Index: privatemsg-list.js
 RCS file: privatemsg-list.js
 diff -N privatemsg-list.js
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ privatemsg-list.js	11 Mar 2009 07:05:24 -0000
++++ privatemsg-list.js	17 Mar 2009 10:30:25 -0000
 @@ -0,0 +1,3 @@
 +Drupal.behaviors.hideButtons = function (context) {
 + $("input.privatemsg-action-button").hide();
@@ -896,7 +925,7 @@ RCS file: /cvs/drupal/contributions/modu
 retrieving revision 1.1
 diff -u -p -r1.1 privatemsg-list.css
 --- styles/privatemsg-list.css	3 Sep 2008 06:24:50 -0000	1.1
-+++ styles/privatemsg-list.css	11 Mar 2009 07:05:24 -0000
++++ styles/privatemsg-list.css	17 Mar 2009 10:30:25 -0000
 @@ -1,3 +1,3 @@
 -.privatemsg-list-subject.privatemsg-unread {
 +tr.privatemsg-unread td.privatemsg-list-subject {
@@ -909,7 +938,7 @@ RCS file: /cvs/drupal/contributions/modu
 retrieving revision 1.1.2.8
 diff -u -p -r1.1.2.8 privatemsg_filter.module
 --- privatemsg_filter/privatemsg_filter.module	5 Mar 2009 18:09:02 -0000	1.1.2.8
-+++ privatemsg_filter/privatemsg_filter.module	11 Mar 2009 07:05:25 -0000
++++ privatemsg_filter/privatemsg_filter.module	17 Mar 2009 10:30:26 -0000
 @@ -290,6 +290,7 @@ function privatemsg_filter_dropdown(&$fo
        '#value'    => t('Filter'),
        '#prefix'   => '<div id="privatemsg-filter-buttons">',
