diff --git a/includes/message_notify.exception.inc b/includes/message_notify.exception.inc
new file mode 100644
index 0000000..58fcd19
--- /dev/null
+++ b/includes/message_notify.exception.inc
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @file
+ * Provide a separate Exception so it can be caught separately.
+ */
+
+class MessageNotifyException extends Exception {}
diff --git a/message_notify.info b/message_notify.info
index 2d1d8a0..9755d7e 100644
--- a/message_notify.info
+++ b/message_notify.info
@@ -2,4 +2,7 @@ name = Message notify
 description = "Message notify."
 core = 7.x
 package = Message
-dependencies[] = message
\ No newline at end of file
+dependencies[] = message
+
+files[] = includes/message_notify.exception.inc
+files[] = plugins/notifier/abstract.inc
\ No newline at end of file
diff --git a/message_notify.module b/message_notify.module
index bb84d8d..a4a86d3 100644
--- a/message_notify.module
+++ b/message_notify.module
@@ -7,80 +7,46 @@
 
 /**
  * Process and send a message.
+ *
+ * @param $message
+ *   The message entity being used for the notification.
+ * @param $options
+ *   Array of options to override the plugin's default ones.
+ * @param $notifier_name
+ *   Optional; The name of the notifier to use. Defaults to "email"
+ *   sending method.
+ *
+ * @return
+ *   Boolean value denoting success or failure of the notification.
  */
-function message_notify_send_mail(Message $message, $options = array()) {
-  // Set default values.
-  $options += array(
-    'save on fail' => TRUE,
-    'save on success' => TRUE,
-    'rendered subject field' => FALSE,
-    'rendered body field' => FALSE,
-    // Override email address.
-    'mail' => FALSE,
-    // Override user's language, and use Message language.
-    'language override' => FALSE
-  );
-
-  $account = user_load($message->uid);
-  $element = $message->buildContent('full', $account->language);
-
-  $message->rendered_subject = $element['subject']['#markup'];
-  $message->rendered_body = $element['text']['#markup'];
-
-  $wrapper = entity_metadata_wrapper('message', $message);
-  if ($options['rendered subject field']) {
-    $wrapper->{$options['rendered subject field']}->set($message->rendered_subject);
+function message_notify_send_message(Message $message, array $options = array(), $notifier_name = 'email') {
+  if (!$plugin = message_notify_get_notifier($notifier_name)) {
+   throw new MessageNotifyException(format_string('Could not send notification using the "@notifier" notifier.'), array('@notifier' => $notifier_name));
   }
-  if ($options['rendered body field']) {
-    // Get the format from the field. We assume the first delta is the
-    // same as the rest.
-    if (empty($wrapper->{$options['rendered body field']}->format)) {
-      $wrapper->{$options['rendered body field']}->set($message->rendered_body);
-    }
-    else {
-      $format = $wrapper->type->{MESSAGE_FIELD_MESSAGE_TEXT}->get(0)->format->value();
-      $wrapper->{$options['rendered body field']}->set(array('value' => $message->rendered_body, 'format' => $format));
-    }
-  }
-
-  $params = array(
-    'message_entity' => $message,
-    'rendered_subject' => $message->rendered_subject,
-    'rendered_body' => $message->rendered_body,
-  );
-
-  $mail = $options['mail'] ? $options['mail'] : $account->mail;
+  $options += $plugin['options'];
+  $plugin['options'] = $options;
 
-  $languages = language_list();
-  if (!$options['language override']) {
-    $lang = !empty($account->language) && $account->language != LANGUAGE_NONE ? $languages[$account->language]: language_default();
-  }
-  else {
-    $lang = $languages[$message->language];
+  $class = ctools_plugin_load_class('message_notify', 'notifier', $notifier_name, 'class');
+  $notifier = new $class($plugin, $message);
+  if ($notifier->access()) {
+    return $notifier->send();
   }
-
-  $result = drupal_mail('message_notify', $message->type, $mail, $lang, $params);
-  if (!$result) {
-    watchdog('message_notify', t('Could not send "@type" email to user ID @uid'), array('@message' => $message->type, '@uid' => $message->uid), WATCHDOG_ERROR);
-    if ($options['save on fail']) {
-      $message->save();
-    }
-  }
-  elseif ($result && $options['save on success']) {
-    $message->save();
-  }
-  return $result;
 }
 
 /**
- * Implements hook_message_view().
+ * Implements hook_entity_info_alter().
+ *
+ * Add a the notifiers view modes.
  */
-function message_notify_message_view($message, $view_mode, $langcode) {
-  if ($message->getType()->category == 'message_type_email') {
-    $message->content['subject'] = array(
-      // Add the subject field.
-      '#markup' => $message->getText($langcode, array('field name' => 'message_text_subject')),
-    );
+function message_notify_entity_info_alter(&$entity_info) {
+  foreach (message_notify_get_notifiers() as $notifier_name => $plugin) {
+    $class = ctools_plugin_load_class('message_notify', 'notifier', $notifier_name, 'class');
+    $view_modes = $class::viewModes();
+    // Set default values.
+    foreach ($view_modes as &$view_mode) {
+      $view_mode += array('custom settings' => FALSE);
+    }
+    $entity_info['message']['view modes'] += $view_modes;
   }
 }
 
@@ -104,6 +70,74 @@ function message_notify_default_message_type_category() {
  * Set's the message subject and body as configured.
  */
 function message_notify_mail($key, &$message, $params) {
-  $message['subject'] = $params['rendered_subject'];
-  $message['body'][] = $params['rendered_body'];
+  $message['subject'] = $params['message_notify_email_subject'];
+  $message['body'][] = $params['message_notify_email_body'];
+}
+
+/**
+ * Implements hook_ctools_plugin_api().
+ */
+function message_notify_ctools_plugin_api($module, $api) {
+  if ($module == 'message_notify' && $api == 'notifier') {
+    return array('version' => 1);
+  }
+}
+
+/**
+ * Implements hook_ctools_plugin_type().
+ */
+function message_notify_ctools_plugin_type() {
+  $plugins['notifier'] = array(
+    'classes' => array('class'),
+    'process' => 'message_notify_plugin_process',
+  );
+  return $plugins;
+}
+
+/**
+ * Implements hook_ctools_plugin_directory().
+ */
+function message_notify_ctools_plugin_directory($module, $plugin) {
+  if ($module == 'message_notify') {
+    return 'plugins/' . $plugin;
+  }
+}
+
+/**
+ * CTools callback; Process the notifier plugins.
+ *
+ * TODO: document keys.
+ */
+function message_notify_plugin_process(&$plugin, $info) {
+  $plugin += array(
+    'description' => '',
+    'options' => array(
+      'save on fail' => TRUE,
+      'save on success' => TRUE,
+      // Override mail.
+      'mail' => FALSE,
+      // Override user's language, and use Message language.
+      'language override' => FALSE,
+      'rendered fields' => array(),
+    ),
+  );
+}
+
+/**
+ * Helper function to include CTools plugins and get a notifier plguin.
+ *
+ * @param $plugin_name
+ *   The plugin that should be laoded.
+ */
+function message_notify_get_notifier($notifier_name) {
+  ctools_include('plugins');
+  return ctools_get_plugins('message_notify', 'notifier', $notifier_name);
+}
+
+/**
+ * Helper function to include CTools plugins and get all notifier plugins.
+ */
+function message_notify_get_notifiers() {
+  ctools_include('plugins');
+  return ctools_get_plugins('message_notify', 'notifier');
 }
diff --git a/plugins/notifier/abstract.inc b/plugins/notifier/abstract.inc
new file mode 100644
index 0000000..600dd20
--- /dev/null
+++ b/plugins/notifier/abstract.inc
@@ -0,0 +1,150 @@
+<?php
+
+/**
+ * Additional behaviors for a Entity Reference field.
+ *
+ * Implementations that wish to provide an implementation of this should
+ * register it using CTools' plugin system.
+ */
+interface MessageNotifierInterface {
+
+  /**
+   * Constructor for the notifier.
+   *
+   * @param $plugin
+   *   The notifier plugin object. Note the "options" values might have
+   *   been overriden in message_notify_send_message().
+   * @param Message $message
+   *   The Message entity.
+   */
+  public function __construct($plugin, Message $message);
+
+  /**
+   * Entry point to send and process a message.
+   */
+  public function send();
+
+  /**
+   * Deliver a message via the required transport method.
+   *
+   * @param $output
+   *   Array keyed by the view mode, and the rendered entity in the
+   *   specified view mode.
+   *
+   * @return
+   *   TRUE or FALSE based on delivery status.
+   */
+  public function deliver(array $output = array());
+
+  /**
+   * Post send operations.
+   */
+  public function postSend($result, array $output = array());
+
+  /**
+   * Determine if user can access notifier.
+   */
+  public function access();
+
+  /**
+   * Allow notifier to define its own view modes.
+   *
+   * Those view modes are later going to be rendered and sent.
+   */
+  public static function viewModes();
+}
+
+/**
+ * An abstract implementation of MessageNotifierInterface.
+ */
+abstract class MessageNotifierBase implements MessageNotifierInterface {
+
+  /**
+   * The plugin definition.
+   */
+  protected $plugin;
+
+  /**
+   * The message entity.
+   */
+  protected $message;
+
+  public function __construct($plugin, Message $message) {
+    $this->plugin = $plugin;
+    $this->message = $message;
+  }
+
+  public function send() {
+    $message = $this->message;
+    $output = array();
+    foreach ($this->viewModes() as $view_mode => $value) {
+      $output[$view_mode] = render($message->view($view_mode));
+    }
+    $result = $this->deliver($output);
+    $this->postSend($result, $output);
+  }
+
+  public function deliver(array $output = array()) {}
+
+  /**
+   * Act upon send result.
+   *
+   * - Save the rendered messages if needed.
+   * - Invoke watchdog error on failure.
+   */
+  public function postSend($result, array $output = array()) {
+    $plugin = $this->plugin;
+    $message = $this->message;
+
+    $options = $plugin['options'];
+
+    $save = FALSE;
+    if (!$result) {
+      watchdog('message_notify', t('Could not send message using @title to user ID @uid.'), array('@label' => $plugin['title'], '@uid' => $message->uid), WATCHDOG_ERROR);
+      if ($options['save on fail']) {
+        $save = TRUE;
+      }
+    }
+    elseif ($result && $options['save on success']) {
+      $save = TRUE;
+    }
+
+    if (!$save) {
+      return;
+    }
+
+    if ($options['rendered fields']) {
+      // Save the rendered output into matching fields.
+      $wrapper = entity_metadata_wrapper('message', $message);
+      foreach ($this->viewModes() as $view_mode) {
+        if (empty($options['rendered fields'][$view_mode])) {
+          throw new MessageNotifyException(format_string('The rendered view mode @mode cannot be saved to field, as there is not a matching one.', array('@mode' => $view_mode)));
+        }
+        $field_name = $options['rendered fields'][$view_mode];
+
+        // Get the format from the field. We assume the first delta is the
+        // same as the rest.
+        if (empty($wrapper->{$field_name}->format)) {
+          $wrapper->{$field_name}->set($output[$view_mode]);
+        }
+        else {
+          $format = $wrapper->type->{MESSAGE_FIELD_MESSAGE_TEXT}->get(0)->format->value();
+          $wrapper->{$field_name}->set(array('value' => $output[$view_mode], 'format' => $format));
+        }
+      }
+    }
+
+    if ($save) {
+      $message->save();
+    }
+  }
+
+  public function access() {
+    return TRUE;
+  }
+
+  public static function viewModes() {
+    return array();
+  }
+
+}
diff --git a/plugins/notifier/email/MessageNotifierEmail.class.php b/plugins/notifier/email/MessageNotifierEmail.class.php
new file mode 100644
index 0000000..6f41331
--- /dev/null
+++ b/plugins/notifier/email/MessageNotifierEmail.class.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Email notifier.
+ */
+class MessageNotifierEmail extends MessageNotifierBase {
+
+  /**
+   * Add Message notify view mode.
+   */
+  public static function viewModes() {
+    return array(
+      'message_notify_email_subject' => array('label' => t('Notify - Email subject')),
+      'message_notify_email_body' => array('label' => t('Notify - Email subject')),
+    );
+  }
+
+  public function deliver(array $output = array()) {
+    $plugin = $this->plugin;
+    $message = $this->message;
+
+    $options = $plugin['options'];
+
+    $account = user_load($message->uid);
+    $mail = $options['mail'] ? $options['mail'] : $account->mail;
+
+    $languages = language_list();
+    if (!$options['language override']) {
+      $lang = !empty($account->language) && $account->language != LANGUAGE_NONE ? $languages[$account->language]: language_default();
+    }
+    else {
+      $lang = $languages[$message->language];
+    }
+
+    return drupal_mail('message_notify', $message->type, $mail, $lang, $output);
+  }
+
+}
diff --git a/plugins/notifier/email/email.inc b/plugins/notifier/email/email.inc
new file mode 100644
index 0000000..fb55c30
--- /dev/null
+++ b/plugins/notifier/email/email.inc
@@ -0,0 +1,7 @@
+<?php
+
+$plugin = array(
+  'title' => t('Email'),
+  'description' => t('Send Message via email.'),
+  'class' => 'MessageNotifierEmail',
+);
