diff --git a/menu_token.admin.inc b/menu_token.admin.inc
index 1f65e72..1cfcf44 100644
--- a/menu_token.admin.inc
+++ b/menu_token.admin.inc
@@ -1,10 +1,8 @@
 <?php
 
-/*
+/**
  * @file
- *
- * Altering menu item edit form.
- *
+ * Contains the admin forms and form related functions.
  */
 
 
@@ -12,48 +10,126 @@
  * Implementation of hook_form_FORM_ID_alter().
  */
 function menu_token_form_menu_edit_item_alter(&$form, &$form_state) {
-  // Create new fieldset
-  $form['menu']['token'] = array(
-    '#type' => 'fieldset',
-    '#collapsible' => FALSE,
-    '#weight' => -1,
-  );
-
-  // Move form elements to the new fieldset.
-  $form['menu']['token']['link_title'] = $form['menu']['link_title'];
-  unset($form['menu']['link_title']);
-  $form['menu']['token']['link_path'] = $form['menu']['link_path'];
-  unset($form['menu']['link_path']);
-  
-  // Load saved token pathes.
-  $menu_token_item = menu_token_get($form['menu']['mlid']['#value']);
-  
-  // Replace fake path (<front>) with user inputed one.
-  if ($menu_token_item) {
-    $form['menu']['token']['link_path']['#default_value'] = $menu_token_item['link_path'];
-  }
+	//print_r($form);
+  if ($form['menu']['module']['#value'] == 'menu') {
+    $types = menu_token_get_plugin_types();
+    $options = $form['menu']['options']['#value'];
+	$has_token = false;
+    // Replace fake path (<front>) with user inputed one.
+    if (!empty($options['menu_token_link_path'])) {
+      $form['menu']['link_path']['#default_value'] = $options['menu_token_link_path'];
+		$has_token=true;
+    }
+	//maintain compatibility with older version entries
+	$pattern = menu_token_get($form['menu']['mlid']['#value']);
+	if (is_array($pattern)) {
+		$form['menu']['link_path']['#default_value'] = $pattern['link_path'];
+		$has_token=true;
+	}
+
+    $form['menu']['link_title']['#weight'] = -5;
+    $form['menu']['link_path']['#weight'] = -4;
+
+    $form['menu']['menu_token_enabled'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Use tokens in title and in path.'),
+      '#default_value' => $has_token,
+      '#weight' => -3,
+    );
+
+    $form['menu']['menu_token_options'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Menu Token options'),
+      '#collapsible' => TRUE,
+      '#weight' => -2,
+      '#states' => array(
+        'visible' => array(
+          ':input[name="menu_token_enabled"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    foreach ($types as $type => $items) {
+      $info = token_get_list($type);
+      $default = NULL;
+
+      if (isset($form_state['values']['menu_token_type_' . $type])) {
+        $default = $form_state['values']['menu_token_type_' . $type];
+      }
+      else if (!empty($options['menu_token_data'][$type])) {
+        $default = $options['menu_token_data'][$type]['plugin'];
+      }
+
+      $default = isset($default) && in_array($default, array_keys($items)) ? $default : NULL;
+
+      $form['menu_token_options'][$type] = array(
+        '#type' => 'container',
+      );
 
-  $form['menu']['token']['token_enabled'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use tokens in title and in path.'),
-    '#default_value' => isset($menu_token_item),
-  );
-
-  // Token substitutions help.
-  $form['menu']['token']['token_help'] = array(
-    '#title' => t('Replacement patterns'),
-    '#type' => 'fieldset',
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-
-  $form['menu']['token']['token_help']['help'] = array(
-    '#value' => theme('token_help', 'global'),
-  );
-
-  // Add custom validation and submit functions.
-  array_unshift($form['#validate'], 'menu_token_form_menu_edit_item_validate');
-  $form['#submit'][] = 'menu_token_form_menu_edit_item_submit';
+      $form['menu']['menu_token_options'][$type]['menu_token_type_' . $type] = array(
+        '#type' => 'select',
+        '#title' => t('Method for') . ' ' . $info['name'],
+        '#description' => $info['description'],
+        '#options' => array('_none' => t('Disabled')),
+        '#default_value' => isset($default) ? $default : array('_none'),
+        '#ajax' => array(
+          'callback' => 'menu_token_method_callback',
+          'wrapper' => 'menu-token-method-options-' . $type,
+          'method' => 'replace',
+          'effect' => 'fade',
+        ),
+      );
+
+      foreach ($items as $name => $label) {
+        $form['menu']['menu_token_options'][$type]['menu_token_type_' . $type]['#options'][$name] = $label;
+      }
+
+      $form['menu']['menu_token_options'][$type]['menu_token_method_options_wrapper'] = array(
+        '#type' => 'container',
+        '#prefix' => '<div id="menu-token-method-options-' . $type . '">',
+        '#suffix' => '</div>',
+      );
+
+      if (isset($default) && $handler = menu_token_get_handler($default)) {
+        if ($append = $handler->form_options($options['menu_token_data'][$type]['options'])) {
+          $form['menu']['menu_token_options'][$type]['menu_token_method_options_wrapper']['menu_token_method_options'] = array(
+            '#type' => 'fieldset',
+            '#title' => t('Method options'),
+            '#collapsible' => TRUE,
+          ) + $append;
+        }
+      }
+    }
+
+    // Create new fieldset
+    $form['menu']['menu_token_replacement_patterns'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Replacement patterns'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => -1,
+      '#states' => array(
+        'visible' => array(
+          ':input[name="menu_token_enabled"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    $form['menu']['menu_token_replacement_patterns']['patterns'] = array(
+      '#theme' => 'token_tree',
+      '#token_types' => array_keys($types),
+    );
+
+    // Add custom validation and submit functions.
+    array_unshift($form['#validate'], 'menu_token_form_menu_edit_item_validate');
+    array_unshift($form['#submit'], 'menu_token_form_menu_edit_item_submit');
+
+    foreach (array_keys(menu_token_get_plugins()) as $plugin) {
+      if ($handler = menu_token_get_handler($plugin)) {
+        $handler->form_alter($form, $form_state);
+      }
+    }
+  }
 }
 
 
@@ -61,32 +137,96 @@ function menu_token_form_menu_edit_item_alter(&$form, &$form_state) {
  * Custom validation for form menu_edit_item.
  */
 function menu_token_form_menu_edit_item_validate($form, &$form_state) {
-  // If token replacing enabled.
-  if ($form_state['values']['menu']['token']['token_enabled']) {
+  $values = &$form_state['values']['menu'];
+
+  // If token replacing is enabled and this is a custom menu item.
+  if ($values['module'] == 'menu' && !empty($values['menu_token_enabled'])) {
+    // Store the actual path in the options array.
+    $values['options']['menu_token_link_path'] = $values['link_path'];
+    $values['options']['menu_token_data'] = array();
+	$values['options']['alter'] = true;
+    foreach (array_keys(menu_token_get_plugin_types()) as $type) {
+      if (!empty($values['menu_token_type_' . $type]) && $values['menu_token_type_' . $type] != '_none') {
+        $plugin = $values['menu_token_type_' . $type];
+
+        if ($handler = menu_token_get_handler($plugin)) {
+          $values['options']['menu_token_data'][$type] = array(
+            'type' => $type,
+            'plugin' => $plugin,
+            'options' => array(),
+          );
+
+          // Validate the form via the handler.
+          if ($output = $handler->form_validate($form, $form_state)) {
+            // We append the return value of the handler's form validator to
+            // the options array.
+            $values['options']['menu_token_data'][$type]['options'] += $output;
+          }
+        }
+      }
+    }
+
     // Substitute link_path with fake well known '<front>'.
-    $form_state['values']['menu']['link_title'] = $form_state['values']['menu']['token']['link_title'];
-    $form_state['values']['menu']['link_path'] = '<front>';
-    // Set 'alter' option to use hook_translated_menu_link().
-    $form_state['values']['menu']['options']['alter'] = TRUE;
+    $values['link_path'] = '<front>';
   }
   else {
-    $form_state['values']['menu']['link_title'] = $form_state['values']['menu']['token']['link_title'];
-    $form_state['values']['menu']['link_path'] = $form_state['values']['menu']['token']['link_path'];
+    // Use unset() rather than setting to empty string to avoid redundant
+    // serialized data being stored.
+    unset($values['options']['attributes']['menu_token_link_path'], $values['options']['menu_token_data']);
   }
 }
 
 
 /**
- * Custom submit function for form menu_edit_form.
+ * Custom submit for form menu_edit_item.
  */
 function menu_token_form_menu_edit_item_submit($form, &$form_state) {
-  $mlid = $form_state['values']['menu']['mlid'];
-  if (!$form_state['values']['menu']['token']['token_enabled']) {
-    menu_token_unset($mlid);
+	//print_r(func_get_args());
+	//exit();
+  $values = &$form_state['values']['menu'];
+	$stored = false;
+  // If token replacing is enabled and this is a custom menu item.
+  if ($values['module'] == 'menu' && !empty($values['menu_token_enabled'])) {
+    foreach (array_keys(menu_token_get_plugin_types()) as $type) {
+      if (!empty($values['menu_token_type_' . $type]) && $values['menu_token_type_' . $type] != '_none') {
+        $plugin = $values['menu_token_type_' . $type];
+
+        if ($handler = menu_token_get_handler($plugin)) {
+          // Validate the form via the handler.
+          if ($output = $handler->form_submit($form, $form_state)) {
+            $values['options']['menu_token_data'][$type]['options'] += $output;
+			$stored = true;
+          }
+        }
+      }
+    }
+	if (!$stored) {
+		
+	}
   }
-  else {
-    menu_token_set($mlid, array(
-      'link_path' => trim($form_state['values']['menu']['token']['link_path'])
-    ));
+}
+
+
+/**
+ * Implementation hook_form_FORM_ID_alter().
+ */
+function menu_token_form_menu_overview_form_alter(&$form, $form_state) {
+  foreach ($form as &$item) {
+    if (isset($item['mlid'], $item['#item']['options']) && isset($item['#item']['options']['menu_token_link_path'])) {
+      $item['title']['#markup'] .= theme('menu_token_uses_tokens');
+    }
   }
-}
\ No newline at end of file
+}
+
+
+/**
+ * Ajax callback for the method select dropdown.
+ */
+function menu_token_method_callback($form, $form_state) {
+  $parents = $form_state['triggering_element']['#array_parents'];
+
+  array_pop($parents);
+  array_push($parents, 'menu_token_method_options_wrapper');
+
+  return drupal_array_get_nested_value($form, $parents);
+}
diff --git a/menu_token.inc b/menu_token.inc
index 5953c30..111d1dc 100644
--- a/menu_token.inc
+++ b/menu_token.inc
@@ -7,17 +7,6 @@
  *
  */
 
-
-/*
- * Load menu token configuration for menu item from database.
- *
- * @param $mlid
- *   Menu item id.
- *
- * @return array
- *   Options array.
- *
- */
 function menu_token_get($mlid) {
   global $menu_token_conf;
 
@@ -33,51 +22,141 @@ function menu_token_get($mlid) {
   return $menu_token_conf[$mlid];
 }
 
+/**
+ * The menu token handler interface should be implemented by all menu token plugins.
+ */
+interface menu_token_handler {
+  /**
+   * You can provide options for your menu token handler via this function.
+   * The return value will be appended to the form as soon as the administrator
+   * chooses your plugin.
+   */
+  function form_options($options);
+
+  /**
+   * This function allows your plugin to act upon form submission. The return
+   * value will be added to the $options array and thus should be an array itself.
+   *
+   * Note: Only invoked for selected plugins.
+   */
+  function form_submit($form, &$form_state);
+
+  /**
+   * This function allows your plugin to act upon form validation. The return
+   * value will be added to the $options array and thus should be an array itself.
+   *
+   * Note: Only invoked for selected plugins.
+   */
+  function form_validate($form, &$form_state);
+
+  /**
+   * You can alter the menu item administration form with this function.
+   */
+  function form_alter(&$form, &$form_state);
+
+  /**
+   * This function is used to load the relevant token replacement object.
+   */
+  function object_load($options);
+}
 
-/*
- * Insert/update menu token configuration for menu item to database.
- *
- * @param $mlid
- *   Menu item id.
+
+/**
+ * Retrieves the handler of a menu token plugin.
  *
- * @param $options
- *   Options array (mlid, link_path).
+ * @param $name
+ *   The name of a plugin.
  *
+ * @return
+ *   A menu_token_handler object that represents the handler of the plugin
+ *   defined by $name or FALSE if no plugin named $name exists.
  */
-function menu_token_set($mlid, $options) {
-  global $menu_token_conf;
+function menu_token_get_handler($name) {
+  static $handlers;
+
+  if (!isset($handlers[$name])) {
+    if ($plugin = menu_token_get_plugin($name)) {
+      $handlers[$name] = new $plugin['class']($plugin);
+    }
+  }
 
-  db_query('DELETE FROM {menu_token} WHERE mlid = %d', $mlid);
-  $options['mlid'] = $mlid;
-  $record = (object) $options;
-  drupal_write_record('menu_token', $record);
+  if (isset($handlers[$name])) {
+    return $handlers[$name];
+  }
 
-  unset ($menu_token_conf[$mlid]);
+  return FALSE;
 }
 
 
-/*
- * Delete menu token configuration for menu item from database.
+/**
+ * Retrieves a menu token plugin.
  *
- * @param $mlid
- *   Menu item id.
+ * @param $name
+ *   The name of a plugin.
  *
+ * @return
+ *   An array containing information about the plugin as returned by the ctools
+ *   plugin API.
  */
-function menu_token_unset($mlid) {
-  global $menu_token_conf;
+function menu_token_get_plugin($name) {
+  $plugins = _menu_token_plugin_info()->plugins;
+  
+  if (isset($plugins[$name])) {
+    return $plugins[$name];
+  }
+
+  return FALSE;
+}
 
-  db_query('DELETE FROM {menu_token} WHERE mlid = %d', $mlid);
 
-  unset ($menu_token_conf[$mlid]);
+/**
+ * Retrieves a list of all available menu token plugins.
+ *
+ * @return
+ *   An array containing all available plugins.
+ */
+function menu_token_get_plugins() {
+  return _menu_token_plugin_info()->plugins;
 }
 
 
 /**
- * Returns true if menu item is being generated by menu administration modules.
+ * Retrieves a list of all token types that are covered by the available menu
+ * token plugins.
  *
- * @see menu_overview_form().
+ * @return
+ *   An array containing all token types covered by menu token plugins.
+ */
+function menu_token_get_plugin_types() {
+  return _menu_token_plugin_info()->types;
+}
+
+
+/**
+ * Builds and returns information about the menu token plugins and their types.
  */
-function _menu_token_menu_admin($item) {
-  global $menu_admin;
-  return $menu_admin;
+function _menu_token_plugin_info() {
+  $cache = cache_get("menu_token_plugins");
+
+  if (!isset($cache)) {
+    ctools_include('plugins');
+    
+    $cache = (object) array(
+      'plugins' => array(),
+      'types' => array(),
+    );
+
+    $info = token_get_info();
+    
+    foreach (ctools_get_plugins('menu_token', 'plugins') as $plugin) {
+      if (isset($info['types'][$plugin['type']]) && $class = ctools_plugin_get_class($plugin, 'handler')) {        
+        $cache->plugins[$plugin['name']] = $plugin;
+        $cache->plugins[$plugin['name']]['class'] = $class;
+        $cache->types[$plugin['type']][$plugin['name']] = $plugin['label'];
+      }
+    }
+  }
+  cache_set("menu_token_plugins", $cache);
+  return $cache;
 }
+
diff --git a/menu_token.info b/menu_token.info
index 3c142fa..d8a6a8a 100644
--- a/menu_token.info
+++ b/menu_token.info
@@ -1,4 +1,7 @@
 name = Menu Token
 description = "Provides tokens in menu items(links)."
 dependencies[] = token
+dependencies[] = ctools
+dependencies[] = menu
+
 core = 6.x
diff --git a/menu_token.install b/menu_token.install
index 7a60a62..58d2b2d 100644
--- a/menu_token.install
+++ b/menu_token.install
@@ -89,4 +89,21 @@ function menu_token_update_6000() {
   }
 
   return $ret;
+}
+
+
+function menu_token_update_6001() {
+	$q = db_query('SELECT * FROM {menu_token}');
+	while($result = db_fetch_array($q)) {
+		$q2 = db_fetch_array(db_query("select options from {menu_links} where mlid = %d", $result['mlid']));
+		$options = unserialize($q2['options']);
+		$options['menu_token_link_path'] = $result['link_path'];
+		$options['menu_token_data'] =  array();
+		$options['alter'] = true;
+		if (!array_key_exists("attributes", $options)) {
+			$options['attributes'] = array("title" => "");
+		}
+		$ret[] = db_query("update {menu_links} set options = '%s' where mlid = %d", serialize($options), $result['mlid']);
+	}
+  return $ret;
 }
\ No newline at end of file
diff --git a/menu_token.module b/menu_token.module
index 60fc1db..5dca310 100644
--- a/menu_token.module
+++ b/menu_token.module
@@ -1,54 +1,12 @@
 <?php
 
-module_load_include('inc', 'menu_token');
-module_load_include('inc', 'menu_token', 'menu_token.admin');
-
 /**
- * Implementation of hook_translated_menu_link().
+ * @file
+ * Menu Token module.
  */
-function menu_token_translated_menu_link_alter(&$item, $map) {
-  $mlid = $item['mlid'];
-  $menu_token_item = menu_token_get($mlid);
-
-  // Check whether we should replace the path.
-  if (isset($menu_token_item)) {
-    // If item is generated by admin menu module, tokens should not be replaced and
-    // indicator that tokens are used should be shown.
-    if (_menu_token_menu_admin($item)) {
-      $item['title'] .= theme('menu_token_uses_tokens');
-      $item['localized_options']['html'] = TRUE;
-    }
-    else {
-      // Replace with tokens.
-      $item['title'] =  token_replace($item['title'], 'global');
-      $item['link_path'] = token_replace($menu_token_item['link_path'], 'global');
-      $item['href'] = $item['link_path'];
-
-      // Override active trail if showing front page but translated link is not to front page.
-      // NOTE: This relies on any parent of a tokenised menu item having "option" flag "alter" set,
-      // which is most easily achieved by setting it to use token translation but not specifying a token.
-      // Otherwise parent does not get processed through this function and because its untranslated child has
-      // an href of <front>, the menu system thinks it is part of the active trail to the front page.
-      if (drupal_is_front_page() && $item['href'] != drupal_get_normal_path(variable_get('site_frontpage', 'node'))) {
-        $item['in_active_trail'] = FALSE;
-      }
-
-      // Check whether path is external.
-      if (menu_path_is_external($item['link_path'])) {
-        return;
-      }
-
-      // Load menu_item and check access.
-      if ($menu_item = menu_get_item($item['link_path'])) {
-        $item['access'] = $menu_item['access'];
-        return;
-      }
-
-      $item['access'] = FALSE;
-    }
-  }
-}
 
+module_load_include('inc', 'menu_token');
+module_load_include('inc', 'menu_token', 'menu_token.admin');
 
 /**
  * Implementation of hook_theme().
@@ -61,10 +19,200 @@ function menu_token_theme() {
 
 
 /**
- * Theming "uses tokens" label.
+ * Appends the "uses tokens" label to links on the admin menu links overview
+ * form.
  */
 function theme_menu_token_uses_tokens() {
   drupal_add_css(drupal_get_path('module', 'menu_token') . '/menu_token.css');
+  return ' <span class="uses-tokens">' . t('uses tokens') . '</span>';
+}
+
+
+/**
+ * Implements hook_ctools_plugin_type().
+ */
+function menu_token_ctools_plugin_type() {
+  return array(
+    'plugins' => array(
+      'cache' => TRUE,
+      'use hooks' => TRUE,
+      'classes' => array('handler'),
+    ),
+  );
+}
+
+
+/**
+ * Implements hook_menu_token_plugins().
+ */
+function menu_token_menu_token_plugins() {
+  if (module_exists('node')) {
+    $plugins['node_context'] = array(
+      'type' => 'node',
+      'label' => t('Node from context'),
+      'description' => t('Picks a node from the current context.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_node_context.inc',
+        'class' => 'menu_token_node_context',
+      ),
+    );
+
+    $plugins['node_random'] = array(
+      'type' => 'node',
+      'label' => t('Random node'),
+      'description' => t('Picks a random node from the database.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_node_random.inc',
+        'class' => 'menu_token_node_random',
+      ),
+    );
+
+    $plugins['node_user_defined'] = array(
+      'type' => 'node',
+      'label' => t('User-defined node'),
+      'description' => t('Uses a user-defined node id to retrieve the node object.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_node_user_defined.inc',
+        'class' => 'menu_token_node_user_defined',
+      ),
+    );
+  }
+
+  if (module_exists('user')) {
+    $plugins['user_context'] = array(
+      'type' => 'user',
+      'label' => t('User from context'),
+      'description' => t('Picks a user from the current context.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_user_context.inc',
+        'class' => 'menu_token_user_context',
+      ),
+    );
+
+    $plugins['user_random'] = array(
+      'type' => 'user',
+      'label' => t('Random user'),
+      'description' => t('Picks a random user from the database.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_user_random.inc',
+        'class' => 'menu_token_user_random',
+      ),
+    );
+
+    $plugins['user_user_defined'] = array(
+      'type' => 'user',
+      'label' => t('User-defined user'),
+      'description' => t('Uses a user-defined user name to retrieve the user object.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_user_user_defined.inc',
+        'class' => 'menu_token_user_user_defined',
+      ),
+    );
+  }
+  
+  if (module_exists('taxonomy')) {
+    $plugins['term_context'] = array(
+      'type' => 'term',
+      'label' => t('Taxonomy term from context'),
+      'description' => t('Picks a taxonomy term from the current context.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_term_context.inc',
+        'class' => 'menu_token_term_context',
+      ),
+    );
+
+    $plugins['term_random'] = array(
+      'type' => 'term',
+      'label' => t('Random taxonomy term'),
+      'description' => t('Picks a random taxonomy term from the one of the defined vocabularies.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_term_random.inc',
+        'class' => 'menu_token_term_random',
+      ),
+    );
+
+    $plugins['term_user_defined'] = array(
+      'type' => 'term',
+      'label' => t('User-defined taxonomy term'),
+      'description' => t('Uses a user-defined term to retrieve the taxonomy term object.'),
+      'handler' => array(
+        'path' => drupal_get_path('module', 'menu_token') . '/plugins',
+        'file' => 'menu_token_term_user_defined.inc',
+        'class' => 'menu_token_term_user_defined',
+      ),
+    );
+  }
+
+  return $plugins;
+}
+
+/**
+ * Implementation of hook_translated_menu_link().
+ */
+function menu_token_translated_menu_link_alter(&$item, $map) {
+  	global $menu_admin;
+	if ($item['menu_name'] == "primary_links") {
+		//print_r($item);
+	}
+	  // Check whether we should replace the path.
+	  if (empty($menu_admin) && isset($item['options']['menu_token_link_path'])) {
+	    $info = token_get_list();
+	    $data = array();
+
+	    if (isset($item['options']['menu_token_data'])) {
+	      foreach ($item['options']['menu_token_data'] as $type => $options) {
+	        if (!empty($info['types'][$type]) && $handler = menu_token_get_handler($options['plugin'])) {
+	          if ($object = $handler->object_load($options['options'])) {
+	            $data[$type] = $object;
+	          }
+	        }
+	      }
+	    }
+	    // If item is generated by admin menu module, tokens should not be replaced and
+	    // indicator that tokens are used should be shown.
+		
+	    $item['title'] =  token_replace($item['title'], "domain");
+	    $item['link_path'] = token_replace($item['options']['menu_token_link_path'], "domain");
+	    $item['href'] = $item['link_path'];
+		//print_r($item);
+	    // Override active trail if showing front page but translated link is not to front page.
+	    // NOTE: This relies on any parent of a tokenised menu item having "option" flag "alter" set,
+	    // which is most easily achieved by setting it to use token translation but not specifying a token.
+	    // Otherwise parent does not get processed through this function and because its untranslated child has
+	    // an href of <front>, the menu system thinks it is part of the active trail to the front page.
+	    if (drupal_is_front_page() && $item['href'] != drupal_get_normal_path(variable_get('site_frontpage', 'node'))) {
+	      $item['in_active_trail'] = FALSE;
+	    }
+
+	    // Check whether path is external.
+	    if (_menu_token_url_is_external($item['link_path'])) {
+	      return;
+	    }
+
+	    // Load menu_item and check access.
+	    if ($menu_item = menu_get_item($item['link_path'])) {
+	      $item['access'] = $menu_item['access'];
+	      return;
+	    }
+
+	    $item['access'] = FALSE;
+	  }
+}
+
+
+function _menu_token_url_is_external($path) {
+  $colonpos = strpos($path, ':');
+  // Only call the slow drupal_strip_dangerous_protocols() if $path contains a
+  // ':' before any / ? or #.
+  return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && check_url($path) == $path;
+}
+
 
-  return '<span class="menu_token_uses_tokens">' . t(' uses tokens') . '</span>';
-}
\ No newline at end of file
diff --git a/plugins/menu_token_node_context.inc b/plugins/menu_token_node_context.inc
new file mode 100644
index 0000000..f01d577
--- /dev/null
+++ b/plugins/menu_token_node_context.inc
@@ -0,0 +1,27 @@
+<?php
+
+class menu_token_node_context implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (arg(0) == 'node' && is_numeric(arg(1))) {
+      return node_load(arg(1));
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_node_random.inc b/plugins/menu_token_node_random.inc
new file mode 100644
index 0000000..6c78ff2
--- /dev/null
+++ b/plugins/menu_token_node_random.inc
@@ -0,0 +1,34 @@
+<?php
+
+class menu_token_node_random implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    $nid = db_select('node', 'n')
+        ->fields('n', array('nid'))
+        ->orderRandom()
+        ->range(0, 1)
+        ->execute()
+        ->fetchField(0);
+
+    if ($nid) {
+      return node_load($nid);
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_node_user_defined.inc b/plugins/menu_token_node_user_defined.inc
new file mode 100644
index 0000000..5461c2d
--- /dev/null
+++ b/plugins/menu_token_node_user_defined.inc
@@ -0,0 +1,43 @@
+<?php
+
+class menu_token_node_user_defined implements menu_token_handler {
+  function form_options($options) {
+    $output['menu_token_node_user_defined'] = array(
+      '#title' => t('Node ID'),
+      '#description' => t('The node id of the node that this token handler should load.'),
+      '#type' => 'textfield',
+      '#default_value' => isset($options['nid']) ? $options : '',
+    );
+
+    return $output;
+  }
+
+  function form_submit($form, &$form_state) {
+    $options['nid'] = $form_state['input']['menu_token_node_user_defined'];
+    return $options;
+  }
+
+  function form_validate($form, &$form_state) {
+    $nid = $form_state['input']['menu_token_node_user_defined'];
+    if (!is_numeric($nid)) {
+      form_set_error('menu_token_node_user_defined', t('Node ID should be numeric.'));
+      return;
+    }
+    if (!node_load($nid)) {
+      form_set_error('menu_token_node_user_defined', t('Node should exist.'));
+      return;
+    }
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (is_numeric($options['nid'])) {
+      return node_load($options['nid']);
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_term_context.inc b/plugins/menu_token_term_context.inc
new file mode 100644
index 0000000..6746edc
--- /dev/null
+++ b/plugins/menu_token_term_context.inc
@@ -0,0 +1,27 @@
+<?php
+
+class menu_token_term_context implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) {
+      return taxonomy_term_load(arg(2));
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_term_random.inc b/plugins/menu_token_term_random.inc
new file mode 100644
index 0000000..d076a2e
--- /dev/null
+++ b/plugins/menu_token_term_random.inc
@@ -0,0 +1,34 @@
+<?php
+
+class menu_token_term_random implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    $tid = db_select('taxonomy_term_data', 't')
+        ->fields('t', array('tid'))
+        ->orderRandom()
+        ->range(0, 1)
+        ->execute()
+        ->fetchField(0);
+
+    if ($tid) {
+      return taxonomy_term_load($tid);
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_term_user_defined.inc b/plugins/menu_token_term_user_defined.inc
new file mode 100644
index 0000000..2c1c38e
--- /dev/null
+++ b/plugins/menu_token_term_user_defined.inc
@@ -0,0 +1,43 @@
+<?php
+
+class menu_token_term_user_defined implements menu_token_handler {
+  function form_options($options) {
+    $output['menu_token_term_user_defined'] = array(
+      '#title' => t('Taxonomy term'),
+      '#description' => t('The taxonomy term ID that this token handler should load.'),
+      '#type' => 'textfield',
+      '#default_value' => isset($options['tid']) ? $options : '',
+    );
+
+    return $output;
+  }
+  
+  function form_submit($form, &$form_state) {
+    $options['tid'] = $form_state['input']['menu_token_term_user_defined'];
+    return $options;
+  }
+
+  function form_validate($form, &$form_state) {
+    $tid = $form_state['input']['menu_token_term_user_defined'];
+    if (!is_numeric($tid)) {
+      form_set_error('menu_token_term_user_defined', t('Taxonomy term ID should be numeric.'));
+      return;
+    }
+    if (!taxonomy_term_load($tid)) {
+      form_set_error('menu_token_term_user_defined', t('Taxonomy term should exist.'));
+      return;
+    }
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (is_numeric($options['tid'])) {
+      return taxonomy_term_load($options['tid']);
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_user_context.inc b/plugins/menu_token_user_context.inc
new file mode 100644
index 0000000..09e53e8
--- /dev/null
+++ b/plugins/menu_token_user_context.inc
@@ -0,0 +1,27 @@
+<?php
+
+class menu_token_user_context implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (arg(0) == 'user' && is_numeric(arg(1))) {
+      return user_load(arg(1));
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_user_random.inc b/plugins/menu_token_user_random.inc
new file mode 100644
index 0000000..dd5307a
--- /dev/null
+++ b/plugins/menu_token_user_random.inc
@@ -0,0 +1,35 @@
+<?php
+
+class menu_token_user_random implements menu_token_handler {
+  function form_options($options) {
+    // Nothing to do here.
+  }
+
+  function form_submit($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_validate($form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    $uid = db_select('users', 'u')
+        ->fields('u', array('uid'))
+        ->condition('uid', 0, '!=')
+        ->orderRandom()
+        ->range(0, 1)
+        ->execute()
+        ->fetchField(0);
+
+    if ($uid) {
+      return user_load($uid);
+    }
+
+    return FALSE;
+  }
+}
diff --git a/plugins/menu_token_user_user_defined.inc b/plugins/menu_token_user_user_defined.inc
new file mode 100644
index 0000000..84bfb37
--- /dev/null
+++ b/plugins/menu_token_user_user_defined.inc
@@ -0,0 +1,43 @@
+<?php
+
+class menu_token_user_user_defined implements menu_token_handler {
+  function form_options($options) {
+    $output['menu_token_user_user_defined'] = array(
+      '#title' => t('User ID'),
+      '#description' => t('The user ID of the user that this token handler should load.'),
+      '#type' => 'textfield',
+      '#default_value' => isset($options['uid']) ? $options : '',
+    );
+
+    return $output;
+  }
+  
+  function form_submit($form, &$form_state) {
+    $options['uid'] = $form_state['input']['menu_token_user_user_defined'];
+    return $options;
+  }
+
+  function form_validate($form, &$form_state) {
+    $uid = $form_state['input']['menu_token_user_user_defined'];
+    if (!is_numeric($uid)) {
+      form_set_error('menu_token_user_user_defined', t('User ID should be numeric.'));
+      return;
+    }
+    if (!user_load($uid)) {
+      form_set_error('menu_token_user_user_defined', t('User should exist.'));
+      return;
+    }
+  }
+
+  function form_alter(&$form, &$form_state) {
+    // Nothing to do here.
+  }
+
+  function object_load($options) {
+    if (is_numeric($options['uid'])) {
+      return user_load($options['uid']);
+    }
+
+    return FALSE;
+  }
+}

