diff --git modules/comment/comment.module modules/comment/comment.module
index 8383681..2b0dacf 100644
--- modules/comment/comment.module
+++ modules/comment/comment.module
@@ -1308,16 +1308,18 @@ function comment_user_cancel($edit, $account, $method) {
         ->condition('last_comment_uid', $account->uid)
         ->execute();
       break;
-
-    case 'user_cancel_delete':
-      module_load_include('inc', 'comment', 'comment.admin');
-      $cids = db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
-      comment_delete_multiple($cids);
-      break;
   }
 }
 
 /**
+ * Implements hook_user_delete().
+ */
+function comment_user_delete($account) {
+  $cids = db_query('SELECT c.cid FROM {comment} c WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
+  comment_delete_multiple($cids);
+}
+
+/**
  * This is *not* a hook_access() implementation. This function is called
  * to determine whether the current user has access to a particular comment.
  *
diff --git modules/node/node.module modules/node/node.module
index 9a14364..99a7e2f 100644
--- modules/node/node.module
+++ modules/node/node.module
@@ -1716,27 +1716,30 @@ function node_user_cancel($edit, $account, $method) {
         ->condition('uid', $account->uid)
         ->execute();
       break;
+  }
+}
 
-    case 'user_cancel_delete':
-      // Delete nodes (current revisions).
-      // @todo Introduce node_mass_delete() or make node_mass_update() more flexible.
-      $nodes = db_select('node', 'n')
-        ->fields('n', array('nid'))
-        ->condition('uid', $account->uid)
-        ->execute()
-        ->fetchCol();
-      node_delete_multiple($nodes);
-      // Delete old revisions.
-      $revisions = db_query('SELECT vid FROM {node_revision} WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
-      foreach ($revisions as $revision) {
-        node_revision_delete($revision);
-      }
-      // Clean history.
-      db_delete('history')
-        ->condition('uid', $account->uid)
-          ->execute();
-      break;
+/**
+ * Implements hook_user_delete().
+ */
+function node_user_delete($account) {
+  // Delete nodes (current revisions).
+  // @todo Introduce node_mass_delete() or make node_mass_update() more flexible.
+  $nodes = db_select('node', 'n')
+    ->fields('n', array('nid'))
+    ->condition('uid', $account->uid)
+    ->execute()
+    ->fetchCol();
+  node_delete_multiple($nodes);
+  // Delete old revisions.
+  $revisions = db_query('SELECT vid FROM {node_revision} WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
+  foreach ($revisions as $revision) {
+    node_revision_delete($revision);
   }
+  // Clean history.
+  db_delete('history')
+    ->condition('uid', $account->uid)
+      ->execute();
 }
 
 /**
diff --git modules/poll/poll.module modules/poll/poll.module
index 6c69fb1..19ade02 100644
--- modules/poll/poll.module
+++ modules/poll/poll.module
@@ -923,16 +923,19 @@ function poll_user_cancel($edit, $account, $method) {
         ->condition('uid', $account->uid)
         ->execute();
       break;
-
-    case 'user_cancel_delete':
-      db_delete('poll_vote')
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
   }
 }
 
 /**
+ * Implements hook_user_delete().
+ */
+function poll_user_delete($account) {
+  db_delete('poll_vote')
+    ->condition('uid', $account->uid)
+    ->execute();
+}
+
+/**
  * Implements hook_rdf_mapping().
  */
 function poll_rdf_mapping() {
diff --git modules/profile/profile.module modules/profile/profile.module
index d39549f..3f238ad 100644
--- modules/profile/profile.module
+++ modules/profile/profile.module
@@ -233,15 +233,22 @@ function profile_user_insert(&$edit, $account, $category) {
 function profile_user_cancel(&$edit, $account, $method) {
   switch ($method) {
     case 'user_cancel_reassign':
-    case 'user_cancel_delete':
       db_delete('profile_value')
         ->condition('uid', $account->uid)
         ->execute();
-      break;
   }
 }
 
 /**
+ * Implements hook_user_delete().
+ */
+function profile_user_delete($account) {
+  db_delete('profile_value')
+    ->condition('uid', $account->uid)
+    ->execute();
+}
+
+/**
  * Implements hook_user_load().
  */
 function profile_user_load($users) {
@@ -621,4 +628,3 @@ function _profile_get_fields($category, $register = FALSE) {
     ->orderBy('weight', 'ASC')
     ->execute();
 }
-
diff --git modules/statistics/statistics.module modules/statistics/statistics.module
index 2f149b5..552551e 100644
--- modules/statistics/statistics.module
+++ modules/statistics/statistics.module
@@ -208,16 +208,19 @@ function statistics_user_cancel($edit, $account, $method) {
         ->condition('uid', $account->uid)
         ->execute();
       break;
-
-    case 'user_cancel_delete':
-      db_delete('accesslog')
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
   }
 }
 
 /**
+ * Implements hook_user_delete().
+ */
+function statistics_user_delete($account) {
+  db_delete('accesslog')
+    ->condition('uid', $account->uid)
+    ->execute();
+}
+
+/**
  * Implements hook_cron().
  */
 function statistics_cron() {
diff --git modules/trigger/trigger.module modules/trigger/trigger.module
index 20e5fae..6bf01ad 100644
--- modules/trigger/trigger.module
+++ modules/trigger/trigger.module
@@ -514,13 +514,19 @@ function trigger_user_update(&$edit, $account, $category) {
 function trigger_user_cancel($edit, $account, $method) {
   switch ($method) {
     case 'user_cancel_reassign':
-    case 'user_cancel_delete':
       _trigger_user('user_delete', $edit, $account, $method);
       break;
   }
 }
 
 /**
+ * Implements hook_user_delete().
+ */
+function trigger_user_delete($account) {
+  _trigger_user('user_delete', $edit, $account, $method);
+}
+
+/**
  * Implements hook_user_view().
  */
 function trigger_user_view($account) {
@@ -618,4 +624,3 @@ function _trigger_get_all_info() {
   drupal_alter('trigger_info', $triggers);
   return $triggers;
 }
-
diff --git modules/user/user.api.php modules/user/user.api.php
index 8cea994..2b34ff4 100644
--- modules/user/user.api.php
+++ modules/user/user.api.php
@@ -32,11 +32,29 @@ function hook_user_load($users) {
 }
 
 /**
+ * Respond to user deletion.
+ *
+ * This hook is invoked from user_delete_multiple() after the account has been
+ * removed from the user tables in the database, and before
+ * field_attach_delete() is called.
+ *
+ * @param $account
+ *   The account that is being deleted.
+ *
+ * @see user_delete_multiple()
+ */
+function hook_user_delete($account) {
+  db_delete('mytable')
+    ->condition('uid', $account->uid)
+    ->execute();
+}
+
+/**
  * Act on user account cancellations.
  *
  * The user account is being canceled. Depending on the account cancellation
- * method, the module should either do nothing, unpublish content, anonymize
- * content, or delete content and data belonging to the canceled user account.
+ * method, the module should either do nothing, unpublish content, or anonymize
+ * content.
  *
  * Expensive operations should be added to the global batch with batch_set().
  *
@@ -83,26 +101,6 @@ function hook_user_cancel($edit, $account, $method) {
         ->condition('uid', $account->uid)
         ->execute();
       break;
-
-    case 'user_cancel_delete':
-      // Delete nodes (current revisions).
-      $nodes = db_select('node', 'n')
-        ->fields('n', array('nid'))
-        ->condition('uid', $account->uid)
-        ->execute()
-        ->fetchCol();
-      foreach ($nodes as $nid) {
-        node_delete($nid);
-      }
-      // Delete old revisions.
-      db_delete('node_revision')
-        ->condition('uid', $account->uid)
-        ->execute();
-      // Clean history.
-      db_delete('history')
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
   }
 }
 
diff --git modules/user/user.module modules/user/user.module
index 4484287..6e69f42 100644
--- modules/user/user.module
+++ modules/user/user.module
@@ -2143,8 +2143,11 @@ function user_cancel($edit, $uid, $method) {
   );
   batch_set($batch);
 
-  // Allow modules to add further sets to this batch.
-  module_invoke_all('user_cancel', $edit, $account, $method);
+  // Modules use hook_user_delete() to respond to deletion.
+  if ($method != 'user_cancel_delete') {
+    // Allow modules to add further sets to this batch.
+    module_invoke_all('user_cancel', $edit, $account, $method);
+  }
 
   // Finish the batch and actually cancel the account.
   $batch = array(
@@ -2192,15 +2195,7 @@ function _user_cancel($edit, $account, $method) {
       if (!empty($edit['user_cancel_notify'])) {
         _user_mail_notify('status_canceled', $account);
       }
-      db_delete('users')
-        ->condition('uid', $account->uid)
-        ->execute();
-      db_delete('users_roles')
-        ->condition('uid', $account->uid)
-        ->execute();
-      db_delete('authmap')
-        ->condition('uid', $account->uid)
-        ->execute();
+      user_delete($account->uid);
       drupal_set_message(t('%name has been deleted.', array('%name' => $account->name)));
       watchdog('user', 'Deleted user: %name %email.', array('%name' => $account->name, '%email' => '<' . $account->mail . '>'), WATCHDOG_NOTICE);
       break;
@@ -2220,6 +2215,45 @@ function _user_cancel($edit, $account, $method) {
 }
 
 /**
+ * Delete a user.
+ *
+ * @param $uid
+ *   A user ID.
+ */
+function user_delete($uid) {
+  user_delete_multiple(array($uid));
+}
+
+/**
+ * Delete multiple user accounts.
+ *
+ * @param $uids
+ *   An array of user IDs.
+ */
+function user_delete_multiple(array $uids) {
+  if (!empty($uids)) {
+    $accounts = user_load_multiple($uids, array());
+
+    foreach ($accounts as $uid => $account) {
+      module_invoke_all('user_delete', $account);
+      field_attach_delete('user', $account);
+    }
+
+    db_delete('users')
+      ->condition('uid', $uids, 'IN')
+      ->execute();
+    db_delete('users_roles')
+      ->condition('uid', $uids, 'IN')
+      ->execute();
+    db_delete('authmap')
+      ->condition('uid', $uids, 'IN')
+      ->execute();
+
+    entity_get_controller('user')->resetCache();
+  }
+}
+
+/**
  * Page callback wrapper for user_view().
  */
 function user_view_page($uid) {
