diff --git a/README.txt b/README.txt
index e46e02f..565eee4 100644
--- a/README.txt
+++ b/README.txt
@@ -1,13 +1,7 @@
 
-Views Send allow sending mass mailing using Views Bulk Operations - VBO
-(http://drupal.org/project/views_bulk_operations). The messages are queued in a
-spool table and delivered only on cron. You can control how many messages will
-be send per cron run.
-
-INSTALLATION
-
-Proceed as with all modules in Drupal (see http://drupal.org/node/70151). Views
-Bulk Operations must be enabled before.
+Views Send allow mass mailing using Views.
+The messages are queued in a spool table and delivered only on cron.
+You can control how many messages will be send per cron run.
 
 CONFIGURATION
 
@@ -18,18 +12,17 @@ USAGE
  1. Create a view and add at least one column containing E-mail addresses.
  2. [Optional] Expose Views filters to let the user easily build list of
     recipients using UI.
- 3. Create a "Page" display and set the Style to "Bulk Operations".
- 4. On "Bulk Operations" Style configuration, under "Selected operations",
-    select Send mass mail (views_send_mail_action).
- 5. Save the view, load the page, use exposed filters to build the list, select
-    all or some rows and choose "Send mass mail".
- 6. Fill the message form to configure the E-mail. Use tokens to personalize
+ 3. Add the "Global: Send E-mail" field to your view. This field provides the checkboxes
+    that allow the user to select multiple rows.
+ 4. Save the view, load the page, use exposed filters to build the list, select
+    all or some rows and choose "Send e-mail".
+ 5. Fill the message form to configure the E-mail. Use tokens to personalize
     your E-mail.
- 7. Preview and send the message.
+ 6. Preview and send the message.
 
 DEPENDENCIES & INTEGRATION
 
- * Views Send depends on Views Bulk Operations.
+ * Views Send depends on Views.
  * The module integrates features from:
   o Mime Mail. When Mime Mail module is enabled, the user can choose to send
     rich HTML messages.
diff --git a/views/views_send.views.inc b/views/views_send.views.inc
new file mode 100644
index 0000000..6b05f6c
--- /dev/null
+++ b/views/views_send.views.inc
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Implements hook_views_data_alter().
+ */
+function views_send_views_data_alter(&$data) {
+  $data['views']['views_send'] = array(
+    'title' => t('Send E-mail'),
+    'help' => t('Provide a checkbox to select the row for email sending.'),
+    'field' => array(
+      'handler' => 'views_send_handler_field_selector',
+      'click sortable' => FALSE,
+    ),
+  );
+}
diff --git a/views/views_send_handler_field_selector.inc b/views/views_send_handler_field_selector.inc
new file mode 100644
index 0000000..66cd3a5
--- /dev/null
+++ b/views/views_send_handler_field_selector.inc
@@ -0,0 +1,60 @@
+<?php
+
+/**
+* @file
+* Views field handler. Outputs a checkbox for selecting a row for email sending.
+* Implements the Views Form API.
+*/
+
+class views_send_handler_field_selector extends views_handler_field {
+  /**
+   * If the view is using a table style, provide a
+   * placeholder for a "select all" checkbox.
+   */
+  function label() {
+    if ($this->view->style_plugin instanceof views_plugin_style_table) {
+      return '<!--views-send-select-all-->';
+    }
+    else {
+      return parent::label();
+    }
+  }
+
+  function query() {
+    // Do nothing.
+  }
+
+  function render($values) {
+    return '<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->';
+  }
+
+  /**
+   * The form which replaces the placeholder from render().
+   */
+  function views_form(&$form, &$form_state) {
+    // The view is empty, abort.
+    if (empty($this->view->result)) {
+      return;
+    }
+
+    $form[$this->options['id']] = array(
+      '#tree' => TRUE,
+    );
+    foreach ($this->view->result as $row_index => $row) {
+      $form[$this->options['id']][$row_index] = array(
+        '#type' => 'checkbox',
+        '#default_value' => FALSE,
+        '#attributes' => array('class' => array('views-send-select')),
+      );
+    }
+  }
+
+  function views_form_validate($form, &$form_state) {
+    $field_name = $this->options['id'];
+    $selection = array_filter($form_state['values'][$field_name]);
+
+    if (empty($selection)) {
+      form_set_error($field_name, t('Please select at least one item.'));
+    }
+  }
+}
diff --git a/views_send.css b/views_send.css
index 5fb6624..bc4e808 100644
--- a/views_send.css
+++ b/views_send.css
@@ -1,3 +1,39 @@
+.views-send-select-all-markup {
+  display: none;
+}
+
+/* "Select all" for table styles. */
+.views-send-selection-form thead .form-type-checkbox {
+  margin: 0;
+}
+.views-send-table-select-all {
+  display: none;
+}
+.views-table-row-select-all {
+  display: none;
+}
+.views-table-row-select-all td {
+  text-align: center;
+}
+.views-send-table-select-this-page {
+  margin: 0 !important;
+  padding: 2px 5px !important;
+}
+
+/* Generic "select all" */
+.views-send-fieldset-select-all {
+  text-align: center;
+  width: 210px;
+  padding: 0.6em 0;
+}
+.views-send-fieldset-select-all .form-item {
+  margin-bottom: 0;
+}
+.views-send-fieldset-select-all div {
+  padding: 0 !important;
+  margin: 0 !important;
+}
+
 
 form.views-send-preview label {
   float: left;
@@ -25,4 +61,3 @@ form.views-send-preview .views-send-preview-value {
   height: 80px;
   font-family: monospace;
 }
-
diff --git a/views_send.info b/views_send.info
index a682909..f8f796a 100644
--- a/views_send.info
+++ b/views_send.info
@@ -1,6 +1,8 @@
 name = "Views Send E-mail"
-descripion = "Implements a new action to be used with VBO in order to send E-mails to a list created with Views"
-dependencies[] = views_bulk_operations
+descripion = "Provides a way to send e-mails from a list created with Views"
+dependencies[] = views
 configure = admin/config/system/views_send
 package = Views
 core = 7.x
+
+files[] = views/views_send_handler_field_selector.inc
diff --git a/views_send.js b/views_send.js
new file mode 100644
index 0000000..724ad2e
--- /dev/null
+++ b/views_send.js
@@ -0,0 +1,46 @@
+(function ($) {
+  Drupal.behaviors.vbo = {
+    attach: function(context) {
+      $('.views-send-selection-form', context).each(function() {
+        Drupal.viewsSend.initTableBehaviors(this);
+        Drupal.viewsSend.initGenericBehaviors(this);
+      });
+    }
+  }
+
+  Drupal.viewsSend = Drupal.viewsSend || {};
+  Drupal.viewsSend.initTableBehaviors = function(form) {
+    $('.views-send-table-select-all', form).show();
+    // This is the "select all" checkbox in (each) table header.
+    $('.views-send-table-select-all', form).click(function() {
+      var table = $(this).closest('table')[0];
+      $('input[id^="edit-views-send"]:not(:disabled)', table).attr('checked', this.checked);
+    });
+  }
+
+  Drupal.viewsSend.initGenericBehaviors = function(form) {
+    // Show the "select all" fieldset.
+    $('.views-send-select-all-markup', form).show();
+
+    $('.views-send-select-this-page', form).click(function() {
+      $('input[id^="edit-views-send"]', form).attr('checked', this.checked);
+
+      // Toggle the "select all" checkbox in grouped tables (if any).
+      $('.views-send-table-select-all', form).attr('checked', this.checked);
+    });
+
+    $('.views-send-select', form).click(function() {
+      // If a checkbox was deselected, uncheck any "select all" checkboxes.
+      if (!this.checked) {
+        $('.views-send-select-this-page', form).attr('checked', false);
+
+        var table = $(this).closest('table')[0];
+        if (table) {
+          // Uncheck the "select all" checkbox in the table header.
+          $('.views-send-table-select-all', table).attr('checked', false);
+        }
+      }
+    });
+  }
+
+})(jQuery);
diff --git a/views_send.module b/views_send.module
index 9c0af69..80de21f 100644
--- a/views_send.module
+++ b/views_send.module
@@ -4,7 +4,7 @@
  * @file
  *   The Views Send module.
  *
- * Views Send allow sending mass mailing using Views Bulk Operations module.
+ * Views Send allow mass mailing using Views.
  *
  * @ingroup views_send
  */
@@ -40,32 +40,114 @@ define('VIEWS_SEND_TOKEN_PATTERN', '[views-send-%s]');
  */
 define('VIEWS_SEND_MIMEMAIL', module_exists('mimemail'));
 
-// === Action implementation ===================================================
+/**
+ * Gets the selector field if it exists on the passed-in view.
+ *
+ * @return
+ *  The field object if found. Otherwise, FALSE.
+ */
+function _views_send_get_field($view) {
+  foreach ($view->field as $field_name => $field) {
+    if ($field instanceof views_send_handler_field_selector) {
+      // Add in the view object for convenience.
+      $field->view = $view;
+      return $field;
+    }
+  }
+  return FALSE;
+}
 
 /**
- * Implements hook_action_info().
+ * Implements hook_views_form_substitutions().
  */
-function views_send_action_info() {
+function views_send_views_form_substitutions() {
+  // Views check_plains the column label, so do the same here in order for the
+  // replace operation to succeed.
+  $select_all_placeholder = check_plain('<!--views-send-select-all-->');
+  $select_all = array(
+    '#type' => 'checkbox',
+    '#default_value' => FALSE,
+    '#attributes' => array('class' => array('views-send-table-select-all')),
+  );
   return array(
-    'views_send_mail_action' => array(
-      'type' => 'system',
-      'label' => t('Send mass mail'),
-      'configurable' => TRUE,
-      'permissions' => array('mass mailing with views_send'),
-      'pass rows' => TRUE,
-    ),
+    $select_all_placeholder => drupal_render($select_all),
   );
 }
 
+
 /**
- * Configuration form for views_send_mail action.
+ * Returns the 'select all' div that gets inserted above the view results
+ * for non-table style plugins.
  *
- * @see http://drupal.org/node/172152
+ * The actual insertion is done by JS, matching the degradation behavior
+ * of Drupal core (no JS - no select all).
  */
-function views_send_mail_action_form($context) {
-  $view = $context['view'];
-  $display = $view->name . ':' . $view->current_display;
+function theme_views_send_select_all($variables) {
   $form = array();
+  $form['select_all'] = array(
+    '#type' => 'fieldset',
+    '#attributes' => array('class' => array('views-send-fieldset-select-all')),
+  );
+  $form['select_all']['this_page'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Select all items on this page'),
+    '#default_value' => '',
+    '#attributes' => array('class' => array('views-send-select-this-page')),
+  );
+
+  $output = '<div class="views-send-select-all-markup">';
+  $output .= drupal_render($form);
+  $output .= '</div>';
+
+  return $output;
+}
+
+/**
+ * Implements hook_form_alter().
+ */
+function views_send_form_alter(&$form, &$form_state, $form_id) {
+  if (strpos($form_id, 'views_form_') === 0) {
+    $field = _views_send_get_field($form_state['build_info']['args'][0]);
+  }
+  // This form isn't used by Views Send.
+  if (empty($field)) {
+    return;
+  }
+
+  // Cache the built form to prevent it from being rebuilt prior to validation
+  // and submission, which could lead to data being processed incorrectly,
+  // because the views rows (and thus, the form elements as well) have changed
+  // in the meantime. Matching views issue: http://drupal.org/node/1473276.
+  $form_state['cache'] = TRUE;
+
+  // Add the custom CSS for all steps of the form.
+  $form['#attached']['css'][] = drupal_get_path('module', 'views_send') . '/views_send.css';
+
+  if ($form_state['step'] == 'views_form_views_form') {
+    $form['actions']['submit']['#value'] = t('Send e-mail');
+    $form['actions']['submit']['#submit'] = array('views_send_form_submit');
+    $form['#prefix'] = '<div class="views-send-selection-form">';
+    $form['#suffix'] = '</div>';
+
+    // Add the custom JS for this step of the form.
+    $form['#attached']['js'][] = drupal_get_path('module', 'views_send') . '/views_send.js';
+
+    // Adds the "select all" functionality for non-table style plugins
+    // if the view has results.
+    if (!empty($field->view->result) && !($field->view->style_plugin instanceof views_plugin_style_table)) {
+      $form['select_all_markup'] = array(
+        '#type' => 'markup',
+        '#markup' => theme('views_send_select_all'),
+      );
+    }
+  }
+}
+
+/**
+ * Multistep form callback for the "configure" step.
+ */
+function views_send_config_form($form, &$form_state, $view, $output) {
+  $display = $view->name . ':' . $view->current_display;
   $form['display'] = array(
     '#type' => 'value',
     '#value' => $display,
@@ -94,7 +176,8 @@ function views_send_mail_action_form($context) {
 
   $fields = array();
   foreach ($view->field as $field_name => $field) {
-    if ($field_name == 'views_bulk_operations') {
+    // Ignore Views Form fields.
+    if (property_exists($field, 'views_form_callback') || method_exists($field, 'views_form')) {
       continue;
     }
     if (!empty($field->field_info)) {
@@ -215,17 +298,30 @@ function views_send_mail_action_form($context) {
     '#title' => t('Remember these values next time when you will send mass mail.'),
     '#default_value' => variable_get('views_send_remember_' . $display, TRUE),
   );
+
+  $query = drupal_get_query_parameters($_GET, array('q'));
+  $form['actions'] = array(
+    '#type' => 'container',
+    '#attributes' => array('class' => array('form-actions')),
+    '#weight' => 999,
+  );
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Next'),
+    '#validate' => array('views_send_config_form_validate'),
+    '#submit' => array('views_send_form_submit'),
+    '#suffix' => l(t('Cancel'), $view->get_url(), array('query' => $query)),
+  );
+
   return $form;
 }
 
 /**
- * Validation callback for views_send_mail action configuration form.
- *
- * @see http://drupal.org/node/172152
+ * Validation callback for the "configure" step.
  */
-function views_send_mail_action_validate($form, $form_state) {
+function views_send_config_form_validate($form, &$form_state) {
   $values =& $form_state['values'];
-  $view =& $form_state['build_info']['args'][0];
+  $view = $form_state['build_info']['args'][0];
 
   // Check if sender's e-mail is a valid one.
   if (!valid_email_address(trim($values['views_send_from_mail']))) {
@@ -239,16 +335,9 @@ function views_send_mail_action_validate($form, $form_state) {
   // Check in the column selected as e-mail contain valid e-mail values.
   if (!empty($values['views_send_to_mail'])) {
     $wrong_addresses = 0;
-    if ($form_state['step'] == 'views_form_views_form') {
-      $vbo = _views_bulk_operations_get_field($view);
-      $selection = _views_bulk_operations_get_selection($vbo, $form_state);
-    }
-    else {
-      $selection = $form_state['selection'];
-    }
 
     $to_mail_field = $values["views_send_to_mail"];
-    foreach ($selection as $row_id => $entity_id) {
+    foreach ($form_state['selection'] as $row_id) {
       $email = _views_send_get_from_views_result($view->result[$row_id], $to_mail_field, 'email');
       if (!valid_email_address(trim($email))) {
         $wrong_addresses++;
@@ -261,7 +350,7 @@ function views_send_mail_action_validate($form, $form_state) {
           'e-mail addresses from a total of @total selected. Choose another ' .
           'field to act as recipient\'s e-mail or narrow the selection to ' .
           'a subset containing only valid addresses.',
-            array('@wrong' => $wrong_addresses, '@total' => count($selection))
+            array('@wrong' => $wrong_addresses, '@total' => count($form_state['selection']))
         )
       );
     }
@@ -269,80 +358,177 @@ function views_send_mail_action_validate($form, $form_state) {
 }
 
 /**
- * Action configuration submission callback.
- *
- * @see http://drupal.org/node/172152
+ * Multistep form callback for the "confirm" step.
+ * Allows the user to preview the whole message before sending it.
  */
-function views_send_mail_action_submit($form, &$form_state) {
-  $display = $form['display']['#value'];
-  $values =& $form_state['values'];
-  $return = array(
-    'views_send_tokens' => $values['views_send_tokens'],
-  );
-  foreach ($values as $key => $value) {
-    $key = ($key == 'format') ? 'views_send_message_format' : $key;
-    if (substr($key, 0, 11) == 'views_send_') {
-      if ($values['views_send_remember']) {
-        variable_set($key . '_' . $display, $value);
+function views_send_confirm_form($form, &$form_state, $view, $output) {
+  drupal_set_title(t('Review and confirm the message that is about to be sent'));
+
+  // Values entered in the "config" step.
+  $configuration = $form_state['configuration'];
+
+  // From: parts.
+  $from_mail = trim($configuration['views_send_from_mail']);
+  $from_name = trim($configuration['views_send_from_name']);
+
+  $form['#attributes']['class'] = array('views-send-preview');
+  $form['from'] = array(
+    '#type' => 'item',
+    '#title' => t('From'),
+    '#markup' => '<div class="views-send-preview-value">' .
+      (empty($from_name) ? $from_mail : $from_name . check_plain(' <' . $from_mail . '>')) .
+      '</div>',
+  );
+
+  $recipients = array();
+  foreach ($form_state['selection'] as $row_id) {
+    $email = trim(_views_send_get_from_views_result($view->result[$row_id], $configuration['views_send_to_mail'], 'email'));
+    $name = _views_send_get_from_views_result($view->result[$row_id], $configuration['views_send_to_name']);
+    $recipients[] = check_plain(empty($name) ? $email : $name . ' <' . $email . '>');
+  }
+
+  $form['to'] = array(
+    '#type' => 'item',
+    '#title' => t('To'),
+    '#markup' => '<div id="views-send-preview-to" class="views-send-preview-value">' . implode(', ', $recipients) . '</div>',
+  );
+  $form['subject'] = array(
+    '#type' => 'item',
+    '#title' => t('Subject'),
+    '#markup' => '<div class="views-send-preview-value">' . $configuration['views_send_subject'] . '</div>',
+  );
+  $form['message'] = array(
+    '#type' => 'item',
+    '#title' => t('Message'),
+    '#markup' => '<div id="views-send-preview-message" class="views-send-preview-value">' . $configuration['views_send_message'] . '</div>',
+  );
+
+  $headers = array();
+  foreach (_views_send_headers($configuration['views_send_receipt'], $configuration['views_send_priority'], $configuration['views_send_from_mail'], $configuration['views_send_headers']) as $key => $value) {
+    $headers[] = $key . ': ' . $value;
+  }
+
+  $form['headers'] = array(
+    '#type' => 'item',
+    '#title' => t('Headers'),
+    '#markup' => '<div id="views-send-preview-headers" class="views-send-preview-value">' . implode('<br />', $headers) . '</div>',
+  );
+
+  $query = drupal_get_query_parameters($_GET, array('q'));
+  $form['actions'] = array(
+    '#type' => 'container',
+    '#attributes' => array('class' => array('form-actions')),
+    '#weight' => 999,
+  );
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Next'),
+    '#submit' => array('views_send_form_submit'),
+    '#suffix' => l(t('Cancel'), $view->get_url(), array('query' => $query)),
+  );
+
+  return $form;
+}
+
+/**
+ * Submit handler for all steps of the Views Send multistep form.
+ */
+function views_send_form_submit($form, &$form_state) {
+  $field = _views_send_get_field($form_state['build_info']['args'][0]);
+
+  switch ($form_state['step']) {
+    case 'views_form_views_form':
+      $field_name = $field->options['id'];
+      $selection = array_filter($form_state['values'][$field_name]);
+      $form_state['selection'] = array_keys($selection);
+
+      $form_state['step'] = 'views_send_config_form';
+      $form_state['rebuild'] = TRUE;
+      break;
+
+    case 'views_send_config_form':
+      $display = $form['display']['#value'];
+      foreach ($form_state['values'] as $key => $value) {
+        $key = ($key == 'format') ? 'views_send_message_format' : $key;
+        if (substr($key, 0, 11) == 'views_send_' && $form_state['values']['views_send_remember']) {
+          variable_set($key . '_' . $display, $value);
+        }
       }
-      $return += array($key => $value);
-    }
+      $form_state['configuration'] = $form_state['values'];
+
+      $form_state['step'] = 'views_send_confirm_form';
+      $form_state['rebuild'] = TRUE;
+      break;
+
+    case 'views_send_confirm_form':
+      // Gather the selected views rows.
+      $selected_rows = array();
+      foreach ($form_state['selection'] as $row_id) {
+        $selected_rows[] = $field->view->result[$row_id];
+      }
+
+      // Queue the email for sending.
+      views_send_queue_mail($form_state['configuration'], $selected_rows);
+
+      // Redirect.
+      $query = drupal_get_query_parameters($_GET, array('q'));
+      $form_state['redirect'] = array('path' => $field->view->get_url(), array('query' => $query));
+      break;
   }
-  $form_state['views_send'] = TRUE;
-  return $return;
 }
 
 /**
- * Main action callback.
+ * Assembles the email and queues it for sending.
  *
- * @see http://drupal.org/node/172152
+ * @param $params
+ *   Data entered in the "config" step of the form.
+ * @param $selected_rows
+ *   An array of selected views rows.
  */
-function views_send_mail_action($object, $context) {
+function views_send_queue_mail($params, $selected_rows) {
   global $user;
-  static $access_denied_message_displayed;
+
   if (!user_access('mass mailing with views_send')) {
-    if (!$access_denied_message_displayed) {
-      drupal_set_message(
-        t('No mails sent since you aren\'t allowed to send mass mail with Views. (<a href="@permurl">Edit the permission.</a>)',
-          array('@permurl' => url('admin/people/permissions', array('fragment' => 'module-views_send')))),
-        'error'
-      );
-    }
-    $access_denied_message_displayed = TRUE;
+    drupal_set_message(
+      t('No mails sent since you aren\'t allowed to send mass mail with Views. (<a href="@permurl">Edit the permission.</a>)',
+        array('@permurl' => url('admin/people/permissions', array('fragment' => 'module-views_send')))),
+      'error'
+    );
     return;
   }
 
   // From: parts.
-  $from_mail = trim($context['views_send_from_mail']);
-  $from_name = $context['views_send_from_name'];
-
-  $views_result = array_shift($context['rows']);
-
-  // To: parts.
-  $to_mail = trim(_views_send_get_from_views_result($views_result, $context['views_send_to_mail'], 'email'));
-  $to_name = _views_send_get_from_views_result($views_result, $context['views_send_to_name']);
-
-  $subject = $context['views_send_subject'];
-  $body = $context['views_send_message'];
-
-  $body = check_markup($body, $context['views_send_message_format']);
-
-  // Populate row/context tokens.
-  $token_keys = $token_values = array();
-  foreach ($context['views_send_tokens'] as $field_key => $field_name) {
-    $token_keys[] = sprintf(VIEWS_SEND_TOKEN_PATTERN, $field_name);
-    if (substr($field_key, 0, 6) == 'field_') {
-      $value = $views_result->{'field_' . $field_key};
-      $token_values[] = drupal_render($value[0]['rendered']);
-    }
-    else {
-      $token_values[] = $views_result->{$field_key};
+  $from_mail = trim($params['views_send_from_mail']);
+  $from_name = $params['views_send_from_name'];
+
+  foreach ($selected_rows as $row) {
+    // To: parts.
+    $to_mail = trim(_views_send_get_from_views_result($row, $params['views_send_to_mail'], 'email'));
+    $to_name = _views_send_get_from_views_result($row, $params['views_send_to_name']);
+
+    $subject = $params['views_send_subject'];
+    $body = $params['views_send_message'];
+
+    $body = check_markup($body, $params['format']);
+
+    // Populate row/context tokens.
+    $token_keys = $token_values = array();
+    foreach ($params['views_send_tokens'] as $field_key => $field_name) {
+      $token_keys[] = sprintf(VIEWS_SEND_TOKEN_PATTERN, $field_name);
+      if (substr($field_key, 0, 6) == 'field_') {
+        $value = $row->{'field_' . $field_key};
+        $token_values[] = drupal_render($value[0]['rendered']);
+      }
+      else {
+        $token_values[] = $row->{$field_key};
+      }
     }
   }
+
   $subject = str_replace($token_keys, $token_values, $subject);
   $body = str_replace($token_keys, $token_values, $body);
 
-  if (($context['views_send_message_format'] == 'php_code') && _views_send_allow_php()) {
+  if (($params['format'] == 'php_code') && _views_send_allow_php()) {
     $body = php_eval($body);
   }
 
@@ -350,7 +536,7 @@ function views_send_mail_action($object, $context) {
     $body = drupal_html_to_text($body);
   }
 
-  if ($context['views_send_message_format'] == VIEWS_SEND_FORMAT_PLAIN) {
+  if ($params['format'] == VIEWS_SEND_FORMAT_PLAIN) {
     $plain_format = TRUE;
   }
   else {
@@ -359,7 +545,7 @@ function views_send_mail_action($object, $context) {
 
   // We transform receipt, priority in headers,
   // merging them to the user defined headers.
-  $headers = _views_send_headers($context['views_send_receipt'], $context['views_send_priority'], $from_mail, $context['views_send_headers']);
+  $headers = _views_send_headers($params['views_send_receipt'], $params['views_send_priority'], $from_mail, $params['views_send_headers']);
 
   // All tokens replacements, PHP processing and formatting were done.
   // We are performing now all usual mail processing, altering and preparing.
@@ -379,7 +565,7 @@ function views_send_mail_action($object, $context) {
   );
   db_insert('views_send_spool')->fields($fields)->execute();
 
-  if (($context['progress']['current'] == $context['progress']['total']) && $context['views_send_carbon_copy'] == 1) {
+  if ($params['views_send_carbon_copy'] == 1) {
     $fields['to_name'] = $from_name;
     $fields['to_mail'] = $from_mail;
     db_insert('views_send_spool')->fields($fields)->execute();
@@ -426,6 +612,9 @@ function views_send_permission() {
  */
 function views_send_theme($existing, $type, $theme, $path) {
   return array(
+    'views_send_select_all' => array(
+      'variables' => array(),
+    ),
     'views_send_token_help' => array(
       'arguments' => array('tokens' => array()),
     ),
@@ -433,74 +622,13 @@ function views_send_theme($existing, $type, $theme, $path) {
 }
 
 /**
- * Implements hook_form_alter().
- *
- * We want to alter the confirmation form, just before processing the action,
- * so the the user can preview the whole message before sending it.
+ * Implements hook_views_api().
  */
-function views_send_form_alter(&$form, &$form_state, $form_id) {
-  if (empty($form_state['step']) || ($form_state['step'] != 'views_bulk_operations_confirm_form')) {
-      return;
-  }
-  if ($form_state['operation']->operationId == 'action::views_send_mail_action') {
-    drupal_set_title(t('Review and confirm the message that is about to be sent'));
-    drupal_add_css(drupal_get_path('module', 'views_send') . '/views_send.css');
-
-    $args =& $form_state['operation']->formOptions;
-
-    // Drop the confirmation form selection message.
-    unset($form['description']);
-
-    // From: parts.
-    $from_mail = trim($args['views_send_from_mail']);
-    $from_name = trim($args['views_send_from_name']);
-
-    $form['#attributes']['class'] .= ' views-send-preview';
-    $form['from'] = array(
-      '#type' => 'item',
-      '#title' => t('From'),
-      '#markup' => '<div class="views-send-preview-value">' .
-        (empty($from_name) ? $from_mail : $from_name . check_plain(' <' . $from_mail . '>')) .
-        '</div>',
-    );
-
-    $recipients = array();
-    $view =& $form_state['build_info']['args'][0];
-    foreach ($form_state['selection'] as $row_id => $selection) {
-      $email = trim(_views_send_get_from_views_result($view->result[$row_id], $args['views_send_to_mail'], 'email'));
-      $name = _views_send_get_from_views_result($view->result[$row_id], $args['views_send_to_name']);
-      $recipients[] = check_plain(empty($name) ? $email : $name . ' <' . $email . '>');
-    }
-
-    $form['to'] = array(
-      '#type' => 'item',
-      '#title' => t('To'),
-      '#markup' => '<div id="views-send-preview-to" class="views-send-preview-value">' . implode(', ', $recipients) . '</div>',
-    );
-    $form['subject'] = array(
-      '#type' => 'item',
-      '#title' => t('Subject'),
-      '#markup' => '<div class="views-send-preview-value">' . $args['views_send_subject'] . '</div>',
-    );
-    $form['message'] = array(
-      '#type' => 'item',
-      '#title' => t('Message'),
-      '#markup' => '<div id="views-send-preview-message" class="views-send-preview-value">' . $args['views_send_message'] . '</div>',
-    );
-
-    $headers = array();
-    foreach (_views_send_headers($args['views_send_receipt'], $args['views_send_priority'], $args['views_send_from_mail'], $args['views_send_headers']) as $key => $value) {
-      $headers[] = $key . ': ' . $value;
-    }
-
-    $form['headers'] = array(
-      '#type' => 'item',
-      '#title' => t('Headers'),
-      '#markup' => '<div id="views-send-preview-headers" class="views-send-preview-value">' . implode('<br />', $headers) . '</div>',
-    );
-
-    $form['actions']['#weight'] = 100;
-  }
+function views_send_views_api() {
+  return array(
+    'api' => 3,
+    'path' => drupal_get_path('module', 'views_send') . '/views',
+  );
 }
 
 /**
