diff --git a/entity_translation.api.php b/entity_translation.api.php
index c048d11..67a8258 100644
--- a/entity_translation.api.php
+++ b/entity_translation.api.php
@@ -30,17 +30,21 @@
  * - class: The name of the translation handler class, which is used to handle
  *   the translation process. Defaults to 'EntityTranslationDefaultHandler'.
  * - base path: The base menu router path to which attach the administration
- *   user interface. Defaults to ENTITY_TYPE/%ENTITY_TYPE.
+ *   user interface. Defaults to ENTITY_TYPE/%ENTITY_TYPE. This element may be
+ *   specified as an array to declare multiple base paths.
  * - access callback: The access callback for the translation pages. Defaults to
  *   'entity_translation_tab_access'.
  * - access arguments: The access arguments for the translation pages. Defaults
  *   to "array($entity_type)".
  * - view path: The menu router path to be used to view the entity. Defaults to
- *   the base path.
+ *   the base path. This element may be specified as an array to declare
+ *   multiple view paths.
  * - edit path: The menu router path to be used to edit the entity. Defaults to
- *   "$base_path/edit".
+ *   "$base_path/edit". This element may be specified as an array to declare
+ *   multiple edit paths.
  * - path wildcard: The menu router path wildcard identifying the entity.
- *   Defaults to %ENTITY_TYPE.
+ *   Defaults to %ENTITY_TYPE. This element may be specified as an array to
+ *   declare multiple path wildcards.
  * - 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
diff --git a/entity_translation.module b/entity_translation.module
index 7b9c707..16023f7 100644
--- a/entity_translation.module
+++ b/entity_translation.module
@@ -91,42 +91,67 @@ function entity_translation_entity_info() {
  * Implements hook_entity_info_alter().
  */
 function entity_translation_entity_info_alter(&$entity_info) {
-  $edit_form_info = array();
-
   // 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';
 
+      // Make sure that all path related parameters are arrays. Strings are
+      // still supported for backwards compatibility.
+      foreach (array('base path', 'edit path', 'view path', 'path wildcard') as $key) {
+        if (!isset($et_info[$key])) {
+          $et_info[$key] = array();
+        }
+        elseif (!is_array($et_info[$key])) {
+          $et_info[$key] = array($et_info[$key]);
+        }
+      }
+
       // 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['base path'])) {
+        $fallback = array(
+          'base path' => array("$entity_type/%$entity_type"),
+          'path wildcard' => array("%$entity_type"),
+        );
+        $et_info = drupal_array_merge_deep($fallback, $et_info);
       }
 
-      $path = $entity_info[$entity_type]['translation']['entity_translation']['base path'];
+      // Create and add a "view path" and an "edit path" for every existing
+      // "base path". Only add them if they don't exist already. We walk through
+      // base paths in reverse order to ensure that the keys for base, view
+      // edit path match up.
+      $base_paths = array_reverse($et_info['base path']);
+      foreach ($base_paths as $path) {
+        $view_path = $path;
+        $edit_path = $path . '/edit';
+        if (!in_array($view_path, $et_info['view path'])) {
+          array_unshift($et_info['view path'], $path);
+        }
+        if (!in_array($edit_path, $et_info['edit path'])) {
+          array_unshift($et_info['edit path'], $path . '/edit');
+        }
+      }
 
-      $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(
+        'path wildcard' => array("%$entity_type"),
         '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;
       }
@@ -189,104 +214,118 @@ function entity_translation_menu_alter(&$items) {
     // 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'];
+      $base_paths = $info['translation']['entity_translation']['base path'];
+
+      // Remove base paths which are incompatible with defined menu items.
+      foreach ($base_paths as $delta => $path) {
+        if(!isset($paths[preg_replace($regex, '%', $path)])) {
+          drupal_set_message(t('Invalid base path defined for entities of type %entity_type: %path', array('%entity_type' => $info['label'], '%path' => $path)), 'warning');
+          unset($base_paths[$delta]);
+        }
+      }
 
-      // 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)])) {
+      // If no valid base path is defined we cannot provide the entity
+      // translation UI for this entity type.
+      if (empty($base_paths)) {
         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;
       }
 
-      $keys = array('theme callback', 'theme arguments', 'access callback', 'access arguments', 'load arguments');
-      $item = array_intersect_key($info['translation']['entity_translation'], drupal_map_assoc($keys));
+      foreach ($base_paths as $delta => $path) {
+        $keys = array('theme callback', 'theme arguments', 'access callback', 'access arguments', 'load arguments');
+        $item = array_intersect_key($info['translation']['entity_translation'], drupal_map_assoc($keys));
 
-      $item += array(
-        'file' => 'entity_translation.admin.inc',
-        'module' => 'entity_translation',
-      );
+        $item += array(
+          'file' => 'entity_translation.admin.inc',
+          'module' => 'entity_translation',
+        );
 
-      $entity_position = count(explode('/', $path)) - 1;
-      $source_position = $entity_position + 4;
-      $language_position = $entity_position + 3;
+        $entity_position = count(explode('/', $path)) - 1;
+        $source_position = $entity_position + 4;
+        $language_position = $entity_position + 3;
 
-      // Backup existing values for the translate overview page.
-      if (isset($items["$path/translate"])) {
-        $backup[$entity_type] = $items["$path/translate"];
-      }
+        // Backup existing values for the translate overview page.
+        if (isset($items["$path/translate"])) {
+          $backup[$entity_type] = $items["$path/translate"];
+        }
 
-      $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;
+        $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;
+      }
 
       $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);
-        }
-        while (!empty($edit_form_item['type']) && $edit_form_item['type'] == MENU_DEFAULT_LOCAL_TASK);
+      $edit_paths = $et_info['edit path'];
+
+      foreach ($edit_paths as $delta => $edit_path) {
+        // Use base path with same delta, or simply the first one.
+        $path = isset($et_info['base path'][$delta]) ? $et_info['base path'][$delta] : $et_info['base path'][0];
+
+        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);
+          }
+          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;
-        }
+          // 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;
+          }
 
-        // 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;
+          // Replace the main edit callback with our proxy implementation to set
+          // form language to the current language and check access.
+          $entity_position = count(explode('/', $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;
+        }
       }
     }
   }
@@ -459,12 +498,15 @@ function entity_translation_admin_paths() {
       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;
+      foreach ($info['translation']['entity_translation']['base path'] as $base_path) {
+        $base_path = preg_replace('|%[^/]*|', '*', $base_path);
+        $paths["$base_path/translate"] = TRUE;
+        $paths["$base_path/translate/*"] = TRUE;
+      }
+      foreach ($info['translation']['entity_translation']['edit path'] as $edit_path) {
+        $edit_path = preg_replace('|%[^/]*|', '*', $edit_path);
+        $paths["$edit_path/*"] = TRUE;
+      }
     }
   }
   return $paths;
diff --git a/includes/translation.handler.inc b/includes/translation.handler.inc
index 5c64f3b..d7e8b5b 100644
--- a/includes/translation.handler.inc
+++ b/includes/translation.handler.inc
@@ -259,9 +259,9 @@ class EntityTranslationDefaultHandler implements EntityTranslationHandlerInterfa
     $this->sourceLanguage = FALSE;
 
     $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->basePath = $this->getPathInstance($info['base path'][0]);
+    $this->editPath = isset($info['edit path'][0]) ? $this->getPathInstance($info['edit path'][0]) : FALSE;
+    $this->viewPath = isset($info['view path'][0]) ? $this->getPathInstance($info['view path'][0]) : FALSE;
   }
 
   /**
diff --git a/views/entity_translation_handler_field_translate_link.inc b/views/entity_translation_handler_field_translate_link.inc
index bc8d8b9..40d8ca8 100644
--- a/views/entity_translation_handler_field_translate_link.inc
+++ b/views/entity_translation_handler_field_translate_link.inc
@@ -86,7 +86,8 @@ 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'];
+    // Find the base path. Use the first one if there are multiple paths.
+    $path = $info['translation']['entity_translation']['base path'][0];
     $path = str_replace($info['translation']['entity_translation']['path wildcard'], $entity_id, $path);
     $this->options['alter']['make_link'] = TRUE;
     $this->options['alter']['path'] = $path . '/translate';
