diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 6c81cfc0f54bcd26c6a1517150aea449f2d476ae..087d150bb105bf05173178b5136e7580d400fd6d 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -32,6 +32,7 @@ Drupal x.x.x, xxxx-xx-xx (development version)
 - user module:
     * added hook_profile_alter().
     * e-mail verification is made optional.
+    * added mass editing on admin/user/user.
 - PHP Template engine:
     * add the ability to look for a series of suggested templates.
     * look for page templates based upon the path.
diff --git a/modules/user/user.module b/modules/user/user.module
index acd22b470f802216d765ca5abcbd38dfcca489f8..8469051b291e9bedc272d2829fa33b3c1a1ecf1e 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -1378,13 +1378,7 @@ function user_edit($category = 'account') {
 
   if (arg(2) == 'delete') {
     if ($edit['confirm']) {
-      db_query('DELETE FROM {users} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {sessions} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {authmap} WHERE uid = %d', $account->uid);
-      watchdog('user', t('Deleted user: %name %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', '<'. $account->mail .'>'))), WATCHDOG_NOTICE);
-      drupal_set_message(t('The account has been deleted.'));
-      module_invoke_all('user', 'delete', $edit, $account);
+      user_delete($edit, $account->uid);
       drupal_goto('admin/user/user');
     }
     else {
@@ -1413,6 +1407,24 @@ function user_edit($category = 'account') {
   return drupal_get_form('user_edit', $form);
 }
 
+/**
+ * Delete a user.
+ *
+ * @param $edit An array of submitted form values.
+ * @param $uid The user ID of the user to delete.
+ */
+function user_delete($edit, $uid) {
+  $account = user_load(array('uid' => $uid));
+  db_query('DELETE FROM {users} WHERE uid = %d', $uid);
+  db_query('DELETE FROM {sessions} WHERE uid = %d', $uid);
+  db_query('DELETE FROM {users_roles} WHERE uid = %d', $uid);
+  db_query('DELETE FROM {authmap} WHERE uid = %d', $uid);
+  $array = array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', '<'. $account->mail .'>'));
+  watchdog('user', t('Deleted user: %name %email.', $array), WATCHDOG_NOTICE);
+  drupal_set_message(t('%name has been deleted.', $array));
+  module_invoke_all('user', 'delete', $edit, $account);
+}
+
 function user_edit_validate($form_id, $form_values) {
   user_module_invoke('validate', $form_values, $form_values['_account'], $form_values['_category']);
   // Validate input to ensure that non-privileged users can't alter protected data.
@@ -1898,31 +1910,248 @@ function theme_user_admin_new_role($form) {
 }
 
 function user_admin_account() {
+  if ($_POST['edit']['accounts'] && $_POST['edit']['operation'] == 'delete') {
+    return user_multiple_delete_confirm();
+  }
+
   $header = array(
+    array(),
     array('data' => t('Username'), 'field' => 'u.name'),
     array('data' => t('Status'), 'field' => 'u.status'),
+    t('Roles'),
     array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
     array('data' => t('Last access'), 'field' => 'u.access'),
     t('Operations')
   );
+
   $sql = 'SELECT u.uid, u.name, u.status, u.created, u.access FROM {users} u WHERE uid != 0';
   $sql .= tablesort_sql($header);
   $result = pager_query($sql, 50);
 
+  $form['options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Update options'),
+    '#prefix' => '<div class="container-inline">',
+    '#suffix' => '</div>',
+  );
+  $options = array();
+  foreach (module_invoke_all('user_operations') as $key => $value) {
+    $options[$key] = $value[0];
+  }
+  $form['options']['operation'] = array(
+    '#type' => 'select',
+    '#options' => $options,
+    '#default_value' => 'unblock',
+  );
+  $form['options']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update'),
+  );
+
+  $destination = drupal_get_destination();
+
   $status = array(t('blocked'), t('active'));
+  $roles = user_roles(1);
+
   while ($account = db_fetch_object($result)) {
-    $rows[] = array(theme('username', $account),
-                    $status[$account->status],
-                    format_interval(time() - $account->created),
-                    $account->access ? t('%time ago', array('%time' => format_interval(time() - $account->access))) : t('never'),
-                    l(t('edit'), "user/$account->uid/edit", array()));
+    $accounts[$account->uid] = '';
+    $form['name'][$account->uid] = array('#value' => theme('username', $account));
+    $form['status'][$account->uid] =  array('#value' => $status[$account->status]);
+    $users_roles = array();
+    $roles_result = db_query('SELECT rid FROM {users_roles} WHERE uid = %d', $account->uid);
+    while ($user_role = db_fetch_object($roles_result)) {
+      $users_roles[] = $roles[$user_role->rid];
+    }
+    asort($users_roles);
+    $form['roles'][$account->uid][0] = array('#value' => theme('item_list', $users_roles));
+    $form['member_for'][$account->uid] = array('#value' => format_interval(time() - $account->created));
+    $form['last_access'][$account->uid] =  array('#value' => $account->access ? t('%time ago', array('%time' => format_interval(time() - $account->access))) : t('never'));
+    $form['operations'][$account->uid] = array('#value' => l(t('edit'), "user/$account->uid/edit", array(), $destination));
+  }
+  $form['accounts'] = array(
+    '#type' => 'checkboxes',
+    '#options' => $accounts
+  );
+  $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
+
+  // Call the form first, to allow for the form_values array to be populated.
+  $output .= drupal_get_form('user_admin_account', $form);
+
+  return $output;
+}
+
+/**
+ * Theme user administration overview.
+ */
+function theme_user_admin_account($form) {
+  // Overview table:
+  $header = array(
+    array(),
+    array('data' => t('Username'), 'field' => 'u.name'),
+    array('data' => t('Status'), 'field' => 'u.status'),
+    t('Roles'),
+    array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
+    array('data' => t('Last access'), 'field' => 'u.access'),
+    t('Operations')
+  );
+
+  $output .= form_render($form['options']);
+  if (isset($form['name']) && is_array($form['name'])) {
+    foreach (element_children($form['name']) as $key) {
+      $rows[] = array(
+        form_render($form['accounts'][$key]),
+        form_render($form['name'][$key]),
+        form_render($form['status'][$key]),
+        form_render($form['roles'][$key]),
+        form_render($form['member_for'][$key]),
+        form_render($form['last_access'][$key]),
+        form_render($form['operations'][$key]),
+      );
+    }
   }
+  else  {
+    $rows[] = array(array('data' => t('No users available.'), 'colspan' => '7'));
+  }
+
+  $output .= theme('table', $header, $rows);
+  if ($form['pager']['#value']) {
+    $output .= form_render($form['pager']);
+  }
+
+  $output .= form_render($form);
 
-  $output = theme('table', $header, $rows);
-  $output .= theme('pager', NULL, 50, 0);
   return $output;
 }
 
+/**
+ * Submit the user administration update form.
+ */
+function user_admin_account_submit($form_id, $edit) {
+  $operations = module_invoke_all('user_operations');
+  $operation = $operations[$edit['operation']];
+  // Filter out unchecked accounts.
+  $accounts = array_filter($edit['accounts']);
+  if ($function = $operation[1]) {
+    call_user_func($function, $accounts);
+    cache_clear_all();
+    drupal_set_message(t('The update has been performed.'));
+  }
+}
+
+function user_admin_account_validate($form_id, $edit) {
+  $edit['accounts'] = array_filter($edit['accounts']);
+  if (count($edit['accounts']) == 0) {
+    form_set_error('', t('No users selected.'));
+  }
+}
+
+/**
+ * Implementation of hook_user_operations().
+ */
+function user_user_operations() {
+  global $form_values;
+
+  $roles = user_roles(1);
+  unset($roles[2]);  // Can't edit authenticated role.
+
+  $add_roles = array();
+  foreach ($roles as $key => $value) {
+    $add_roles['add_role-'. $key] = $value;
+  }
+
+  $remove_roles = array();
+  foreach ($roles as $key => $value) {
+    $remove_roles['remove_role-'. $key] = $value;
+  }
+
+  $operations = array(
+    'unblock' => array(t('Unblock the selected users'), 'user_user_operations_unblock'),
+    'block' => array(t('Block the selected users'), 'user_user_operations_block'),
+    t('Add a role to the selected users') => array($add_roles),
+    t('Remove a role from the selected users') => array($remove_roles),
+    'delete' => array(t('Delete the selected users'), ''),
+  );
+
+  // If the form has been posted, we need to insert the proper data for role editing if necessary.
+  if ($form_values) {
+    $operation = explode('-', $form_values['operation']);
+    if ($operation[0] == 'add_role' || $operation[0] == 'remove_role') {
+      $operations[$form_values['operation']] =  array(NULL, 'user_multiple_role_edit');
+    }
+  }
+
+  return $operations;
+}
+
+/**
+ * Callback function for admin mass unblocking users.
+ */
+function user_user_operations_unblock($accounts) {
+  db_query('UPDATE {users} SET status = 1 WHERE uid IN(%s)', implode(',', $accounts));
+}
+
+/**
+ * Callback function for admin mass blocking users.
+ */
+function user_user_operations_block($accounts) {
+  db_query('UPDATE {users} SET status = 0 WHERE uid IN(%s)', implode(',', $accounts));
+}
+
+/**
+ * Callback function for admin mass adding/deleting a user role.
+ */
+function user_multiple_role_edit($accounts) {
+  global $form_values;
+
+  // Get the operation and role from the posted form.
+  $operation_rid = explode('-', $form_values['operation']);
+  $operation = $operation_rid[0];
+  $rid = $operation_rid[1];
+
+  switch ($operation) {
+    case 'add_role':
+      foreach ($accounts as $uid) {
+        // Skip adding the role to the user if they already have it.
+        if (!db_result(db_query('SELECT uid FROM {users_roles} WHERE uid = %d AND rid = %d', $uid, $rid))) {
+          db_query('INSERT INTO {users_roles} VALUES (%d, %d)', $uid, $rid);
+        }
+      }
+      break;
+    case 'remove_role':
+      foreach ($accounts as $uid) {
+        db_query('DELETE FROM {users_roles} WHERE rid = %d AND uid IN(%s)', $rid, implode(',', $accounts));
+      }
+      break;
+  }
+}
+
+function user_multiple_delete_confirm() {
+  $edit = $_POST['edit'];
+
+  $form['accounts'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
+  // array_filter returns only elements with TRUE values
+  foreach (array_filter($edit['accounts']) as $uid => $value) {
+    $user = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $uid));
+    $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '<li>', '#suffix' => check_plain($user) ."</li>\n");
+  }
+  $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
+
+  return confirm_form('user_multiple_delete_confirm', $form,
+                      t('Are you sure you want to delete these users?'),
+                      'admin/user/user', t('This action cannot be undone.'),
+                      t('Delete all'), t('Cancel'));
+}
+
+function user_multiple_delete_confirm_submit($form_id, $edit) {
+  if ($edit['confirm']) {
+    foreach ($edit['accounts'] as $uid => $value) {
+      user_delete($edit, $uid);
+    }
+    drupal_set_message(t('The users have been deleted.'));
+  }
+  return 'admin/user/user';
+}
+
 function user_admin_settings() {
   // User registration settings.
   $form['registration'] = array('#type' => 'fieldset', '#title' => t('User registration settings'));