diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 2379156..b47529c 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,11 @@
+Administration Menu select 7.x-1.1 (2012-04-13)
+--------------------------------------------------------------------------------
+
+- #1125012 by Dave Reid, deciphered: Added support for Toolbar module.
+- #1125012 by Dave Reid, deciphered: Rewrote core functionality and API.
+- Added API documentation.
+
+
 Administration Menu select 7.x-1.0 (2012-04-12)
 --------------------------------------------------------------------------------
 
diff --git a/README.txt b/README.txt
index 904025a..7dc6411 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,16 @@
-The Admin Select module is a very basic module that provides a selectbox on the
-user settings form allowing the user to choose which Administration menu module
-they wish to use.
+The Administration Menu select module is a very basic module that provides a
+selectbox on the user settings form allowing the user to choose which
+Administration menu module they wish to use.
 
-Formatter Settings was written and is maintained by Stuart Clark (deciphered).
+Administration Menu select was written and is maintained by Stuart Clark
+(deciphered).
 - http://stuar.tc/lark
+
+
+Features
+--------------------------------------------------------------------------------
+
+* Support for:
+  * Admin module.
+  * Administration menu module.
+  * Toolbar module.
diff --git a/admin_select.api.php b/admin_select.api.php
new file mode 100644
index 0000000..2efa375
--- /dev/null
+++ b/admin_select.api.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Administration Menu select API documentation.
+ */
+
+/**
+ * Implements hook_admin_select_info().
+ *
+ * @return
+ *   An associative array of Administration Menu modules provided by this
+ *   module, keyed by tag name with the following properties:
+ *   - title: The human readable name of the module.
+ *   - access arguments: An array of arguments for user_access().
+ *   - suppress callback: The modules suppress function.
+ *   - file: (optional) The include file where the callback function resides.
+ */
+function hook_admin_select_info() {
+  $info = array();
+
+  $info['MYMODULE'] = array(
+    'title' => t('My Module'),
+    'access arguments' => array('access MYMODULE'),
+    'suppress callback' => 'MYMODULE_suppress',
+    'file' => drupal_get_path('module', 'MYMODULE') . '/MYMODULE.admin_select.inc',
+  );
+
+  return $info;
+}
diff --git a/admin_select.info b/admin_select.info
index d56c972..845a1f5 100644
--- a/admin_select.info
+++ b/admin_select.info
@@ -4,4 +4,4 @@ name = "Administration Menu select"
 files[] = admin_select.module
 files[] = includes/admin.inc
 files[] = includes/admin_menu.inc
-files[] = includes/system.inc
+files[] = includes/toolbar.inc
diff --git a/admin_select.module b/admin_select.module
index 861866c..34b1ba7 100644
--- a/admin_select.module
+++ b/admin_select.module
@@ -14,28 +14,59 @@ foreach (module_list() as $module) {
 }
 
 /**
+ * Implements hook_init().
+ */
+function admin_select_init() {
+  if (isset($GLOBALS['user']->data['admin_select'])) {
+    $current = $GLOBALS['user']->data['admin_select'];
+    $info = admin_select_get_admin_select_info();
+    foreach ($info as $key => $item) {
+      if ($key != $current) {
+        admin_select_suppress($item);
+      }
+    }
+  }
+}
+
+function admin_select_get_admin_select_info($check_access = TRUE) {
+  $info = module_invoke_all('admin_select_info');
+  drupal_alter('admin_select_info', $info);
+
+  if ($check_access) {
+    $info = array_map('_admin_select_check_access', $info);
+  }
+
+  return $info;
+}
+
+/**
  * Implements hook_form_user_profile_form_alter().
  */
 function admin_select_form_user_profile_form_alter(&$form, &$form_state) {
   if ($form['#user_category'] == 'account') {
-    $admin_modules = module_invoke_all('admin_select_module');
-    if (count($admin_modules) > 1) {
-      $form['admin_select'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Admin Select settings'),
-        '#collapsible' => TRUE,
-        '#weight' => 2,
-      );
-      $form['admin_select']['admin_select'] = array(
-        '#type' => 'select',
-        '#options' => $admin_modules,
-        '#default_value' => isset($form['#user']->data['admin_select']) ? $form['#user']->data['admin_select'] : current(array_keys($admin_modules)),
-      );
+    $info = admin_select_get_admin_select_info();
+    $options = array();
+    foreach ($info as $key => $item) {
+      if (!empty($item['access'])) {
+        $options[$key] = $item['title'];
+      }
     }
+    asort($options);
+    $form['admin_select'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Administration Select menu settings'),
+      '#collapsible' => TRUE,
+      '#weight' => 10,
+      '#access' => !empty($options),
+    );
+    $form['admin_select']['admin_select'] = array(
+      '#type' => 'select',
+      '#options' => array('' => t('None')) + $options,
+      '#default_value' => isset($form['#user']->data['admin_select']) ? $form['#user']->data['admin_select'] : '',
+    );
   }
 }
 
-
 /**
  * Implements hook_user_presave().
  */
@@ -44,3 +75,56 @@ function admin_select_user_presave(&$edit, $account, $category) {
     $edit['data']['admin_select'] = $edit['admin_select'];
   }
 }
+
+/**
+ * Implements hook_field_extra_fields().
+ */
+function admin_select_field_extra_fields() {
+  $info['user']['user']['form']['admin_select'] = array(
+    'label' => 'Admin select',
+    'description' => t('Admin select module account form elements'),
+    'weight' => 10,
+  );
+
+  return $info;
+}
+
+/**
+ * Suppress and admin item.
+ */
+function admin_select_suppress($item) {
+  if (!empty($item['include'])) {
+    include_once $item['include'];
+  }
+
+  if (!empty($item['suppress callback']) && function_exists($item['suppress callback'])) {
+    $item['suppress callback']();
+  }
+}
+
+/**
+ * Check to see if the current user has access to an admin item.
+ */
+function _admin_select_check_access(&$item) {
+  // Determine access callback, which will decide whether or not the current
+  // user has access to this path.
+  $item += array('access callback' => 'user_access');
+  $callback = empty($item['access callback']) ? FALSE : trim($item['access callback']);
+  // Check for a TRUE or FALSE value.
+  if (is_bool($callback)) {
+    $item['access'] = $callback;
+  }
+  else {
+    $arguments = isset($item['access arguments']) ? $item['access arguments'] : array();
+    // As call_user_func_array is quite slow and user_access is a very common
+    // callback, it is worth making a special case for it.
+    if ($callback == 'user_access') {
+      $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
+    }
+    elseif (function_exists($callback)) {
+      $item['access'] = call_user_func_array($callback, $arguments);
+    }
+  }
+
+  return $item;
+}
diff --git a/includes/admin.inc b/includes/admin.inc
index 52e6bc5..10b0662 100644
--- a/includes/admin.inc
+++ b/includes/admin.inc
@@ -5,19 +5,16 @@
  */
 
 /**
- * Implements hook_admin_select_init() on behalf of admin.module.
+ * Implements hook_admin_select_info() on behalf of admin.module.
  */
-function admin_admin_select_init($admin) {
-  if ($admin != 'admin') {
-    admin_suppress();
-  }
-}
+function admin_admin_select_info() {
+  $info = array();
 
-/**
- * Implements hook_admin_select_module().
- */
-function admin_admin_select_module() {
-  if (user_access('use admin toolbar')) {
-    return array('admin' => t('Admin module'));
-  }
+  $info['admin'] = array(
+    'title' => t('Admin module'),
+    'access arguments' => array('use admin toolbar'),
+    'suppress callback' => 'admin_suppress',
+  );
+
+  return $info;
 }
diff --git a/includes/admin_menu.inc b/includes/admin_menu.inc
index b489139..6892a0f 100644
--- a/includes/admin_menu.inc
+++ b/includes/admin_menu.inc
@@ -5,19 +5,16 @@
  */
 
 /**
- * Implements hook_admin_select_init() on behalf of admin_menu.module.
+ * Implements hook_admin_select_info() on behalf of admin_menu.module.
  */
-function admin_menu_admin_select_init($admin) {
-  if ($admin != 'admin_menu') {
-    admin_menu_suppress();
-  }
-}
+function admin_menu_admin_select_info() {
+  $info = array();
 
-/**
- * Implements hook_admin_select_module().
- */
-function admin_menu_admin_select_module() {
-  if (user_access('access administration menu')) {
-    return array('admin_menu' => t('Administration menu module'));
-  }
+  $info['admin_menu'] = array(
+    'title' => t('Administration menu module'),
+    'access arguments' => array('access administration menu'),
+    'suppress callback' => 'admin_menu_suppress',
+  );
+
+  return $info;
 }
diff --git a/includes/system.inc b/includes/system.inc
deleted file mode 100644
index 7bbe647..0000000
--- a/includes/system.inc
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- * @file
- * System module integration.
- */
-
-/**
- * Implements hook_init().
- */
-function admin_select_init() {
-  $admin_modules = module_invoke_all('admin_select_module');
-  if (count($admin_modules) > 1) {
-    global $user;
-    $admin = isset($user->data['admin_select']) ? $user->data['admin_select'] : current(array_keys($admin_modules));
-
-    // Invokes hook_admin_select_init().
-    module_invoke_all('admin_select_init', $admin);
-  }
-}
diff --git a/includes/toolbar.inc b/includes/toolbar.inc
new file mode 100644
index 0000000..721c9c7
--- /dev/null
+++ b/includes/toolbar.inc
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @file
+ * Toolbar module integration.
+ */
+
+/**
+ * Implements hook_admin_select_info() on behalf of toolbar.module.
+ */
+function toolbar_admin_select_info() {
+  $info = array();
+
+  $info['toolbar'] = array(
+    'title' => t('Toolbar'),
+    'access arguments' => array('access toolbar'),
+    'suppress callback' => 'admin_select_toolbar_suppress',
+  );
+
+  return $info;
+}
+
+/**
+ * Implements hook_page_alter() on behalf of toolbar.module.
+ *
+ * We have to do this as there is no toolbar_suppress() function in core so we
+ * must manually disable the toolbar in the page render array if desired.
+ *
+ * @see admin_select_toolbar_suppress()
+ */
+function admin_select_page_alter(&$page) {
+  if (admin_select_toolbar_suppress(FALSE) && !empty($page['page_top']['toolbar'])) {
+    $page['page_top']['toolbar']['#access'] = FALSE;
+  }
+}
+
+/**
+ * Adds a suppress callback on behalf of toolbar.module.
+ *
+ * @see admin_select_page_alter()
+ */
+function admin_select_toolbar_suppress($set = TRUE) {
+  static $suppress = FALSE;
+  if (!empty($set)) {
+    $suppress = TRUE;
+  }
+  return $suppress;
+}

