diff --git a/entity_translation.admin.inc b/entity_translation.admin.inc
index f1ccf6e..8f33536 100644
--- a/entity_translation.admin.inc
+++ b/entity_translation.admin.inc
@@ -66,6 +66,7 @@ function entity_translation_overview($entity_type, $entity, $callback = NULL) {
   }
 
   $handler = entity_translation_get_handler($entity_type, $entity);
+  $handler->initPathScheme();
 
   // Initialize translations if they are empty.
   $translations = $handler->getTranslations();
@@ -85,7 +86,6 @@ function entity_translation_overview($entity_type, $entity, $callback = NULL) {
   $header = array(t('Language'), t('Source language'), t('Translation'), t('Status'), t('Operations'));
   $languages = entity_translation_languages();
   $source = $translations->original;
-  $base_path = $handler->getBasePath();
   $path = $handler->getViewPath();
   $rows = array();
 
@@ -101,9 +101,9 @@ function entity_translation_overview($entity_type, $entity, $callback = NULL) {
       $language_name = $language->name;
       $langcode = $language->language;
       $edit_path = $handler->getEditPath($langcode);
-      $add_path = "$base_path/edit/add/$source/$langcode";
+      $add_path = "{$handler->getEditPath()}/add/$source/$langcode";
 
-      if ($base_path) {
+      if ($edit_path) {
         $add_links = EntityTranslationDefaultHandler::languageSwitchLinks($add_path);
         $edit_links = EntityTranslationDefaultHandler::languageSwitchLinks($edit_path);
       }
@@ -227,7 +227,7 @@ function entity_translation_delete_confirm($form, $form_state, $entity_type, $en
   return confirm_form(
     $form,
     t('Are you sure you want to delete the @language translation of %label?', array('@language' => $languages[$langcode]->name, '%label' => $handler->getLabel())),
-    "{$handler->getBasePath()}/edit/$langcode",
+    $handler->getEditPath($langcode),
     t('This action cannot be undone.'),
     t('Delete'),
     t('Cancel')
@@ -250,7 +250,7 @@ function entity_translation_delete_confirm_submit($form, &$form_state) {
   // Remove any existing path alias for the removed translation.
   path_delete(array('source' => $handler->getViewPath(), 'language' => $langcode));
 
-  $form_state['redirect'] = "{$handler->getBasePath()}/translate";
+  $form_state['redirect'] = $handler->getTranslatePath();
 }
 
 /*
diff --git a/entity_translation.api.php b/entity_translation.api.php
index b968878..eb73866 100644
--- a/entity_translation.api.php
+++ b/entity_translation.api.php
@@ -16,11 +16,12 @@
  * To make Entity Translation automatically support an entity type some keys
  * may need to be defined, but none of them is required except the 'base path'
  * key if the entity path is different from ENTITY_TYPE/%ENTITY_TYPE (e.g.
- * taxonomy/term/1). The 'base path' key is used to attach the 'Translate' tab
- * and to reliably alter menu information to provide the translation UI. If the
- * entity path matches the default pattern above, and there is no need for a
- * dedicated translation handler class, Entity Translation will provide built-in
- * support for the entity.
+ * taxonomy/term/1). The 'base path' key is used to determine the view, edit and
+ * translate path if they follow the default path patterns  and to reliably
+ * alter menu information to provide the translation UI. If the entity path
+ * matches the default pattern above, and there is no need for a dedicated
+ * translation handler class, Entity Translation will provide built-in support
+ * for the entity.
  *
  * The entity translation info is an associative array that has to match the
  * following structure. Three nested sub-arrays keyed respectively by entity
@@ -39,8 +40,20 @@
  *   the base path.
  * - edit path: The menu router path to be used to edit the entity. Defaults to
  *   "$base_path/edit".
+ * - translate path: The menu router path to be used for attaching the
+ *   translation UI. Defaults to "$base_path/translate".
  * - path wildcard: The menu router path wildcard identifying the entity.
  *   Defaults to %ENTITY_TYPE.
+ * - admin theme: Whether the translation UI should use the administration
+ *   theme. Defaults to TRUE.
+ * - path schemes: An array of menu router path schemes used for attaching the
+ *   entity translation UI. This element can be used to declare additional path
+ *   schemes, if an entity type uses multiple schemes for managing entities
+ *   (e.g. different schemes for different bundles). Each path scheme can define
+ *   the following elements (descriptions see above): 'base path', 'view path',
+ *   'edit path', 'translate path', 'path wildcard' and 'admin theme'. All path
+ *   elements that are defined directly on the entity translation info array are
+ *   automatically added as a 'default' path scheme.
  * - theme callback: The callback to be used to determine the translation
  *   theme. Defaults to 'variable_get'.
  * - theme arguments: The arguments to be used to determine the translation
@@ -64,6 +77,26 @@ function hook_entity_info() {
     ),
   );
 
+  // Entity type which has multiple (e.g. bundle-specific) paths.
+  $info['custom_entity_2'] = array(
+    'translation' => array(
+      'entity_translation' => array(
+        'class' => 'EntityTranslationCustomEntityHandler',
+        'path sets' => array(
+          'default' => array(
+            'base path' => 'custom_entity_2/%custom_entity',
+            'path wildcard' => '%custom_entity',
+          ),
+          'fancy' => array(
+            // Base path is not required.
+            'edit path' => 'fancy/%entity/edit',
+            'path wildcard' => '%entity',
+          ),
+        ),
+      )
+    )
+  );
+
   return $info;
 }
 
diff --git a/entity_translation.module b/entity_translation.module
index d3c5162..967953b 100644
--- a/entity_translation.module
+++ b/entity_translation.module
@@ -58,6 +58,7 @@ function entity_translation_entity_info() {
         'class' => 'EntityTranslationNodeHandler',
         'access callback' => 'entity_translation_node_tab_access',
         'access arguments' => array(1),
+        'admin theme' => variable_get('node_admin_theme'),
       ),
     ),
   );
@@ -67,6 +68,7 @@ function entity_translation_entity_info() {
       'translation' => array(
         'entity_translation' => array(
           'class' => 'EntityTranslationCommentHandler',
+          'admin theme' => FALSE,
         ),
       ),
     );
@@ -99,42 +101,67 @@ function entity_translation_entity_info() {
  * Implements hook_entity_info_alter().
  */
 function entity_translation_entity_info_alter(&$entity_info) {
-  $edit_form_info = array();
+  $path_scheme_keys = array_flip(array('base path', 'view path', 'edit path', 'translate path', 'path wildcard', 'admin theme'));
 
   // Provide defaults for translation info.
   foreach ($entity_info as $entity_type => $info) {
     if (!isset($entity_info[$entity_type]['translation']['entity_translation'])) {
       $entity_info[$entity_type]['translation']['entity_translation'] = array();
     }
+    $et_info = &$entity_info[$entity_type]['translation']['entity_translation'];
 
     // Every fieldable entity type must have a translation handler class, no
     // matter if it is enabled for translation or not. As a matter of fact we
     // might need it to correctly switch field translatability when a field is
     // shared accross different entities.
-    $entity_info[$entity_type]['translation']['entity_translation'] += array('class' => 'EntityTranslationDefaultHandler');
+    $et_info += array('class' => 'EntityTranslationDefaultHandler');
 
     if (entity_translation_enabled($entity_type, TRUE)) {
       $entity_info[$entity_type]['language callback'] = 'entity_translation_language';
 
+      // Insert the default path scheme into the 'path schemes' array and remove
+      // respective elements from the entity_translation info array.
+      $default_scheme = array_intersect_key($et_info, $path_scheme_keys);
+      if (!empty($default_scheme)) {
+        $et_info['path schemes']['default'] = $default_scheme;
+        $et_info = array_diff_key($et_info, $path_scheme_keys);
+      }
+
       // If no base path is provided we default to the common "node/%node"
       // pattern.
-      if (!isset($entity_info[$entity_type]['translation']['entity_translation']['base path'])) {
-        $path = "$entity_type/%$entity_type";
-        $entity_info[$entity_type]['translation']['entity_translation']['base path'] = $path;
+      if (empty($et_info['path schemes']['default']['base path'])) {
+        $et_info['path schemes']['default']['base path'] = "$entity_type/%$entity_type";
       }
 
-      $path = $entity_info[$entity_type]['translation']['entity_translation']['base path'];
+      foreach ($et_info['path schemes'] as $delta => $scheme) {
+        // If there is a base path, then we automatically create the other path
+        // elements based on the base path.
+        if (!empty($scheme['base path'])) {
+          $view_path = $scheme['base path'];
+          $edit_path = $scheme['base path'] . '/edit';
+          $translate_path = $scheme['base path'] . '/translate';
+
+          $et_info['path schemes'][$delta] += array(
+            'view path' => $view_path,
+            'edit path' => $edit_path,
+            'translate path' => $translate_path,
+          );
+        }
+
+        // Merge in default values for other scheme elements.
+        $et_info['path schemes'][$delta] += array(
+          'admin theme' => TRUE,
+          'path wildcard' => "%$entity_type",
+        );
+      }
 
-      $entity_info[$entity_type]['translation']['entity_translation'] += array(
-        'view path' => $path,
-        'edit path' => "$path/edit",
-        'path wildcard' => "%$entity_type",
+      // Merge in default values for remaining keys.
+      $et_info += array(
         'access callback' => 'entity_translation_tab_access',
         'access arguments' => array($entity_type),
       );
 
       // Interpret a TRUE value for the 'edit form' key as the default value.
-      $et_info = &$entity_info[$entity_type]['translation']['entity_translation'];
       if (!isset($et_info['edit form']) || $et_info['edit form'] === TRUE) {
         $et_info['edit form'] = $entity_type;
       }
@@ -175,130 +202,247 @@ function entity_translation_menu() {
 }
 
 /**
+ * Validate the given set of path schemes and remove invalid elements.
+ *
+ * Each path scheme needs to fulfill the following requirements:
+ * - The 'path wildcard' key needs to be specified.
+ * - Every path (base/view/edit/translate) needs to contain the path wildcard.
+ * - The following path definitions (if specified) need to match existing menu
+ *   items: 'base path', 'view path', 'edit path'.
+ * - The 'translate path' definition needs to have an existing parent menu item.
+ *
+ * This function needs to be called once with a list of menu items passed as the
+ * last parameter, before it can be used for validation.
+ *
+ * @param $schemes
+ *   The array of path schemes.
+ * @param $entity_type_label
+ *   The label of the current entity type. This is used in error messages.
+ * @param $items
+ *   A list of menu items.
+ */
+function _entity_translation_validate_path_schemes(&$schemes, $entity_type_label, $items = FALSE) {
+  $paths = &drupal_static(__FUNCTION__);
+  static $regex = '|%[^/]+|';
+
+  if (!empty($items)) {
+    // Some menu loaders in the item paths might have been altered: we need to
+    // replace any menu loader with a plain % to check if base paths are still
+    // compatible.
+    $paths = array();
+    foreach ($items as $path => $item) {
+      $path = preg_replace($regex, '%', $path);
+      $paths[$path] = $path;
+    }
+  }
+
+  if (empty($schemes)) {
+    return;
+  }
+
+  // Make sure we have a set of paths to validate the scheme against.
+  if (empty($paths)) {
+    // This should never happen.
+    throw new Exception('The Entity Translation path scheme validation function has not been initialized properly.');
+  }
+
+  foreach ($schemes as $delta => $scheme) {
+    // Every path scheme needs to declare a path wildcard for the entity id.
+    if (empty($scheme['path wildcard'])) {
+      $t_args = array('%scheme' => $delta, '%entity_type' => $entity_type_label);
+      drupal_set_message(t('Entity Translation path scheme %scheme for entities of type %entity_type does not declare a path wildcard.', $t_args));
+      unset($schemes[$delta]);
+      continue;
+    }
+
+    $wildcard = $scheme['path wildcard'];
+    $validate_keys = array('base path' => FALSE, 'view path' => FALSE, 'edit path' => FALSE, 'translate path' => TRUE);
+
+    foreach ($validate_keys as $key => $check_parent) {
+      if (isset($scheme[$key])) {
+        $path = $scheme[$key];
+        $parts = explode('/', $path);
+        $schemes[$delta][$key . ' parts'] = $parts;
+
+        // Check that the path contains the path wildcard.
+        if (!in_array($wildcard, $parts)) {
+          $t_args = array('%path_key' => $key, '%entity_type' => $entity_type_label, '%wildcard' => $wildcard, '%path' => $path);
+          drupal_set_message(t('Invalid %path_key defined for entities of type %entity_type: entity wildcard %wildcard not found in %path.', $t_args), 'warning');
+        }
+
+        // Check that the current element has a parent path which matches an
+        // existing menu path.
+        if ($check_parent) {
+          $parent_path = implode('/', array_slice($parts, 0, -1));
+          if (!isset($paths[preg_replace($regex, '%', $parent_path)])) {
+            $t_args = array('%path_key' => $key, '%entity_type' => $entity_type_label, '%path' => $path);
+            drupal_set_message(t('Invalid %path_key defined for entities of type %entity_type: parent menu item not found for %path', $t_args), 'warning');
+            unset($schemes[$delta][$key]);
+          }
+        }
+        // Check that the current element matches an existing menu path.
+        elseif (!isset($paths[preg_replace($regex, '%', $path)])) {
+          $t_args = array('%path_key' => $key, '%entity_type' => $entity_type_label, '%path' => $path);
+          drupal_set_message(t('Invalid %path_key defined for entities of type %entity_type: matching menu item not found for %path', $t_args), 'warning');
+          unset($schemes[$delta][$key]);
+        }
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_menu_alter().
  */
 function entity_translation_menu_alter(&$items) {
   $backup = array();
   $languages = entity_translation_languages();
 
-  // Some menu loaders in the item paths might have been altered: we need to
-  // replace any menu loader with a plain % to check if base paths are still
-  // compatible.
-  $paths = array();
-  $regex = '|%[^/]+|';
-  foreach ($items as $path => $item) {
-    $path = preg_replace($regex, '%', $path);
-    $paths[$path] = $path;
-  }
+  // Initialize path schemes validation function with set of current menu items.
+  $_null = NULL;
+  _entity_translation_validate_path_schemes($_null, FALSE, $items);
 
   // Create tabs for all possible entity types.
   foreach (entity_get_info() as $entity_type => $info) {
     // Menu is rebuilt while determining entity translation base paths and
     // callbacks so we might not have them available yet.
     if (entity_translation_enabled($entity_type)) {
-      // Extract informations from the bundle description.
-      $path = $info['translation']['entity_translation']['base path'];
+      $et_info = $info['translation']['entity_translation'];
 
-      // If the base path is not defined or is not compatible with any defined
-      // one we cannot provide the translation UI for this entity type.
-      if (!isset($paths[preg_replace($regex, '%', $path)])) {
-        drupal_set_message(t('The entities of type %entity_type do not define a valid base path: it will not be possible to translate them.', array('%entity_type' => $info['label'])), 'warning');
-        continue;
-      }
+      // Flag for tracking whether we have managed to attach the translate UI
+      // successfully at least once.
+      $translate_ui_attached = FALSE;
 
-      $keys = array('theme callback', 'theme arguments', 'access callback', 'access arguments', 'load arguments');
-      $item = array_intersect_key($info['translation']['entity_translation'], drupal_map_assoc($keys));
+      // Validate path schemes for current entity type. Also removes invalid
+      // ones and adds '... path parts' elements.
+      _entity_translation_validate_path_schemes($et_info['path schemes'], $info['label']);
 
-      $item += array(
-        'file' => 'entity_translation.admin.inc',
-        'module' => 'entity_translation',
-      );
+      foreach ($et_info['path schemes'] as $scheme) {
+        $translate_item = NULL;
+        $edit_item = NULL;
 
-      $entity_position = count(explode('/', $path)) - 1;
-      $source_position = $entity_position + 4;
-      $language_position = $entity_position + 3;
+        // If we have a translate path then attach the translation UI, and
+        // register the callback for deleting a translation.
+        if (isset($scheme['translate path'])) {
+          $translate_path = $scheme['translate path'];
 
-      // Backup existing values for the translate overview page.
-      if (isset($items["$path/translate"])) {
-        $backup[$entity_type] = $items["$path/translate"];
-      }
+          $keys = array('theme callback', 'theme arguments', 'access callback', 'access arguments', 'load arguments');
+          $item = array_intersect_key($info['translation']['entity_translation'], drupal_map_assoc($keys));
 
-      $items["$path/translate"] = array(
-        'title' => 'Translate',
-        'page callback' => 'entity_translation_overview',
-        'page arguments' => array($entity_type, $entity_position),
-        'type' => MENU_LOCAL_TASK,
-        'weight' => 2,
-      ) + $item;
+          $item += array(
+            'file' => 'entity_translation.admin.inc',
+            'module' => 'entity_translation',
+          );
 
-      $et_info = $info['translation']['entity_translation'];
-      $edit_path = $et_info['edit path'];
-
-      if (isset($items[$edit_path])) {
-        // If the edit path is a default local task we need to find the parent
-        // item.
-        $edit_path_split = explode('/', $edit_path);
-        do {
-          $edit_form_item = &$items[implode('/', $edit_path_split)];
-          array_pop($edit_path_split);
+          $entity_position = array_search($scheme['path wildcard'], $scheme['translate path parts']);
+
+          // Backup existing values for the translate overview page.
+          if (isset($items[$translate_path])) {
+            $backup[$entity_type] = $items[$translate_path];
+          }
+
+          $items[$translate_path] = array(
+            'title' => 'Translate',
+            'page callback' => 'entity_translation_overview',
+            'page arguments' => array($entity_type, $entity_position),
+            'type' => MENU_LOCAL_TASK,
+            'weight' => 2,
+          ) + $item;
+
+          // Delete translation callback.
+          $language_position = count($scheme['translate path parts']) + 1;
+          $items["$translate_path/delete/%entity_translation_language"] = array(
+            'title' => 'Delete',
+            'page callback' => 'drupal_get_form',
+            'page arguments' => array('entity_translation_delete_confirm', $entity_type, $entity_position, $language_position),
+          ) + $item;
+
+          $translate_item = &$items[$translate_path];
         }
-        while (!empty($edit_form_item['type']) && $edit_form_item['type'] == MENU_DEFAULT_LOCAL_TASK);
 
-        // Make the "Translate" local task follow the "Edit" one when possibile.
-        if (isset($edit_form_item['weight'])) {
-          $items["$path/translate"]['weight'] = $edit_form_item['weight'] + 1;
+        // If we have an edit path, then replace the menu edit form with our
+        // proxy implementation, and register new callbacks for adding and
+        // editing a translation.
+        if (isset($scheme['edit path'])) {
+          $edit_path = $scheme['edit path'];
+          $edit_path_parts = $scheme['edit path parts'];
+
+          // If the edit path is a default local task we need to find the parent
+          // item.
+          do {
+            $edit_item = &$items[implode('/', $edit_path_parts)];
+            array_pop($edit_path_parts);
+          }
+          while (!empty($edit_item['type']) && $edit_item['type'] == MENU_DEFAULT_LOCAL_TASK);
+
+          // Reset edit path parts to ensure proper position calculations.
+          $edit_path_parts = $scheme['edit path parts'];
+
+          // Replace the main edit callback with our proxy implementation to set
+          // form language to the current language and check access.
+          $entity_position = array_search($scheme['path wildcard'], $edit_path_parts);
+          $original_item = $edit_item;
+          $args = array($entity_type, $entity_position, FALSE, $original_item);
+          $edit_item['page callback'] = 'entity_translation_edit_page';
+          $edit_item['page arguments'] = array_merge($args, $original_item['page arguments']);
+          $edit_item['access callback'] = 'entity_translation_edit_access';
+          $edit_item['access arguments'] = array_merge($args, $original_item['access arguments']);
+
+          // Edit translation callback.
+          $translation_position = count($edit_path_parts);
+          $args = array($entity_type, $entity_position, $translation_position, $original_item);
+          $items["$edit_path/%entity_translation_language"] = array(
+            'type' => MENU_DEFAULT_LOCAL_TASK,
+            'title callback' => 'entity_translation_edit_title',
+            'title arguments' => array($translation_position),
+            'page callback' => 'entity_translation_edit_page',
+            'page arguments' => array_merge($args, $original_item['page arguments']),
+            'access callback' => 'entity_translation_edit_access',
+            'access arguments' => array_merge($args, $original_item['access arguments']),
+          )
+          // We need to inherit the remaining menu item keys, mostly 'module'
+          // and 'file' to keep ajax callbacks working (see form_get_cache() and
+          // drupal_retrieve_form()).
+          + $original_item;
+
+          // Add translation callback.
+          $add_path = "$edit_path/add/%entity_translation_language/%entity_translation_language";
+          $source_position = count($edit_path_parts) + 1;
+          $target_position = count($edit_path_parts) + 2;
+          $args = array($entity_type, $entity_position, $source_position, $target_position, $original_item);
+          $items[$add_path] = array(
+            'title callback' => 'Add translation',
+            'page callback' => 'entity_translation_add_page',
+            'page arguments' => array_merge($args, $original_item['page arguments']),
+            'type' => MENU_LOCAL_TASK,
+            'access callback' => 'entity_translation_add_access',
+            'access arguments' => array_merge($args, $original_item['access arguments']),
+          ) + $original_item;
+        }
+
+        // Make the "Translate" tab follow the "Edit" tab if possible.
+        if ($translate_item && $edit_item && isset($edit_item['weight'])) {
+          $translate_item['weight'] = $edit_item['weight'] + 1;
         }
 
-        // Replace the main edit callback with our proxy implementation to set
-        // form language to the current language and check access.
-        $entity_position = count(explode('/', $et_info['base path'])) - 1;
-        $edit_position = count(explode('/', $edit_path)) - 1;
-        $original_item = $edit_form_item;
-        $args = array($entity_type, $entity_position, FALSE, $original_item);
-        $edit_form_item['page callback'] = 'entity_translation_edit_page';
-        $edit_form_item['page arguments'] = array_merge($args, $original_item['page arguments']);
-        $edit_form_item['access callback'] = 'entity_translation_edit_access';
-        $edit_form_item['access arguments'] = array_merge($args, $original_item['access arguments']);
-
-        // Edit translation callback.
-        $translation_position = $edit_position + 1;
-        $args = array($entity_type, $entity_position, $translation_position, $original_item);
-        $items["$edit_path/%entity_translation_language"] = array(
-          'type' => MENU_DEFAULT_LOCAL_TASK,
-          'title callback' => 'entity_translation_edit_title',
-          'title arguments' => array($translation_position),
-          'page callback' => 'entity_translation_edit_page',
-          'page arguments' => array_merge($args, $original_item['page arguments']),
-          'access callback' => 'entity_translation_edit_access',
-          'access arguments' => array_merge($args, $original_item['access arguments']),
-        )
-        // We need to inherit the remaining menu item keys, mostly 'module' and
-        // 'file' to keep ajax callbacks working (see drupal_retrieve_form() and
-        // form_get_cache()).
-        + $original_item;
-
-        // Add translation callback.
-        $add_path = "$edit_path/add/%entity_translation_language/%entity_translation_language";
-        $source_position = $edit_position + 2;
-        $items[$add_path] = array(
-          'title callback' => 'Add translation',
-          'page callback' => 'entity_translation_add_page',
-          'page arguments' => array_merge(array($entity_type, $entity_position, $source_position, $source_position + 1, $original_item), $original_item['page arguments']),
-          'type' => MENU_LOCAL_TASK,
-          'access callback' => 'entity_translation_add_access',
-          'access arguments' => array_merge(array($entity_type, $entity_position, $source_position, $source_position + 1, $original_item), $original_item['access arguments']),
-        ) + $original_item;
-
-        // Delete translation callback.
-        $items["$path/translate/delete/%entity_translation_language"] = array(
-          'title' => 'Delete',
-          'page callback' => 'drupal_get_form',
-          'page arguments' => array('entity_translation_delete_confirm', $entity_type, $entity_position, $language_position),
-        ) + $item;
+        // If we have both an edit item and a translate item, then we know that
+        // the translate UI has been attached properly (at least once).
+        $translate_ui_attached = $translate_ui_attached || ($translate_item && $edit_item);
+
+        // Cleanup reference variables, so we don't accidentially overwrite
+        // something in a later iteration.
+        unset($translate_item, $edit_item);
+      }
+
+      if ($translate_ui_attached == FALSE) {
+        drupal_set_message(t('The entities of type %entity_type do not define a valid path scheme: it will not be possible to translate them.', array('%entity_type' => $info['label'])), 'warning');
       }
     }
   }
 
+  // Avoid bloating memory with unused data.
+  drupal_static_reset('_entity_translation_validate_path_schemes');
+
   // Node-specific menu alterations.
   entity_translation_node_menu_alter($items, $backup);
 }
@@ -323,6 +467,7 @@ function entity_translation_edit_page() {
 
   // Set the current form language.
   $handler = entity_translation_get_handler($entity_type, $entity);
+  $handler->initPathScheme();
   $translations = $handler->getTranslations();
   $langcode = entity_translation_form_language($langcode, $handler);
   $handler->setFormLanguage($langcode);
@@ -436,6 +581,7 @@ function entity_translation_add_page() {
   $edit_form_item = array_shift($args);
 
   $handler = entity_translation_get_handler($entity_type, $entity);
+  $handler->initPathScheme();
   $handler->setFormLanguage($langcode);
   $handler->setSourceLanguage($source);
 
@@ -460,19 +606,20 @@ function _entity_translation_callback($callback, $args, $info = array()) {
 function entity_translation_admin_paths() {
   $paths = array();
   foreach (entity_get_info() as $entity_type => $info) {
-    // Only mark node related paths as admin paths, if the user has
-    // configured Drupal to use the administration theme when editing or
-    // creating content.
-    if ($entity_type == 'node' && !variable_get('node_admin_theme')) {
-      continue;
-    }
-    if (entity_translation_enabled($entity_type, TRUE) && isset($info['translation']['entity_translation']['base path'])) {
-      $base_path = preg_replace('|%[^/]*|', '*', $info['translation']['entity_translation']['base path']);
-      $paths["$base_path/translate"] = TRUE;
-      $paths["$base_path/translate/*"] = TRUE;
-
-      $edit_path = preg_replace('|%[^/]*|', '*', $info['translation']['entity_translation']['edit path']);
-      $paths["$edit_path/*"] = TRUE;
+    if (entity_translation_enabled($entity_type, TRUE)) {
+      foreach ($info['translation']['entity_translation']['path schemes'] as $scheme) {
+        if (!empty($scheme['admin theme'])) {
+          if (isset($scheme['translate path'])) {
+            $translate_path = preg_replace('|%[^/]*|', '*', $scheme['translate path']);
+            $paths[$translate_path] = TRUE;
+            $paths["$translate_path/*"] = TRUE;
+          }
+          if (isset($scheme['edit path'])) {
+            $edit_path = preg_replace('|%[^/]*|', '*', $scheme['edit path']);
+            $paths["$edit_path/*"] = TRUE;
+          }
+        }
+      }
     }
   }
   return $paths;
@@ -1086,7 +1233,7 @@ function entity_translation_entity_form_source_language_submit($form, &$form_sta
  */
 function entity_translation_entity_form_delete_translation_submit($form, &$form_state) {
   $handler = entity_translation_entity_form_get_handler($form, $form_state);
-  $form_state['redirect'] = "{$handler->getBasePath()}/translate/delete/{$handler->getFormLanguage()}";
+  $form_state['redirect'] = "{$handler->getTranslatePath()}/delete/{$handler->getFormLanguage()}";
 }
 
 /**
diff --git a/includes/translation.handler.inc b/includes/translation.handler.inc
index a2dc998..098b43d 100644
--- a/includes/translation.handler.inc
+++ b/includes/translation.handler.inc
@@ -139,11 +139,41 @@ interface EntityTranslationHandlerInterface {
   public function getEditPath($langcode = NULL);
 
   /**
+   * Returns the path of the translation overview page.
+   */
+  public function getTranslatePath();
+
+  /**
    * Returns the path of the entity view page.
    */
   public function getViewPath();
 
   /**
+   * Returns the active path scheme.
+   */
+  public function getPathScheme();
+
+  /**
+   * Changes the active path scheme.
+   *
+   * @param $scheme
+   *   The new path scheme.
+   */
+  public function setPathScheme($scheme);
+
+  /**
+   * Initializes the most suited path scheme based on the given path.
+   *
+   * @param $path
+   *   (optional) The path to match the defined path schemes against. Defaults
+   *   to the current path.
+   *
+   * @return
+   *   The matched path scheme key.
+   */
+  public function initPathScheme($path = NULL);
+
+  /**
    * A string allowing the user to identify the entity.
    */
   public function getLabel();
@@ -231,9 +261,13 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
   private $formLanguage;
   private $sourceLanguage;
 
+  private $pathScheme;
+  private $pathWildcard;
   private $basePath;
   private $editPath;
+  private $translatePath;
   private $viewPath;
+  private $routerMap;
 
   /**
    * Initializes an instance of the translation handler.
@@ -257,11 +291,10 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
     $this->outdated = FALSE;
     $this->formLanguage = FALSE;
     $this->sourceLanguage = FALSE;
+    $this->pathScheme = 'default';
+    $this->routerMap = array();
 
-    $info = $entity_info['translation']['entity_translation'];
-    $this->basePath = $this->getPathInstance($info['base path']);
-    $this->editPath = isset($info['edit path']) ? $this->getPathInstance($info['edit path']) : FALSE;
-    $this->viewPath = isset($info['view path']) ? $this->getPathInstance($info['view path']) : FALSE;
+    $this->initPathVariables();
   }
 
   /**
@@ -629,7 +662,14 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
    * @see EntityTranslationHandlerInterface::getEditPath()
    */
   public function getEditPath($langcode = NULL) {
-    return empty($langcode) ? $this->editPath : $this->editPath . '/' . $langcode;
+    return empty($this->editPath) ? FALSE : (empty($langcode) ? $this->editPath : $this->editPath . '/' . $langcode);
+  }
+
+  /**
+   * @see EntityTranslationHandlerInterface::getTranslatePath()
+   */
+  public function getTranslatePath() {
+    return $this->translatePath;
   }
 
   /**
@@ -640,6 +680,83 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
   }
 
   /**
+   * @see EntityTranslationHandlerInterface::getPathScheme()
+   */
+  public function getPathScheme() {
+    return $this->pathScheme;
+  }
+
+  /**
+   * @see EntityTranslationHandlerInterface::setPathScheme()
+   */
+  public function setPathScheme($scheme) {
+    if ($scheme != $this->pathScheme) {
+      $this->pathScheme = $scheme;
+      $this->initPathVariables();
+    }
+  }
+
+  /**
+   * @see EntityTranslationHandlerInterface::initPathScheme()
+   */
+  public function initPathScheme($path = NULL) {
+    $scheme = 'default';
+
+    // If only one path scheme is defined no need to find one.
+    if (count($this->entityInfo['translation']['entity_translation']['path schemes']) > 1) {
+      $item = menu_get_item($path);
+      if (!empty($item['path'])) {
+        $current_path_scheme = $this->findMatchingPathScheme($item['path']);
+        if ($current_path_scheme) {
+          $scheme = $current_path_scheme;
+          $this->routerMap = $item['original_map'];
+        }
+      }
+    }
+
+    $this->setPathScheme($scheme);
+    return $scheme;
+  }
+
+  /**
+   * Find a path scheme matching the given path.
+   *
+   * @param $router_path
+   *   The path to match against.
+   *
+   * @return
+   *   The key of the path scheme if found, FALSE otherwise.
+   */
+  protected function findMatchingPathScheme($router_path) {
+    $path_keys = array_flip(array('base path', 'view path', 'edit path', 'translate path'));
+
+    foreach ($this->entityInfo['translation']['entity_translation']['path schemes'] as $delta => $scheme) {
+      // Construct regular expression pattern for determining whether any path
+      // in the current scheme matches the current request path.
+      $path_elements = array_intersect_key($scheme, $path_keys);
+
+      // Add additional path elements which were added during
+      // entity_translation_menu_alter().
+      if (isset($path_elements['edit path'])) {
+        $path_elements[] = $path_elements['edit path'] . '/%entity_translation_language';
+        $path_elements[] = $path_elements['edit path'] . '/add/%entity_translation_language/%entity_translation_language';
+      }
+      if (isset($path_elements['translate path'])) {
+        $path_elements[] = $path_elements['translate path'] . '/delete/%entity_translation_language';
+      }
+
+      // Replace wildcards with % for matching parameters.
+      $path_elements = array_flip(preg_replace('|%[^/]+|', '%', $path_elements));
+
+      if (isset($path_elements[$router_path])) {
+        return $delta;
+      }
+    }
+
+    return FALSE;
+  }
+
+  /**
    * @see EntityTranslationHandlerInterface::getLabel()
    */
   public function getLabel() {
@@ -1074,6 +1191,24 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
   }
 
   /**
+   * Initializes handler path variables based on the active path scheme.
+   *
+   * @throws Exception
+   */
+  private function initPathVariables() {
+    if (empty($this->pathScheme) || !isset($this->entityInfo['translation']['entity_translation']['path schemes'][$this->pathScheme])) {
+      throw new Exception("Cannot initialize entity translation path variables (invalid path scheme).");
+    }
+
+    $path_scheme = $this->entityInfo['translation']['entity_translation']['path schemes'][$this->pathScheme];
+    $this->pathWildcard = $path_scheme['path wildcard'];
+    $this->basePath = isset($path_scheme['base path']) ? $this->getPathInstance($path_scheme['base path']) : FALSE;
+    $this->editPath = isset($path_scheme['edit path']) ? $this->getPathInstance($path_scheme['edit path']) : FALSE;
+    $this->translatePath = isset($path_scheme['translate path']) ? $this->getPathInstance($path_scheme['translate path']) : FALSE;
+    $this->viewPath = isset($path_scheme['view path']) ? $this->getPathInstance($path_scheme['view path']) : FALSE;
+  }
+
+  /**
    * Returns an instance of the given path.
    *
    * @param $path
@@ -1083,8 +1218,18 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
    *   The instantiated path.
    */
   protected function getPathInstance($path) {
-    $wildcard = $this->entityInfo['translation']['entity_translation']['path wildcard'];
-    return str_replace($wildcard, $this->getEntityId(), $path);
+    $path_segments = explode('/', $path);
+
+    foreach ($path_segments as $index => $segment) {
+      if ($segment == $this->pathWildcard) {
+        $path_segments[$index] = $this->getEntityId();
+      }
+      elseif ($segment{0} == '%' && isset($this->routerMap[$index])) {
+        $path_segments[$index] = $this->routerMap[$index];
+      }
+    }
+
+    return implode('/', $path_segments);
   }
 
   /**
diff --git a/views/entity_translation_handler_field_translate_link.inc b/views/entity_translation_handler_field_translate_link.inc
index bc8d8b9..f41ffed 100644
--- a/views/entity_translation_handler_field_translate_link.inc
+++ b/views/entity_translation_handler_field_translate_link.inc
@@ -86,10 +86,10 @@ class entity_translation_handler_field_translate_link extends views_handler_fiel
     // We use the entity info here to avoid having to call entity_load() for all
     // the entities.
     $info = entity_get_info($entity_type);
-    $path = $info['translation']['entity_translation']['base path'];
-    $path = str_replace($info['translation']['entity_translation']['path wildcard'], $entity_id, $path);
+    $path = $info['translation']['entity_translation']['path schemes']['default']['translate path'];
+    $path = str_replace($info['translation']['entity_translation']['path schemes']['default']['path wildcard'], $entity_id, $path);
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = $path . '/translate';
+    $this->options['alter']['path'] = $path;
     $this->options['alter']['query'] = drupal_get_destination();
     $text = !empty($this->options['text']) ? $this->options['text'] : t('translate');
     return $text;
