diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
index 9c3af8e..40afc94 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
@@ -47,7 +47,7 @@ function setUp() {
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 
     // Set "Article" content type to use multilingual support.
-    $edit = array('node_type_language_hidden' => FALSE);
+    $edit = array('language_configuration[language_hidden]' => FALSE);
     $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
 
     // Enable content language negotiation UI.
diff --git a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
index 77e6937..0ac151f 100644
--- a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
+++ b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
@@ -51,7 +51,7 @@ function setUp() {
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 
     // Set "Article" content type to use multilingual support with translation.
-    $edit = array('node_type_language_hidden' => FALSE, 'node_type_language_translation_enabled' => TRUE);
+    $edit = array('language_configuration[language_hidden]' => FALSE, 'node_type_language_translation_enabled' => TRUE);
     $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Article content type has been updated.');
   }
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index c0c22b2..9146e0e 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -226,6 +226,8 @@ function language_process_language_select($element) {
   if (!isset($element['#options'])) {
     $element['#options'] = array();
     foreach (language_list($element['#languages']) as $langcode => $language) {
+      // @todo: http://drupal.org/node/1739928#comment-6471438
+      // Is this flipped? If it's locked, put it in t() so it can be translated?
       $element['#options'][$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
     }
   }
@@ -233,6 +235,224 @@ function language_process_language_select($element) {
 }
 
 /**
+ * Implements hook_element_info().
+ */
+function language_element_info() {
+  $types['language_configuration'] = array(
+    '#input' => TRUE,
+    '#tree' => TRUE,
+    '#process' => array('language_configuration_element_process'),
+  );
+  return $types;
+}
+
+/**
+ * Returns the default options for the language configuration form element.
+ *
+ * @return array
+ *   An array containing the default options.
+ */
+function language_configuration_element_default_options() {
+  $language_options = array();
+
+  $languages = language_list(LANGUAGE_ALL);
+  foreach ($languages as $langcode => $language) {
+    $language_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
+  }
+
+  $language_options += array(
+    'site_default' => t("Site's default language (!language)", array('!language' => language_default()->name)),
+    'current_interface' => t('Current interface language'),
+    'authors_default' => t("Author's preferred language"),
+  );
+  return $language_options;
+}
+
+/**
+ * Process handler for the language_configuration form element.
+ */
+function language_configuration_element_process($element, &$form_state, &$form) {
+  $options = isset($element['#options']) ? $element['#options'] : array();
+  // Avoid validation failure since we are moving the '#options' key in the
+  // nested 'language' select element.
+  unset($element['#options']);
+  $element['langcode'] = array(
+    '#type' => 'select',
+    '#title' => t('Default language'),
+    '#options' => $options + language_configuration_element_default_options(),
+    '#description' => t('Explanation of the language options is found on the <a href="@languages_list_page">languages list page</a>.', array('@languages_list_page' => url('admin/config/regional/language'))),
+    '#default_value' => isset($element['#default_value']['langcode']) ? $element['#default_value']['langcode'] : NULL,
+  );
+
+  $element['language_hidden'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Hide language selection'),
+    '#default_value' => isset($element['#default_value']['language_hidden']) ? $element['#default_value']['language_hidden'] : NULL,
+    '#description' => t('Language selector appears on create and edit pages.'),
+  );
+
+  // Add the entity type and bundle information to the form if they are set.
+  // They will be used, in the submit handler, to generate the names of the
+  // variables that will store the settings and are a way to uniquely identify
+  // the entity.
+  if (!isset($form_state['language'])) {
+    $form_state['language'] = array();
+  }
+  $form_state['language'] += array(
+    $element['#name'] => array(
+      'entity_type' => $element['#entity_information']['entity_type'],
+      'bundle' => $element['#entity_information']['bundle'],
+    ),
+  );
+
+  return $element;
+}
+
+/**
+ * Submit handler for the forms that have a language_configuration element.
+ */
+function language_configuration_element_submit(&$form, &$form_state) {
+  // Iterate through all the language_configuration elements and save their
+  // values.
+  if (isset($form_state['language'])) {
+    foreach ($form_state['language'] as $element_name => $values) {
+      language_save_default_configuration($values['entity_type'], $values['bundle'],  $form_state['values'][$element_name]);
+    }
+  }
+}
+
+/**
+ * Saves a language configuration that is attached to an entity type and bundle.
+ *
+ * @param string $entity_type
+ *   A string representing the entity type.
+ * @param string $bundle
+ *   A string representing the bundle.
+ * @param array $values
+ *   An array holding the values to be saved having the following keys:
+ *   - langcode: the language code.
+ *   - language_hidden: if the language element should be hidden or not.
+ */
+function language_save_default_configuration($entity_type, $bundle, $values = array()) {
+  config('language.settings')->set(language_get_default_configuration_settings_path($entity_type, $bundle), array('langcode' => $values['langcode'], 'language_hidden' => $values['language_hidden']))->save();
+}
+
+/**
+ * Returns the language configuration stored for an entity type and bundle.
+ *
+ * @param string $entity_type
+ *   A string representing the entity type.
+ * @param string $bundle
+ *   A string representing the bundle.
+ *
+ * @return array
+ *   An array with the following keys:
+ *   - langcode: the language code.
+ *   - language_hidden: if the language element is hidden or not.
+ */
+function language_get_default_configuration($entity_type, $bundle) {
+  // @todo: http://drupal.org/node/1783346 for unresolved CMI issue.
+  $configuration = config('language.settings')->get(language_get_default_configuration_settings_path($entity_type, $bundle));
+  if (is_null($configuration)) {
+    $configuration = array();
+  }
+  $configuration += array('langcode' => 'site_default', 'language_hidden' => TRUE);
+  return $configuration;
+}
+
+/**
+ * Clears the default language configuration for an entity type and bundle.
+ *
+ * @param string $entity_type
+ *   A string representing the entity type.
+ * @param string $bundle
+ *   A string representing the bundle.
+ */
+function language_clear_default_configuration($entity_type, $bundle) {
+  config('language.settings')->clear(language_get_default_configuration_settings_path($entity_type, $bundle))->save();
+}
+
+/**
+ * Returns the root name of the variables used to store the configuration.
+ *
+ * Based on the entity type and bundle, the variables used to store the
+ * configuration will have a common root name.
+ *
+ * @param string $entity_type
+ *   A string representing the entity type.
+ * @param string $bundle
+ *   A string representing the bundle.
+ *
+ * @return string
+ *   The root name of the variables.
+ */
+function language_get_default_configuration_settings_path($entity_type, $bundle) {
+  // @todo: http://drupal.org/node/1739928#comment-6471438
+  // Since these values are more or less coming in directly from
+  // $form_state['values'], should there be some sanitization here to ensure
+  // people aren't putting nonsense like "../../../../" in there?
+  return $entity_type . '.' . $bundle . '.language.default_configuration';
+}
+
+/**
+ * Implements hook_node_type_update().
+ */
+function language_node_type_update($info) {
+  if (!empty($info->old_type) && $info->old_type != $info->type) {
+    language_save_default_configuration('node', $info->type, language_get_default_configuration('node', $info->old_type));
+    language_clear_default_configuration('node', $info->old_type);
+  }
+}
+
+/**
+ * Returns the default language code assigned to an entity type and a bundle.
+ *
+ * @param string $entity_type
+ *   The entity type.
+ * @param string $bundle
+ *   The bundle name.
+ *
+ * @return string
+ *   The language code.
+ */
+function language_get_default_langcode($entity_type, $bundle) {
+  $configuration = language_get_default_configuration($entity_type, $bundle);
+
+  if (!isset($configuration['langcode'])) {
+    $configuration['langcode'] = 'site_default';
+  }
+
+  $default_value = NULL;
+  $language_interface = language(LANGUAGE_TYPE_INTERFACE);
+  switch ($configuration['langcode']) {
+    case 'site_default':
+      $default_value = language_default()->langcode;
+      break;
+
+    case 'current_interface':
+      $default_value = $language_interface->langcode;
+      break;
+
+    case 'authors_default':
+      global $user;
+      if (!empty($user->preferred_langcode)) {
+        $default_value = $user->preferred_langcode;
+      }
+      else {
+        $default_value = $language_interface->langcode;
+      }
+      break;
+  }
+  if ($default_value) {
+    return $default_value;
+  }
+
+  // If we still do not have a default value, just return the value stored in
+  // the configuration; it has to be an actual language code.
+  return $configuration['langcode'];
+}
+
+/**
  * API function to add or update a language.
  *
  * @param $language
@@ -292,6 +512,7 @@ function language_update_count() {
  *
  * @param $langcode
  *   Language code of the language to be deleted.
+ *
  * @return
  *   TRUE if language is successfully deleted. Otherwise FALSE.
  */
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageConfigurationElementTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigurationElementTest.php
new file mode 100644
index 0000000..6f8d9c8
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigurationElementTest.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\language\Tests\LanguageConfigurationElementTest.
+ */
+
+namespace Drupal\language\Tests;
+
+use Drupal\simpletest\WebTestBase;
+use Drupal\Core\Language\Language;
+
+/**
+ * Functional tests for language configuration's effect on negotiation setup.
+ */
+class LanguageConfigurationElementTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'language_elements_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Language configuration form element tests',
+      'description' => 'Tests the features of the language configuration element field.',
+      'group' => 'Language',
+    );
+  }
+
+  /**
+   * Tests the language settings have been saved.
+   */
+  public function testLanguageConfigurationElement() {
+    $this->drupalGet('language-tests/language_configuration_element');
+    $edit['lang_configuration[langcode]'] = 'current_interface';
+    $edit['lang_configuration[language_hidden]'] = TRUE;
+    $this->drupalPost(NULL, $edit, 'Save');
+    $lang_conf = language_get_default_configuration('some_custom_type', 'some_bundle');
+
+    // Check that the settings have been saved.
+    $this->assertEqual($lang_conf['langcode'], 'current_interface');
+    $this->assertTrue($lang_conf['language_hidden']);
+    $this->drupalGet('language-tests/language_configuration_element');
+    $this->assertOptionSelected('edit-lang-configuration-langcode', 'current_interface');
+    $this->assertFieldChecked('edit-lang-configuration-language-hidden');
+
+    // Reload the page and save again.
+    $this->drupalGet('language-tests/language_configuration_element');
+    $edit['lang_configuration[langcode]'] = 'authors_default';
+    $edit['lang_configuration[language_hidden]'] = FALSE;
+    $this->drupalPost(NULL, $edit, 'Save');
+    $lang_conf = language_get_default_configuration('some_custom_type', 'some_bundle');
+
+    // Check that the settings have been saved.
+    $this->assertEqual($lang_conf['langcode'], 'authors_default');
+    $this->assertFalse($lang_conf['language_hidden']);
+    $this->drupalGet('language-tests/language_configuration_element');
+    $this->assertOptionSelected('edit-lang-configuration-langcode', 'authors_default');
+    $this->assertNoFieldChecked('edit-lang-configuration-language-hidden');
+  }
+
+  /**
+   * Tests that the language_get_default_langcode() returns the correct values.
+   */
+  public function testDefaultLangcode() {
+    // Add some custom languages.
+    foreach (array('aa', 'bb', 'cc') as $language_code) {
+      $language = new Language(array(
+        'langcode' => $language_code,
+        'name' => $this->randomName(),
+      ));
+      language_save($language);
+    }
+
+    // Fixed language.
+    language_save_default_configuration('custom_type', 'custom_bundle', array('langcode' => 'bb', 'language_hidden' => FALSE));
+    $langcode = language_get_default_langcode('custom_type', 'custom_bundle');
+    $this->assertEqual($langcode, 'bb');
+
+    // Current interface.
+    language_save_default_configuration('custom_type', 'custom_bundle', array('langcode' => 'current_interface', 'language_hidden' => FALSE));
+    $langcode = language_get_default_langcode('custom_type', 'custom_bundle');
+    $language_interface = language(LANGUAGE_TYPE_INTERFACE);
+    $this->assertEqual($langcode, $language_interface->langcode);
+
+    // Site's default.
+    $old_default = language_default();
+    $old_default->default = FALSE;
+    language_save($old_default);
+    $new_default = language_load('cc');
+    $new_default->default = TRUE;
+    language_save($new_default);
+    language_save_default_configuration('custom_type', 'custom_bundle', array('langcode' => 'site_default', 'language_hidden' => FALSE));
+    $langcode = language_get_default_langcode('custom_type', 'custom_bundle');
+    $this->assertEqual($langcode, 'cc');
+
+    // Check the default value of a language field when authors preferred option
+    // is selected.
+    // Create first an user and assign a preferred langcode to him.
+    $some_user = $this->drupalCreateUser();
+    $some_user->preferred_langcode = 'bb';
+    $some_user->save();
+    $this->drupalLogin($some_user);
+    language_save_default_configuration('custom_type', 'some_bundle', array('langcode' => 'authors_default', 'language_hidden' => FALSE));
+    $this->drupalGet('language-tests/language_configuration_element_test');
+    $this->assertOptionSelected('edit-langcode', 'bb');
+  }
+
+  /**
+   * Tests that the configuration is updated when the node type is changed.
+   */
+  public function testNodeTypeUpdate() {
+    // Create the article content type first if the profile used is not the
+    // standard one.
+    if ($this->profile != 'standard') {
+      $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
+    }
+    $admin_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($admin_user);
+    $edit = array(
+      'language_configuration[langcode]' => 'current_interface',
+      'language_configuration[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
+    // Check the language default configuration for the articles.
+    $configuration = language_get_default_configuration('node', 'article');
+    $this->assertEqual($configuration, array('langcode' => 'current_interface', 'language_hidden' => 0), 'The default language configuration has been saved on the Article content type.');
+    // Rename the article content type.
+    $edit = array(
+      'type' => 'article_2'
+    );
+    $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
+    // Check that we still have the settings for the new node type.
+    $configuration = language_get_default_configuration('node', 'article_2');
+    $this->assertEqual($configuration, array('langcode' => 'current_interface', 'language_hidden' => 0), 'The default language configuration has been kept on the new Article content type.');
+  }
+}
diff --git a/core/modules/language/tests/language_elements_test/language_elements_test.info b/core/modules/language/tests/language_elements_test/language_elements_test.info
new file mode 100644
index 0000000..c88befb
--- /dev/null
+++ b/core/modules/language/tests/language_elements_test/language_elements_test.info
@@ -0,0 +1,6 @@
+name = "Language form elements test"
+description = "Support module for the language form elements tests."
+core = 8.x
+package = Testing
+version = VERSION
+hidden = TRUE
diff --git a/core/modules/language/tests/language_elements_test/language_elements_test.module b/core/modules/language/tests/language_elements_test/language_elements_test.module
new file mode 100644
index 0000000..b44cc45
--- /dev/null
+++ b/core/modules/language/tests/language_elements_test/language_elements_test.module
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Mock module for language form elements test.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function language_elements_test_menu() {
+  $items['language-tests/language_configuration_element'] = array(
+    'title' => 'Language configuration form element',
+    'type' => MENU_CALLBACK,
+    'access callback' => TRUE,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('language_elements_configuration_element'),
+  );
+  $items['language-tests/language_configuration_element_test'] = array(
+    'title' => 'Language configuration form element',
+    'type' => MENU_CALLBACK,
+    'access callback' => TRUE,
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('language_elements_configuration_element_test'),
+  );
+  return $items;
+}
+
+function language_elements_configuration_element() {
+  $conf = language_get_default_configuration('some_custom_type', 'some_bundle');
+
+  $form['lang_configuration'] = array(
+    '#type' => 'language_configuration',
+    '#entity_information' => array(
+      'entity_type' => 'some_custom_type',
+      'bundle' => 'some_bundle',
+    ),
+    '#default_value' => $conf,
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Save',
+  );
+  $form['#submit'][] = 'language_configuration_element_submit';
+  return $form;
+}
+
+function language_elements_configuration_element_test() {
+  $form['langcode'] = array(
+    '#type' => 'language_select',
+    '#default_value' => language_get_default_langcode('custom_type', 'some_bundle'),
+  );
+  return $form;
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
index a41d68b..d30526a 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleContentTest.php
@@ -88,7 +88,7 @@ function testContentTypeLanguageConfiguration() {
     $this->drupalGet('admin/structure/types/manage/page');
     $this->assertText(t('Language settings'), t('Multilingual support fieldset present on content type configuration form.'));
     $edit = array(
-      'node_type_language_hidden' => FALSE,
+      'language_configuration[language_hidden]' => FALSE,
     );
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
@@ -156,7 +156,7 @@ function testContentTypeDirLang() {
     // Set "Article" content type to use multilingual support.
     $this->drupalGet('admin/structure/types/manage/article');
     $edit = array(
-      'node_type_language_hidden' => FALSE,
+      'language_configuration[language_hidden]' => FALSE,
     );
     $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), t('Article content type has been updated.'));
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
index 9f63420..ebcafe3 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
@@ -63,7 +63,7 @@ function testUninstallProcess() {
     $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, $this->langcode, t('Current language: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode)));
 
     // Enable multilingual workflow option for articles.
-    variable_set('node_type_language_hidden_article',FALSE);
+    language_save_default_configuration('node', 'article', array('langcode' => 'site_default', 'language_hidden' => FALSE));
     // Change JavaScript translations directory.
     variable_set('locale_js_directory', 'js_translations');
     // Build the JavaScript translation file for French.
diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc
index 3c8812d..b2b5263 100644
--- a/core/modules/node/content_types.inc
+++ b/core/modules/node/content_types.inc
@@ -206,19 +206,6 @@ function node_type_form($form, &$form_state, $type = NULL) {
     '#description' => t('Users with the <em>Administer content</em> permission will be able to override these options.'),
   );
   if (module_exists('language')) {
-    $lang_options = array();
-
-    $languages = language_list(LANGUAGE_ALL);
-    foreach ($languages as $langcode => $language) {
-      $lang_options[$langcode] = $language->locked ? t('- @name -', array('@name' => $language->name)) : $language->name;
-    }
-
-    $lang_options += array(
-      'site_default' => t("Site's default language"),
-      'current_interface' => t('Current interface language'),
-      'authors_default' => t("Author's preferred language"),
-    );
-
     $form['language'] = array(
       '#type' => 'fieldset',
       '#title' => t('Language settings'),
@@ -226,18 +213,20 @@ function node_type_form($form, &$form_state, $type = NULL) {
       '#collapsed' => TRUE,
       '#group' => 'additional_settings',
     );
-    $form['language']['node_type_language_default'] = array(
-      '#type' => 'select',
-      '#title' => t('Default language'),
-      '#options' => $lang_options,
-      '#default_value' => variable_get('node_type_language_default_' . $type->type, 'site_default'),
-      '#description' => t('Explanation of the language options is found on the <a href="@languages_list_page">languages list page</a>.', array('@languages_list_page' => url('admin/config/regional/language'))),
-    );
-    $form['language']['node_type_language_hidden'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Hide language selector'),
-      '#default_value' => variable_get('node_type_language_hidden_' . $type->type, TRUE),
+
+    // @todo: http://drupal.org/node/1739928#comment-6471438
+    // In taxonomy module, this was wrapped in an if (module_exists('language'))
+    // check. Why is it not here?
+    $language_configuration = language_get_default_configuration('node', $type->type);
+    $form['language']['language_configuration'] = array(
+      '#type' => 'language_configuration',
+      '#entity_information' => array(
+        'entity_type' => 'node',
+        'bundle' => $type->type,
+      ),
+      '#default_value' => $language_configuration,
     );
+    $form['#submit'][] = 'language_configuration_element_submit';
   }
   $form['display'] = array(
     '#type' => 'fieldset',
@@ -293,6 +282,7 @@ function node_type_form($form, &$form_state, $type = NULL) {
       );
     }
   }
+  $form['#submit'][] = 'node_type_form_submit';
 
   return $form;
 }
diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js
index 87fc460..d2a63b6 100644
--- a/core/modules/node/content_types.js
+++ b/core/modules/node/content_types.js
@@ -24,7 +24,7 @@ Drupal.behaviors.contentTypes = {
     $('fieldset#edit-language', context).drupalSetSummary(function(context) {
       var vals = [];
 
-      vals.push($(".form-item-node-type-language-default select option:selected", context).text());
+      vals.push($(".form-item-language-configuration-langcode select option:selected", context).text())
 
       $('input:checked', context).next('label').each(function() {
         vals.push(Drupal.checkPlain($(this).text()));
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index b9bf7eb..09a8ca8 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -98,12 +98,13 @@ public function form(array $form, array &$form_state, EntityInterface $node) {
       $form['title']['#weight'] = -5;
     }
 
+    $language_configuration = module_invoke('language', 'get_default_configuration', 'node', $node->type);
     $form['langcode'] = array(
       '#title' => t('Language'),
       '#type' => 'language_select',
       '#default_value' => $node->langcode,
       '#languages' => LANGUAGE_ALL,
-      '#access' => !variable_get('node_type_language_hidden_' . $node->type, TRUE),
+      '#access' => isset($language_configuration['language_hidden']) && !$language_configuration['language_hidden'],
     );
 
     $form['additional_settings'] = array(
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
index 838f855..9c3dd06 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
@@ -53,7 +53,7 @@ function setUp() {
 
     // Set "Basic page" content type to use multilingual support.
     $edit = array(
-      'node_type_language_hidden' => FALSE,
+      'language_configuration[language_hidden]' => FALSE,
     );
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.');
@@ -69,7 +69,7 @@ function setUp() {
    */
   function testMultilingualNodeForm() {
     // Create "Basic page" content.
-    $langcode = node_type_get_default_langcode('page');
+    $langcode = language_get_default_langcode('node', 'page');
     $title_key = "title";
     $title_value = $this->randomName(8);
     $body_key = "body[$langcode][0][value]";
@@ -117,7 +117,7 @@ function testMultilingualNodeForm() {
    */
   function testMultilingualDisplaySettings() {
     // Create "Basic page" content.
-    $langcode = node_type_get_default_langcode('page');
+    $langcode = language_get_default_langcode('node', 'page');
     $title_key = "title";
     $title_value = $this->randomName(8);
     $body_key = "body[$langcode][0][value]";
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
index e191eca..c2407c2 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
@@ -42,8 +42,8 @@ function setUp() {
    */
   function testNodeTypeInitialLanguageDefaults() {
     $this->drupalGet('admin/structure/types/manage/article');
-    $this->assertOptionSelected('edit-node-type-language-default', 'site_default', 'The default inital language is the site default.');
-    $this->assertFieldChecked('edit-node-type-language-hidden', 'Language selector is hidden by default.');
+    $this->assertOptionSelected('edit-language-configuration-langcode', 'site_default', 'The default inital language is the site default.');
+    $this->assertFieldChecked('edit-language-configuration-language-hidden', 'Language selector is hidden by default.');
 
     // Tests if the language field cannot be rearranged on the manage fields tab.
     $this->drupalGet('admin/structure/types/manage/article/fields');
@@ -64,9 +64,9 @@ function testNodeTypeInitialLanguageDefaults() {
     $this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
 
     // Tests the initial language after changing the site default language.
-    // First unhide the language selector
+    // First unhide the language selector.
     $edit = array(
-      'node_type_language_hidden' => FALSE,
+      'language_configuration[language_hidden]' => FALSE,
     );
     $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->drupalGet('node/add/article');
@@ -87,7 +87,7 @@ function testNodeTypeInitialLanguageDefaults() {
 
     // Changes the inital language settings.
     $edit = array(
-      'node_type_language_default' => 'en',
+      'language_configuration[langcode]' => 'en',
     );
     $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
     $this->drupalGet('node/add/article');
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 6847fb4..b62f71d 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -472,11 +472,10 @@ function node_uninstall() {
         ->condition('name', 'node_options_' . $type)
         ->condition('name', 'node_submitted_' . $type)
         ->condition('name', 'node_permissions_' . $type)
-        ->condition('name', 'node_type_language_default_' . $type)
-        ->condition('name', 'node_type_language_hidden_' . $type)
         ->condition('name', 'node_type_language_translation_enabled_' . $type)
       )
       ->execute();
+    config('language.settings')->clear('node. ' . $type . '.language.default_configuration')->save();
   }
 
   // Delete node search ranking variables.
@@ -678,6 +677,21 @@ function node_update_8006(&$sandbox) {
 }
 
 /**
+ * Move the language default values to config.
+ */
+function node_update_8007() {
+  $types = db_query('SELECT type FROM {node_type}')->fetchCol();
+  foreach ($types as $type) {
+    $language_default = update_variable_get('node_type_language_default_' . $type, NULL);
+    $language_hidden = update_variable_get('node_type_language_hidden_' . $type, NULL);
+    if (isset($language_default) || isset($language_hidden)) {
+      $values = array('langcode' => $language_default, 'language_hidden' => $language_hidden);
+      config('language.settings')->set('node.' . $type . '.language.default_configuration', $values)->save();
+    }
+  }
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x"
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 2dd1b57..ab69ff7 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -692,13 +692,16 @@ function node_field_extra_fields() {
     // Add also the 'language' select if Language module is enabled and the
     // bundle has multilingual support.
     // Visibility of the ordering of the language selector is the same as on the
-    // node/add form, i.e. node_type_language_hidden_TYPE variable.
-    if ($module_language_enabled && !variable_get('node_type_language_hidden_' . $bundle->type, TRUE)) {
-      $extra['node'][$bundle->type]['form']['language'] = array(
-        'label' => t('Language'),
-        'description' => $description,
-        'weight' => 0,
-      );
+    // node/add form.
+    if ($module_language_enabled) {
+      $configuration = language_get_default_configuration('node', $bundle->type);
+      if (!$configuration['language_hidden']) {
+        $extra['node'][$bundle->type]['form']['language'] = array(
+          'label' => t('Language'),
+          'description' => $description,
+          'weight' => 0,
+        );
+      }
     }
     $extra['node'][$bundle->type]['display']['language'] = array(
       'label' => t('Language'),
@@ -712,47 +715,6 @@ function node_field_extra_fields() {
 }
 
 /**
- * Get the default language for a node type.
- *
- * @param string $node_type
- *   The type of node.
- *
- * @return string
- *   The language code of the node type's default langcode.
- */
-function node_type_get_default_langcode($node_type) {
-  $default_value = variable_get('node_type_language_default_' . $node_type, 'site_default');
-
-  $language_interface = language(LANGUAGE_TYPE_INTERFACE);
-
-  if ($default_value == LANGUAGE_NOT_SPECIFIED) {
-    return LANGUAGE_NOT_SPECIFIED;
-  }
-
-  switch ($default_value) {
-    case 'site_default':
-      $default_value = language_default()->langcode;
-      break;
-
-    case 'current_interface':
-      $default_value = $language_interface->langcode;
-      break;
-
-    case 'authors_default':
-      global $user;
-      if (!empty($user->preferred_langcode)) {
-        $default_value = $user->preferred_langcode;
-      }
-      else {
-        $default_value = $language_interface->langcode;
-      }
-      break;
-  }
-
-  return $default_value;
-}
-
-/**
  * Deletes a node type from the database.
  *
  * @param $name
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index 570ae88..a21db55 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -103,11 +103,12 @@ function node_add($node_type) {
   global $user;
 
   $type = $node_type->type;
+  $langcode = module_invoke('language', 'get_default_langcode', 'node', $type);
   $node = entity_create('node', array(
     'uid' => $user->uid,
     'name' => (isset($user->name) ? $user->name : ''),
     'type' => $type,
-    'langcode' => node_type_get_default_langcode($type)
+    'langcode' => $langcode ? $langcode : language_default()->langcode,
   ));
   drupal_set_title(t('Create @name', array('@name' => $node_type->name)), PASS_THROUGH);
   $output = entity_get_form($node);
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
index 691c537..e6fd10d 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
@@ -31,7 +31,7 @@ function setUp() {
     parent::setUp();
 
     // Create and login user.
-    $this->web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'translate all content', 'access administration pages'));
+    $this->web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'translate all content', 'access administration pages', 'administer content types'));
     $this->drupalLogin($this->web_user);
 
     // Enable French language.
@@ -50,7 +50,11 @@ function setUp() {
    */
   function testAliasTranslation() {
     // Set 'page' content type to enable translation.
-    variable_set('node_type_language_hidden_page', FALSE);
+    $edit = array(
+      'language_configuration[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
+    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.');
     variable_set('node_type_language_translation_enabled_page', TRUE);
 
     $english_node = $this->drupalCreateNode(array('type' => 'page'));
diff --git a/core/modules/poll/lib/Drupal/poll/Tests/PollTranslateTest.php b/core/modules/poll/lib/Drupal/poll/Tests/PollTranslateTest.php
index 4d9299a..d1ce358 100644
--- a/core/modules/poll/lib/Drupal/poll/Tests/PollTranslateTest.php
+++ b/core/modules/poll/lib/Drupal/poll/Tests/PollTranslateTest.php
@@ -54,7 +54,7 @@ function testPollTranslate() {
 
     // Set "Poll" content type to use multilingual support with translation.
     $this->drupalGet('admin/structure/types/manage/poll');
-    $edit = array('node_type_language_hidden' => FALSE, 'node_type_language_translation_enabled' => TRUE);
+    $edit = array('language_configuration[language_hidden]' => FALSE, 'node_type_language_translation_enabled' => TRUE);
     $this->drupalPost('admin/structure/types/manage/poll', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Poll')), 'Poll content type has been updated.');
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
index de68e52..c7acd4d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
@@ -86,7 +86,7 @@ function testEntityFormLanguage() {
 
     // Enable language selector.
     $this->drupalGet('admin/structure/types/manage/page');
-    $edit = array('node_type_language_hidden' => FALSE, 'node_type_language_default' => LANGUAGE_NOT_SPECIFIED);
+    $edit = array('language_configuration[language_hidden]' => FALSE, 'language_configuration[langcode]' => LANGUAGE_NOT_SPECIFIED);
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), 'Basic page content type has been updated.');
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
index c7ee415..77d0874 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
@@ -41,12 +41,13 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
       '#format' => $term->format,
       '#weight' => 0,
     );
-
+    $language_configuration = module_invoke('language', 'get_default_configuration', 'vocabulary', $vocabulary->machine_name);
     $form['langcode'] = array(
       '#type' => 'language_select',
       '#title' => t('Language'),
       '#languages' => LANGUAGE_ALL,
       '#default_value' => $term->langcode,
+      '#access' => !is_null($language_configuration['language_hidden']) && !$language_configuration['language_hidden'],
     );
 
     $form['vocabulary_machine_name'] = array(
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
index f64cf58..b609dfe 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
@@ -33,21 +33,23 @@ function setUp() {
 
     // Create a vocabulary to which the terms will be assigned.
     $this->vocabulary = $this->createVocabulary();
+
+    // Add some custom languages.
+    foreach (array('aa', 'bb', 'cc') as $language_code) {
+      $language = new Language(array(
+        'langcode' => $language_code,
+        'name' => $this->randomName(),
+      ));
+      language_save($language);
+    }
   }
 
   function testTermLanguage() {
-    // Add first some custom languages.
-    $language = new Language(array(
-      'langcode' => 'aa',
-      'name' => $this->randomName(),
-    ));
-    language_save($language);
-
-    $language = new Language(array(
-      'langcode' => 'bb',
-      'name' => $this->randomName(),
-    ));
-    language_save($language);
+    // Configure the vocabulary to not hide the language selector.
+    $edit = array(
+      'default_language[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $edit, t('Save'));
 
     // Add a term.
     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add');
@@ -75,4 +77,43 @@ function testTermLanguage() {
     $this->drupalGet('taxonomy/term/' . $term->tid . '/edit');
     $this->assertOptionSelected('edit-langcode', $edit['langcode'], t('The term language was correctly selected.'));
   }
+
+  function testDefaultTermLanguage() {
+    // Configure the vocabulary to not hide the language selector, and make the
+    // default language of the terms fixed.
+    $edit = array(
+      'default_language[langcode]' => 'bb',
+      'default_language[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $edit, t('Save'));
+    $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add');
+    $this->assertOptionSelected('edit-langcode', 'bb');
+
+    // Make the default language of the terms to be the current interface.
+    $edit = array(
+      'default_language[langcode]' => 'current_interface',
+      'default_language[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $edit, t('Save'));
+    $this->drupalGet('aa/admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add');
+    $this->assertOptionSelected('edit-langcode', 'aa');
+    $this->drupalGet('bb/admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add');
+    $this->assertOptionSelected('edit-langcode', 'bb');
+
+    // Change the default language of the site and check if the default terms
+    // language is still correctly selected.
+    $old_default = language_default();
+    $old_default->default = FALSE;
+    language_save($old_default);
+    $new_default = language_load('cc');
+    $new_default->default = TRUE;
+    language_save($new_default);
+    $edit = array(
+      'default_language[langcode]' => 'site_default',
+      'default_language[language_hidden]' => FALSE,
+    );
+    $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/edit', $edit, t('Save'));
+    $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->machine_name . '/add');
+    $this->assertOptionSelected('edit-langcode', 'cc');
+  }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php
index f4368b7..f61b9e5 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyLanguageTest.php
@@ -30,10 +30,8 @@ function setUp() {
     // Create an administrative user.
     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy'));
     $this->drupalLogin($this->admin_user);
-  }
 
-  function testVocabularyLanguage() {
-    // Add first some custom languages.
+    // Add some custom languages.
     $language = new Language(array(
       'langcode' => 'aa',
       'name' => $this->randomName(),
@@ -45,8 +43,14 @@ function testVocabularyLanguage() {
       'name' => $this->randomName(),
     ));
     language_save($language);
+  }
 
+  /**
+   * Tests language settings for vocabularies.
+   */
+  function testVocabularyLanguage() {
     $this->drupalGet('admin/structure/taxonomy/add');
+
     // Check that we have the language selector available.
     $this->assertField('edit-langcode', t('The language selector field was found on the page'));
 
@@ -70,4 +74,67 @@ function testVocabularyLanguage() {
     $this->drupalGet('admin/structure/taxonomy/' . $machine_name . '/edit');
     $this->assertOptionSelected('edit-langcode', $edit['langcode'], t('The vocabulary language was correctly selected.'));
   }
+
+  /**
+   * Tests term language settings for vocabulary terms are saved and updated.
+   */
+  function testVocabularyDefaultLanguageForTerms() {
+    // Add a new vocabulary and check that the default language settings are for
+    // the terms are saved.
+    $edit = array(
+      'name' => $this->randomName(),
+      'machine_name' => drupal_strtolower($this->randomName()),
+      'default_language[langcode]' => 'bb',
+      'default_language[language_hidden]' => FALSE,
+    );
+    $machine_name = $edit['machine_name'];
+    $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
+
+    // Check that the vocabulary was actually created.
+    $this->drupalGet('admin/structure/taxonomy/' . $edit['machine_name'] . '/edit');
+    $this->assertResponse(200, 'The vocabulary has been created.');
+
+    // Check that the language settings were saved.
+    $language_settings = language_get_default_configuration('vocabulary', $edit['machine_name']);
+    $this->assertEqual($language_settings['langcode'], 'bb');
+    $this->assertEqual($language_settings['language_hidden'], FALSE);
+
+    // Check that the correct options are selected in the interface.
+    $this->assertOptionSelected('edit-default-language-langcode', 'bb', 'The correct default language for the terms of this vocabulary is selected.');
+    $this->assertNoFieldChecked('edit-default-language-language-hidden', 'Hide language selection option is not checked.');
+
+    // Edit the vocabulary and check that the new settings are updated.
+    $edit = array(
+      'default_language[langcode]' => 'aa',
+      'default_language[language_hidden]' => TRUE,
+    );
+    $this->drupalPost('admin/structure/taxonomy/' . $machine_name . '/edit', $edit, t('Save'));
+
+    // And check again the settings and also the interface.
+    $language_settings = language_get_default_configuration('vocabulary', $machine_name);
+    $this->assertEqual($language_settings['langcode'], 'aa');
+    $this->assertEqual($language_settings['language_hidden'], TRUE);
+
+    $this->drupalGet('admin/structure/taxonomy/' . $machine_name . '/edit');
+    $this->assertOptionSelected('edit-default-language-langcode', 'aa', 'The correct default language for the terms of this vocabulary is selected.');
+    $this->assertFieldChecked('edit-default-language-language-hidden', 'Hide language selection option is not checked.');
+
+    // Check that, if the machine name of the vocabulary is changed, then the
+    // settings are applied on the new machine name.
+     $edit = array(
+      'machine_name' => $machine_name . '_new',
+      'default_language[langcode]' => 'authors_default',
+      'default_language[language_hidden]' => TRUE,
+    );
+    $new_machine_name = $edit['machine_name'];
+    $this->drupalPost('admin/structure/taxonomy/' . $machine_name . '/edit', $edit, t('Save'));
+
+    // Check that the old settings are empty.
+    $old_settings = config('language.settings')->get(language_get_default_configuration_settings_path('vocabulary', $machine_name));
+    $this->assertNull($old_settings, 'The old vocabulary settings were deleted.');
+    // Check that we have the new settings.
+    $new_settings = language_get_default_configuration('vocabulary', $new_machine_name);
+    $this->assertEqual($new_settings['langcode'], 'authors_default');
+    $this->assertEqual($new_settings['language_hidden'], TRUE);
+  }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
index bdeea4c..450cd55 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
@@ -44,12 +44,31 @@ public function form(array $form, array &$form_state, EntityInterface $vocabular
       '#title' => t('Description'),
       '#default_value' => $vocabulary->description,
     );
+
+    // $form['langcode'] is not wrapped in an if (module_exists('language'))
+    // check because the language_select form element works also without the
+    // language module being installed.
+    // http://drupal.org/node/1749954 documents the new element.
     $form['langcode'] = array(
       '#type' => 'language_select',
-      '#title' => t('Language'),
+      '#title' => t('Vocabulary language'),
       '#languages' => LANGUAGE_ALL,
       '#default_value' => $vocabulary->langcode,
     );
+    if (module_exists('language')) {
+      $form['default_terms_language'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Terms language'),
+      );
+      $form['default_terms_language']['default_language'] = array(
+        '#type' => 'language_configuration',
+        '#entity_information' => array(
+          'entity_type' => 'vocabulary',
+          'bundle' => $vocabulary->machine_name,
+        ),
+        '#default_value' => language_get_default_configuration('vocabulary', $vocabulary->machine_name),
+      );
+    }
     // Set the hierarchy to "multiple parents" by default. This simplifies the
     // vocabulary form and standardizes the term form.
     $form['hierarchy'] = array(
@@ -72,6 +91,12 @@ protected function actions(array $form, array &$form_state) {
     if (empty($form_state['confirm_delete'])) {
       $actions = parent::actions($form, $form_state);
       array_unshift($actions['delete']['#submit'], array($this, 'submit'));
+      // Add the language configuration submit handler. This is needed because
+      // the submit button has custom submit handlers.
+      if (module_exists('language')) {
+        array_unshift($actions['submit']['#submit'],'language_configuration_element_submit');
+        array_unshift($actions['submit']['#submit'], array($this, 'languageConfigurationSubmit'));
+      }
       return $actions;
     }
     else {
@@ -100,6 +125,22 @@ public function validate(array $form, array &$form_state) {
   }
 
   /**
+   * Submit handler to update the bundle for the default language configuration.
+   */
+  public function languageConfigurationSubmit(array &$form, array &$form_state) {
+    $vocabulary = $this->getEntity($form_state);
+    // Delete the old language settings for the vocabulary, if the machine name
+    // is changed.
+    if ($vocabulary && isset($vocabulary->machine_name) && $vocabulary->machine_name != $form_state['values']['machine_name']) {
+      language_clear_default_configuration('vocabulary', $vocabulary->machine_name);
+    }
+    // Since the machine name is not known yet, and it can be changed anytime,
+    // we have to also update the bundle property for the default language
+    // configuration in order to have the correct bundle value.
+    $form_state['language']['default_language']['bundle'] = $form_state['values']['machine_name'];
+  }
+
+  /**
    * Overrides Drupal\Core\Entity\EntityFormController::submit().
    */
   public function submit(array $form, array &$form_state) {
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index be305f6..273b35c 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -120,7 +120,6 @@ function taxonomy_vocabulary_add() {
   $vocabulary = entity_create('taxonomy_vocabulary', array(
     // Default the new vocabulary to the site's default language. This is the
     // most likely default value until we have better flexible settings.
-    // @todo See http://drupal.org/node/258785 and followups.
     'langcode' => language_default()->langcode,
   ));
   return entity_get_form($vocabulary);
@@ -534,6 +533,9 @@ function theme_taxonomy_overview_terms($variables) {
  */
 function taxonomy_term_add($vocabulary) {
   $term = entity_create('taxonomy_term', array('vid' => $vocabulary->vid, 'vocabulary_machine_name' => $vocabulary->machine_name));
+  if (module_exists('language')) {
+    $term->langcode = language_get_default_langcode('vocabulary', $vocabulary->machine_name);
+  }
   return entity_get_form($term);
 }
 
diff --git a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
index a9fae77..fccb453 100644
--- a/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
+++ b/core/modules/translation/lib/Drupal/translation/Tests/TranslationTest.php
@@ -51,7 +51,7 @@ function setUp() {
     // Set "Basic page" content type to use multilingual support with
     // translation.
     $this->drupalGet('admin/structure/types/manage/page');
-    $edit = array('node_type_language_hidden' => FALSE, 'node_type_language_translation_enabled' => TRUE);
+    $edit = array('language_configuration[language_hidden]' => FALSE, 'node_type_language_translation_enabled' => TRUE);
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
 
@@ -230,7 +230,7 @@ function testLanguageSwitcherBlockIntegration() {
     // Disable translation support to check that the language switcher is left
     // untouched only for new nodes.
     $this->drupalLogin($this->admin_user);
-    $edit = array('node_type_language_hidden' => TRUE, 'node_type_language_translation_enabled' => FALSE);
+    $edit = array('language_configuration[language_hidden]' => TRUE, 'node_type_language_translation_enabled' => FALSE);
     $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
     $this->drupalLogin($this->translator);
 
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index bf1e528..e7f22fd 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -173,7 +173,7 @@ function translation_form_node_type_form_alter(&$form, &$form_state) {
  * and language selector is not hidden, translation cannot be enabled.
  */
 function translation_node_type_language_translation_enabled_validate($element, &$form_state, $form) {
-  if (language_is_locked($form_state['values']['node_type_language_default']) && $form_state['values']['node_type_language_hidden'] && $form_state['values']['node_type_language_translation_enabled']) {
+  if (language_is_locked($form_state['values']['language_configuration']['langcode']) && $form_state['values']['language_configuration']['language_hidden'] && $form_state['values']['node_type_language_translation_enabled']) {
     foreach (language_list(LANGUAGE_LOCKED) as $language) {
       $locked_languages[] = $language->name;
     }
