diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index d692c9b..5d930b5 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -106,6 +106,14 @@ function entity_info_cache_clear() {
 }
 
 /**
+ * Returns the defined bundles for the given entity type.
+ */
+function entity_get_bundles($entity_type) {
+  $entity_info = entity_get_info($entity_type);
+  return isset($entity_info['bundles']) ? array_keys($entity_info['bundles']) : array($entity_type);
+}
+
+/**
  * Loads an entity from the database.
  *
  * @param string $entity_type
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index b99a839..caf9a94 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1144,6 +1144,16 @@ function comment_links(Comment $comment, Node $node) {
       $links['comment-forbidden']['html'] = TRUE;
     }
   }
+
+  // Add translations link for translation-enabled comment bundles.
+  if (module_exists('translation_entity') && translation_entity_translate_access($comment)) {
+    $links['comment-translations'] = array(
+      'title' => t('translations'),
+      'href' => 'comment/' . $comment->id() . '/translations',
+      'html' => TRUE,
+    );
+  }
+
   return $links;
 }
 
diff --git a/core/modules/node/node.js b/core/modules/node/node.js
index 33bc88a..e54a4d4 100644
--- a/core/modules/node/node.js
+++ b/core/modules/node/node.js
@@ -52,7 +52,7 @@ Drupal.behaviors.nodeFieldsetSummaries = {
       }
       else {
         $checkbox = $context.find('.form-item-translation-retranslate input');
-        translate = $checkbox.is(':checked') ? Drupal.t('Flag translations as outdated') : Drupal.t('Do not flag translations as outdated');
+        translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated');
       }
 
       return translate;
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index eeab29b..d523adf 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -314,6 +314,7 @@ function node_admin_paths() {
       'node/*/revisions' => TRUE,
       'node/*/revisions/*/revert' => TRUE,
       'node/*/revisions/*/delete' => TRUE,
+      'node/*/translations' => TRUE,
       'node/add' => TRUE,
       'node/add/*' => TRUE,
     );
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index b614947..7275ab9 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -412,6 +412,7 @@ function taxonomy_admin_paths() {
   $paths = array(
     'taxonomy/term/*/edit' => TRUE,
     'taxonomy/term/*/delete' => TRUE,
+    'taxonomy/term/*/translations' => TRUE,
   );
   return $paths;
 }
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
index 39d3013..d6a8181 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/EntityTranslationController.php
@@ -22,10 +22,12 @@ class EntityTranslationController implements EntityTranslationControllerInterfac
    *
    * @param string $entity_type
    *   The type of the entity being translated.
+   * @param array $entity_info
+   *   The info array of the given entity type.
    */
-  public function __construct($entity_type) {
+  public function __construct($entity_type, $entity_info) {
     $this->entityType = $entity_type;
-    $this->entityInfo = entity_get_info($entity_type);
+    $this->entityInfo = $entity_info;
   }
 
   /**
@@ -120,7 +122,13 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
     // have at least one translation.
     $languages = language_list();
     if (isset($languages[$form_langcode]) && (!$no_translations || $new_translation)) {
-      drupal_set_title($this->entityFormTitle($entity) . ' [' . $languages[$form_langcode]->name . ']', PASS_THROUGH);
+      $title = $this->entityFormTitle($entity);
+      // When editing the original values display just the entity label.
+      if ($form_langcode != $entity->language()->langcode) {
+        $t_args = array('%language' => $languages[$form_langcode]->name, '%title' => $entity->label());
+        $title = empty($source_langcode) ? $title . ' [' . t('%language translation', $t_args) . ']' : t('Create %language translation of %title', $t_args);
+      }
+      drupal_set_title($title, PASS_THROUGH);
     }
 
     // Display source language selector only if we are creating a new
@@ -128,7 +136,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
     if (!$no_translations && $new_translation) {
       $form['source_langcode'] = array(
         '#type' => 'fieldset',
-        '#title' => t('Source language'),
+        '#title' => t('Source language: @language', array('@language' => $languages[$source_langcode]->name)),
         '#collapsible' => TRUE,
         '#collapsed' => TRUE,
         '#tree' => TRUE,
@@ -207,9 +215,9 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
       if (!$translate) {
         $form['translation']['retranslate'] = array(
           '#type' => 'checkbox',
-          '#title' => t('Flag translations as outdated'),
+          '#title' => t('Flag other translations as outdated'),
           '#default_value' => FALSE,
-          '#description' => t('If you made a significant change, which means translations should be updated, you can flag all translations of this post as outdated. This will not change any other property of those posts, like whether they are published or not.'),
+          '#description' => t('If you made a significant change, which means the other translations should be updated, you can flag all translations of this content as outdated. This will not change any other property of them, like whether they are published or not.'),
         );
       }
       else {
@@ -217,7 +225,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
           '#type' => 'checkbox',
           '#title' => t('This translation needs to be updated'),
           '#default_value' => $translate,
-          '#description' => t('When this option is checked, this translation needs to be updated because the source post has changed. Uncheck when the translation is up to date again.'),
+          '#description' => t('When this option is checked, this translation needs to be updated because the source content has changed. Uncheck when the translation is up to date again.'),
         );
       }
     }
@@ -261,11 +269,11 @@ public function entityFormEntityBuild($entity_type, $entity, $form, &$form_state
   public function entityFormSourceChange($form, &$form_state) {
     $form_controller = translation_entity_form_controller($form_state);
     $entity = $form_controller->getEntity($form_state);
-    $langcode = $form_state['values']['source_langcode']['source'];
-    $path = $this->getBasePath($entity) . '/translations/add/' . $langcode;
+    $source = $form_state['values']['source_langcode']['source'];
+    $path = $this->getBasePath($entity) . '/translations/add/' . $source . '/' . $form_controller->getFormLangcode($form_state);
     $form_state['redirect'] = array('path' => $path);
     $languages = language_list();
-    drupal_set_message(t('Source language set to: %language', array('%language' => t($languages[$langcode]->name))));
+    drupal_set_message(t('Source language set to: %language', array('%language' => t($languages[$source]->name))));
   }
 
   /**
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
index ee9dc59..1bec14f 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
@@ -53,11 +53,6 @@ function setUp() {
       $this->assertText($name, 'Language added successfully.');
     }
 
-    // @todo This should not be need.
-    // Enable URL language detection for content language.
-    $edit = array('language_content[enabled][language-url]' => TRUE);
-    $this->drupalPost('admin/config/regional/language/detection', $edit, t('Save settings'));
-
     // Enable translation for the entity_test entity type and ensure the change
     // is picked up.
     variable_set('translation_entity_enabled_entity_test_entity_test', TRUE);
@@ -111,7 +106,7 @@ function testTranslationUI() {
       'field_test_text' => $this->randomName(16),
     );
 
-    $this->drupalPost($langcode . '/entity-test/manage/' . $entity->id() . '/translations/add/' . $default_langcode, $this->getEditValues($values, $langcode), t('Save'));
+    $this->drupalPost($langcode . '/entity-test/manage/' . $entity->id() . '/translations/add/' . $default_langcode . '/' . $langcode, $this->getEditValues($values, $langcode), t('Save'));
     $this->assertFieldByXPath('//select[@id="edit-langcode" and @disabled]', $default_langcode, 'Language selector correclty disabled on translations.');
     $entity = entity_test_load($entity->id(), TRUE);
 
@@ -119,7 +114,7 @@ function testTranslationUI() {
     $langcode = 'fr';
     $source_langcode = 'it';
     $edit = array('source_langcode[source]' => $source_langcode);
-    $this->drupalPost($langcode . '/entity-test/manage/' . $entity->id() . '/translations/add/' . $default_langcode, $edit, t('Change'));
+    $this->drupalPost($langcode . '/entity-test/manage/' . $entity->id() . '/translations/add/' . $default_langcode . '/' . $langcode, $edit, t('Change'));
     $this->assertFieldByXPath('//input[@name="field_test_text[fr][0][value]"]', $values[$source_langcode]['field_test_text'], 'Source language correctly switched.');
 
     // Add another translation and mark the other ones as outdated.
diff --git a/core/modules/translation_entity/translation_entity.install b/core/modules/translation_entity/translation_entity.install
index c86a5f5..ff7a7d7 100644
--- a/core/modules/translation_entity/translation_entity.install
+++ b/core/modules/translation_entity/translation_entity.install
@@ -50,3 +50,10 @@ function translation_entity_schema() {
   );
   return $schema;
 }
+
+/**
+ * Implements hook_install().
+ */
+function translation_entity_install() {
+  language_negotiation_set(LANGUAGE_TYPE_CONTENT, array(LANGUAGE_NEGOTIATION_URL => 0));
+}
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index cfe928b..fa8b476 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -53,10 +53,8 @@ function translation_entity_entity_info_alter(&$entity_info) {
 
       $entity_position = count(explode('/', $path)) - 1;
       $entity_info[$entity_type]['translation']['translation_entity'] += array(
-        'access callback' => 'translation_entity_tab_access',
+        'access callback' => 'translation_entity_translate_access',
         'access arguments' => array($entity_position),
-        'theme callback' => 'variable_get',
-        'theme arguments' => array('admin_theme'),
       );
     }
   }
@@ -88,9 +86,9 @@ function translation_entity_menu() {
       // Add translation callback.
       // @todo Add the access callback instead of replacing it as soon as the
       // routing system supports multiple callbacks.
-      $add_path = "$path/translations/add/%language";
+      $add_path = "$path/translations/add/%language/%language";
       $language_position = $entity_position + 3;
-      $args = array($entity_position, $language_position);
+      $args = array($entity_position, $language_position, $language_position + 1);
       $items[$add_path] = array(
         'title' => 'Add',
         'page callback' => 'translation_entity_add_page',
@@ -176,9 +174,9 @@ function translation_entity_menu_alter(&$items) {
 /**
  * Access callback.
  */
-function translation_entity_tab_access(EntityInterface $entity) {
+function translation_entity_translate_access(EntityInterface $entity) {
   $entity_type = $entity->entityType();
-  return empty($entity->language()->locked) && language_multilingual() && (user_access('translate any entity') || user_access("translate $entity_type entities"));
+  return empty($entity->language()->locked) && language_multilingual() && translation_entity_enabled($entity_type, $entity->bundle()) && (user_access('translate any entity') || user_access("translate $entity_type entities"));
 }
 
 /**
@@ -202,9 +200,7 @@ function translation_entity_enabled($entity_type, $bundle = NULL, $skip_handler
     $enabled = variable_get("translation_entity_enabled_{$entity_type}_{$bundle}");
   }
   else {
-    $entity_info = entity_get_info($entity_type);
-    $bundles = isset($entity_info['bundles']) ? $entity_info['bundles'] : array($entity_type => NULL);
-    foreach ($bundles as $bundle => $info) {
+    foreach (entity_get_bundles($entity_type) as $bundle) {
       if (variable_get("translation_entity_enabled_{$entity_type}_{$bundle}")) {
         $enabled = TRUE;
         break;
@@ -228,7 +224,7 @@ function translation_entity_controller($entity_type) {
   $entity_info = entity_get_info($entity_type);
   // @todo Throw an exception if the key is missing.
   $class = $entity_info['translation']['translation_entity']['class'];
-  return new $class($entity_type);
+  return new $class($entity_type, $entity_info);
 }
 
 /**
@@ -385,6 +381,27 @@ function translation_entity_entity_update(EntityInterface $entity) {
 }
 
 /**
+ * Implements hook_field_extra_fields().
+ */
+function translation_entity_field_extra_fields() {
+  $extra = array();
+
+  foreach (entity_get_info() as $entity_type => $info) {
+    foreach (entity_get_bundles($entity_type) as $bundle) {
+      if (translation_entity_enabled($entity_type, $bundle)) {
+        $extra[$entity_type][$bundle]['form']['translation'] = array(
+          'label' => t('Translation'),
+          'description' => t('Translation settings'),
+          'weight' => 10,
+        );
+      }
+    }
+  }
+
+  return $extra;
+}
+
+/**
  * Implements hook_form_FORM_ID_alter().
  */
 function translation_entity_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
diff --git a/core/modules/translation_entity/translation_entity.pages.inc b/core/modules/translation_entity/translation_entity.pages.inc
index 050b43d..c688a81 100644
--- a/core/modules/translation_entity/translation_entity.pages.inc
+++ b/core/modules/translation_entity/translation_entity.pages.inc
@@ -23,7 +23,7 @@ function translation_entity_overview(EntityInterface $entity) {
   $base_path = $controller->getBasePath($entity);
   $edit_path = $controller->getEditPath($entity);
 
-  $header = array(t('Language'), t('Source language'), t('Translation'), t('Status'), t('Operations'));
+  $header = array(t('Language'), t('Translation'), t('Source language'), t('Status'), t('Operations'));
   $rows = array();
 
   if (language_multilingual()) {
@@ -37,7 +37,7 @@ function translation_entity_overview(EntityInterface $entity) {
       $options = array();
       $language_name = $language->name;
       $langcode = $language->langcode;
-      $add_path = "$base_path/translations/add/$original";
+      $add_path = $base_path . '/translations/add/' . $original . '/' . $langcode;
 
       if ($base_path) {
         $add_links = _translation_entity_get_switch_links($add_path);
@@ -71,7 +71,7 @@ function translation_entity_overview(EntityInterface $entity) {
 
         if ($is_original) {
           $language_name = t('<strong>@language_name</strong>', array('@language_name' => $language_name));
-          $source_name = t('(original content)');
+          $source_name = t('(original language)');
         }
         else {
           $source_name = isset($languages[$source]) ? $languages[$source]->name : t('n/a');
@@ -99,7 +99,7 @@ function translation_entity_overview(EntityInterface $entity) {
         }
         $status = t('Not translated');
       }
-      $rows[] = array($language_name, $source_name, $row_title, $status, implode(" | ", $options));
+      $rows[] = array($language_name, $row_title, $source_name, $status, implode(" | ", $options));
     }
   }
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 1856a7b..cfa1cc6 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1457,6 +1457,7 @@ function user_admin_paths() {
     'user/*/cancel' => TRUE,
     'user/*/edit' => TRUE,
     'user/*/edit/*' => TRUE,
+    'user/*/translations' => TRUE,
   );
   return $paths;
 }
