diff -urp privatemsg/privatemsg.install privatemsg_upgrade/privatemsg.install
--- privatemsg/privatemsg.install	2008-07-27 02:42:01.000000000 +0100
+++ privatemsg_upgrade/privatemsg.install	2008-09-26 01:35:17.405000000 +0100
@@ -17,24 +17,114 @@ function privatemsg_schema() {
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
-      'recipient'     => array(
-        'description'   => t('UID of the recipient'),
+      'uid'     => array(
+        'description'   => t('UID of either the author or the recipient'),
         'type'          => 'int',
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+      'new'     => array(
+        'description'   => t('Whether the user read his message'),
+        'type'          => 'int',
+        'default'       => 1,
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
+      'deleted' => array(
+        'description'   => t('Whether the user has deleted this message'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0
+      ),
+
+    ),
+    'indexes'         => array(
+      '`mid`'               => array('`mid`'),
+      '`thread_id`'         => array('`thread_id`'),
+      '`uid`'         => array('`uid`'),
+      '`new`'              => array('`mid`','`uid`','`new`',),
+    ),
+  );
+  
+  $schema['pm_message'] = array(
+    'description'       => t('{pm_messages} holds the message information'),
+    'fields'        => array(
+      'mid'    => array(
+        'description'   => t('Private Message ID'),
+        'type'          => 'serial',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
       'author'     => array(
         'description'   => t('UID of the author'),
         'type'          => 'int',
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+      'subject'     => array(
+        'description'   => t('Subject text of the message'),
+        'type'          => 'varchar',
+        'length'        => 255,
+        'not null'      => TRUE,
+      ),
+      'body'     => array(
+        'description'   => t('Body of the message'),
+        'type'          => 'text',
+        'not null'      => TRUE,
+        'size'          => 'big',
+      ),
       'timestamp'     => array(
         'description'   => t('Time when the message was sent'),
         'type'          => 'int',
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+    ),
+    'primary key'     => array('mid'),
+    'indexes'         => array(
+      '`author`'            => array('`author`'),
+      '`subject`'           => array(array('`subject`', 20)),
+      '`timestamp`'         => array('`timestamp`'),
+    ),
+  );
+  
+  
+  return $schema;
+}
+function privatemsg_install() {
+  drupal_install_schema('privatemsg');
+  
+}
+
+function privatemsg_uninstall() {
+  drupal_uninstall_schema('privatemsg');
+}
+
+function privatemsg_update_6000() {
+  // Update the database schema and transfer data to new tables.
+  $schema = array();
+  $schema['pm_index'] = array(
+    'description'       => t('{pm_index} holds indexing information about messages and recepients for fast retrieval'),
+    'fields'        => array(
+      'mid'    => array(
+        'description'   => t('Private Message ID'),
+        'type'          => 'int',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
+      'thread_id'     => array(
+        'description'   => t('Messages thread ID'),
+        'type'          => 'int',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
+      'uid'     => array(
+        'description'   => t('UID of either the author or the recipient'),
+        'type'          => 'int',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
       'new'     => array(
         'description'   => t('Whether the user read his message'),
         'type'          => 'int',
@@ -42,14 +132,20 @@ function privatemsg_schema() {
         'not null'      => TRUE,
         'unsigned'      => TRUE,
       ),
+      'deleted' => array(
+        'description'   => t('Whether the user has deleted this message'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0
+      ),
+
     ),
     'indexes'         => array(
       '`mid`'               => array('`mid`'),
-      '`author`'            => array('`author`'),
       '`thread_id`'         => array('`thread_id`'),
-      '`recipient`'         => array('`recipient`'),
-      '`timestamp`'         => array('`timestamp`'),
-      '`new`'              => array('`mid`','`recipient`','`new`',),
+      '`uid`'         => array('`uid`'),
+      '`new`'              => array('`mid`','`uid`','`new`',),
     ),
   );
   
@@ -80,22 +176,50 @@ function privatemsg_schema() {
         'not null'      => TRUE,
         'size'          => 'big',
       ),
+      'timestamp'     => array(
+        'description'   => t('Time when the message was sent'),
+        'type'          => 'int',
+        'not null'      => TRUE,
+        'unsigned'      => TRUE,
+      ),
     ),
     'primary key'     => array('mid'),
     'indexes'         => array(
       '`author`'            => array('`author`'),
       '`subject`'           => array(array('`subject`', 20)),
+      '`timestamp`'         => array('`timestamp`'),
     ),
   );
   
+  $ret = array();
+  db_create_table($ret, 'pm_message', $schema['pm_message']);
+  db_create_table($ret, 'pm_index', $schema['pm_index']);
   
-  return $schema;
-}
-function privatemsg_install() {
-  drupal_install_schema('privatemsg');
-  
-}
+  $data = db_query("SELECT * FROM {privatemsg_archive}");
+  while ($result = db_fetch_array($data)) {
+    if ($result['thread'] == 0) {
+      $result['thread'] = $result['id'];
+    }
+    if ($result['author'] <> $result['recipient']) {
+      $ret = db_query("INSERT INTO {pm_message} (mid, author, subject, body, timestamp) VALUES ( %d, %d, '%s', '%s', %d )", $result['id'], $result['author'], $result['subject'], $result['message'], $result['timestamp']);
+      $ret = db_query("INSERT INTO {pm_index} (mid, thread_id, uid, new, deleted) VALUES ( %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['recipient'], 0, 0);
+    }
+    $ret = db_query("INSERT INTO {pm_index} (mid, thread_id, uid, new, deleted) VALUES ( %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['author'], 0, 0);
+  }
 
-function privatemsg_uninstall() {
-  drupal_uninstall_schema('privatemsg');
+  $data = db_query("SELECT * FROM {privatemsg}");
+  while ($result = db_fetch_array($data)) {
+    if ($result['thread'] == 0) {
+      $result['thread'] = $result['id'];
+    }
+    if ($result['author'] <> $result['recipient']) {
+      $ret = db_query("INSERT INTO {pm_message} (mid, author, subject, body, timestamp) VALUES ( %d, %d, '%s', '%s', %d )", $result['id'], $result['author'], $result['subject'], $result['message'], $result['timestamp']);
+      $ret = db_query("INSERT INTO {pm_index} (mid, thread_id, uid, new, deleted) VALUES ( %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['recipient'], $result['newmsg'], $result['recipient_del']);
+    }
+    $ret = db_query("INSERT INTO {pm_index} (mid, thread_id, uid, new, deleted) VALUES ( %d, %d, %d, %d, %d )", $result['id'], $result['thread'], $result['author'], 0, $result['author_del']);
+  }
+  db_drop_table($ret, 'privatemsg');
+  db_drop_table($ret, 'privatemsg_archive');
+  
+  return $ret;
 }
diff -urp privatemsg/privatemsg.module privatemsg_upgrade/privatemsg.module
--- privatemsg/privatemsg.module	2008-09-20 21:22:20.000000000 +0100
+++ privatemsg_upgrade/privatemsg.module	2008-09-25 23:52:30.821400000 +0100
@@ -251,7 +251,7 @@ function privatemsg_list($uid = NULL) {
 
   $messages = array();
   while ($row = db_fetch_array($result)) {
-    $row['subject'] = l($row['subject'], 'messages/view/'. $row['id']);
+    $row['subject'] = l($row['subject'], 'messages/view/'. $row['thread_id']);
     $messages[] = $row;
   }
 
@@ -262,12 +262,6 @@ function privatemsg_list($uid = NULL) {
       switch ($index) {
         case 'id':
           continue 2;
-        case 'author':
-      	  $col = 'from';
-      	  break;
-        case 'recipient':
-          $col = 'to';
-          break;
         case 'timestamp':
           $col = arg(1) == 'sent' ? 'sent' : 'received';
           break;
@@ -362,7 +356,7 @@ function privatemsg_set_new_status($acco
     global $user;
     $account = $user;
   }
-  $query = "UPDATE {pm_index} pmi SET new = %d WHERE recipient = %d AND new = %d";
+  $query = "UPDATE {pm_index} pmi SET new = %d WHERE uid = %d AND new = %d";
   $arg[] = $new;
   $arg[] = $account->uid;
   $arg[] = ($new == 0) ? 1 : 0;
@@ -604,7 +598,8 @@ function pm_send($form, &$form_state) {
   $args[] = $message['subject'];
   $args[] = $message['author']->uid;
   $args[] = $message['body'];
-  $query = "INSERT INTO {pm_message} (mid, subject, author, body) VALUES (null, '%s', %d, '%s')";
+  $args[] = $message['timestamp'];
+  $query = "INSERT INTO {pm_message} (mid, subject, author, body, timestamp) VALUES (null, '%s', %d, '%s', %d)";
   $resuld = db_query($query, $args);
   $mid = db_last_insert_id('pm_message', 'mid');
   $message['mid'] = $mid;
@@ -615,13 +610,14 @@ function pm_send($form, &$form_state) {
   }
   // 2) Save message to recipients.
   // Each recipient gets a record in the pm_index table.
-  $query = "INSERT INTO {pm_index} (mid, thread_id, recipient, author, timestamp, new) VALUES (%d, %d, %d, %d, %d, 1)";
+  $query = "INSERT INTO {pm_index} (mid, thread_id, uid, new, deleted) VALUES (%d, %d, %d, %d, 0)";
   foreach ($message['recipients'] as $recipient) {
     $mid = $message['mid'];
     $thread_id  = $message['thread_id'];
-    $timestamp = $message['timestamp'];
-    db_query($query, $mid, $thread_id, $recipient->uid, $message['author']->uid , $timestamp);
+    db_query($query, $mid, $thread_id, $recipient->uid, 1);
   }
+  // Also add a record for tha author to the pm_index table - set  column "new" to 0.
+  db_query($query, $mid, $thread_id, $message['author']->uid, 0);
 
   drupal_set_message('A private message has been sent to '. $form_state['values']['recipient']);
 }
@@ -666,33 +662,22 @@ function pm_preview($form, &$form_state)
 function privatemsg_privatemsg_list_sent_alter(&$fragments, $account) {
   $fragments['primary_table'] = '{pm_message} pm';
 
-  $fragments['select'][]      = 'MAX(pm.mid) as id';
   $fragments['select'][]      = 'pmi.thread_id';
   $fragments['select'][]      = 'pm.subject';
-  if ($account->uid != $GLOBALS['user']->uid) {
-    $fragments['select'][] = 'pmi.author';
-  }
-  $fragments['select'][] = 'pmi.recipient';
-  $fragments['select'][] = 'pmi.timestamp';
+  $fragments['select'][]      = 'MAX(pm.timestamp) as timestamp';
   $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
-  $fragments['where'][]       = 'pmi.author = %d';
+  $fragments['where'][]       = 'pm.author = %d';
+  $fragments['where'][]       = 'pmi.deleted = 0';
   $fragments['group_by'][]  = 'pmi.thread_id';
-  $order = 'MAX(pmi.timestamp)';
+  $order = 'timestamp';
   $sort = 'desc';
   if (isset($_GET['order'])) {
     switch ($_GET['order']) {
       case ('subject'):
         $order = 'pm.subject';
         break;
-      case ('from'):
-        $order = 'pmi.author';
-        break;
-      case ('to'):
-        $order = 'pmi.recipient';
-        break;
-      case ('sent'):
       default:
-        $order = 'pmi.timestamp';
+        $order = 'timestamp';
     }
     $sort = isset($_GET['sort']) && ($_GET['sort'] == 'asc' || $_GET['sort'] == 'desc') ? $_GET['sort'] : 'desc';
   }
@@ -703,18 +688,14 @@ function privatemsg_privatemsg_list_sent
 function privatemsg_privatemsg_list_alter(&$fragments, $account) {
   $fragments['primary_table'] = '{pm_message} pm';
 
-  $fragments['select'][]      = 'MAX(pmi.mid) as id';
   $fragments['select'][]      = 'pmi.thread_id';
   $fragments['select'][]      = 'pm.subject';
-  $fragments['select'][]      = 'pmi.author';
-  if ($account->uid != $GLOBALS['user']->uid) {
-    $fragments['select'][] = 'pmi.recipient';
-  }
-  $fragments['select'][] = 'pmi.timestamp';
-  $fragments['select'][] = 'MAX(pmi.new) as new';
+  $fragments['select'][]      = 'MAX(pm.timestamp) as timestamp';
+  $fragments['select'][]      = 'MAX(pmi.new) as new';
   $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
-  $fragments['where'][]       = 'pmi.recipient = %d';
-  $fragments['group_by'][]  = 'pmi.thread_id';
+  $fragments['where'][]       = 'pmi.uid = %d';
+  $fragments['where'][]       = 'pmi.deleted = 0';
+  $fragments['group_by'][]    = 'pmi.thread_id';
   $order = 'pmi.new';
   $sort = 'desc';
   if (isset($_GET['order'])) {
@@ -722,15 +703,8 @@ function privatemsg_privatemsg_list_alte
       case ('subject'):
         $order = 'pm.subject';
         break;
-      case ('from'):
-        $order = 'pmi.author';
-        break;
-      case ('to'):
-        $order = 'pmi.recipient';
-        break;
-      case ('received'):
       default:
-        $order = 'MAX(pmi.timestamp)';
+        $order = 'timestamp';
     }
     $sort = isset($_GET['sort']) && ($_GET['sort'] == 'asc' || $_GET['sort'] == 'desc') ? $_GET['sort'] : 'desc';
   }
@@ -749,8 +723,7 @@ function privatemsg_privatemsg_load_alte
   $fragments['inner_join'][]  = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
   $fragments['where'][]       = 'pmi.mid = %d';
   $fragments['query_args'][]  = $pmid;
-  $fragments['where'][]       = 'pmi.recipient = %d or pmi.author = %d';
-  $fragments['query_args'][]  = $uid;
+  $fragments['where'][]       = 'pmi.uid = %d';
   $fragments['query_args'][]  = $uid;
 }
 
@@ -761,25 +734,18 @@ function privatemsg_privatemsg_messages_
   $fragments['where'][]       = 'pmi.thread_id = %d';
   $fragments['query_args'][]  = $thread_id;
   if (!(user_access('read all private messages'))) {
-    $fragments['where'][]       = 'pmi.author = %d';
-    $fragments['query_args'][]  = $uid;
-    $fragments['union_select'][]      = 'DISTINCT(pmi.mid) as mid';
-    $fragments['union_where'][]       = 'pmi.thread_id = %d';
-    $fragments['union_where'][]       = 'pmi.recipient = %d';
-    $fragments['query_args'][]  = $thread_id;
+    $fragments['where'][]       = 'pmi.uid = %d';
     $fragments['query_args'][]  = $uid;
   }
+  $fragments['where'][]       = 'pmi.deleted = 0';
   $fragments['order_by'][]  = 'mid ASC';
 }
 
 function privatemsg_privatemsg_participants_alter(&$fragments, $thread_id) {
   $fragments['primary_table'] = '{pm_index} pmi';
 
-  $fragments['select'][]      = 'pmi.recipient as uid';
+  $fragments['select'][]      = 'DISTINCT(pmi.uid) as uid';
   $fragments['where'][]       = 'pmi.thread_id = %d';
-  $fragments['union_select'][] = 'pmi.author as uid';
-  $fragments['union_where'][] = 'pmi.thread_id = %d';
-  $fragments['query_args'][]  = $thread_id;
   $fragments['query_args'][]  = $thread_id;
 }
 
@@ -787,9 +753,9 @@ function privatemsg_privatemsg_participa
 function privatemsg_privatemsg_unread_count_alter(&$fragments, $account) {
   $fragments['primary_table'] = '{pm_index} pmi';
 
-  $fragments['select'][]      = 'count(*) as unread_count';
+  $fragments['select'][]      = 'COUNT(DISTINCT thread_id) as unread_count';
   $fragments['where'][]       = 'pmi.new = 1';
-  $fragments['where'][]       = 'pmi.recipient = %d';
+  $fragments['where'][]       = 'pmi.uid = %d';
   $fragments['query_args'][]  = $account->uid;
 }
 
diff -urp privatemsg/privatemsgapi/privatemsgapi.inc privatemsg_upgrade/privatemsgapi/privatemsgapi.inc
--- privatemsg/privatemsgapi/privatemsgapi.inc	2008-09-20 21:22:20.000000000 +0100
+++ privatemsg_upgrade/privatemsgapi/privatemsgapi.inc	2008-09-23 21:53:59.011200000 +0100
@@ -67,9 +67,6 @@ function _privatemsg_assemble_query($que
   $SELECT = array();
   $INNER_JOIN = array();
   $WHERE = array();
-  $UNION_SELECT = array();
-  $UNION_INNER_JOIN = array();
-  $UNION_WHERE = array();
   $GROUP_BY = array();
   $ORDER_BY = array();
   $QUERY_ARGS = array();
@@ -79,9 +76,6 @@ function _privatemsg_assemble_query($que
     'select'      => $SELECT,
     'inner_join'  => $INNER_JOIN,
     'where'       => $WHERE,
-    'union_select'       => $UNION_SELECT,
-    'union_inner_join'  => $UNION_INNER_JOIN,
-    'union_where'       => $UNION_WHERE,
     'group_by'    => $GROUP_BY,
     'order_by'    => $ORDER_BY,
     'query_args'  => $QUERY_ARGS,
@@ -109,9 +103,6 @@ function _privatemsg_assemble_query($que
   $SELECT = $fragments['select'];
   $INNER_JOIN = $fragments['inner_join'];
   $WHERE = $fragments['where'];
-  $UNION_SELECT = $fragments['union_select'];
-  $UNION_INNER_JOIN = $fragments['union_inner_join'];
-  $UNION_WHERE = $fragments['union_where'];
   $GROUP_BY = $fragments['group_by'];
   $ORDER_BY = $fragments['order_by'];
   $QUERY_ARGS = $fragments['query_args'];
@@ -133,18 +124,6 @@ function _privatemsg_assemble_query($que
       $str_where = '('. implode(') AND (', $WHERE) .')';
       $query .= " WHERE {$str_where}";
     }
-    if (!empty($UNION_SELECT)) {
-      $str_union_select = implode(", ", $UNION_SELECT);
-      $query .= "UNION SELECT {$str_union_select} FROM ". $primary_table;
-    }
-    if (!empty($UNION_INNER_JOIN)) {
-      $str_union_inner_join = implode(' ', $UNION_INNER_JOIN);
-      $query .= " {$str_union_inner_join}";
-    }
-    if (!empty($UNION_WHERE)) {
-      $str_union_where = '('. implode(') AND (', $UNION_WHERE) .')';
-      $query .= " WHERE {$str_union_where}";
-    }
     if (!empty($GROUP_BY)) {
       $str_group_by = ' GROUP BY '. implode(", ", $GROUP_BY) ;
       $query .= " {$str_group_by}";
