diff --git a/entity_translation.api.php b/entity_translation.api.php
index c048d11..d55e94f 100644
--- a/entity_translation.api.php
+++ b/entity_translation.api.php
@@ -17,7 +17,7 @@
  * 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
+ * and to reliably alter menu information to provide the translation UI. [@todo update docs] 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.
@@ -30,7 +30,7 @@
  * - 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. [@todo update docs]
  * - 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
@@ -40,7 +40,7 @@
  * - edit path: The menu router path to be used to edit the entity. Defaults to
  *   "$base_path/edit".
  * - path wildcard: The menu router path wildcard identifying the entity.
- *   Defaults to %ENTITY_TYPE.
+ *   Defaults to %ENTITY_TYPE. Can be an array to designate 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 9d93464..e2e0eb0 100644
--- a/entity_translation.module
+++ b/entity_translation.module
@@ -108,19 +108,32 @@ function entity_translation_entity_info_alter(&$entity_info) {
     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 supported for BC.
+      foreach (array('base path', 'edit path', 'view path', 'path wildcard') as $key) {
+        if (isset($entity_info[$entity_type]['translation']['entity_translation'][$key]) && !is_array($entity_info[$entity_type]['translation']['entity_translation'][$key])) {
+            $entity_info[$entity_type]['translation']['entity_translation'][$key] = array($entity_info[$entity_type]['translation']['entity_translation'][$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;
+        $entity_info[$entity_type]['translation']['entity_translation']['base path'] = array($path);
       }
 
-      $path = $entity_info[$entity_type]['translation']['entity_translation']['base path'];
+      $view_path = $entity_info[$entity_type]['translation']['entity_translation']['base path'];
+      $edit_path = array_map(function($s) { return $s . '/edit'; }, $view_path);
+
+      // @todo Move to media module (or somewhere else).
+      if ($entity_type == 'file') {
+        $edit_path[] = 'media/%file/edit/%ctools_js';
+      }
 
       $entity_info[$entity_type]['translation']['entity_translation'] += array(
-        'view path' => $path,
-        'edit path' => "$path/edit",
-        'path wildcard' => "%$entity_type",
+        'view path' => $view_path,
+        'edit path' => $edit_path,
+        'path wildcard' => array("%$entity_type"),
         'access callback' => 'entity_translation_tab_access',
         'access arguments' => array($entity_type),
         'theme callback' => 'variable_get',
@@ -191,104 +204,112 @@ 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'];
+
+      foreach ($base_paths as $delta => $path) {
+        // If the (first) base path is not defined or is not compatible with
+        // any defined one we cannot provide the translation UI for this entity
+        // type.
+        if ($delta == 0 && !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;
+        }
 
-      // 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;
-      }
+        $keys = array('theme callback', 'theme arguments', 'access callback', 'access arguments', 'load arguments');
+        $item = array_intersect_key($info['translation']['entity_translation'], drupal_map_assoc($keys));
 
-      $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;
+        }
       }
     }
   }
@@ -455,10 +476,12 @@ function entity_translation_admin_paths() {
   $paths = array();
   foreach (entity_get_info() as $entity_type => $info) {
     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;
-      $paths["$base_path/edit/*"] = 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;
+        $paths["$base_path/edit/*"] = TRUE;
+      }
     }
   }
   return $paths;
diff --git a/includes/translation.handler.inc b/includes/translation.handler.inc
index a538060..da35d96 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';
