diff --git modules/sms_user/includes/sms_user_handler_field_status.inc modules/sms_user/includes/sms_user_handler_field_status.inc
index 0439f2e..f74881a 100644
--- modules/sms_user/includes/sms_user_handler_field_status.inc
+++ modules/sms_user/includes/sms_user_handler_field_status.inc
@@ -16,6 +16,7 @@ class sms_user_handler_field_status extends views_handler_field {
     $status_defined = array(
       SMS_USER_PENDING    => t('Pending'),
       SMS_USER_CONFIRMED  => t('Confirmed'),
+      SMS_USER_ACTIVE  => t('Confirmed and Active'),
     );
     return $status_defined[$status];
   }
diff --git modules/sms_user/includes/sms_user_handler_filter_status.inc modules/sms_user/includes/sms_user_handler_filter_status.inc
index 2fd164f..a23fba7 100644
--- modules/sms_user/includes/sms_user_handler_filter_status.inc
+++ modules/sms_user/includes/sms_user_handler_filter_status.inc
@@ -15,6 +15,7 @@ class sms_user_handler_filter_status extends views_handler_filter_in_operator {
       $this->value_options = array(
         SMS_USER_PENDING    => t('Pending'),
         SMS_USER_CONFIRMED  => t('Confirmed'),
+        SMS_USER_ACTIVE  => t('Confirmed and Active'),
       );
     }
   }
diff --git modules/sms_user/sms_user.admin.inc modules/sms_user/sms_user.admin.inc
index 033e3f4..0e47853 100644
--- modules/sms_user/sms_user.admin.inc
+++ modules/sms_user/sms_user.admin.inc
@@ -35,6 +35,13 @@ function sms_user_admin_settings() {
 
   $form['tokens']['content']['#value'] = theme('token_help', 'sms_user');
 
+  $form['sms_user_multiple_numbers'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable multiple mobile numbers'),
+    '#description' => t('If checked, users will be able to add more than one mobile number for their account. One can be set active for outgoing messages, all work for incoming.'),
+    '#default_value' => variable_get('sms_user_multiple_numbers', FALSE),
+  );
+
   $form['sms_user_sleep'] = array(
     '#type' => 'checkbox',
     '#title' => t('Enable sleep hours'),
diff --git modules/sms_user/sms_user.install modules/sms_user/sms_user.install
index 3dc643e..9cb048c 100644
--- modules/sms_user/sms_user.install
+++ modules/sms_user/sms_user.install
@@ -13,6 +13,7 @@ function sms_user_install() {
 function sms_user_schema() {
   $schema['sms_user'] = array(
     'fields' => array(
+      'sid'       => array('description' => 'SMS number id', 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, ),
       'uid'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
       'number'    => array('type' => 'varchar', 'not null' => TRUE, 'length' => 32),
       'status'    => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE),
@@ -20,12 +21,19 @@ function sms_user_schema() {
       'gateway'   => array('type' => 'text'),
     ),
     'primary key' => array('number'),
-    'indexes' => array('uid' => array('uid')),
+    'indexes' => array('uid' => array('uid'), 'sid' => array('sid')),
   );
 
   return $schema;
 }
 
+function sms_user_update_2() {
+  $ret = array();
+  // @todo update all SMS_USER_CONFIRMED 2 status to SMS_USER_ACTIVE 3
+  return $ret;
+}
+
+
 /**
  * Implementation of hook_update().
  *
@@ -56,4 +64,4 @@ function sms_user_uninstall() {
     variable_del($variable);
   }
 
-}
\ No newline at end of file
+}
diff --git modules/sms_user/sms_user.module modules/sms_user/sms_user.module
index 1f6cfc6..230b8e5 100644
--- modules/sms_user/sms_user.module
+++ modules/sms_user/sms_user.module
@@ -7,6 +7,7 @@
 
 define('SMS_USER_PENDING', 1);
 define('SMS_USER_CONFIRMED', 2);
+define('SMS_USER_ACTIVE', 3);
 
 define('SMS_USER_MAX_CHARS', 140);
 
@@ -34,23 +35,65 @@ function sms_user_menu() {
     'description' => 'Edit options for SMS and user integration.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('sms_user_admin_settings'),
-    'access arguments' => array('administer sms'),
+    'access arguments' => array('administer smsframework'),
     'file' => 'sms_user.admin.inc',
   );
 
   $items['user/%user/edit/mobile'] = array(
     'title' => 'Mobile',
-    'page callback' => 'sms_user_settings',
+    'page callback' => 'sms_user_settings_page',
     'page arguments' => array(1),
     'type' => MENU_LOCAL_TASK,
     'access callback' => 'sms_user_edit_access',
     'access arguments' => array(1),
     'tab_parent' => 'user/%/edit',
+    'file' => 'sms_user.settings.inc',
   );
+
+  $items['user/%user/edit/mobile/add'] = array(
+    'title' => 'Add mobile number',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('sms_user_settings_add_form', 1),
+    'type' => MENU_CALLBACK,
+    'access callback' => 'sms_user_edit_access', // @todo and not if set and no multiple
+    'access arguments' => array(1),
+    'file' => 'sms_user.settings.inc',
+  );
+
+  $items['user/%user/edit/mobile/%/delete'] = array(
+    'title' => 'Delete mobile number',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('sms_user_settings_delete_form', 1, 4),
+    'type' => MENU_CALLBACK,
+    'access callback' => 'sms_user_delete_access',
+    'access arguments' => array(1, 4),
+    'file' => 'sms_user.settings.inc',
+  );
+
   return $items;
 }
 
 /**
+ * Implementation of hook_theme().
+ */
+function sms_user_theme() {
+  return array(
+    'sms_user_settings_page' => array(
+      'arguments' => array('content' => NULL),
+      'file' => 'sms_user.settings.inc',
+    ),
+    'sms_user_settings_active_form' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'sms_user.settings.inc',
+    ),
+    'sms_user_settings_confirm_form' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'sms_user.settings.inc',
+    ),
+  );
+}
+
+/**
  * Access control on edit users sms number.
  */
 function sms_user_edit_access($account) {
@@ -58,6 +101,18 @@ function sms_user_edit_access($account) {
 }
 
 /**
+ * Access control on delete users sms number.
+ */
+function sms_user_delete_access($account, $number) {
+  if (sms_user_edit_access($account)) {
+    if ($account->uid == sms_user_get_uid($number)) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
  * Send a message to a user.
  */
 function sms_user_send($uid, $message) {
@@ -132,212 +187,6 @@ function _sms_user_sleep_active($account) {
   return FALSE;
 }
 
-/**
- * Menu callback; provides the forms for adding and confirming a user's mobile number.
- */
-function sms_user_settings($account) {
-  switch (isset($account->sms_user) ? $account->sms_user['status'] : 0) {
-    case 0:
-      $output = drupal_get_form('sms_user_settings_add_form', $account);
-      break;
-    case SMS_USER_PENDING:
-      $output = drupal_get_form('sms_user_settings_confirm_form', $account);
-      break;
-    case SMS_USER_CONFIRMED:
-      $output = drupal_get_form('sms_user_settings_reset_form', $account);
-      break;
-  }
-
-  if (variable_get('sms_user_sleep', 1)) {
-    $output .= drupal_get_form('sms_user_settings_sleep_form', $account);
-  }
-
-  return $output;
-}
-
-function sms_user_settings_add_form(&$form_state, $account) {
-  $form = sms_send_form();
-  $form['uid'] = array(
-    '#type' => 'hidden',
-    '#value' => $account->uid,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Confirm number'),
-  );
-
-  return $form;
-}
-
-function sms_user_settings_add_form_validate($form, &$form_state) {
-  if ($error = sms_user_validate_number($form_state['values']['number'])) {
-    form_set_error('number', $error);
-  }
-
-  if (empty($form_state['values']['gateway'])) {
-   $form_state['values']['gateway'] = array();
-  }
-}
-
-function sms_user_settings_add_form_submit($form, &$form_state, $account = NULL) {
-  if (!$account) {
-    $account = user_load(array('uid' => $form_state['values']['uid']));
-  }
-  sms_user_send_confirmation($account, $form_state['values']['number'], $form_state['values']['gateway']);
-}
-
-function sms_user_settings_confirm_form(&$form_state, $account) {
-  $form['uid'] = array(
-    '#type' => 'hidden',
-    '#value' => $account->uid,
-  );
-  $form['number'] = array(
-    '#type' => 'item',
-    '#title' => t('Mobile phone number'),
-    '#value' => $account->sms_user['number'],
-  );
-  $form['confirm_code'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Confirmation code'),
-    '#description' => t('Enter the confirmation code sent by SMS to your mobile phone.'),
-    '#size' => 4,
-    '#maxlength' => 4,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Confirm number'),
-  );
-  $form['reset'] = array(
-    '#type' => 'submit',
-    '#value' => t('Delete & start over'),
-    '#access' => user_access('edit own sms number'),
-  );
-  return $form;
-}
-
-function sms_user_settings_confirm_form_validate($form, &$form_state) {
-  if ($form_state['clicked_button']['#value'] == t('Confirm number')) {
-    $account = user_load(array('uid' => $form_state['values']['uid']));
-    if ($form_state['values']['confirm_code'] != $account->sms_user['code']) {
-      form_set_error('confirm_code', t('The confirmation code is invalid.'));
-    }
-  }
-}
-
-function sms_user_settings_confirm_form_submit($form, &$form_state) {
-  $account = user_load(array('uid' => $form_state['values']['uid']));
-  if ($form_state['clicked_button']['#value'] == t('Delete & start over')) {
-    sms_user_delete($account->uid);
-  }
-  else {
-    $data = array(
-      'number'  => $account->sms_user['number'],
-      'status'  => SMS_USER_CONFIRMED,
-      'gateway' => $account->sms_user['gateway'],
-    );
-
-    user_save($account, array('sms_user' => $data), 'mobile');
-    // If the rule module is installed, fire rules
-    if (module_exists('rules')) {
-      rules_invoke_event('sms_user_validated', $account);
-    }
-  }
-}
-
-function sms_user_settings_reset_form(&$form_state, $account) {
-  $form['uid'] = array(
-    '#type' => 'hidden',
-    '#value' => $account->uid,
-  );
-  $form['sms_user']['number'] = array(
-    '#type' => 'item',
-    '#title' => t('Your mobile phone number'),
-    '#value' => $account->sms_user['number'],
-    '#description' => t('Your mobile phone number has been confirmed.')
-  );
-
-  $form['reset'] = array(
-    '#type' => 'submit',
-    '#value' => t('Delete & start over'),
-    '#access' => user_access('edit own sms number'),
-  );
-
-  return $form;
-}
-
-function sms_user_settings_reset_form_submit($form, &$form_state) {
-  $account = user_load(array('uid' => $form_state['values']['uid']));
-  sms_user_delete($account->uid);
-  if (module_exists('rules')) {
-    rules_invoke_event('sms_user_removed', $account);
-  }
-  drupal_set_message(t('Your mobile information has been removed'), 'status');
-}
-
-function sms_user_settings_sleep_form(&$form_state, $account) {
-  $form['uid'] = array(
-    '#type' => 'hidden',
-    '#value' => $account->uid,
-  );
-  $form['sleep'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sleep Time'),
-    '#collapsible' => TRUE,
-  );
-
-  $form['sleep']['sleep_enabled'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Disable messages between these hours'),
-    '#description' => t('If enabled, you will not receive messages between the specified hours.'),
-    '#default_value' => isset($account->sms_user['sleep_enabled']) ? $account->sms_user['sleep_enabled'] : NULL,
-  );
-
-  // Determine whether to use the 24-hour or 12-hour clock based on site settings
-  if (strpos(variable_get('date_format_short', 'm/d/Y - H:i'), 'g')) {
-    $format = 'g A';
-  }
-  else {
-    $format = 'H:00';
-  }
-  // Build the list of options based on format
-  $hour = 0;
-  while ($hour < 24) {
-    $options[$hour] = date($format, mktime($hour));
-    $hour++;
-  }
-
-  $form['sleep']['sleep_start_time'] = array(
-    '#type' => 'select',
-    '#multiple' => FALSE,
-    '#options' => $options,
-    '#default_value' => isset($account->sms_user['sleep_start_time']) ? $account->sms_user['sleep_start_time'] : NULL,
-  );
-
-  $form['sleep']['sleep_end_time'] = array(
-    '#type' => 'select',
-    '#multiple' => FALSE,
-    '#options' => $options,
-    '#default_value' => isset($account->sms_user['sleep_end_time']) ? $account->sms_user['sleep_end_time'] : NULL,
-  );
-
-  $form['sleep']['save'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-
-  return $form;
-}
-
-function sms_user_settings_sleep_form_submit($form, &$form_state) {
-  $account = user_load(array('uid' => $form_state['values']['uid']));
-  $data = $account->sms_user;
-  $data['sleep_enabled'] = $form_state['values']['sleep_enabled'];
-  $data['sleep_start_time'] = $form_state['values']['sleep_start_time'];
-  $data['sleep_end_time'] = $form_state['values']['sleep_end_time'];
-  user_save($account, array('sms_user' => $data), 'mobile');
-  drupal_set_message(t('The changes have been saved.'), 'status');
-}
-
 function sms_user_send_confirmation($account, $number, $options) {
   $code = rand(1000, 9999);
   $number = sms_formatter($number);
@@ -347,11 +196,54 @@ function sms_user_send_confirmation($account, $number, $options) {
     'code'    => $code,
     'gateway' => $options,
   );
-
   user_save($account, array('sms_user' => $data), 'mobile');
   sms_send($number, _sms_user_confirm_message($code), $options);
 }
 
+/**
+ * Confirm a number with confirmation code.
+ *
+ * @param $account
+ *   user object.
+ * @param $number
+ *   number to confirm.
+ * @param $code
+ *   confirmation code.
+ * @param
+ *   bool TRUE if only validating and not confirming.
+ * @return
+ *   bool TRUE if code correct for number.
+ */
+function sms_user_confirm($account, $number, $code, $validate = FALSE) {
+  foreach ($account->sms_user as $acc_number) {
+    if ($acc_number['number'] == $number) {
+      if ($acc_number['code'] != $code) {
+        // incorrect code.
+        return FALSE;
+      }
+      if (! $validate) {
+        $data = array(
+          'number'  => $number,
+          'status'  => isset($account->sms_user[1]) ? SMS_USER_CONFIRMED : SMS_USER_ACTIVE,
+          'gateway' => $acc_number['gateway'],
+        );
+
+        user_save($account, array('sms_user' => $data), 'mobile');
+        // If the rule module is installed, fire rules
+        if (module_exists('rules')) {
+          rules_invoke_event('sms_user_validated', $account);
+        }
+      }
+      
+      // correct code for number.
+      return TRUE;
+    }
+  }
+
+  // incorrect number.
+  return FALSE;
+}
+
 function sms_user_validate_number(&$number) {
   if ($error = sms_validate_number($number)) {
     return $error;
@@ -368,7 +260,7 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) {
   global $user;
   switch ($op) {
     case 'load':
-      return sms_user_load($edit, $account, $category);
+      return sms_user_load($account, $category);
     case 'update':
     case 'insert':
       return sms_user_save($edit, $account, $category);
@@ -403,7 +295,7 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) {
       break;
     case 'login':
       // Check if first it's the user's first time logging in.
-      if (!$account->access && !empty($account->sms_user['number']) && $account->sms_user['status'] != SMS_USER_CONFIRMED) {
+      if (!$account->access && !empty($account->sms_user['number']) && $account->sms_user['status'] < SMS_USER_CONFIRMED) {
         sms_user_send_confirmation($account, $account->sms_user['number'], $account->sms_user['gateway']);
         drupal_set_message(t('A confirmation message has been sent to your mobile phone. Please !link.', array('!link' => l(t('confirm your number'), 'user/'. $account->uid .'/edit/mobile'))), 'status');
       }
@@ -421,24 +313,40 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) {
 /**
  * Load user mobile data into the user object.
  *
+ * @todo this is called often, the $account->sms_user content could be 
+ *   update and trusted?
  * @see sms_user_user()
  */
-function sms_user_load(&$edit, &$account, $category) {
-  $result = db_query("SELECT number, status, code, gateway FROM {sms_user} WHERE uid = %d", $account->uid);
-
+function sms_user_load(&$account, $category) {
   $account->sms_user = array();
-  while ($data = db_fetch_array($result)) {
+
+  if (variable_get('sms_user_sleep', 1)) {
+    // all the sms_user data is stored in {users}.data 
+    // using this for sleep settings, 
+    // but trusting the {sms_user} table for numbers
     $user_data = unserialize($account->data);
-    $account->sms_user = $user_data['sms_user'];
-    $account->sms_user['number'] = $data['number'];
-    $account->sms_user['status'] = $data['status'];
-    $account->sms_user['code'] = $data['code'];
-    $account->sms_user['gateway'] = unserialize($data['gateway']);
+    $account->sms_user['sleep_enabled'] = isset($user_data['sms_user']['sleep_enabled']) ? $user_data['sms_user']['sleep_enabled'] : FALSE;
+    $account->sms_user['sleep_start_time'] = isset($user_data['sms_user']['sleep_start_time']) ? $user_data['sms_user']['sleep_start_time'] : 0;
+    $account->sms_user['sleep_end_time'] = isset($user_data['sms_user']['sleep_end_time']) ? $user_data['sms_user']['sleep_end_time'] : 0;
   }
 
-  // @todo: the following is to support messaging that expect account details
-  // with a delta of 0
-  $account->sms_user[0] = $account->sms_user;
+  $result = db_query("SELECT number, status, code, gateway FROM {sms_user} WHERE uid = %d", $account->uid);
+
+  while ($data = db_fetch_array($result)) {
+    $data['gateway'] = unserialize($data['gateway']);
+
+    /**
+     * At present modules access $sms_user['field'] 
+     * or $sms_user[0]['field'] to get the active number's 'field'.
+     */
+    if ($data['status'] == SMS_USER_ACTIVE) {
+      array_unshift($account->sms_user, $data);
+      array_merge($account->sms_user, $data);
+    }
+    else {
+      $account->sms_user[] = $data;
+    }
+  }
 }
 
 /**
@@ -449,18 +357,15 @@ function sms_user_load(&$edit, &$account, $category) {
 function sms_user_save(&$edit, &$account, $category) {
   if (($category == 'mobile' || $category == 'account') && $edit['sms_user']) {
     $number = $edit['sms_user'];
-    $db_values = array($number['number'], $number['status'], isset($number['code']) ? $number['code'] : NULL, serialize($number['gateway']));
+    $number['gateway'] = serialize($number['gateway']);
+    $number['uid'] = $account->uid;
 
-    db_query("UPDATE {sms_user} SET number = '%s', status = %d, code = '%s', gateway = '%s'
-        WHERE uid = %d AND number = '%s'", array_merge($db_values, array($account->uid, $number['number'])));
-    if ($number['number'] && !db_affected_rows()) {
-      db_query("INSERT INTO {sms_user} (number, status, code, gateway, uid)
-        VALUES ('%s', %d, '%s', '%s', %d)", array_merge($db_values, array($account->uid)));
+    drupal_write_record('sms_user', $number, array('number', 'uid'));
+    if (! db_affected_rows()) {
+      $result = drupal_write_record('sms_user', $number);
     }
-    $edit['sms_user']['number'] = NULL;
-    $edit['sms_user']['status'] = NULL;
-    $edit['sms_user']['code'] = NULL;
-    $edit['sms_user']['gateway'] = NULL;
+
+    $account->sms_user = $edit;
   }
 }
 
@@ -472,6 +377,8 @@ function sms_user_save(&$edit, &$account, $category) {
  * @param $number
  *   The number to delete. Defaults to FALSE which will delete all numbers.
  *
+ * Note: this doesn't delete from $account->sms_user that removed on re-load.
+ *
  * @see sms_user_user()
  */
 function sms_user_delete($uid, $number = FALSE) {
@@ -488,6 +395,21 @@ function sms_user_delete($uid, $number = FALSE) {
 }
 
 /**
+ * Set active number.
+ *
+ * For sms_user_multiple_numbers.
+ *
+ * @param $uid
+ *   User id.
+ * @param $number
+ *   Mobile number to set as default.
+ */
+function sms_user_active_set($uid, $number) {
+  db_query('UPDATE {sms_user} SET status = %d WHERE uid = %d AND status = %d', SMS_USER_CONFIRMED, $uid, SMS_USER_ACTIVE);
+  db_query("UPDATE {sms_user} SET status = %d WHERE uid = %d AND number = '%s'", SMS_USER_ACTIVE, $uid, $number);
+}
+
+/**
  * Create a confirmation message sent to a user, this contains a code which is
  * used to confirm that the number is actually correct.
  *
@@ -765,8 +687,62 @@ function sms_user_logout() {
 }
 
 /**
+ * Helper function returns numbers array indexed by status, or number.
+ *
+ * @param $account
+ *   User object.
+ * @param $index
+ *   string key to use to index.
+ * @param $nocache
+ *   bool set to true when user account could have just been updated.
+ * @return 
+ *   array numbers indexed by key value.
+ */
+function sms_user_numbers($account, $index, $nocache = FALSE) {
+  static $numbers = array();
+
+  if ($nocache) {
+    $numbers[$account->uid] = array();
+  }
+
+  if (! isset($numbers[$account->uid][$index])) {
+    foreach ($account->sms_user as $key => $number) {
+      // skip the active number elements that are included as $sms_user['key'];
+      if (! is_numeric($key) || ! is_array($number)) {
+        continue;
+      }
+      if ($index == 'number') {
+        $numbers[$account->uid][$index][$number[$index]] = $number;
+      }
+      else {
+        $numbers[$account->uid][$index][$number[$index]][] = $number;
+      }
+    }
+  }
+
+  return $numbers[$account->uid][$index];
+}
+
+/**
  * Implementation of hook_views_api().
  */
 function sms_user_views_api() {
   return array('api' => 2);
 }
+
+/**
+ * Implements hook_usermerge_merge_users().
+ *
+ * Takes numbers from user to delete and adds them to user to keep.
+ * @todo sleep settings.
+ */
+function sms_user_usermerge_merge_users($user_to_delete, $user_to_keep) {
+  $numbers = db_query('SELECT * FROM {sms_user} WHERE uid = %d', $user_to_delete->uid);
+  while ($number = db_fetch_object($numbers)) {
+    $number->uid = $user_to_keep->uid;
+    if (! drupal_write_record('sms_user', $number, 'number')) {
+      // bail out - @todo error
+      return;
+    }
+  }
+}
diff --git modules/sms_user/sms_user.settings.inc modules/sms_user/sms_user.settings.inc
new file mode 100644
index 0000000..8dd632c
--- /dev/null
+++ modules/sms_user/sms_user.settings.inc
@@ -0,0 +1,421 @@
+<?php
+
+/** 
+ * @file
+ *   SMS Framework user module. User settings, add, remove, verify numbers.
+ */
+
+/**
+ * Form: User numbers overview.
+ *
+ * @param $account
+ *   User object.
+ */
+function sms_user_settings_page($account) {
+  $content = array();
+
+  /**
+   * First add a number (and check if a number has been added).
+   */
+  $content['add'] = drupal_get_form('sms_user_settings_add_form', $account);
+  
+
+  /**
+   * Check for any validations done or todo.
+   */
+  $content['validate'] = drupal_get_form('sms_user_settings_confirm_form', $account, $number);
+
+  /**
+   * List active numbers,
+   */
+  $content['active'] = drupal_get_form('sms_user_settings_active_form', $account);
+
+  /**
+   * Sleep.
+   */
+  if (variable_get('sms_user_sleep', 1)) {
+    $content['sleep'] = drupal_get_form('sms_user_settings_sleep_form', $account, TRUE);
+  }
+  
+  return theme('sms_user_settings_page', $content);
+}
+
+/**
+ * Form: Add a new mobile number to an account.
+ *
+ * @param $account 
+ *   User object to add number to.
+ * @param $fieldset
+ *   Bool TRUE if form should be in fieldset.
+ */
+function sms_user_settings_add_form(&$form_state, $account) {
+  // refresh the numbers, no form if number and not multiple
+  $numbers = sms_user_numbers($account, 'numbers', TRUE);
+  if (count($numbers) && ! variable_get('sms_user_multiple_numbers', FALSE)) {
+    return;
+  }
+
+  $form = array();
+  $form['uid'] = array('#type' => 'value', '#value' => $account->uid);
+  $form['add'] = sms_send_form();
+  $form['add']['add_submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add number'),
+  );
+
+  // place in a fieldset if there is more than one number 
+  if (count($numbers)) {
+    $form['add']['#type'] = 'fieldset';
+    $form['add']['#title'] = t('Add another number');
+    $form['add']['#collapsible'] = TRUE;
+    $form['add']['#collapsed'] = TRUE;
+  }
+  return $form;
+}
+
+function sms_user_settings_add_form_validate($form, &$form_state) {
+  if ($error = sms_user_validate_number($form_state['values']['number'])) {
+    form_set_error('number', $error);
+  }
+
+  if (empty($form_state['values']['gateway'])) {
+   $form_state['values']['gateway'] = array();
+  }
+}
+
+function sms_user_settings_add_form_submit($form, &$form_state) {
+  $account = user_load(array('uid' => $form_state['values']['uid']));
+  sms_user_send_confirmation($account, $form_state['values']['number'], $form_state['values']['gateway']);
+}
+
+/**
+ * Form: Confirm a mobile number.
+ * 
+ * @param $account
+ *   User object.
+ * @param $number
+ *   Number array (@todo or delta?)
+ */
+function sms_user_settings_confirm_form(&$form_state, $account, $number) {
+  // get and reset numbers list, return if none pending confirmation.
+  $numbers = sms_user_numbers($account, 'status', TRUE);
+  if (! count($numbers[SMS_USER_PENDING])) {
+    return;
+  }
+
+  $form = array();
+  // force a reload of the numbers, if just changed gets new account
+  $form['uid'] = array('#type' => 'value', '#value' => $account->uid);
+
+  foreach ($numbers[SMS_USER_PENDING] as $number) {
+    $form[$number['number']]['confirm_number[' . $number['number'] .']'] = array(
+      '#type' => 'item',
+      '#title' => t('Mobile phone number'),
+      '#value' => $number['number'],
+    );
+    $form[$number['number']]['confirm_code[' . $number['number'] .']'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Confirmation code'),
+      '#description' => t('The code sent by SMS to your mobile phone.'),
+      '#size' => 4,
+      '#maxlength' => 4,
+      '#parent' => $number['number'],
+    );
+    $form[$number['number']]['confirm_submit[' . $number['number'] . ']'] = array(
+      '#type' => 'submit',
+      '#value' => t('Confirm'),
+    );
+    $form[$number['number']]['confirm_delete[' . $number['number'] .']'] = array(
+      '#type' => 'item',
+      '#value' => l(t('Delete'), 'user/' . $account->uid . '/edit/mobile/' . $number['number'] . '/delete', array('query' => drupal_get_destination())),
+      '#access' => user_access('edit own sms number'),
+    );
+  }
+
+  return $form;
+}
+
+function sms_user_settings_confirm_form_validate($form, &$form_state) {
+  $account = user_load(array('uid' => $form_state['values']['uid']));
+  $filled = FALSE;
+  foreach ($form_state['clicked_button']['#post']['confirm_code'] as $number => $code) {
+    if (! empty($code)) {
+      $filled = TRUE;
+      if (! sms_user_confirm($account, $number, $code, TRUE)) {
+        form_set_error('confirm_code[' . $number . ']', t('The confirmation code for number %number is invalid.', array('%number' => $number)));
+      }
+    }
+  }
+  // @todo do we want this message, if so it might need attaching to something.
+  if (! $filled) {
+    form_set_error(NULL, t('To confirm a number you must enter the code sent by SMS to you mobile phone.'));
+  }
+}
+
+function sms_user_settings_confirm_form_submit($form, &$form_state) {
+  $account = user_load(array('uid' => $form_state['values']['uid']));
+  foreach ($form_state['clicked_button']['#post']['confirm_code'] as $number => $code) {
+   if (! empty($code)) {
+     sms_user_confirm($account, $number, $code);
+   }
+ }
+}
+
+/**
+ * Form: Lists confirmed number(s). For multiples allows setting active number.
+ */
+function sms_user_settings_active_form(&$form_state, $account) {
+  $form = array();
+  $form['uid'] = array('#type' => 'value', '#value' => $account->uid);
+
+  // we want to list numbers in a consistent order.
+  $numbers = sms_user_numbers($account, 'number', TRUE);
+  ksort($numbers);
+
+  foreach ($numbers as $number) {
+    if ($number['status'] == SMS_USER_PENDING) {
+      // skip numbers that aren't confirmed.
+      continue;
+    }
+    $row = array();
+    $row['number'] = array(
+      '#type' => 'item',
+      '#title' => t('Your mobile phone number'),
+      '#value' => $number['number'],
+      '#description' => t('Your mobile phone number has been confirmed.')
+    );
+    if (variable_get('sms_user_multiple_numbers', FALSE)) {
+      $options[$number['number']] = '';
+      if ($number['status'] == SMS_USER_ACTIVE) {
+        $active = $number['number'];
+      }
+    }
+    $row['confirm_delete'] = array(
+      '#type' => 'item',
+      '#value' => l(t('Delete'), 'user/' . $account->uid . '/edit/mobile/' . $number['number'] . '/delete', array('query' => drupal_get_destination())),
+      '#access' => user_access('edit own sms number'),
+    );
+    $form[$number['number']] = $row;
+  }
+
+  // if there is more than one number, add radio buttons to select the active one.
+  if (variable_get('sms_user_multiple_numbers', FALSE)) {
+    $form['active'] = array(
+      '#type' => 'radios',
+      '#options' => $options,
+      '#default_value' => $active,
+    );
+    if (count($options)) {
+      $form['submit'] = array(
+        '#type' => 'submit',
+        '#value' => t('Set active'),
+      );
+    }
+  }
+
+  return $form;
+}
+
+function sms_user_settings_active_form_submit($form, &$form_state) {
+  sms_user_active_set($form_state['values']['uid'], $form_state['values']['active']);
+}
+
+/**
+ * Form: Delete number from account.
+ */
+function sms_user_settings_delete_form(&$form_state, $account, $number) {
+  $form = array();
+  $form['uid'] = array('#type' => 'value', '#value' => $account->uid);
+  $form['number'] = array('#type' => 'value', '#value' => $number);
+
+  return confirm_form($form,
+    t('Are you sure you want to delete mobile number %number?', array('%number' => $number)),
+    isset($_GET['destination']) ? $_GET['destination'] : 'user/'. $account->uid .'/edit/mobile',
+    NULL,
+    t('Delete'),
+    t('Cancel')
+  );
+}
+
+function sms_user_settings_delete_form_submit($form, &$form_state) {
+  if ($form_state['clicked_button']['#value'] == t('Delete')) {
+    sms_user_delete($form_state['values']['uid'], $form_state['values']['number']);
+  }
+  drupal_goto();
+}
+
+/**
+ * Form: Account mobile sleep settings.
+ *
+ * @param $account
+ *   User object.
+ * @param $fieldset
+ *   Bool TRUE if should be in a fieldset.
+ */
+function sms_user_settings_sleep_form(&$form_state, $account, $fieldset = FALSE) {
+  $form['uid'] = array('#type' => 'value', '#value' => $account->uid);
+
+  $form['sleep']['sleep_enabled'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Disable messages between these hours'),
+    '#description' => t('If enabled, you will not receive messages between the specified hours.'),
+    '#default_value' => isset($account->sms_user['sleep_enabled']) ? $account->sms_user['sleep_enabled'] : NULL,
+  );
+
+  // Determine whether to use the 24-hour or 12-hour clock based on site settings
+  if (strpos(variable_get('date_format_short', 'm/d/Y - H:i'), 'g')) {
+    $format = 'g A';
+  }
+  else {
+    $format = 'H:00';
+  }
+  // Build the list of options based on format
+  $hour = 0;
+  while ($hour < 24) {
+    $options[$hour] = date($format, mktime($hour));
+    $hour++;
+  }
+
+  $form['sleep']['sleep_start_time'] = array(
+    '#type' => 'select',
+    '#multiple' => FALSE,
+    '#options' => $options,
+    '#default_value' => isset($account->sms_user['sleep_start_time']) ? $account->sms_user['sleep_start_time'] : NULL,
+  );
+
+  $form['sleep']['sleep_end_time'] = array(
+    '#type' => 'select',
+    '#multiple' => FALSE,
+    '#options' => $options,
+    '#default_value' => isset($account->sms_user['sleep_end_time']) ? $account->sms_user['sleep_end_time'] : NULL,
+  );
+
+  $form['sleep']['save'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+
+  if ($fieldset) {
+    $form['sleep']['#type'] = 'fieldset';
+    $form['sleep']['#title'] = t('Set sleep Time');
+    $form['sleep']['#collapsible'] = TRUE;
+    $form['sleep']['#collapsed'] = TRUE;
+  }
+
+  return $form;
+}
+
+function sms_user_settings_sleep_form_submit($form, &$form_state) {
+  $account = user_load(array('uid' => $form_state['values']['uid']));
+  $data = $account->sms_user;
+  $data['sleep_enabled'] = $form_state['values']['sleep_enabled'];
+  $data['sleep_start_time'] = $form_state['values']['sleep_start_time'];
+  $data['sleep_end_time'] = $form_state['values']['sleep_end_time'];
+  user_save($account, array('sms_user' => $data), 'mobile');
+  drupal_set_message(t('The changes have been saved.'), 'status');
+}
+
+/********
+ * Theme Functions
+ */
+
+/**
+ * Theme function for combined user settings page.
+ *
+ * @param $content
+ *   array of forms: active, validate, add and sleep.
+ * @ingroup themeable
+ */
+function theme_sms_user_settings_page($content) {
+  $output = $content['active'];
+  $output .= $content['validate'];
+  $output .= $content['add']; 
+  $output .= $content['sleep'];
+  return $output;
+}
+
+/**
+ * Theme function for the confirm numbers form.
+ *
+ * @param $form
+ *   An associative array containing the structure of the form.
+ * @ingroup themeable
+ */
+function theme_sms_user_settings_confirm_form($form) {
+  $output = '';
+
+  if (variable_get('sms_user_multiple_numbers', FALSE)) {
+    $rows = array();
+
+    foreach (element_children($form) as $key) {
+      if (! isset($form[$key]['confirm_number[' . $key . ']'])) {
+        // just putting the numbers (and their selector) in a table
+        continue;
+      }
+
+      $number = $form[$key];
+      unset($form[$key]);
+
+      unset($number['confirm_code[' . $key . ']']['#title']);
+      unset($number['confirm_code[' . $key . ']']['#description']);
+
+      $row = array();
+      $row[] = $number['confirm_number[' . $key . ']']['#value'];
+      $row[] = drupal_render($number['confirm_code[' . $key . ']']);
+      $row[] = drupal_render($number['confirm_submit[' . $key . ']']);
+      $row[] = drupal_render($number['confirm_delete[' . $key . ']']);
+      $rows[] = $row;
+
+    }
+
+    if (count($rows)) {
+      $header = array(t('Mobile phone number'), t('Confirmation code'), '', '');
+      $output .= theme('table', $header, $rows);
+      $output .= t('The confirmation code sent by SMS to your mobile phone.');
+    }
+  }
+
+  $output .= drupal_render($form); 
+  return $output;
+}
+
+
+/**
+ * Theme function for the active numbers form.
+ *
+ * @param $form
+ *   An associative array containing the structure of the form.
+ * @ingroup themeable
+ */
+function theme_sms_user_settings_active_form($form) {
+  $output = '';
+
+  if (variable_get('sms_user_multiple_numbers', FALSE)) {
+    $rows = array();
+
+    foreach (element_children($form) as $key) {
+      if (! isset($form[$key]['number'])) {
+        // just putting the numbers (and their selector) in a table
+        continue;
+      }
+      $number = $form[$key];
+      unset($form[$key]);
+
+      $row = array();
+      $row[] = $number['number']['#value'];
+      $row[] = drupal_render($form['active'][$key]);
+      $row[] = drupal_render($number['confirm_delete']);
+      $rows[] = $row;
+    }
+
+    if (count($rows)) {
+      $header = array(t('Mobile phone number'), t('Active'), '');
+      $output .= theme('table', $header, $rows);
+      $output .= t('You can select the <em>active</em> number to receive SMS from the site. All numbers will be able to send SMS to the site.');
+    }
+  }
+
+  $output .= drupal_render($form); 
+  return $output;
+}
+
