diff -urp privatemsg/privatemsg.module privatemsg_inbox/privatemsg.module
--- privatemsg/privatemsg.module	2009-03-23 16:29:59.856110800 +0000
+++ privatemsg_inbox/privatemsg.module	2009-03-23 16:46:56.840710800 +0000
@@ -80,26 +80,18 @@ function privatemsg_menu() {
     'title'            => 'Messages',
     'title callback'  => 'privatemsg_title_callback',
     'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('privatemsg_list'),
+    'page arguments'   => array('privatemsg_list', 'list'),
     'access callback'  => 'privatemsg_user_access',
     'type'             => MENU_NORMAL_ITEM,
   );
-  $items['messages/inbox'] = array(
-    'title'            => 'All messages',
+  $items['messages/list'] = array(
+    'title'            => 'Messages',
     'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('privatemsg_list'),
+    'page arguments'   => array('privatemsg_list', 'list'),
     'access callback'  => 'privatemsg_user_access',
     'type'             => MENU_DEFAULT_LOCAL_TASK,
     'weight'           => -10,
   );
-  $items['messages/sent'] = array(
-    'title'            => 'Sent messages',
-    'page callback'    => 'drupal_get_form',
-    'page arguments'   => array('privatemsg_list'),
-    'access callback'  => 'privatemsg_user_access',
-    'type'             => MENU_LOCAL_TASK,
-    'weight'           => -5,
-  );
   $items['messages/view/%privatemsg_thread'] = array(
     'title'            => 'Read message',
     'page callback'    => 'privatemsg_view',
@@ -272,11 +264,11 @@ function private_message_settings() {
     '#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' => array(
-      'author'          => t('Author'),
+      'participants'    => t('participants'),
       'thread_started'  => t('Started'),
       'count'           => t('Answers'),
     ),
-    '#default_value' => variable_get('privatemsg_display_fields', array('author')),
+    '#default_value' => variable_get('privatemsg_display_fields', array('participants')),
   );
 
   $form['#submit'][] = 'private_message_settings_submit';
@@ -362,9 +354,16 @@ function privatemsg_preprocess_privatems
 /**
  * List messages.
  *
- * @param $uid - user id for whom to load messages.
+ * @param $form_state
+ *   Form state array
+ * @param $argument
+ *   An argument to pass through to the query builder.
+ * @param $uid
+ *   User id messages of another user should be displayed
+ *
+ * @return array Form array
  */
-function privatemsg_list(&$form_state, $uid = NULL) {
+function privatemsg_list(&$form_state, $argument = 'list', $uid = NULL) {
   global $user;
 
   // Setting default behavior...
@@ -380,14 +379,8 @@ function privatemsg_list(&$form_state, $
     }
   }
   // 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.
-  switch (arg(1)) {
-    case 'sent':
-      $query = _privatemsg_assemble_query('list_sent', $account);
-      break;
-    case 'inbox':
-    default:
-      $query = _privatemsg_assemble_query('list', $account);
-  }
+
+  $query = _privatemsg_assemble_query('list', $account, $argument);
   $result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']);
 
   $threads = array();
@@ -398,7 +391,7 @@ function privatemsg_list(&$form_state, $
     $threads[$row['thread_id']] = '';
   }
   if (empty($form['#data'])) {
-    $keys = array('subject', 'author', 'last_updated');
+    $keys = array('subject', 'participants', 'last_updated');
   }
   else {
     // Load the keys of the first row in data, we don't know the key
@@ -693,44 +686,10 @@ function pm_preview($form, &$form_state)
   $form_state['rebuild'] = TRUE; //this forces our form to be rebuilt instead of being submitted.
 }
 
-function privatemsg_sql_list_sent(&$fragments, $account) {
+function privatemsg_sql_list(&$fragments, $account, $argument = 'list') {
   $fragments['primary_table'] = '{pm_message} pm';
 
-  $fragments['select'][]      = 'pmi.thread_id';
-  $fragments['select'][]      = 'pm.subject';
-  if ($GLOBALS['db_type'] == 'pgsql') {
-    $fragments['select'][]      = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid))
-                                                         FROM {pm_index} pmia
-                                                         WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d), ',') AS recipient";
-
-  }
-  else {
-    $fragments['select'][]      = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",")
-                                                         FROM {pm_index} pmia
-                                                         WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d) AS recipient';
-
-  }
-  $fragments['query_args'][] = $account->uid;
-
-  $fragments['select'][]      = 'MAX(pm.timestamp) as last_updated';
-  $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
-  $fragments['where'][]       = 'pmi.uid = %d';
-  $fragments['query_args'][]  = $account->uid;
-  $fragments['where'][]       = 'pm.author = %d';
-  $fragments['query_args'][]  = $account->uid;
-  $fragments['where'][]       = 'pmi.deleted = 0';
-  $fragments['group_by'][]  = 'pmi.thread_id';
-  $fragments['group_by'][]  = 'pm.subject';
-
-  // We can use tablesort_sql now, but we don't need the ORDER BY part of the query.
-  $order_by = drupal_substr(tablesort_sql(_privatemsg_list_headers( FALSE, array('subject', 'recipient', 'last_updated'))), 9);
-  $fragments['order_by'][]  = $order_by;
-}
-
-function privatemsg_sql_list(&$fragments, $account) {
-  $fragments['primary_table'] = '{pm_message} pm';
-
-  $fields = array_filter(variable_get('privatemsg_display_fields', array('author')));
+  $fields = array_filter(variable_get('privatemsg_display_fields', array('participants')));
 
   $fragments['select'][]      = 'pmi.thread_id';
   $fragments['select'][]      = 'MIN(pm.subject) as subject';
@@ -740,15 +699,18 @@ function privatemsg_sql_list(&$fragments
   if (in_array('count', $fields)) {
     $fragments['select'][]      = 'COUNT(pmi.thread_id) as count';
   }
-  if (in_array('author', $fields)) {
+  if (in_array('participants', $fields)) {
     if ($GLOBALS['db_type'] == 'pgsql') {
-      $fragments['select'][]      = "array_to_string(array(SELECT DISTINCT textin(int4out(pma.author))
-                                                           FROM {pm_message} pma
-                                                           INNER JOIN pm_index pmia ON pma.mid = pmia.mid
-                                                           WHERE pmia.thread_id = pmi.thread_id),',') AS author";
+      $fragments['select'][]      = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid))
+                                                           FROM {pm_index} pmia
+                                                           WHERE pmia.thread_id = pmi.thread_id), ',') AS participants";
+
     }
     else {
-      $fragments['select'][]      = 'GROUP_CONCAT(DISTINCT author SEPARATOR ",") as author';
+      $fragments['select'][]      = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",")
+                                                           FROM {pm_index} pmia
+                                                           WHERE pmia.thread_id = pmi.thread_id) AS participants';
+
     }
   }
   if (in_array('thread_started', $fields)) {
@@ -954,7 +916,6 @@ function _privatemsg_block_menu() {
   }
   if (privatemsg_user_access('read privatemsg') || privatemsg_user_access('read all private messages') ) {
     $links[] = l(privatemsg_title_callback(), 'messages');
-    $links[] = l(t('Sent messages'), 'messages/sent');
   }
   if ( count( $links ) ) {
     $block = array(
@@ -1292,6 +1253,7 @@ function _privatemsg_assemble_query($que
   $INNER_JOIN = array();
   $WHERE = array();
   $GROUP_BY = array();
+  $HAVING   = array();
   $ORDER_BY = array();
   $QUERY_ARGS = array();
   $primary_table = '';
@@ -1301,6 +1263,7 @@ function _privatemsg_assemble_query($que
     'inner_join'  => $INNER_JOIN,
     'where'       => $WHERE,
     'group_by'    => $GROUP_BY,
+    'having'      => $HAVING,
     'order_by'    => $ORDER_BY,
     'query_args'  => $QUERY_ARGS,
     'primary_table'  => $primary_table,
@@ -1334,6 +1297,7 @@ function _privatemsg_assemble_query($que
   $INNER_JOIN = $fragments['inner_join'];
   $WHERE = $fragments['where'];
   $GROUP_BY = $fragments['group_by'];
+  $HAVING   = $fragments['having'];
   $ORDER_BY = $fragments['order_by'];
   $QUERY_ARGS = $fragments['query_args'];
   $primary_table = $fragments['primary_table'];
@@ -1345,35 +1309,28 @@ function _privatemsg_assemble_query($que
   // Perform the whole query assembly only if we have something to select.
   if (!empty($SELECT)) {
     $str_select = implode(", ", $SELECT);
-    $query = "SELECT {$str_select} FROM ". $primary_table;
 
-    // Also build a count query which can be passed to pager_query to get a "page count" as that does not play well with queries including "GROUP BY".
-    // In most cases,  "COUNT(*)" is enough to get the count query, but in queries involving a GROUP BY, we want a count of the number of groups we have, not the count of elements inside each group.
-    // So we test if there is GROUP BY and if there is, count the number of distinct groups. If not, we go the normal wal and do a plain COUNT(*).
-    if (!empty($GROUP_BY)) {
-      // PostgreSQL does not support COUNT(sometextfield, someintfield), so I'm only using the first one
-      // Works fine for thread_id/list but may generate an error when a more complex GROUP BY is used.
-      $str_group_by_count = current($GROUP_BY);
-      $count = "SELECT COUNT(DISTINCT {$str_group_by_count}) FROM ". $primary_table;
-    }
-    else {
-      $count = "SELECT COUNT(*) FROM ". $primary_table;
-    }
+    $query = "SELECT {$str_select} FROM ". $primary_table;
 
     if (!empty($INNER_JOIN)) {
       $str_inner_join = implode(' ', $INNER_JOIN);
       $query .= " {$str_inner_join}";
-      $count .= " {$str_inner_join}";
     }
     if (!empty($WHERE)) {
       $str_where = '('. implode(') AND (', $WHERE) .')';
       $query .= " WHERE {$str_where}";
-      $count .= " WHERE {$str_where}";
     }
     if (!empty($GROUP_BY)) {
       $str_group_by = ' GROUP BY '. implode(", ", $GROUP_BY) ;
       $query .= " {$str_group_by}";
     }
+    if (!empty($HAVING)) {
+      $str_having = '('. implode(') AND (', $HAVING) .')';
+      $query .= " HAVING {$str_having}";
+    }
+    // Add the count query - this should work with both mysql and pgsql as outlined in http://drupal.org/node/303087#comment-1370752 .
+    // THis is done before adding the ORDER BY as that is not needed for the COUNT query and will just slow things down.
+    $count = 'SELECT COUNT(*) FROM ('. $query .') as count';
     if (!empty($ORDER_BY)) {
       $str_order_by = ' ORDER BY '. implode(", ", $ORDER_BY) ;
       $query .= " {$str_order_by}";
diff -urp privatemsg/privatemsg.theme.inc privatemsg_inbox/privatemsg.theme.inc
--- privatemsg/privatemsg.theme.inc	2009-03-23 16:29:59.887310800 +0000
+++ privatemsg_inbox/privatemsg.theme.inc	2009-03-23 16:32:17.593510800 +0000
@@ -9,25 +9,14 @@
 function theme_privatemsg_list_field($thread) {
 }
 
-function phptemplate_privatemsg_list_field__author($thread) {
-  if (empty($thread['author'])) {
+function phptemplate_privatemsg_list_field__participants($thread) {
+  if (empty($thread['participants'])) {
     return;
   }
-  $authors = _privatemsg_generate_user_array($thread['author']);
+  $participants = _privatemsg_generate_user_array($thread['participants']);
   $field = array();
-  $field['data'] = _privatemsg_format_participants($authors, 3, TRUE);
-  $field['class'] = 'privatemsg-list-author';
-  return $field;
-}
-
-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);
-  $field['class'] = 'privatemsg-list-recipient';
+  $field['data'] = _privatemsg_format_participants($participants, 3, TRUE);
+  $field['class'] = 'privatemsg-list-participants';
   return $field;
 }
 
@@ -82,20 +71,11 @@ function phptemplate_privatemsg_list_hea
   );
 }
 
-function phptemplate_privatemsg_list_header__author() {
-  return array(
-      'data'    => t('Authors'),
-      'key'     => 'author',
-      'class'   => 'privatemsg-header-authors',
-      '#weight' => -30,
-  );
-}
-
-function phptemplate_privatemsg_list_header__recipient() {
+function phptemplate_privatemsg_list_header__participants() {
   return array(
-      'data'    => t('Recipients'),
-      'key'     => 'recipient',
-      'class'   => 'privatemsg-header-recipients',
+      'data'    => t('Participants'),
+      'key'     => 'participants',
+      'class'   => 'privatemsg-header-participants',
       '#weight' => -30,
   );
 }
diff -urp privatemsg/privatemsg_filter/privatemsg_filter.module privatemsg_inbox/privatemsg_filter/privatemsg_filter.module
--- privatemsg/privatemsg_filter/privatemsg_filter.module	2009-03-23 16:29:59.918510800 +0000
+++ privatemsg_inbox/privatemsg_filter/privatemsg_filter.module	2009-03-23 16:32:46.032310800 +0000
@@ -36,6 +36,30 @@ function privatemsg_filter_menu() {
     'access arguments' => array('administer privatemsg settings'),
     'type'             => MENU_LOCAL_TASK,
   );
+  $items['messages/list/all'] = array(
+    'title'            => 'All messages',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('privatemsg_list', 'list'),
+    'access callback'  => 'privatemsg_user_access',
+    'type'             => MENU_DEFAULT_LOCAL_TASK,
+    'weight'           => -10,
+  );
+  $items['messages/list/inbox'] = array(
+    'title'            => 'Inbox',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('privatemsg_list', 'inbox'),
+    'access callback'  => 'privatemsg_user_access',
+    'type'             => MENU_LOCAL_TASK,
+    'weight'           => -10,
+  );
+  $items['messages/list/sent'] = array(
+    'title'            => 'Sent Messages',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('privatemsg_list', 'sent'),
+    'access callback'  => 'privatemsg_user_access',
+    'type'             => MENU_LOCAL_TASK,
+    'weight'           => -10,
+  );
   return $items;
 }
 
@@ -267,7 +291,7 @@ function privatemsg_filter_dropdown(&$fo
 
   $form['filter']['author'] = array(
       '#type' => 'select',
-      '#title' => t('Authors'),
+      '#title' => t('Users'),
       '#options' => privatemsg_filter_get_author_data($account),
       '#multiple' => TRUE,
       '#size' => 5,
@@ -348,14 +372,14 @@ function privatemsg_filter_dropdown_subm
       $_SESSION['privatemsg_filter'] = $filter;
       break;
     case t('Filter'):
-      drupal_goto('messages', privatemsg_filter_create_get_query($form_state['values']));
+      drupal_goto($_GET['q'], privatemsg_filter_create_get_query($form_state['values']));
       return;
       break;
     case t('Reset'):
       $_SESSION['privatemsg_filter'] = array();
       break;
   }
-  $form_state['redirect'] = 'messages';
+  $form_state['redirect'] = $_GET['q'];
 }
 
 function privatemsg_filter_create_get_query($filter)
@@ -416,12 +440,24 @@ function privatemsg_filter_form_privatem
 /**
  * Hook into the query builder to add the tagging info to the correct query
  */
-function privatemsg_filter_privatemsg_sql_list_alter(&$fragments, $account) {
+function privatemsg_filter_privatemsg_sql_list_alter(&$fragments, $account, $argument) {
+
+  // Check if its a filtered view.
+  if ($argument == 'sent') {
+    $fragments['where'][]       = "pm.author = %d";
+    $fragments['query_args'][]   = $account->uid;
+  }
+  if ($argument == 'inbox') {
+    $fragments['select'][]      = '(SELECT pmf.author FROM {pm_message} pmf WHERE pmf.mid = pmi.thread_id) AS first_author';
+    $fragments['having'][]       = '(first_author = %d AND COUNT(pmi.thread_id) > 1) OR first_author <> %d';
+    $fragments['query_args'][]   = $account->uid;
+    $fragments['query_args'][]   = $account->uid;
+  }
+
   // Filter the message listing by any set tags.
   if ($filter = privatemsg_filter_get_filter($account)) {
-
+    $count = 0;
     if (isset($filter['tags']) && !empty($filter['tags'])) {
-      $count = 0;
       foreach ($filter['tags'] as $tag) {
         $fragments['inner_join'][]  = "INNER JOIN {pm_tags_index} pmti$count ON (pmti$count.thread_id = pmi.thread_id AND pmti$count.uid = pmi.uid)";
         $fragments['where'][]       = "pmti$count.tag_id = %d";
@@ -431,10 +467,9 @@ function privatemsg_filter_privatemsg_sq
     }
 
     if (isset($filter['author']) && !empty($filter['author'])) {
-      $count = 0;
       foreach ($filter['author'] as $author) {
-        $fragments['inner_join'][]  = "INNER JOIN {users} u$count ON (u$count.uid = pm.author)";
-        $fragments['where'][]       = "u$count.uid = %d";
+        $fragments['inner_join'][]  = "INNER JOIN {pm_index} pmi$count ON (pmi$count.mid = pm.mid)";
+        $fragments['where'][]       = "pmi$count.uid = %d";
         $fragments['query_args'][]   = $author;
         $count++;
       }
