diff --git a/session_limit.info b/session_limit.info
index 03c74c5..d165221 100644
--- a/session_limit.info
+++ b/session_limit.info
@@ -3,4 +3,5 @@ description = "Limit simultaneous user sessions."
 core = 7.x
 dependencies[] = trigger
 files[] = session_limit.install
-files[] = session_limit.module
\ No newline at end of file
+files[] = session_limit.module
+files[] = session_limit.tokens.inc
diff --git a/session_limit.install b/session_limit.install
index 57ea268..1d43e23 100644
--- a/session_limit.install
+++ b/session_limit.install
@@ -10,7 +10,7 @@
  */
 function session_limit_uninstall() {
   variable_del('session_limit_max');
-  variable_del('session_limit_auto_drop');
+  variable_del('session_limit_behaviour');
   variable_del('session_limit_masquerade_ignore');
   db_query('DELETE FROM {variable} WHERE name LIKE "session_limit_rid_%"');
 }
diff --git a/session_limit.module b/session_limit.module
index ae39c5e..ddc151a 100644
--- a/session_limit.module
+++ b/session_limit.module
@@ -6,6 +6,21 @@
  */
 
 /**
+ * Do nothing if the session limit is exceeded.
+ */
+define('SESSION_LIMIT_DO_NOTHING', 0);
+
+/**
+ * Automatically drop sessions that would exceed the limit.
+ */
+define('SESSION_LIMIT_DROP', 1);
+
+/**
+ * Disallow sessions that would exceed the limit.
+ */
+define('SESSION_LIMIT_DISALLOW_NEW', 2);
+
+/**
  * Implements hook_help().
  */
 function session_limit_help($path, $args) {
@@ -30,12 +45,12 @@ function session_limit_help($path, $args) {
 function session_limit_perm() {
   return array(
     'administer session limits by role' => array(
-	  'title' => t('Administer session limits by role'),
-	  'description' = t(''),
+      'title' => t('Administer session limits by role'),
+      'description' => t(''),
     ),
     'administer session limits per user' => array(
-	  'title' => t('Administer session limits by user'),
-	  'description' = t(''),
+      'title' => t('Administer session limits by user'),
+      'description' => t(''),
     ),
   );
 }
@@ -58,29 +73,26 @@ function session_limit_menu() {
     'access callback' => 'user_is_logged_in',
     'type' => MENU_SUGGESTED_ITEM,
   );
-  $items['admin/user/session_limit'] = array(
+  $items['admin/people/session_limit'] = array(
     'title' => 'Session limit',
     'description' => 'Configure session limits.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('session_limit_settings'),
-    'access callback' => 'user_access',
     'access arguments' => array('administer site configuration'),
     'type' => MENU_NORMAL_ITEM,
   );
-  $items['admin/user/session_limit/defaults'] = array(
+  $items['admin/people/session_limit/defaults'] = array(
     'title' => 'Defaults',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('session_limit_settings'),
-    'access callback' => 'user_access',
     'access arguments' => array('administer site configuration'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
-  $items['admin/user/session_limit/roles'] = array(
+  $items['admin/people/session_limit/roles'] = array(
     'title' => 'Role limits',
     'description' => 'Configure session limits by role.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('session_limit_settings_byrole'),
-    'access callback' => 'user_access',
     'access arguments' => array('administer session limits by role'),
     'type' => MENU_LOCAL_TASK,
   );
@@ -89,7 +101,6 @@ function session_limit_menu() {
     'description' => 'Configure session limit for one user.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('session_limit_user_settings', 1),
-    'access callback' => 'user_access',
     'access arguments' => array('administer session limits per user'),
     'type' => MENU_LOCAL_TASK,
   );
@@ -105,10 +116,16 @@ function session_limit_settings() {
     '#maxlength' => 3,
     '#description' => t('The maximum number of active sessions a user can have. 0 implies unlimited sessions.'),
   );
-  $form['session_limit_auto_drop'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Automatically drop the oldest sessions without prompting.'),
-    '#default_value' => variable_get('session_limit_auto_drop', 0),
+  $limit_behaviours = array(
+    SESSION_LIMIT_DO_NOTHING => t('Do nothing.'),
+    SESSION_LIMIT_DROP => t('Automatically drop the oldest sessions without prompting.'),
+    SESSION_LIMIT_DISALLOW_NEW => t('Prevent new session.'),
+  );
+  $form['session_limit_behaviour'] = array(
+    '#type' => 'radios',
+    '#title' => t('When the session limit is exceeded'),
+    '#default_value' => variable_get('session_limit_behaviour', SESSION_LIMIT_DO_NOTHING),
+    '#options' => $limit_behaviours,
   );
   if (module_exists('masquerade')) {
     $form['session_limit_masquerade_ignore'] = array(
@@ -133,9 +150,13 @@ function session_limit_settings_validate($form, &$form_state) {
 }
 
 function session_limit_settings_byrole() {
-  $result = db_query('SELECT name, value FROM {variable} WHERE name LIKE "session_limit_rid_%" ORDER BY name');
+  $result = db_select('variable', 'v')
+    ->fields('v', array('name', 'value'))
+    ->condition('name', 'session_limit_rid_%', 'LIKE')
+    ->orderBy('name')
+    ->execute();
 
-  while ($setting = db_fetch_object($result)) {
+  foreach ($result as $setting) {
     $role_limits[$setting->name] = unserialize($setting->value);
   }
 
@@ -156,7 +177,10 @@ function session_limit_settings_byrole() {
 }
 
 function session_limit_settings_byrole_submit($form, &$form_state) {
-  db_query('DELETE FROM {variable} WHERE name LIKE "session_limit_rid_%"');
+  db_delete('variable')
+    ->condition('name', 'session_limit_rid_%', 'LIKE')
+    ->execute();
+
   foreach ($form_state['values'] as $setting_name => $setting_limit) {
     variable_set($setting_name, $setting_limit);
   }
@@ -185,16 +209,17 @@ function session_limit_init() {
       return;
     }
     if (module_exists('masquerade') && variable_get('session_limit_masquerade_ignore', FALSE)) {
-      $result = db_query('SELECT COUNT(s.uid) FROM {sessions} AS s
-        LEFT JOIN {masquerade} AS m ON s.uid = m.uid_as AND s.sid = m.sid
-        WHERE s.uid = %d AND m.sid IS NULL', $user->uid);
+      $query = db_select('sessions', 's')->condition('s.uid', $user->uid);
+      $query->leftJoin('masquerade', 'm', 's.uid = m.uid_as AND s.sid = m.sid');
+      $query->isNull('m.sid');
+      $result = $query->countQuery()->execute()->fetchField();
     }
     else {
-      $result = db_query('SELECT COUNT(*) FROM {sessions} WHERE uid = :uid', array(':uid' => $user->uid));
+      $result = db_select('sessions')->condition('uid', $user->uid)->countQuery()->execute()->fetchField();
     }
 
     $max_sessions = session_limit_user_max_sessions();
-    if (!empty($max_sessions) && $result->fetchField() > $max_sessions) {
+    if (!empty($max_sessions) && $result > $max_sessions) {
       session_limit_invoke_session_limit(session_id(), 'collision');
     }
     else {
@@ -230,38 +255,6 @@ function session_limit_action_info_alter(&$info) {
 }
 
 /**
- * Implements hook_token_list().
- */
-function session_limit_token_list($type = 'all') {
-  $tokens = array();
-
-  if ($type == 'session_limit' || $type == 'user' || $type == 'all') {
-    $tokens['session_limit']['session-limit-default'] = 'Maximum number of active sessions configured specific to the user.';
-    $tokens['session_limit']['session-limit-max']     = 'Maximum number of active sessions allowed, accounting for all configuration possibilities.';
-    $tokens['session_limit']['session-limit-role']    = 'Maximum number of active sessions allowed by role.';
-    $tokens['session_limit']['session-limit-user']    = 'Maximum number of active sessions configured specific to the user.';
-  }
-
-  return $tokens;
-}
-
-/**
- * Implements hook_token_values().
- */
-function session_limit_token_values($type, $object = NULL, $options = array()) {
-
-  if ($object == 'session_limit' || $object == 'system' || $type == 'global') {
-    global $user;
-    $tokens['session-limit-default'] = variable_get('session_limit_max', 1);
-    $tokens['session-limit-max']     = session_limit_user_max_sessions($user);
-    $tokens['session-limit-role']    = session_limit_user_max_sessions_byrole($user);
-    $tokens['session-limit-user']    = empty($user->session_limit) ? 0 : check_plain($user->session_limit);
-
-    return $tokens;
-  }
-}
-
-/**
  * Implements hook_user_view().
  */
 function session_limit_user_view($account, $view_mode) {
@@ -269,22 +262,23 @@ function session_limit_user_view($account, $view_mode) {
     $account->content['session_limit'] = array(
       '#title' => t('Session limit'),
       '#type' => 'user_profile_category',
-      'session_limit' => array('#value' => empty($account->session_limit) ? t('Default') : $account->session_limit)
+      'session_limit' => array('#value' => empty($account->data['session_limit']) ? t('Default') : $account->data['session_limit'])
     );
   }
 }
 
-function session_limit_user_settings($args, $account) {
+function session_limit_user_settings($form, $form_state, $account) {
   $form['account'] = array(
     '#type' => 'value',
     '#value' => $account,
   );
+
   $form['session_limit'] = array(
     '#type' => 'select',
     '#title' => t('Maximum sessions'),
     '#description' => t('Total number simultaneous active sessions this user may have at one time. The default defers to the limits that apply to each of the user\'s roles.'),
     '#required' => FALSE,
-    '#default_value' => empty($account->session_limit) ? 0 : $account->session_limit,
+    '#default_value' => empty($account->data['session_limit']) ? 0 : $account->data['session_limit'],
     '#options' => _session_limit_user_options(),
   );
   $form['submit'] = array(
@@ -306,7 +300,7 @@ function session_limit_user_settings_submit($form, &$form_state) {
   if (empty($form_state['values']['session_limit'])) {
     $form_state['values']['session_limit'] = NULL;
   }
-  user_save($form_state['values']['account'], array('session_limit' => $form_state['values']['session_limit']));
+  user_save($form_state['values']['account'], array('data' => array('session_limit' => $form_state['values']['session_limit'])));
   drupal_set_message(t('Session limit updated for %user.', array('%user' => $form_state['values']['account']->name)), 'status', TRUE);
 }
 
@@ -316,21 +310,32 @@ function session_limit_user_settings_submit($form, &$form_state) {
 function session_limit_page() {
   global $user;
 
-  if (variable_get('session_limit_auto_drop', 0)) {
+  if (variable_get('session_limit_behaviour', SESSION_LIMIT_DO_NOTHING) == SESSION_LIMIT_DROP) {
     // Get the oldest sessions.
-    $count = db_result(db_query("SELECT COUNT(sid) FROM {sessions} WHERE uid = :uid", array(':uid' => $user->uid)));
+    $count = db_query("SELECT COUNT(sid) FROM {sessions} WHERE uid = :uid", array(':uid' => $user->uid))->fetchField();
     $max_sessions = $count - session_limit_user_max_sessions($user);
-    $result = db_query_range("SELECT sid FROM {sessions} WHERE uid = :uid ORDER BY timestamp", array(':uid' => $user->uid), 0, $max_sessions);
 
-    while ($sids = db_fetch_object($result)) {
-      session_limit_invoke_session_limit($sids->sid, 'disconnect');
-    }
+    $result = db_select('sessions', 's')
+      ->condition('s.uid', $user->uid)
+      ->fields('s', array('sid'))
+      ->orderBy('timestamp', 'ASC')
+      ->range(0, $max_sessions)
+      ->execute();
 
+    foreach ($result as $session) {
+      session_limit_invoke_session_limit($session->sid, 'disconnect');
+    }
     drupal_goto();
   }
+  else if (variable_get('session_limit_behaviour', SESSION_LIMIT_DO_NOTHING) == SESSION_LIMIT_DISALLOW_NEW) {
+    session_destroy();
+    $user = drupal_anonymous_user();
+  
+    return;
+  }
 
-  $result = db_query('SELECT * FROM {sessions} WHERE uid = %d', $user->uid);
-  while ($obj =  db_fetch_object($result)) {
+  $result = db_query('SELECT * FROM {sessions} WHERE uid = :uid', array(':uid' => $user->uid));
+  foreach ($result as $obj) {
     $message = $user->sid == $obj->sid ? t('Your current session.') : '';
 
     $sids[$obj->sid] = t('<strong>Host:</strong> %host (idle: %time) <b>@message</b>',
@@ -356,12 +361,10 @@ function session_limit_page() {
  * Handler for submissions from session_limit_page().
  */
 function session_limit_page_submit($form, &$form_state) {
-  global $user;
-
   // There used to be drupal_set_messages here for the disconnect,
   // but now that there is trigger/action support built in, you can add
   // a message through there and make it say whatever you want.
-  if ($user->sid == $form_state['values']['sid']) {
+  if ($GLOBALS['user']->sid == $form_state['values']['sid']) {
     // force a normal logout for ourself.
     drupal_goto('user/logout');
   }
@@ -379,26 +382,9 @@ function _session_limit_user_options() {
   return $options;
 }
 
-/**
- * Implements hook_trigger_info().
- */
-function session_limit_trigger_info() {
-  return array(
-    'session_limit' => array(
-      'session_limit_collision' => array(
-        'label' => t('User logs in and has too many active sessions'),
-      ),
-      'session_limit_disconnect' => array(
-        'label' => t('When an active user is logged out by a newer session'),
-      ),
-    ),
-  );
-}
-
 function session_limit_user_max_sessions($account = array()) {
   if (empty($account)) {
-    global $user;
-    $account = $user;
+    $account = $GLOBALS['user'];
   }
 
   static $limits;
@@ -415,7 +401,7 @@ function session_limit_user_max_sessions($account = array()) {
 }
 
 function session_limit_user_max_sessions_byuser($account) {
-  return empty($account->session_limit) ? 0 : check_plain($account->session_limit);
+  return empty($account->data['session_limit']) ? 0 : check_plain($account->data['session_limit']);
 }
 
 function session_limit_user_max_sessions_byrole($account) {
@@ -429,16 +415,34 @@ function session_limit_user_max_sessions_byrole($account) {
 }
 
 /**
- * Implements hook_trigger_name().
+ * Implements hook_trigger_info().
+ */
+function session_limit_trigger_info() {
+  return array(
+    'session_limit' => array(
+      'session_limit_collision' => array(
+        'label' => t('User logs in and has too many active sessions'),
+      ),
+      'session_limit_disconnect' => array(
+        'label' => t('When an active user is logged out by a newer session'),
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_session_limit().
  */
 function session_limit_session_limit($sid, $op) {
-  $aids = _trigger_get_hook_aids('session_limit', $op);
+  // Find all the actions against this $op.
+  // Note: this notation requires the $op to match the bit in the trigger info keys after session_limit!
+  $aids = trigger_get_assigned_actions('session_limit_' . $op);
   $context = array(
     'hook' => 'session_limit',
     'op' => $op,
     'sid' => $sid,
   );
-  actions_do(array_keys($aids), $user, $context);
+  actions_do(array_keys($aids), $GLOBALS['user'], $context);
 
   switch ($op) {
     case 'collision':
@@ -449,8 +453,14 @@ function session_limit_session_limit($sid, $op) {
 
     case 'disconnect':
       $logout_message = t('You have been automatically logged out. Someone else has logged in with your username and password and the maximum number of @number simultaneous sessions was exceeded. This may indicate that your account has been compromised or that account sharing is not allowed on this site. Please contact the site administrator if you suspect your account has been compromised.', array('@number' => session_limit_user_max_sessions()));
-      $logout_message = 'messages|'. serialize(array('error' => array($logout_message)));
-      db_query("UPDATE {sessions} SET uid = 0, session = '%s' WHERE sid = '%s'", $logout_message, $sid);
+      $logout_message = 'messages|' . serialize(array('error' => array($logout_message)));
+      $query = db_update('sessions')
+        ->fields(array(
+          'uid' => 0,
+          'session' => $logout_message,
+        ))
+        ->condition('sid', $sid)
+        ->execute();
 
       watchdog('session_limit', 'Disconnected for excess active sessions.', array(), WATCHDOG_NOTICE);
       break;
