diff --git token_example/token_example.info token_example/token_example.info
new file mode 100644
index 0000000..eb89198
--- /dev/null
+++ token_example/token_example.info
@@ -0,0 +1,10 @@
+; $Id$
+
+name = Token example
+description = An example module showing how to define and use tokens.
+dependencies[] = token
+package = Example modules
+core = 6.x
+files[] = token_example.module
+files[] = token_example.tokens.inc
+files[] = token_example.test
diff --git token_example/token_example.module token_example/token_example.module
new file mode 100644
index 0000000..7877117
--- /dev/null
+++ token_example/token_example.module
@@ -0,0 +1,252 @@
+<?php
+// $Id$
+
+/**
+ * Implements hook_menu().
+ */
+function token_example_menu() {
+  $items['examples/token'] = array(
+    'title' => 'Token example',
+    'description' => 'Test replacement tokens in real time.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('token_example_example_form'),
+    'access callback' => TRUE,
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_entity_info_alter().
+ *
+ * @todo Remove this when the testbot can properly pick up dependencies
+ * for contrib modules.
+ */
+function token_example_entity_info_alter(&$info) {
+  if (isset($info['taxonomy_term'])) {
+    $info['taxonomy_term']['token type'] = 'term';
+  }
+  if (isset($info['taxonomy_vocabulary'])) {
+    $info['taxonomy_vocabulary']['token type'] = 'vocabulary';
+  }
+}
+
+/**
+ * Form builder; display lists of supported token entities and text to tokenize.
+ */
+function token_example_example_form(&$form_state) {
+  $token_types = token_get_list();
+
+  // Scan through the list of token classes for supported token entities.
+  foreach ($token_types as $type => $info) {
+    $object_callback = "_token_example_get_{$type}";
+    if (function_exists($object_callback) && $objects = $object_callback()) {
+      $form[$type] = array(
+        '#type' => 'select',
+        '#title' => $type,
+        '#options' => array(0 => t('Not selected')) + $objects,
+        '#default_value' => isset($form_state['storage'][$type]) ? $form_state['storage'][$type] : 0,
+        '#access' => !empty($objects),
+      );
+    }
+  }
+
+  $form['text'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Enter your text here'),
+    '#default_value' => 'Hello [user]!'
+    );
+
+  // Display the results of tokenized text.
+  if (!empty($form_state['storage']['text'])) {
+    $form['text']['#default_value'] = $form_state['storage']['text'];
+    
+    //apply token_replace to other classes of tokens (user, node, ...)
+    $processed_text = $form_state['storage']['text'];
+    foreach ($token_types as $type => $info){
+      $replace_callback = "_token_example_replace_{$type}";
+      if (function_exists($replace_callback) && !empty($form_state['storage'][$type])){
+        $processed_text = $replace_callback($processed_text,$form_state['storage'][$type]);
+      }
+    }
+    
+    //replace global token class
+    $processed_text = _token_example_replace_global($processed_text);
+    
+    // Display the tokenized text.
+    $form['text_tokenized'] = array(
+    '#type' => 'item',
+    '#title' => t('Result'),
+    '#value' => $processed_text,
+    );
+  }
+
+  $form['submit'] = array(
+  '#type' => 'submit',
+  '#value' => t('Submit'),
+  );
+
+  if (module_exists('token')) {
+    $form['token_tree'] = array(
+    '#theme' => 'token_tree',
+    '#token_types' => $token_types,
+    );
+  }
+  else {
+    $form['token_tree'] = array(
+    '#markup' => '<p>' . t('Enable the <a href="@drupal-token">Token module</a> to view the available token browser.', array('@drupal-token' => 'http://drupal.org/project/token')) . '</p>',
+    );
+  }
+
+  return $form;
+}
+
+/**
+ * Submit callback; store the submitted values into storage.
+ */
+function token_example_example_form_submit($form, &$form_state) {
+  $form_state['storage'] = $form_state['values'];
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Build a list of available content.
+ */
+function _token_example_get_node() {
+  if (!user_access('access content') && !user_access('bypass node access')) {
+    return array();
+  }
+
+  $node_result = db_query_range('SELECT n.nid, n.title FROM {node} n WHERE n.status=%d ORDER BY n.created DESC',1,0,10);
+  $nodes = Array();
+  while ($node = db_fetch_array($node_result)){
+    $nodes[$node['nid']] = $node['title'];
+  }
+  $nodes = array_map('check_plain',$nodes);
+  return $nodes;
+}
+
+/**
+ * Build a list of available comments.
+ */
+function _token_example_get_comment() {
+  if (!module_exists('comment') || (!user_access('access comments') && !user_access('administer comments'))) {
+    return array();
+  }
+
+  $comment_result = db_query_range('SELECT c.cid, c.subject FROM {comments} c
+  									INNER JOIN {node} n ON c.cid=n.nid WHERE n.status=%d AND c.status=%d',
+                                    1,0,0,10);
+  $comments = Array();
+  while ($comment = db_fetch_array($comment_result)){
+    $comments[$comment['cid']] = $comment['subject'];
+  }
+  $comments = array_map('check_plain',$comments);
+  return $comments;
+}
+
+/**
+ * Build a list of available user accounts.
+ */
+function _token_example_get_user() {
+  if (!user_access('access user profiles') && !user_access('administer users')) {
+    return array();
+  }
+
+  $account_result = db_query_range('SELECT u.uid, u.name FROM {users} u WHERE uid > %d AND status=%d',0,1,0,10);
+  $accounts = Array();
+  while ($user = db_fetch_array($account_result)){
+    $accounts[$user['uid']] = $user['name'];
+  }
+  $accounts = array_map('check_plain',$accounts);
+  return $accounts;
+}
+
+/**
+ * Build a list of available taxonomy terms.
+ */
+function _token_example_get_taxonomy() {
+  $term_result = db_query_range('SELECT t.tid, t.name FROM {term_data} t',0,10);
+  $terms = Array();
+  while ($term = db_fetch_array($term_result)){
+    $terms[$term['tid']] = $term['name'];
+  }
+  $terms = array_map('check_plain',$terms);
+  return $terms;
+}
+
+/**
+ * Replace global token class.
+ * 
+ * @param $string 
+ * 	String to be processed with token replacement.
+ * 
+ * @return
+ * 	Processed text.
+ */
+function _token_example_replace_global($string){
+  return token_replace($string, 'global');
+}
+
+/**
+ * Replace user token class.
+ * 
+ * @param $string
+ * 	String to be processed with token replacement.
+ * @param $uid
+ * 	ID of user to be used for replacement.
+ * 
+ * @return
+ * 	Processed text.
+ */
+function _token_example_replace_user($string, $uid){
+  $user = db_fetch_object(db_query_range("SELECT * FROM {users} u WHERE u.uid={$uid}",0,1));
+  return token_replace($string,'user',$user);
+}
+
+/**
+ * Replace node token class.
+ * 
+ * @param $string
+ * 	String to be processed with token replacement.
+ * @param $nid
+ * 	ID of node to be used for replacement.
+ * 
+ * @return
+ * 	Processed text.
+ */
+function _token_example_replace_node($string, $nid){
+  $node = db_fetch_object(db_query_range("SELECT * FROM {node} n WHERE n.nid={$nid}",0,1));
+  return token_replace($string,'node',$node);
+}
+
+/**
+ * Replace comment token class.
+ * 
+ * @param $string
+ * 	String to be processed with token replacement.
+ * @param $cid
+ * 	ID of comment to be used for replacement.
+ * 
+ * @return
+ * 	Processed text.
+ */
+function _token_example_replace_comment($string, $cid){
+  $comment = db_fetch_object(db_query_range("SELECT * FROM {comments} c WHERE c.cid={$cid}",0,1));
+  return token_replace($string,'comment',$comment);
+}
+
+/**
+ * Replace taxonomy token class.
+ * 
+ * @param $string
+ * 	String to be processed with token replacement.
+ * @param $tid
+ * 	ID of taxonomy to be used for replacement.
+ * 
+ * @return
+ * 	Processed text.
+ */
+function _token_example_replace_taxonomy($string, $tid){
+  $taxonomy = db_fetch_object(db_query_range("SELECT * FROM {term_data} t WHERE t.tid={$tid}",0,1));
+  return token_replace($string,'taxonomy',$taxonomy);
+}
