diff --git a/pathauto.test b/pathauto.test
index 988b0d2..ab8717b 100644
--- a/pathauto.test
+++ b/pathauto.test
@@ -275,7 +275,7 @@ class PathautoUnitTestCase extends PathautoTestHelper {
    * Test the handling of path vs non-path tokens in pathauto_clean_token_values().
    */
   function testPathTokens() {
-    variable_set('pathauto_taxonomy_term_pattern', '[term:parent:url:alias]/[term:name]');
+    variable_set('pathauto_taxonomy_term_pattern', '[term:parent:url:path]/[term:name]');
     $vocab = $this->addVocabulary();
 
     $term1 = $this->addTerm($vocab, array('name' => 'Parent term'));
@@ -672,3 +672,69 @@ class PathautoBulkUpdateTestCase extends PathautoFunctionalTestHelper {
     $this->assertEntityAliasExists('node', $new_node);
   }
 }
+
+/**
+ * Token functionality tests.
+ */
+class PathautoTokenTestCase extends PathautoFunctionalTestHelper {
+  public static function getInfo() {
+    return array(
+      'name' => 'Pathauto tokens',
+      'description' => 'Tests tokens provided by Pathauto.',
+      'group' => 'Pathauto',
+      'dependencies' => array('token'),
+    );
+  }
+
+  function testPathautoTokens() {
+    $array = array(
+      'test first arg',
+      'The Array / value',
+    );
+
+    $tokens = array(
+      'joined-path' => 'test-first-arg/array-value',
+    );
+    $data['array'] = $array;
+    $replacements = $this->assertTokens('array', $data, $tokens);
+
+    // Ensure that the pathauto_clean_token_values() function does not alter
+    // this token value.
+    module_load_include('inc', 'pathauto');
+    pathauto_clean_token_values($replacements, $data, array());
+    $this->assertEqual($replacements['[array:joined-path]'], 'test-first-arg/array-value');
+  }
+
+  /**
+   * Function copied from TokenTestHelper::assertTokens().
+   */
+  function assertTokens($type, array $data, array $tokens, array $options = array()) {
+    $input = $this->mapTokenNames($type, array_keys($tokens));
+    $replacements = token_generate($type, $input, $data, $options);
+    foreach ($tokens as $name => $expected) {
+      $token = $input[$name];
+      if (!isset($expected)) {
+        $this->assertTrue(!isset($values[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
+      }
+      elseif (!isset($replacements[$token])) {
+        $this->fail(t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
+      }
+      elseif (!empty($options['regex'])) {
+        $this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
+      }
+      else {
+        $this->assertIdentical($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
+      }
+    }
+
+    return $replacements;
+  }
+
+  function mapTokenNames($type, array $tokens = array()) {
+    $return = array();
+    foreach ($tokens as $token) {
+      $return[$token] = "[$type:$token]";
+    }
+    return $return;
+  }
+}
diff --git a/pathauto.tokens.inc b/pathauto.tokens.inc
index 716b1bf..4aaab76 100644
--- a/pathauto.tokens.inc
+++ b/pathauto.tokens.inc
@@ -4,14 +4,40 @@
  * Implements hook_token_info().
  */
 function pathauto_token_info() {
-  // This file was committed prematurely, so return an empty array for now.
-  return array();
+  $info = array();
+
+  $info['tokens']['array']['joined-path'] = array(
+    'name' => t('Joined path'),
+    'description' => t('The array values each cleaned by Pathauto and then joined with the slash into a string that resembles an URL.'),
+  );
+
+  return $info;
 }
 
 /**
  * Implements hook_tokens().
  */
 function pathauto_tokens($type, $tokens, array $data = array(), array $options = array()) {
-  // This file was committed prematurely, so return an empty array for now.
-  return array();
+  $replacements = array();
+
+  if ($type == 'array' && !empty($data['array'])) {
+    $array = $data['array'];
+
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        case 'joined-path':
+          module_load_include('inc', 'pathauto');
+          $values = array();
+          foreach (element_children($array) as $key) {
+            $value = is_array($array[$key]) ? render($array[$key]) : (string) $array[$key];
+            $value = pathauto_cleanstring($value);
+            $values[] = $value;
+          }
+          $replacements[$original] = implode('/', $values);
+          break;
+      }
+    }
+  }
+
+  return $replacements;
 }
