diff --git a/js/views_bulk_operations.css b/js/views_bulk_operations.css
index 9d18a40..5d07794 100644
--- a/js/views_bulk_operations.css
+++ b/js/views_bulk_operations.css
@@ -1,35 +1,34 @@
-
-/*
-** definitions for bulk operation views
-*/
-
-/* Float operation selection element */
-#views-bulk-operations-select {
-}
-
-/* Put some margins on the Execute button */
 #views-bulk-operations-dropdown {
   float: left;
   padding: 3px;
 }
 
-/* Put some margins on the Execute button */
 #views-bulk-operations-submit {
   padding: 14px 0px 0px 0px;
 }
 
-/* Style the admin operations link */
 #views-bulk-operations-admin {
   clear:both;
 }
 
-/* Clear the node selector dropdown */
 .views-node-selector {
   clear: both;
 }
 
-/* Select All row */
-.view-field-select-all {
+.views-field-select-all {
   text-align: center;
+}
+
+.views-field-select-all span.select {
   display: none;
 }
+
+.views-field-select-all span.select label {
+  display: inline;
+  font-weight: normal;
+}
+
+.views-field-select-all span.count {
+  font-weight: bold;
+}
+
diff --git a/js/views_bulk_operations.js b/js/views_bulk_operations.js
index c43870f..dc6604d 100644
--- a/js/views_bulk_operations.js
+++ b/js/views_bulk_operations.js
@@ -15,58 +15,108 @@ Drupal.behaviors.vbo = function(context) {
     .each(Drupal.vbo.prepareSelectors);
 }
 
-Drupal.vbo.selectionModes = {
-  all: 1,
-  allPages: 2,
-  none: 3
-}
-
 Drupal.vbo.prepareSelectors = function() {
   var $form = $(this);
   var form_id = $form.attr('id');
+  var $table = $('table.views-table', $form);
 
-  $('select.views-bulk-operations-selector', $form).change(function() {
-    if (this.options[this.selectedIndex].value == Drupal.vbo.selectionModes.all || this.options[this.selectedIndex].value == Drupal.vbo.selectionModes.allPages) {
-      var selection = {};
-      $('input:checkbox.vbo-select', $form).each(function() {
-        this.checked = true;
-        $(this).parents('tr:first').addClass('selected');
-        selection[this.value] = 1;
-      });
-      selection['selectall'] = this.options[this.selectedIndex].value == Drupal.vbo.selectionModes.allPages ? 1 : 0;
-      $('input#edit-objects-selectall', $form).val(selection['selectall']);
+  // Adjust selection and update server.
+  var updateSelection = function(selectall, selection) {
+    selection = selection || {};
+    selection.selectall = Number(selectall);
 
-      if (Drupal.settings.vbo[form_id].options.preserve_selection) {
-        $.post(Drupal.settings.vbo[form_id].ajax_select, {view_name: Drupal.settings.vbo[form_id].view_name, view_id: Drupal.settings.vbo[form_id].view_id, selection: JSON.stringify(selection)});
-      }
-    }
-    else if (this.options[this.selectedIndex].value == Drupal.vbo.selectionModes.none) {
-      $('input:checkbox.vbo-select', $form).each(function() {
-        this.checked = false;
-        $(this).parents('tr:first').removeClass('selected');
-      });
-      $('input#edit-objects-selectall', $form).val(0);
+    // Adjust form value.
+    $('input#edit-objects-selectall', $form).val(Number(selectall > 0));
 
-      if (Drupal.settings.vbo[form_id].options.preserve_selection) {
-        $.post(Drupal.settings.vbo[form_id].ajax_select, {view_name: Drupal.settings.vbo[form_id].view_name, view_id: Drupal.settings.vbo[form_id].view_id, selection: JSON.stringify({'selectall': -1})});
+    // Adjust UI.
+    $('.views-field-select-all input:radio#' + (selectall > 0 ? 'select-all-pages' : 'select-this-page'), $form).attr('checked', 'checked');
+    $('.views-field-select-all span.select', $form)[$('th.select-all input:checkbox', $table).is(':checked') ? 'show' : 'hide']();
+
+    // Update selection on server.
+    if (Drupal.settings.vbo[form_id].options.preserve_selection) {
+      $.post(
+        Drupal.settings.vbo[form_id].ajax_select,
+        {
+          view_name: Drupal.settings.vbo[form_id].view_name,
+          view_id: Drupal.settings.vbo[form_id].view_id,
+          selection: JSON.stringify(selection)
+        },
+        function(data) {
+          var count = data.selectall ? Drupal.settings.vbo[form_id].total_rows - data.unselected : data.selected;
+          $('.views-field-select-all span.count', $form).text(count);
+        },
+        'json'
+      );
+    }
+    else {
+      // Adjust item count for local page.
+      var count;
+      switch (Number(selectall)) {
+        case -1:
+          count = 0;
+          break;
+        case 0:
+          count = $checkboxes.filter(':checked').length;
+          break;
+        case 1:
+          count = Drupal.settings.vbo[form_id].total_rows - $checkboxes.filter(':not(:checked)').length;
+          break;
+        default:
+          console.log('[vbo] Unknown value ' + selectall + ' when refreshing item count.');
+          break;
       }
+      $('.views-field-select-all span.count', $form).text(count);
     }
+  }
+
+  // Handle select-all checkbox.
+  $('th.select-all', $table).click(function() {
+    var selection = {};
+    var checked = $('input:checkbox', this).attr('checked');
+    $('input:checkbox.select', $form).each(function() {
+      selection[this.value] = checked;
+    });
+    setTimeout(function() {
+      updateSelection(false, selection);
+    }, 1);
   });
 
+  // Handle select-all-pages button.
+  $('.views-field-select-all span.select input:radio', $form).click(function() {
+    updateSelection($(this).val());
+  });
+
+  // Handle clear-selection button.
+  $('.views-field-select-all input#clear-selection', $form).click(function() {
+    $('th.select-all input:checkbox', $table).attr('checked', false);
+    $('input:checkbox.select', $form).attr('checked', false).each(function() {
+      $(this).parents('tr:first').removeClass('selected');
+    });
+    updateSelection(-1); // reset selection
+  });
+
+  // Save the operation value.
   $('#views-bulk-operations-dropdown select', $form).change(function() {
     if (Drupal.settings.vbo[form_id].options.preserve_selection) {
-      $.post(Drupal.settings.vbo[form_id].ajax_select, {view_name: Drupal.settings.vbo[form_id].view_name, view_id: Drupal.settings.vbo[form_id].view_id, selection: JSON.stringify({'operation': this.options[this.selectedIndex].value})});
+      $.post(
+        Drupal.settings.vbo[form_id].ajax_select,
+        {
+          view_name: Drupal.settings.vbo[form_id].view_name,
+          view_id: Drupal.settings.vbo[form_id].view_id,
+          selection: JSON.stringify({'operation': this.options[this.selectedIndex].value})
+        }
+      );
     }
   });
 
-  $(':checkbox.vbo-select', $form).click(function() {
-    var selection = {};
-    selection[this.value] = this.checked ? 1 : 0;
+  // Save the selected items.
+  var $checkboxes = $('input:checkbox.select', $form).click(function() {
     $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected');
-
-    if (Drupal.settings.vbo[form_id].options.preserve_selection) {
-      $.post(Drupal.settings.vbo[form_id].ajax_select, {view_name: Drupal.settings.vbo[form_id].view_name, view_id: Drupal.settings.vbo[form_id].view_id, selection: JSON.stringify(selection)});
-    }
+    var selection = {};
+    selection[this.value] = this.checked;
+    setTimeout(function() { // setTimeout is used to ensure that whatever events are queued to be executed will get executed before this code.
+      updateSelection($('input#edit-objects-selectall', $form).val(), selection);
+    }, 1);
   }).each(function() {
     $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected');
   });
@@ -74,7 +124,7 @@ Drupal.vbo.prepareSelectors = function() {
   // Set up the ability to click anywhere on the row to select it.
   $('tr.rowclick', $form).click(function(event) {
     if (event.target.nodeName.toLowerCase() != 'input' && event.target.nodeName.toLowerCase() != 'a') {
-      $(':checkbox.vbo-select', this).each(function() {
+      $('input:checkbox.select', this).each(function() {
         var checked = this.checked;
         // trigger() toggles the checkmark *after* the event is set,
         // whereas manually clicking the checkbox toggles it *beforehand*.
@@ -87,6 +137,14 @@ Drupal.vbo.prepareSelectors = function() {
       });
     }
   });
+
+  // Set up UI based on initial values.
+  setTimeout(function() { // setTimeout is used to ensure that whatever events are queued to be executed will get executed before this code.
+    if ($checkboxes.length == $checkboxes.filter(':checked').length) {
+      $('th.select-all input:checkbox', $table).attr('checked', true);
+      $('.views-field-select-all span.select', $form).show();
+    }
+  }, 1);
 }
 
 Drupal.vbo.prepareAction = function() {
diff --git a/views-bulk-operations-table.tpl.php b/views-bulk-operations-table.tpl.php
deleted file mode 100644
index 6eaa8bd..0000000
--- a/views-bulk-operations-table.tpl.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * @file views-bulk-operations-table.tpl.php
- * Template to display a VBO as a table.
- *
- * - $title : The title of this group of rows.  May be empty.
- * - $header: An array of header labels keyed by field id.
- * - $fields: An array of CSS IDs to use for each field id.
- * - $class: A class or classes to apply to the table, based on settings.
- * - $row_classes: An array of classes to apply to each row, indexed by row
- *   number. This matches the index in $rows.
- * - $rows: An array of row items. Each row is an array of content.
- *   $rows are keyed by row number, fields within rows are keyed by field ID.
- * @ingroup views_templates
- */
-?>
-<table class="<?php print $class; ?>">
-   <?php if (!empty($title)) : ?>
-     <caption><?php print $title; ?></caption>
-   <?php endif; ?>
-  <thead>
-    <tr>
-      <?php foreach ($header as $key => $value): ?>
-        <?php if ($key == 'select') { ?>
-          <th class="select"><?php print $value ?></th>
-        <?php } else { ?>
-          <th class="views-field views-field-<?php print $fields[$key] ?>"><?php print $value ?></th>
-        <?php } ?>
-      <?php endforeach; ?>
-    </tr>
-  </thead>
-  <tbody>
-    <?php foreach ($rows as $count => $row): ?>
-      <tr class="<?php print implode(' ', $row_classes[$count]); ?>">
-        <?php foreach ($row as $field => $content): ?>
-          <?php if ($field == 'select') { ?>
-            <td class="views-field select">
-          <?php } else { ?>
-            <td class="views-field <?php if (!empty($fields[$field])) print "views-field-{$fields[$field]}"; ?>">
-          <?php } ?>
-              <?php print $content; ?>
-            </td>
-        <?php endforeach; ?>
-      </tr>
-    <?php endforeach; ?>
-  </tbody>
-</table>
diff --git a/views_bulk_operations.module b/views_bulk_operations.module
index 534e628..1568ce1 100644
--- a/views_bulk_operations.module
+++ b/views_bulk_operations.module
@@ -191,11 +191,6 @@ define('VBO_ACCESS_OP_UPDATE',    0x02);
 define('VBO_ACCESS_OP_CREATE',    0x04);
 define('VBO_ACCESS_OP_DELETE',    0x08);
 
-// Item selectors.
-define('VBO_SELECTOR_ALL',        1);
-define('VBO_SELECTOR_ALL_PAGES',  2);
-define('VBO_SELECTOR_NONE',       3);
-
 /**
  * Implementation of hook_cron_queue_info().
  */
@@ -255,27 +250,13 @@ function views_node_selector_process($element, $edit) {
   $element['selection'] = array(
     '#options' => $options,
     '#value' => $element['#default_value']['selection'],
-    '#attributes' => array('class' => 'vbo-select'),
+    '#attributes' => array('class' => 'select'),
   );
   $element['selection'] = expand_checkboxes($element['selection']);
   $element['selectall'] = array(
     '#type' => 'hidden',
     '#default_value' => $element['#default_value']['selectall']
   );
-
-  // Create selector FAPI element.
-  $options = array(
-    0 => t('Select...'),
-    VBO_SELECTOR_ALL => t('All (this page)'),
-    VBO_SELECTOR_ALL_PAGES => t('All (all pages)'),
-    VBO_SELECTOR_NONE => t('None'),
-  );
-  $element['selector'] = array(
-    '#type' => 'select',
-    '#options' => $options,
-    '#attributes' => array('class' => 'views-bulk-operations-selector'),
-    '#default_value' => $element['#default_value']['selectall'] ? VBO_SELECTOR_ALL_PAGES : 0,
-  );
   return $element;
 }
 
@@ -290,9 +271,8 @@ function views_bulk_operations_theme() {
     'views_bulk_operations_confirmation' => array(
       'arguments' => array('objects' => NULL, 'invert' => FALSE, 'view' => NULL),
     ),
-    'views_bulk_operations_table' => array(
-      'arguments' => array('header' => array(), 'rows' => array(), 'attributes' => array(), 'title' => NULL, 'view' => NULL),
-      'template' => 'views-bulk-operations-table',
+    'views_bulk_operations_select_all_row' => array(
+      'arguments' => array('view' => NULL, 'colspan' => 0, 'selection' => 0),
     ),
   );
   foreach (_views_bulk_operations_load_actions() as $file) {
@@ -305,45 +285,6 @@ function views_bulk_operations_theme() {
 }
 
 /**
- * Template preprocessor for theme function 'views_bulk_operations_table'.
- */
-function template_preprocess_views_bulk_operations_table(&$vars, $hook) {
-  $view = $vars['view'];
-
-  $options  = $view->style_plugin->options;
-  $handler  = $view->style_plugin;
-
-  $fields   = &$view->field;
-  $columns  = $handler->sanitize_columns($options['columns'], $fields);
-
-  $active   = !empty($handler->active) ? $handler->active : '';
-
-  foreach ($columns as $field => $column) {
-    $vars['fields'][$field] = views_css_safe($field);
-    if ($active == $field) {
-      $vars['fields'][$field] .= ' active';
-    }
-  }
-
-  $count = 0;
-  foreach ($vars['rows'] as $num => $row) {
-    $vars['row_classes'][$num][] = ($count++ % 2 == 0) ? 'odd rowclick' : 'even rowclick';
-  }
-
-  $vars['row_classes'][0][] = 'views-row-first';
-  $vars['row_classes'][count($vars['row_classes']) - 1][] = 'views-row-last';
-
-  $vars['class'] = 'views-bulk-operations-table';
-  if ($view->style_plugin->options['sticky']) {
-    drupal_add_js('misc/tableheader.js');
-    $vars['class'] .= ' sticky-enabled';
-  }
-  $vars['class'] .= ' cols-'. count($vars['rows']);
-  $vars['class'] .= ' views-table';
-}
-
-
-/**
  * Theme function for views_node_selector element.
  */
 function theme_views_node_selector($element) {
@@ -378,31 +319,61 @@ function theme_views_node_selector($element) {
     }
 
     // Add checkboxes to the header and the rows.
+    $rows = array();
     if (empty($view->style_plugin->options['hide_selector'])) {
-      $headers['select'] = theme('select', $element['selector']);
+      $headers[] = theme('table_select_header_cell');
+
+      // Add extra status row if needed.
+      $items_per_page = method_exists($view, 'get_items_per_page') ? $view->get_items_per_page() : (isset($view->pager) ? $view->pager['items_per_page'] : 0);
+      if ($items_per_page && $view->total_rows > $items_per_page) {
+        $row = theme('views_bulk_operations_select_all_row', $view, count($vars['header']) + 1, _views_bulk_operations_get_selection_count($view->style_plugin, $element['#default_value']));
+        $rows[] = $row;
+      }
     }
     else {
-      $headers['select'] = '';
+      $headers[] = array('class' => 'no-select-all');
     }
     foreach ($vars['header'] as $field => $label) {
-      $headers[$field] = $label;
+      $headers[] = array('data' => $label, 'class' => "views-field views-field-{$vars['fields'][$field]}");
     }
-    $rows = array();
     foreach ($records as $num => $object) {
-      $row['select'] =  theme('checkbox', $element['selection'][_views_bulk_operations_hash_object($object)]);
+      $row = array('class' => 'rowclick', 'data' => array());
+      $row['data'][] =  theme('checkbox', $element['selection'][_views_bulk_operations_hash_object($object)]);
       foreach ($vars['rows'][$num] as $field => $content) {
-        $row[$field] = $content;
+        $row['data'][] = array('data' => $content, 'class' => "views-field views-field-{$vars['fields'][$field]}");
       }
       $rows[] = $row;
     }
 
-    $output .= theme('views_bulk_operations_table', $headers, $rows, array('class' => $vars['class']), $title, $view);
+    $output .= theme('table', $headers, $rows, array('class' => $vars['class']), $title);
     $output .= theme('hidden', $element['selectall']);
   }
   return theme('form_element', $element, $output);
 }
 
 /**
+ * Theme function for 'views_bulk_operations_select_all_row'.
+ */
+function theme_views_bulk_operations_select_all_row($view, $colspan, $selection) {
+  $clear_selection = t('Clear selection');
+  $select_label = t('Select all items:');
+  $this_page = t('on this page only');
+  $all_pages = t('across all pages');
+  $this_page_checked = $selection['selectall'] ? '' : ' checked';
+  $all_pages_checked = $selection['selectall'] ? ' checked' : '';
+  $output = <<<EOF
+<span class="count">{$selection['selected']}</span> items selected.
+<span class="select">
+$select_label
+<input type="radio" name="select-all" id="select-this-page" value="0"$this_page_checked><label for="select-this-page">$this_page</label>
+<input type="radio" name="select-all" id="select-all-pages" value="1"$all_pages_checked><label for="select-all-pages">$all_pages</label>
+</span>
+<input type="button" id="clear-selection" value="$clear_selection">
+EOF;
+  return array(array('data' => $output, 'class' => 'views-field views-field-select-all', 'colspan' => $colspan));
+}
+
+/**
  * Form implementation for main VBO multistep form.
  */
 function views_bulk_operations_form($form_state, $form_id, $plugin) {
@@ -558,7 +529,7 @@ function views_bulk_operations_form($form_state, $form_id, $plugin) {
       $form += _views_bulk_operations_action_form(
         $operation,
         $plugin->view,
-        _views_bulk_operations_get_selection_objects($plugin, $form_state),
+        _views_bulk_operations_get_selection_full($plugin, $form_state),
         $operation['options']['settings']
       );
       $form['execute'] = array(
@@ -707,7 +678,7 @@ function views_bulk_operations_form_submit($form, &$form_state) {
   unset($_SESSION['vbo_values'][$view->name]);
 
   // Execute the VBO.
-  $objects = _views_bulk_operations_get_selection_objects($plugin, $form_state);
+  $objects = _views_bulk_operations_get_selection_full($plugin, $form_state);
   $operation = $form_state['storage']['operation'];
   $operation_arguments = array();
   if ($operation['configurable']) {
@@ -744,15 +715,16 @@ function _views_bulk_operations_get_selection($plugin, $form_state, $form_id) {
     $result = $_SESSION['vbo_values'][$view_name][$view_id]['result'];
     $selection = $_SESSION['vbo_values'][$view_name][$view_id]['selection'];
   }
-  return $form_state['values']['objects']['selectall'] ?
+  $selection = $form_state['values']['objects']['selectall'] ?
     array_intersect_key($result, array_filter($selection, '_views_bulk_operations_filter_invert')) :
     array_intersect_key($result, array_filter($selection));
+  return $selection;
 }
 
 /**
  * Compute the actual selected objects based on the settings.
  */
-function _views_bulk_operations_get_selection_objects($plugin, $form_state) {
+function _views_bulk_operations_get_selection_full($plugin, $form_state) {
   // Get the objects from the view if selectall was chosen.
   $view = $plugin->view;
   if ($form_state['storage']['selectall']) {
@@ -776,6 +748,23 @@ function _views_bulk_operations_get_selection_objects($plugin, $form_state) {
 }
 
 /**
+ * Compute the actual number of selected items.
+ */
+function _views_bulk_operations_get_selection_count($plugin, $selection) {
+  if ($plugin->options['preserve_selection']) {
+    $view_id = _views_bulk_operations_view_id($plugin->view);
+    $view_name = $plugin->view->name;
+    $selection = $_SESSION['vbo_values'][$view_name][$view_id];
+  }
+  return array(
+    'selectall' => $selection['selectall'],
+    'selected'  => $selection['selectall'] ?
+      $plugin->view->total_rows - count(array_filter($selection['selection'], '_views_bulk_operations_filter_invert')) :
+      count(array_filter($selection['selection']))
+  );
+}
+
+/**
  * Theme function to show the confirmation page before executing the action.
  */
 function theme_views_bulk_operations_confirmation($objects, $invert, $view) {
@@ -1059,20 +1048,20 @@ function views_bulk_operations_select() {
       break;
     case 'selectall':
       $_SESSION['vbo_values'][$view_name][$view_id]['selectall'] = $value > 0;
-      if ($value == -1) {
+      if ($value == -1) { // -1 => reset selection
         $_SESSION['vbo_values'][$view_name][$view_id]['selection'] = array();
       }
       break;
     default:
-      if ($value) {
-        $_SESSION['vbo_values'][$view_name][$view_id]['selection'][$selection] = TRUE;
-      }
-      else {
-        $_SESSION['vbo_values'][$view_name][$view_id]['selection'][$selection] = FALSE;
-      }
+      $_SESSION['vbo_values'][$view_name][$view_id]['selection'][$selection] = $value > 0;
       break;
     }
   }
+  drupal_json(array(
+    'selected'   => count(array_filter($_SESSION['vbo_values'][$view_name][$view_id]['selection'])),
+    'unselected' => count(array_filter($_SESSION['vbo_values'][$view_name][$view_id]['selection'], '_views_bulk_operations_filter_invert')),
+    'selectall'  => $_SESSION['vbo_values'][$view_name][$view_id]['selectall'],
+  ));
   exit;
 }
 
@@ -1142,7 +1131,7 @@ function views_bulk_operations_action_form($context) {
     '#default_value' => @$context['operation_key'],
     '#ahah' => array(
       'path' => 'views-bulk-operations/js/action',
-      'wrapper' => 'vbo-operation-wrapper',
+      'wrapper' => 'operation-wrapper',
       'method' => 'replace',
     ),
   );
@@ -1156,7 +1145,7 @@ function views_bulk_operations_action_form($context) {
   $form['operation_arguments']['wrapper'] = array(
     '#type' => 'markup',
     '#value' => '',
-    '#prefix' => '<div id="vbo-operation-wrapper">',
+    '#prefix' => '<div id="operation-wrapper">',
     '#suffix' => '</div>',
   );
   if (isset($form['#operation']) && $form['#operation']['configurable'] && isset($form['#plugin'])) {
@@ -1267,7 +1256,7 @@ function& views_bulk_operations_action_form_operation(&$form, $form_state) {
     $form['operation_arguments']['wrapper'] = array(
       '#type' => 'markup',
       '#value' => '',
-      '#prefix' => '<div id="vbo-operation-wrapper">',
+      '#prefix' => '<div id="operation-wrapper">',
       '#suffix' => '</div>',
     );
     $form['operation_arguments']['wrapper']['operation_form'] = _views_bulk_operations_action_form(
@@ -1961,6 +1950,7 @@ function _views_bulk_operations_add_js($plugin, $form_dom_id, $form_id) {
       'view_id' => _views_bulk_operations_view_id($plugin->view),
       'options' => $plugin->options,
       'ajax_select' => url('views-bulk-operations/js/select'),
+      'total_rows' => $plugin->view->total_rows,
     ))), 'setting');
     $views[$form_id] = TRUE;
   }
@@ -2017,7 +2007,8 @@ function _views_bulk_operations_view_id($view) {
     }
   }
   $exposed_input = array_filter($exposed_input);
-  return md5(serialize(array($view->name, $view->args, $exposed_input)));
+  $view_id = md5(serialize(array($view->name, $view->args, $exposed_input)));
+  return $view_id;
 }
 
 /**
diff --git a/views_bulk_operations_plugin_style.inc b/views_bulk_operations_plugin_style.inc
index 4e4697c..8786d36 100644
--- a/views_bulk_operations_plugin_style.inc
+++ b/views_bulk_operations_plugin_style.inc
@@ -182,6 +182,9 @@ class views_bulk_operations_plugin_style extends views_plugin_style_table {
         call_user_func($form_function, $form, array('values' => $options['settings']));
       }
     }
+
+    // Reset runtime settings for this view.
+    unset($_SESSION['vbo_values'][$this->view->name]);
   }
 
   /**
