diff --git a/includes/simplenews.mail.inc b/includes/simplenews.mail.inc
index 5dd0948..48eb574 100644
--- a/includes/simplenews.mail.inc
+++ b/includes/simplenews.mail.inc
@@ -78,9 +78,17 @@ function simplenews_send_test($node, $test_addresses) {
   foreach ($test_addresses as $mail) {
     $mail = trim($mail);
     if (!empty($mail)) {
-      $account = simplenews_load_user_by_mail($mail);
-      $subscriber = simplenews_get_subscription($account);
-      if ($account->uid) {
+      $subscriber = simplenews_subscriber_load_by_mail($mail);
+      if (!$subscriber) {
+        // The source expects a subscriber object with mail and language set.
+        // @todo: Find a cleaner way to do this.
+        $subscriber = new stdClass();
+        $subscriber->uid = 0;
+        $subscriber->mail = $mail;
+        $subscriber->language = $GLOBALS['language']->language;
+      }
+
+      if (!empty($account->uid)) {
         $recipients['user'][] = $account->name . ' <' . $mail . '>';
       }
       else {
@@ -339,7 +347,7 @@ function simplenews_get_spool($status, $limit = SIMPLENEWS_UNLIMITED) {
         $message->data = unserialize($message->data);
       }
       else {
-        $message->data = simplenews_get_subscription(simplenews_load_user_by_mail($message->mail));
+        $message->data = simplenews_subscriber_load_by_mail($message->mail);
       }
       $messages[$message->msid] = $message;
     }
diff --git a/includes/simplenews.source.inc b/includes/simplenews.source.inc
index f9b01cc..340aa5b 100644
--- a/includes/simplenews.source.inc
+++ b/includes/simplenews.source.inc
@@ -280,7 +280,7 @@ class SimplenewsSpool implements SimplenewsSpoolInterface {
       $subscriber = $spool_data->data;
     }
     else {
-      $subscriber = simplenews_get_subscription(simplenews_load_user_by_mail($spool_data->mail));
+      $subscriber = simplenews_subscriber_load_by_mail($spool_data->mail);
     }
 
     $source_class = $this->getSourceImplementation($spool_data);
diff --git a/includes/simplenews.subscription.inc b/includes/simplenews.subscription.inc
index 39618cc..302f036 100644
--- a/includes/simplenews.subscription.inc
+++ b/includes/simplenews.subscription.inc
@@ -49,7 +49,7 @@
  * @see simplenews_subscriptions_account_form_submit()
  */
 function simplenews_subscriptions_account_form(&$form, &$form_state, $account) {
-  $subscription = simplenews_get_subscription($account);
+  $subscriber = simplenews_subscriber_load_by_mail($account->mail);
 
   $options = array();
   $default_value = array();
@@ -68,7 +68,7 @@ function simplenews_subscriptions_account_form(&$form, &$form_state, $account) {
   $form['subscriptions']['newsletters'] = array(
     '#type' => 'checkboxes',
     '#options' => $options,
-    '#default_value' => array_merge($default_value, (array)$subscription->tids),
+    '#default_value' => array_merge($default_value, $subscriber->tids),
   );
 
   $form['subscriptions']['#title'] =  t('Current newsletter subscriptions');
@@ -84,9 +84,8 @@ function simplenews_subscriptions_account_form(&$form, &$form_state, $account) {
  */
 function simplenews_subscriptions_account_form_submit($form, &$form_state) {
   global $user;
-  // Get current subscriptions if any. Defined in user_profile_form
+
   $account = $form['#user'];
-  $subscription = simplenews_get_subscription($account);
 
   // We first subscribe, then unsubscribe. This prevents deletion of subscriptions
   // when unsubscribed from the
@@ -205,7 +204,7 @@ function simplenews_block_form_submit($form, &$form_state) {
 function simplenews_subscriptions_page_form($form, &$form_state) {
   global $user;
 
-  $subscription = simplenews_get_subscription($user);
+  $subscriber = !empty($user->mail) ? simplenews_subscriber_load_by_mail($user->mail) : FALSE;
 
   $form = array();
   $options = array();
@@ -218,21 +217,26 @@ function simplenews_subscriptions_page_form($form, &$form_state) {
     $default_value[$newsletter->tid] = FALSE;
   }
 
+  if ($subscriber) {
+    // If there is an existing subscriber object, use the existing settings.
+    $default_value = array_merge($default_value, $subscriber->tids);
+  }
+
   $form['subscriptions'] = array(
     '#type' => 'fieldset',
   );
   $form['subscriptions']['newsletters'] = array(
     '#type' => 'checkboxes',
     '#options' => $options,
-    '#default_value' => array_merge($default_value, (array)$subscription->tids),
+    '#default_value' => $default_value
   );
 
   // If current user is logged in, just display email.
   // Anonymous users see an email box and will receive confirmations
-  if ($subscription->mail) {
-    $form['subscriptions']['#title'] = t('Subscriptions for %mail', array('%mail' => $subscription->mail));
+  if (user_is_logged_in()) {
+    $form['subscriptions']['#title'] = t('Subscriptions for %mail', array('%mail' => $user->mail));
     $form['subscriptions']['#description'] = t('Check the newsletters you want to subscribe to. Uncheck the ones you want to unsubscribe from.');
-    $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $subscription->mail);
+    $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $user->mail);
     $form['update'] = array(
       '#type' => 'submit',
       '#value' => t('Update'),
@@ -291,7 +295,8 @@ function simplenews_subscriptions_page_form_validate($form, &$form_state) {
  * FAPI PAGE subscription form_submit.
  */
 function simplenews_subscriptions_page_form_submit($form, &$form_state) {
-  $account = simplenews_get_subscription(simplenews_load_user_by_mail($form_state['values']['mail']));
+  $mail = $form_state['values']['mail'];
+  $account = simplenews_load_user_by_mail($mail);
 
   switch ($form_state['values']['op']) {
     case t('Update'):
@@ -303,7 +308,7 @@ function simplenews_subscriptions_page_form_submit($form, &$form_state) {
           simplenews_subscribe_user($account->mail, $tid, FALSE, 'website');
         }
         else {
-          simplenews_unsubscribe_user($account->mail, $tid, FALSE, 'website');
+          simplenews_unsubscribe_user($mail, $tid, FALSE, 'website');
         }
       }
       drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
@@ -314,7 +319,7 @@ function simplenews_subscriptions_page_form_submit($form, &$form_state) {
         if ($checked) {
           $confirm = simplenews_require_double_opt_in($tid, $account);
           $confirm_any |= $confirm;
-          simplenews_subscribe_user($account->mail, $tid, $confirm, 'website');
+          simplenews_subscribe_user($mail, $tid, $confirm, 'website');
         }
       }
       if ($confirm_any) {
@@ -330,7 +335,7 @@ function simplenews_subscriptions_page_form_submit($form, &$form_state) {
         if ($checked) {
           $confirm = simplenews_require_double_opt_in($tid, $account);
           $confirm_any |= $confirm;
-          simplenews_unsubscribe_user($account->mail, $tid, $confirm, 'website');
+          simplenews_unsubscribe_user($mail, $tid, $confirm, 'website');
         }
       }
       if ($confirm_any) {
@@ -354,8 +359,7 @@ function simplenews_subscriptions_page_form_submit($form, &$form_state) {
 function simplenews_subscriptions_multi_block_form($form, &$form_state) {
   global $user;
 
-  $subscription = simplenews_get_subscription($user);
-
+  $subscriber = !empty($user->mail) ? simplenews_subscriber_load_by_mail($user->mail) : FALSE;
   // If someone not authorized to edit their subscription, return empty form.
   if (!user_access('subscribe to newsletters')) {
     return;
@@ -372,17 +376,22 @@ function simplenews_subscriptions_multi_block_form($form, &$form_state) {
     $default_value[$newsletter->tid] = FALSE;
   }
 
+  if ($subscriber) {
+    // If there is an existing subscriber object, use the existing settings.
+    $default_value = array_merge($default_value, $subscriber->tids);
+  }
+
   $form['newsletters'] = array(
     '#type' => 'checkboxes',
     '#options' => $options,
-    '#default_value' => array_merge($default_value, (array)$subscription->tids),
+    '#default_value' => $default_value,
   );
 
   // If current user is logged in, just display email.
   // Anonymous users see an email box and will receive confirmations
-  if ($subscription->mail) {
+  if (user_is_logged_in()) {
     // @todo why not simply Manage your subscriptions?
-    $form['mail'] = array('#type' => 'value', '#value' => $subscription->mail);
+    $form['mail'] = array('#type' => 'value', '#value' => $user->mail);
     $form['update'] = array(
       '#type' => 'submit',
       '#value' => t('Update'),
@@ -590,8 +599,7 @@ function simplenews_confirm_removal_form_submit($form, &$form_state) {
  * @see simplenews_subscriptions_admin_form_submit()
  */
 function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
-  $account = (object) array('snid' => $snid);
-  $subscription = simplenews_get_subscription($account);
+  $subscriber = simplenews_subscriber_load($snid);
 
   $form = array();
   $options = array();
@@ -605,14 +613,14 @@ function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
   }
 
   $form['subscriptions'] = array(
-    '#title' => t('Subscriptions for %mail', array('%mail' => $subscription->mail)),
+    '#title' => t('Subscriptions for %mail', array('%mail' => $subscriber->mail)),
     '#type' => 'fieldset',
     '#description' => t('Select the newsletter(s) to add/remove from subscription.'),
   );
   $form['subscriptions']['newsletters'] = array(
     '#type' => 'checkboxes',
     '#options' => $options,
-    '#default_value' => array_merge($default_value, (array)$subscription->tids),
+    '#default_value' => array_merge($default_value, $subscriber->tids),
   );
 
   $form['activated'] = array(
@@ -623,7 +631,7 @@ function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
   $form['activated']['activated'] = array(
     '#type' => 'checkbox',
     '#title' => t('Activated'),
-    '#default_value' => $subscription->activated,
+    '#default_value' => $subscriber->activated,
   );
 
   if ((variable_get('language_count', 1) > 1)) {
@@ -635,30 +643,30 @@ function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
       $language_options[$langcode] = $name . ($item->native != $name ? ' ('. $item->native .')' : '');
     }
     // std users have language in profile. disable
-    $disabled = $subscription->uid ? TRUE : FALSE;
+    $disabled = $subscriber->uid ? TRUE : FALSE;
     $form['language'] = array(
       '#type' => 'fieldset',
       '#title' => 'Preferred language',
       '#description' => t('The e-mails will be localized in language chosen. Real users have their preference in account settings.'),
       '#disabled' => FALSE,
     );
-    if ($subscription->uid) {
+    if ($subscriber->uid) {
       // fapi error: disabled not supported for select type. workaround: output markup
       $form['language']['language'] = array(
         '#type' => 'markup',
-        '#value' => $language_options[$subscription->language],
+        '#value' => $language_options[$subscriber->language],
       );
     }
     else {
       $form['language']['language'] = array(
         '#type' => 'select',
-        '#default_value' => $subscription->language,
+        '#default_value' => $subscriber->language,
         '#options' => $language_options,
       );
     }
   }
 
-  $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $subscription->mail);
+  $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $subscriber->mail);
   $form['update'] = array(
     '#type' => 'submit',
     '#value' => t('Update'),
@@ -676,14 +684,14 @@ function simplenews_subscriptions_admin_form($form, &$form_state, $snid) {
  * FAPI ADMIN subscription form_validate.
  */
 function simplenews_subscriptions_admin_form_validate($form, &$form_state) {
-  $subscription = simplenews_get_subscription(simplenews_load_user_by_mail($form_state['values']['mail']));
+  $subscriber = simplenews_subscriber_load_by_mail($form_state['values']['mail']);
 
   $valid_email = valid_email_address($form_state['values']['mail']);
   if (!$valid_email) {
     form_set_error('mail', t('The e-mail address you supplied is not valid.'));
   }
   $checked_newsletters = array_filter($form_state['values']['newsletters']);
-  if (!count($checked_newsletters) && !$subscription) {
+  if (!count($checked_newsletters) && !$subscriber) {
     form_set_error('newsletters', t('You must select at least one newsletter.'));
   }
   $languages = language_list('enabled');
@@ -697,7 +705,7 @@ function simplenews_subscriptions_admin_form_validate($form, &$form_state) {
  * FAPI ADMIN subscription form_submit.
  */
 function simplenews_subscriptions_admin_form_submit($form, &$form_state) {
-  $subscription = simplenews_get_subscription(simplenews_load_user_by_mail($form_state['values']['mail']));
+  $subscriber = simplenews_subscriber_load_by_mail($form_state['values']['mail']);
 
   // update subscriptions
   arsort($form_state['values']['newsletters'], SORT_NUMERIC);
@@ -712,13 +720,13 @@ function simplenews_subscriptions_admin_form_submit($form, &$form_state) {
 
   // update subscriber
   $data = array();
-  $subscription->activated = $form_state['values']['activated'];
-  if (!$subscription->uid) {
+  $subscriber->activated = $form_state['values']['activated'];
+  if (!$subscriber->uid) {
     if (isset($form_state['values']['language'])) {
-      $subscription->language = $form_state['values']['language'];
+      $subscriber->language = $form_state['values']['language'];
     }
   }
-  simplenews_subscriber_save($subscription);
+  simplenews_subscriber_save($subscriber);
 
   drupal_set_message(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $form_state['values']['mail'])));
 }
diff --git a/simplenews.module b/simplenews.module
index 2d019c5..8a8af90 100644
--- a/simplenews.module
+++ b/simplenews.module
@@ -356,7 +356,7 @@ function simplenews_node_view($node, $view_mode) {
   );
 
   // If the current user is a subscriber, extend context.
-  if ($GLOBALS['user']->uid > 0 && $subscriber = simplenews_get_subscription($GLOBALS['user'])) {
+  if ($GLOBALS['user']->uid > 0 && $subscriber = simplenews_subscriber_load_by_mail($GLOBALS['user']->mail)) {
     $context['simplenews_subscriber'] = $subscriber;
   }
 
@@ -901,12 +901,11 @@ function simplenews_form_user_register_form_alter(&$form, &$form_state) {
  *
  * Update uid and preferred language when the new account was already subscribed.
  */
-function simplenews_user_insert(&$edit, $account, $category) {  // Use the email address to check if new account is already subscribed.
-  $subscriber = new stdClass();
-  $subscriber->mail = $edit['mail'];
-  $subscription = simplenews_get_subscription($subscriber);
+function simplenews_user_insert(&$edit, $account, $category) {
+  // Use the email address to check if new account is already subscribed.
+  $subscription = simplenews_subscriber_load_by_mail($edit['mail']);
   // If the user is subscribed, we update the subscriber with uid and language.
-  if (!empty($subscription->snid)) {
+  if ($subscription) {
     $subscriber->uid = $edit['uid'];
     $subscriber->language = $edit['language'];
     $subscriber->activated = 1;
@@ -974,12 +973,9 @@ function simplenews_user_presave(&$edit, $account, $category) {
     case 'account':
       // We only process existing accounts.
       if (!empty($account->uid)) {
-        $subscription = simplenews_get_subscription((object)array('uid' => $account->uid));
-        // Only process existing subscriptions.
-        if ($subscription->snid) {
-          $subscriber = simplenews_subscriber_load($subscription->snid);
+        $subscriber = simplenews_subscriber_load_by_uid($account->uid);
+        if ($subscriber) {
           // Update mail, status and language if they are changed.
-          $fields = array();
           if (isset($edit['mail'])) {
             $subscriber->mail = $edit['mail'];
           }
@@ -1014,14 +1010,9 @@ function simplenews_user_cancel($edit, $account, $method) {
  * Implements hook_user_delete().
  */
 function simplenews_user_delete($account) {
-  // Delete subscription and all newsletter subscriptions when account is removed.
-  // We don't use simplenews_get_subscription() here because the user is already
-  // deleted from the {user} table.
-  $subscribers = simplenews_subscribers_load_multiple(array(), array('mail' => $account->mail));
-  $subscriber = $subscribers ? reset($subscribers) : FALSE;
-
+  // Delete subscription when account is removed.
+  $subscriber = simplenews_subscriber_load_by_mail($account->mail);
   if ($subscriber) {
-    simplenews_subscription_delete(array('snid' => $subscriber->snid));
     simplenews_subscriber_delete($subscriber);
   }
 }
@@ -1047,7 +1038,7 @@ function simplenews_user_categories() {
  */
 function simplenews_form_user_profile_form_alter(&$form, &$form_state) {
   if ($form['#user_category'] == 'simplenews') {
-    $subscription = simplenews_get_subscription($form['#user']);
+    $subscription = simplenews_subscriber_load_by_mail($form['#user']->mail);
     module_load_include('inc', 'simplenews', 'includes/simplenews.subscription');
     simplenews_subscriptions_account_form($form, $form_state, $subscription);
     $form['subscriptions']['#title'] =  t('Newsletter subscriptions');
@@ -1068,7 +1059,7 @@ function simplenews_user_view($account, $build_mode) {
     // Collect newsletter to which the current user is subscribed.
     // 'hidden' newsletters are not listed.
     $newsletters = simplenews_get_mailing_lists();
-    $subscription = simplenews_get_subscription($account);
+    $subscription = simplenews_subscriber_load_by_mail($account->mail);
 
     foreach ($newsletters as $newsletter) {
       if (isset($subscription->newsletter_subscription[$newsletter->tid]) && $subscription->newsletter_subscription[$newsletter->tid]->status == TRUE) {
@@ -1299,10 +1290,10 @@ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unkn
   global $language;
 
   // Get current subscriptions if any.
-  $subscriber = simplenews_get_subscription(simplenews_load_user_by_mail($mail));
+  $subscriber = simplenews_subscriber_load_by_mail($mail);
 
   // If user is not subscribed to ANY newsletter, create a subscription account
-  if ($subscriber->snid == 0) {
+  if (!$subscriber) {
     // To subscribe a user:
     //   - Fetch the users uid.
     //   - Determine the user preferred language.
@@ -1329,6 +1320,7 @@ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unkn
       $preferred_language = '';
     }
 
+    $subscriber = new stdClass();
     $subscriber->mail = $mail;
     $subscriber->uid = $account->uid;
     $subscriber->language = $preferred_language;
@@ -1357,7 +1349,6 @@ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unkn
   elseif (!isset($subscriber->tids[$tid])) {
     // Subscribe the user if not already subscribed.
     // @todo rewrite if subscription object is loaded in $subscriber->tids[$tid]
-    // @todo See simplenews_get_subscription()
     $subscription = new stdClass();
     $subscription->snid = $subscriber->snid;
     $subscription->tid = $tid;
@@ -1393,7 +1384,7 @@ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unkn
  *   - action: Drupal actions.
  */
 function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE, $source = 'unknown') {
-  $subscriber = simplenews_get_subscription(simplenews_load_user_by_mail($mail));
+  $subscriber = simplenews_subscriber_load_by_mail($mail);
 
   // The unlikely case that a user is unsubscribed from a non existing mailing list is logged
   if (!$category = simplenews_category_load($tid)) {
@@ -1414,7 +1405,6 @@ function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE, $source = 'un
   elseif (isset($subscriber->tids[$tid])) {
     // Unsubscribe the user from the mailing list.
     // @todo rewrite if subscription object is loaded in $subscriber->tids[$tid]
-    // @todo See simplenews_get_subscription()
     $subscription = new stdClass();
     $subscription->snid = $subscriber->snid;
     $subscription->tid = $tid;
@@ -1441,129 +1431,21 @@ function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE, $source = 'un
  *   TRUE if the email address is subscribed; otherwise false.
  *
  * @todo Only return active subscriptions.
- * @todo Caching should be done in simplenews_get_subscription().
+ * @todo Caching should be done in simplenews_load_user_by_mail().
  */
 function simplenews_user_is_subscribed($mail, $tid) {
   $subscribed = &drupal_static(__FUNCTION__, array());
 
   if (!isset($subscribed[$mail][$tid])) {
-    $subscription = simplenews_get_subscription(simplenews_load_user_by_mail($mail));
-    $subscribed[$mail][$tid] = isset($subscription->tids[$tid]);
+    $subscriber = simplenews_subscriber_load_by_mail($mail);
+    // Check that a subscriber was found, he is active and subscribed to the
+    // requested tid.
+    $subscribed[$mail][$tid] = $subscriber && $subscriber->activated && isset($subscriber->tids[$tid]);
   }
   return $subscribed[$mail][$tid];
 }
 
 /**
- * Return a default subscriber object.
- */
-function simplenews_subscriber_defaults($account = NULL) {
-  $subscriber = new stdClass();
-  $subscriber->snid = NULL;
-  $subscriber->name = '';
-  $subscriber->activated = 0;
-  $subscriber->uid = NULL;
-  $subscriber->mail = NULL;
-  $subscriber->language = language_default()->language;
-  $subscriber->tids = array();
-  $subscriber->newsletter_subscription = array();
-
-  if (isset($account->uid)) {
-    $subscriber->uid = $account->uid ? $account->uid : NULL;
-  }
-  if (isset($account->mail)) {
-    $subscriber->mail = $account->mail ? $account->mail : NULL;
-  }
-  if (isset($account->language)) {
-    $subscriber->language = user_preferred_language($account)->language;
-  }
-
-  return $subscriber;
-}
-
-/**
- * Get the subscription object for the given account.
- *
- * Account is defined by (in order of preference) snid, email address or uid.
- * If the account is not subscribed a default subscription object is returned
- * containing all available account info.
- *
- * @param object $account
- *   The account details, which may contain the following properties:
- *   - snid: The subscription id.
- *   - mail: The email address.
- *   - uid: The user uid.
- *
- * @return object
- *   The subscription object, which contains the following properties:
- *   - snid: The subscription id, or 0 if the account is not subscribed.
- *   - tids: The array of tid's of active subscriptions for the account.
- *   - newsletter_subscriptions: The array of newsletter subscription objects.
- *   - uid: The user id, or 0 if the subscription is not associated with a user.
- *   - mail: The user email address, or empty if unknown.
- *   - name: An empty string added for compatibility with user account object.
- *   - language: The user-prefered or default language object.
- *
- * @todo Consider adding the following properties to the return object:
- * - subscribed: An array of subscription objects of newsletters to which the
- *   user is subscribed.
- * - unsubscribed: An array of subscription objects of newsletters to which the
- *   user is not subscribed.
- * Both arrays should have newsletter ID (tid) as the key.  Then the 'tids' and
- * 'newsletter_subscriptions' properties could be dropped.
- * @todo Cache the $subscription object.
- * @todo Combine the two queries into one.
- * @todo Load the subscription object into the 'tids' array.
- */
-function simplenews_get_subscription($account) {
-  // Load subscription data based on available account information.
-  // NOTE that the order of checking for 'snid', 'mail' and 'uid' is critical.
-  // The 'mail' property must be checked *before* 'uid'. See
-  // simplenews_subscribe_user()
-  $query = db_select('simplenews_subscriber', 's');
-  $query->leftJoin('users', 'u', 'u.uid = s.uid');
-  $query->fields('s')
-    ->fields('u', array('name'));
-  if (isset($account->snid)) {
-    $query->condition('s.snid', $account->snid);
-  }
-  elseif (isset($account->mail)) {
-    $query->condition('s.mail', $account->mail, 'LIKE');
-  }
-  elseif (isset($account->uid) && $account->uid > 0) {
-    $query->condition('s.uid', $account->uid);
-  }
-  else {
-    // No conditions applied!
-    return simplenews_subscriber_defaults($account);
-  }
-  $query->range(0, 1);
-  $result = $query->execute();
-
-  if ($result->rowCount()) {
-    $subscription = $result->fetch();
-    $query = db_select('simplenews_subscription', 'ss')
-      ->fields('ss')
-      ->condition('snid', $subscription->snid);
-
-    $subscription->tids = array();
-    foreach ($query->execute() as $newsletter_subscription) {
-      if ($newsletter_subscription->status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) {
-        $subscription->tids[$newsletter_subscription->tid] = $newsletter_subscription->tid;
-      }
-      $subscription->newsletter_subscription[$newsletter_subscription->tid] = $newsletter_subscription;
-    }
-    $subscription->language = user_preferred_language($subscription)->language;
-  }
-  else {
-    // The account was not found in the subscription table.
-    // Create and return a default subscription object.
-    return simplenews_subscriber_defaults($account);
-  }
-
-  return $subscription;
-}
-
-/**
  * @todo
  */
 function simplenews_get_subscriptions_by_list($tid) {
@@ -1630,23 +1512,58 @@ function simplenews_subscription_delete($conditions = array()) {
 }
 
 /**
- * Get a simplenews newsletter subscriber object.
+ * Load a simplenews newsletter subscriber object.
  *
  * @param $snid
  *   Simplenews subscriber ID.
  * @return
- *   Newsletter subscriber object.
- *   FALSE if subscriber does not exist.
+ *   Newsletter subscriber object, FALSE if subscriber does not exist.
  */
 function simplenews_subscriber_load($snid, $reset = FALSE) {
-  $subscribers = simplenews_subscribers_load_multiple(array($snid), $reset);
+  $subscribers = simplenews_subscriber_load_multiple(array($snid), $reset);
   return $subscribers ? reset($subscribers) : FALSE;
 }
 
 /**
- * @todo
+ * Load a simplenews newsletter subscriber object.
+ *
+ * @param $mail
+ *   Subscriber e-mail address.
+ * @return
+ *   Newsletter subscriber object, FALSE if subscriber does not exist.
+ */
+function simplenews_subscriber_load_by_mail($mail) {
+  $subscribers = simplenews_subscriber_load_multiple(array(), array('mail' => $mail));
+  return $subscribers ? reset($subscribers) : FALSE;
+}
+
+/**
+ * Load a simplenews newsletter subscriber object.
+ *
+ * @param $uid
+ *   Subscriber user id.
+ * @return
+ *   Newsletter subscriber object, FALSE if subscriber does not exist.
+ */
+function simplenews_subscriber_load_by_uid($uid) {
+  $subscribers = simplenews_subscriber_load_multiple(array(), array('uid' => $uid));
+  return $subscribers ? reset($subscribers) : FALSE;
+}
+
+/**
+ * Loads simplenews subscriber objects.
+ *
+ * @param $snids
+ *   (Optional) Array of subscriber ID's.
+ * @param $conditions
+ *   (Optional) Array of query conditions.
+ * @param $reset
+ *   Reset the static cache.
+ *
+ * @return
+ *   Array of subscriber objects that match the given ID's/conditions.
  */
-function simplenews_subscribers_load_multiple($snids = array(), $conditions = array(), $reset = FALSE) {
+function simplenews_subscriber_load_multiple($snids = array(), $conditions = array(), $reset = FALSE) {
   $subscribers = &drupal_static(__FUNCTION__, array());
 
   // Only cache if we load all records from the database.
@@ -1665,6 +1582,23 @@ function simplenews_subscribers_load_multiple($snids = array(), $conditions = ar
     }
 
     $subscribers = $query->execute()->fetchAllAssoc('snid');
+    if (!empty($subscribers)) {
+      // Initialize default values.
+      foreach ($subscribers as $subscriber) {
+        $subscriber->tids = array();
+      }
+
+      $query = db_select('simplenews_subscription', 'ss')
+        ->fields('ss')
+        ->condition('snid', array_keys($subscribers));
+
+      foreach ($query->execute() as $subscription) {
+        if ($subscription->status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) {
+          $subscribers[$subscription->snid]->tids[$subscription->tid] = $subscription->tid;
+        }
+        $subscribers[$subscription->snid]->newsletter_subscription[$subscription->tid] = $subscription;
+      }
+    }
   }
   return $subscribers;
 }
@@ -1703,12 +1637,13 @@ function simplenews_subscriber_save(&$subscriber) {
 }
 
 /**
- * Delete subscriber from the database.
+ * Delete subscriber and corresponding subscriptions from the database.
  *
  * @param $snid
  *   Simplenews subscriber object.
  */
 function simplenews_subscriber_delete(stdClass $subscriber) {
+  simplenews_subscription_delete(array('snid' => $subscriber->snid));
   db_delete('simplenews_subscriber')
     ->condition('snid', $subscriber->snid)
     ->execute();
@@ -2066,6 +2001,9 @@ function simplenews_tokens($type, $tokens, $data = array(), $options = array())
 
   switch ($type) {
     case 'simplenews-subscriber':
+      if (!isset($data['simplenews_subscriber'])) {
+        return;
+      }
       $subscriber = $data['simplenews_subscriber'];
       $category = $data['category'];
       $language = isset($subscriber->language->language) ? $subscriber->language : user_preferred_language($subscriber);
@@ -2100,6 +2038,9 @@ function simplenews_tokens($type, $tokens, $data = array(), $options = array())
       break;
 
     case 'simplenews-category':
+      if (!isset($data['category'])) {
+        return;
+      }
       $category = $data['category'];
       foreach ($tokens as $name => $original) {
         switch ($name) {
diff --git a/tests/simplenews.test b/tests/simplenews.test
index 18eb2d9..38ebf41 100644
--- a/tests/simplenews.test
+++ b/tests/simplenews.test
@@ -137,7 +137,7 @@ class SimplenewsTestCase extends DrupalWebTestCase {
     $this->assertText('The block configuration has been saved.', 'The newsletter block configuration has been saved.');
   }
 
-  function setUpSubscribers($count = 100) {
+  function setUpSubscribers($count = 100, $tid = 1) {
     // Subscribe users.
     $this->subscribers = array();
     for ($i = 0; $i < $count; $i++) {
@@ -150,7 +150,7 @@ class SimplenewsTestCase extends DrupalWebTestCase {
     $edit = array(
       'emails' => implode(',', $this->subscribers),
       // @todo: Don't hardcode the default tid.
-      'newsletters[1]' => TRUE,
+      'newsletters[' . $tid . ']' => TRUE,
     );
     $this->drupalPost(NULL, $edit, t('Subscribe'));
   }
@@ -218,8 +218,7 @@ class SimplenewsSubscribeTestCase extends SimplenewsTestCase {
     $this->drupalPost(NULL, $edit, t('Subscribe'));
     $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'), t('Subscription confirmation e-mail sent.'));
 
-    $subscriber = (object)array('mail' => $mail);
-    $subscriber = simplenews_get_subscription($subscriber);
+    $subscriber = simplenews_subscriber_load_by_mail($mail);
     $subscription = db_query('SELECT * FROM {simplenews_subscription} WHERE snid = :snid AND tid = :tid', array(':snid' => $subscriber->snid, ':tid' => $tid))->fetchObject();
     $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNCONFIRMED, $subscription->status, t('Subscription is unconfirmed'));
 
@@ -402,8 +401,7 @@ class SimplenewsSubscribeTestCase extends SimplenewsTestCase {
     $this->drupalPost(NULL, $edit, t('Subscribe'));
     $this->assertText(t('You have been subscribed.'), t('Anonymous subscriber added to newsletter'));
 
-    $account = (object)array('mail' => $mail);
-    $subscriber = simplenews_get_subscription($account);
+    $subscriber = simplenews_subscriber_load_by_mail($mail);
   }
 
   /**
@@ -483,11 +481,10 @@ class SimplenewsSubscribeTestCase extends SimplenewsTestCase {
     $this->drupalPost($url, $edit, t('Save'));
     $this->assertRaw(t('The changes have been saved.', array('%mail' => $subscriber_user->mail)), t('Authenticated user unsubscribed on the account page.'));
 
-    $subscriber = simplenews_get_subscription($subscriber_user);
+    $subscriber = simplenews_subscriber_load_by_mail($subscriber_user->mail);
     $subscription = db_query('SELECT * FROM {simplenews_subscription} WHERE snid = :snid AND tid = :tid', array(':snid' => $subscriber->snid, ':tid' => $tid))->fetchObject();
     $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED, $subscription->status, t('Subscription is unsubscribed'));
 
-
     // 5. Subscribe authenticated via account page
     // Subscribe + submit
     // Assert confirmation message
@@ -971,9 +968,51 @@ class SimpleNewsAdministrationTestCase extends SimplenewsTestCase {
       $this->assertNoText($mail);
     }
 
-    // @todo Test Admin subscriber edit category
+    // Reset list and click on the first subscriber.
+    $this->drupalPost(NULL, array(), t('Reset'));
+    $this->clickLink(t('edit'));
+
+    // Get the subscriber id from the path.
+    $this->assertTrue(preg_match('|admin/people/simplenews/users/edit/(\d+)$|', $this->getUrl(), $matches), 'Subscriber found');
+    $subscriber = simplenews_subscriber_load($matches[1]);
+
+    $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
+    $this->assertFieldChecked('edit-activated--2');
+
+    // Disable account.
+    $edit = array(
+      'activated' => FALSE,
+    );
+    $this->drupalPost(NULL, $edit, t('Update'));
+    drupal_static_reset('simplenews_subscriber_load_multiple');
+    drupal_static_reset('simplenews_user_is_subscribed');
+    $this->assertFalse(simplenews_user_is_subscribed($subscriber->mail, $this->getRandomNewsletter(), t('Subscriber is not active')));
+
+    // Re-enable account.
+    $this->drupalGet('admin/people/simplenews/users/edit/' . $subscriber->snid);
+    $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
+    $this->assertNoFieldChecked('edit-activated--2');
+    $edit = array(
+      'activated' => TRUE,
+    );
+    $this->drupalPost(NULL, $edit, t('Update'));
+    drupal_static_reset('simplenews_subscriber_load_multiple');
+    drupal_static_reset('simplenews_user_is_subscribed');
+    $this->assertTrue(simplenews_user_is_subscribed($subscriber->mail, $this->getRandomNewsletter(), t('Subscriber is active again.')));
+
+    // Remove the category.
+    $this->drupalGet('admin/people/simplenews/users/edit/' . $subscriber->snid);
+    $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
+    $edit = array(
+      'newsletters[' . reset($subscriber->tids) . ']' => FALSE,
+    );
+    $this->drupalPost(NULL, $edit, t('Update'));
+    drupal_static_reset('simplenews_subscriber_load_multiple');
+    drupal_static_reset('simplenews_user_is_subscribed');
+    $this->assertFalse(simplenews_user_is_subscribed($subscriber->mail, reset($subscriber->tids), t('Subscriber not subscribed anymore.')));
+
+
     // @todo Test Admin subscriber edit preferred language $subscription->language
-    // @todo Test Admin subscriber edit Active / Inactive
   }
 
   /**
