diff --git a/core/modules/field/modules/text/text.test b/core/modules/field/modules/text/text.test
index 979079a..2d936be 100644
--- a/core/modules/field/modules/text/text.test
+++ b/core/modules/field/modules/text/text.test
@@ -454,8 +454,8 @@ class TextTranslationTestCase extends DrupalWebTestCase {
     $langcode = LANGUAGE_NONE;
     $body = $this->randomName();
     $edit = array(
-      "title" => $this->randomName(),
-      "language" => 'en',
+      'title' => $this->randomName(),
+      'langcode' => 'en',
       "body[$langcode][0][value]" => $body,
     );
 
@@ -487,7 +487,7 @@ class TextTranslationTestCase extends DrupalWebTestCase {
     $title = $this->randomName();
     $edit = array(
       'title' => $title,
-      'language' => 'en',
+      'langcode' => 'en',
     );
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index d50684e..42d3f7d 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -292,13 +292,13 @@ function locale_field_node_form_submit($form, &$form_state) {
     foreach (field_info_instances('node', $bundle) as $instance) {
       $field_name = $instance['field_name'];
       $field = field_info_field($field_name);
-      $previous_language = $form[$field_name]['#language'];
+      $previous_langcode = $form[$field_name]['#language'];
 
       // Handle a possible language change: new language values are inserted,
       // previous ones are deleted.
-      if ($field['translatable'] && $previous_language != $node->language) {
-        $form_state['values'][$field_name][$node->language] = $node->{$field_name}[$previous_language];
-        $form_state['values'][$field_name][$previous_language] = array();
+      if ($field['translatable'] && $previous_langcode != $node->langcode) {
+        $form_state['values'][$field_name][$node->langcode] = $node->{$field_name}[$previous_langcode];
+        $form_state['values'][$field_name][$previous_langcode] = array();
       }
     }
   }
@@ -1084,15 +1084,15 @@ function locale_form_system_file_system_settings_alter(&$form, $form_state) {
  * Implements MODULE_preprocess_HOOK().
  */
 function locale_preprocess_node(&$variables) {
-  if ($variables['language'] != LANGUAGE_NONE) {
+  if ($variables['langcode'] != LANGUAGE_NONE) {
     global $language;
 
-    $node_language = language_load($variables['language']);
+    $node_language = language_load($variables['langcode']);
     if ($node_language->langcode != $language->langcode) {
       // If the node language was different from the page language, we should
       // add markup to identify the language. Otherwise the page language is
       // inherited.
-      $variables['attributes_array']['lang'] = $variables['language'];
+      $variables['attributes_array']['lang'] = $variables['langcode'];
       if ($node_language->direction != $language->direction) {
         // If text direction is different form the page's text direction, add
         // direction information as well.
diff --git a/core/modules/locale/locale.test b/core/modules/locale/locale.test
index 42a0fbd..6d081a3 100644
--- a/core/modules/locale/locale.test
+++ b/core/modules/locale/locale.test
@@ -1957,7 +1957,7 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
     // Verify language selection appears on add "Basic page" form.
     $this->drupalGet('node/add/page');
     // Verify language select list is present.
-    $this->assertFieldByName('language', NULL, t('Language select present on add Basic page form.'));
+    $this->assertFieldByName('langcode', NULL, t('Language select present on add Basic page form.'));
     // Ensure enabled language appears.
     $this->assertText($name, t('Enabled language present.'));
     // Ensure disabled language doesn't appear.
@@ -1970,7 +1970,7 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
       'type' => 'page',
       'title' => $node_title,
       'body' => array($langcode => array(array('value' => $node_body))),
-      'language' => $langcode,
+      'langcode' => $langcode,
     );
     $node = $this->drupalCreateNode($edit);
     // Edit the content and ensure correct language is selected.
@@ -1979,7 +1979,7 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
     $this->assertRaw('<option value="' . $langcode . '" selected="selected">' .  $name . '</option>', t('Correct language selected.'));
     // Ensure we can change the node language.
     $edit = array(
-      'language' => 'en',
+      'langcode' => 'en',
     );
     $this->drupalPost($path, $edit, t('Save'));
     $this->assertRaw(t('%title has been updated.', array('%title' => $node_title)), t('Basic page content updated.'));
@@ -2062,7 +2062,7 @@ class LocaleContentFunctionalTest extends DrupalWebTestCase {
       'type' => 'article',
       'title' => $node_title,
       'body' => array($langcode => array(array('value' => $node_body))),
-      'language' => $langcode,
+      'langcode' => $langcode,
       'promote' => 1,
     );
     return $this->drupalCreateNode($edit);
@@ -2530,7 +2530,7 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase {
     $edit = array();
     $edit[$title_key] = $title_value;
     $edit[$body_key] = $body_value;
-    $edit['language'] = 'en';
+    $edit['langcode'] = 'en';
     $this->drupalPost('node/add/page', $edit, t('Save'));
 
     // Check that the node exists in the database.
@@ -2544,7 +2544,7 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase {
     $this->drupalGet("node/$node->nid/edit");
     $edit = array(
       $title_key => $this->randomName(8),
-      'language' => 'it'
+      'langcode' => 'it'
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($edit[$title_key]);
@@ -2579,7 +2579,7 @@ class LocaleMultilingualFieldsFunctionalTest extends DrupalWebTestCase {
     $edit = array();
     $edit[$title_key] = $title_value;
     $edit[$body_key] = $body_value;
-    $edit['language'] = 'en';
+    $edit['langcode'] = 'en';
     $this->drupalPost('node/add/page', $edit, t('Save'));
 
     // Check that the node exists in the database.
@@ -2661,7 +2661,7 @@ class LocaleCommentLanguageFunctionalTest extends DrupalWebTestCase {
       $edit = array(
         "title" => $title,
         "body[$langcode_none][0][value]" => $this->randomName(),
-        "language" => $node_langcode,
+        "langcode" => $node_langcode,
       );
       $this->drupalPost("node/add/article", $edit, t('Save'));
       $node = $this->drupalGetNodeByTitle($title);
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index e197f60..9578417 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -435,7 +435,7 @@ function node_admin_nodes() {
 
   // Enable language column if translation module is enabled or if we have any
   // node with language.
-  $multilanguage = (module_exists('translation') || db_query_range("SELECT 1 FROM {node} WHERE language <> :language", 0, 1, array(':language' => LANGUAGE_NONE))->fetchField());
+  $multilanguage = (module_exists('translation') || db_query_range("SELECT 1 FROM {node} WHERE langcode <> :langcode", 0, 1, array(':langcode' => LANGUAGE_NONE))->fetchField());
 
   // Build the sortable table header.
   $header = array(
@@ -446,7 +446,7 @@ function node_admin_nodes() {
     'changed' => array('data' => t('Updated'), 'field' => 'n.changed', 'sort' => 'desc')
   );
   if ($multilanguage) {
-    $header['language_name'] = array('data' => t('Language'), 'field' => 'n.language');
+    $header['language_name'] = array('data' => t('Language'), 'field' => 'n.langcode');
   }
   $header['operations'] = array('data' => t('Operations'));
 
@@ -481,7 +481,7 @@ function node_admin_nodes() {
   $destination = drupal_get_destination();
   $options = array();
   foreach ($nodes as $node) {
-    $l_options = $node->language != LANGUAGE_NONE && isset($languages[$node->language]) ? array('language' => $languages[$node->language]) : array();
+    $l_options = $node->langcode != LANGUAGE_NONE && isset($languages[$node->langcode]) ? array('language' => $languages[$node->langcode]) : array();
     $options[$node->nid] = array(
       'title' => array(
         'data' => array(
@@ -498,7 +498,7 @@ function node_admin_nodes() {
       'changed' => format_date($node->changed, 'short'),
     );
     if ($multilanguage) {
-      $options[$node->nid]['language_name'] = language_name($node->language);
+      $options[$node->nid]['language_name'] = language_name($node->langcode);
     }
     // Build a list of all the accessible operations for the current node.
     $operations = array();
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index b9a5ead..efcce1a 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -32,7 +32,7 @@ function node_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
-      'language' => array(
+      'langcode' => array(
         'description' => 'The {language}.langcode of this node.',
         'type' => 'varchar',
         'length' => 12,
@@ -542,6 +542,20 @@ function node_update_8001() {
 }
 
 /**
+ * Rename node.language field to node.langcode.
+ */
+function node_update_8002() {
+  $spec = array(
+    'description' => 'The {language}.langcode of this node.',
+    'type' => 'varchar',
+    'length' => 12,
+    'not null' => TRUE,
+    'default' => '',
+  );
+  db_change_field('node', 'language', 'langcode', $spec);
+}
+
+/**
  * @} 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 93f0ddc..ab9d518 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1340,7 +1340,7 @@ function node_view($node, $view_mode = 'full', $langcode = NULL) {
     '#theme' => 'node',
     '#node' => $node,
     '#view_mode' => $view_mode,
-    '#language' => $langcode,
+    '#langcode' => $langcode,
   );
 
   // Add contextual links for this node, except when the node is already being
@@ -1724,7 +1724,7 @@ function node_search_execute($keys = NULL, $conditions = NULL) {
 
   // Insert special keywords.
   $query->setOption('type', 'n.type');
-  $query->setOption('language', 'n.language');
+  $query->setOption('langcode', 'n.langcode');
   if ($query->setOption('term', 'ti.tid')) {
     $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
   }
@@ -1764,7 +1764,7 @@ function node_search_execute($keys = NULL, $conditions = NULL) {
       'extra' => $extra,
       'score' => $item->calculated_score,
       'snippet' => search_excerpt($keys, $node->rendered),
-      'language' => $node->language,
+      'langcode' => $node->langcode,
     );
   }
   return $results;
@@ -2848,10 +2848,8 @@ function node_form_search_form_alter(&$form, $form_state) {
 
     // Languages:
     $language_options = array();
-    foreach (language_list() as $key => $entity) {
-      if ($entity->enabled) {
-        $language_options[$key] = $entity->name;
-      }
+    foreach (language_list(TRUE) as $langcode => $language) {
+      $language_options[$langcode] = $language->name;
     }
     if (count($language_options) > 1) {
       $form['advanced']['language'] = array(
@@ -4204,9 +4202,9 @@ function node_file_download_access($field, $entity_type, $entity) {
  * Implements hook_language_delete().
  */
 function node_language_delete($language) {
-  // On nodes with this language, unset the language
+  // On nodes with this language, unset the language.
   db_update('node')
-    ->fields(array('language' => ''))
-    ->condition('language', $language->langcode)
+    ->fields(array('langcode' => ''))
+    ->condition('langcode', $language->langcode)
     ->execute();
 }
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index ab8b5f1..95e2e7d 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -87,7 +87,7 @@ function node_add($type) {
   global $user;
 
   $types = node_type_get_types();
-  $node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => LANGUAGE_NONE);
+  $node = (object) array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'langcode' => LANGUAGE_NONE);
   drupal_set_title(t('Create @name', array('@name' => $types[$type]->name)), PASS_THROUGH);
   $output = drupal_get_form($type . '_node_form', $node);
 
@@ -153,7 +153,7 @@ function node_form($form, &$form_state, $node) {
 
   // Basic node information.
   // These elements are just values so they are not even sent to the client.
-  foreach (array('nid', 'vid', 'uid', 'created', 'type', 'language') as $key) {
+  foreach (array('nid', 'vid', 'uid', 'created', 'type') as $key) {
     $form[$key] = array(
       '#type' => 'value',
       '#value' => isset($node->$key) ? $node->$key : NULL,
@@ -187,20 +187,20 @@ function node_form($form, &$form_state, $node) {
     foreach ($languages as $langcode => $language) {
       $language_options[$langcode] = $language->name;
     }
-    $form['language'] = array(
+    $form['langcode'] = array(
       '#type' => 'select',
       '#title' => t('Language'),
-      '#default_value' => (isset($node->language) ? $node->language : ''),
+      '#default_value' => (isset($node->langcode) ? $node->langcode : ''),
       '#options' => $language_options,
       '#empty_value' => LANGUAGE_NONE,
     );
   }
   else {
-    $form['language'] = array(
+    $form['langcode'] = array(
       '#type' => 'value',
       // New nodes without multilingual support get the default language, old
       // nodes keep their language if language.module is not available.
-      '#value' => !isset($form['#node']->nid) ? language_default()->langcode : $node->language,
+      '#value' => !isset($form['#node']->nid) ? language_default()->langcode : $node->langcode,
     );
   }
 
@@ -358,7 +358,7 @@ function node_form($form, &$form_state, $node) {
   }
   $form += array('#submit' => array());
 
-  field_attach_form('node', $node, $form, $form_state, $node->language);
+  field_attach_form('node', $node, $form, $form_state, $node->langcode);
   return $form;
 }
 
diff --git a/core/modules/node/node.test b/core/modules/node/node.test
index f828164..10c86e3 100644
--- a/core/modules/node/node.test
+++ b/core/modules/node/node.test
@@ -510,7 +510,7 @@ class NodeCreationTestCase extends DrupalWebTestCase {
       'uid'      => $this->loggedInUser->uid,
       'name'     => $this->loggedInUser->name,
       'type'     => 'page',
-      'language' => LANGUAGE_NONE,
+      'langcode' => LANGUAGE_NONE,
       'title'    => 'testing_transaction_exception',
     );
 
@@ -2190,7 +2190,7 @@ class NodeEntityFieldQueryAlter extends DrupalWebTestCase {
     // Creating 4 nodes with an entity field so we can test that sort of query
     // alter. All field values starts with 'A' so we can identify and fetch them
     // in the node_access_test module.
-    $settings = array('language' => LANGUAGE_NONE);
+    $settings = array('langcode' => LANGUAGE_NONE);
     for ($i = 0; $i < 4; $i++) {
       $body = array(
         'value' => 'A' . $this->randomName(32),
@@ -2268,9 +2268,9 @@ class NodeTokenReplaceTestCase extends DrupalWebTestCase {
     $tests['[node:type]'] = 'article';
     $tests['[node:type-name]'] = 'Article';
     $tests['[node:title]'] = check_plain($node->title);
-    $tests['[node:body]'] = _text_sanitize($instance, $node->language, $node->body[$node->language][0], 'value');
-    $tests['[node:summary]'] = _text_sanitize($instance, $node->language, $node->body[$node->language][0], 'summary');
-    $tests['[node:language]'] = check_plain($node->language);
+    $tests['[node:body]'] = _text_sanitize($instance, $node->langcode, $node->body[$node->langcode][0], 'value');
+    $tests['[node:summary]'] = _text_sanitize($instance, $node->langcode, $node->body[$node->langcode][0], 'summary');
+    $tests['[node:langcode]'] = check_plain($node->langcode);
     $tests['[node:url]'] = url('node/' . $node->nid, $url_options);
     $tests['[node:edit-url]'] = url('node/' . $node->nid . '/edit', $url_options);
     $tests['[node:author]'] = check_plain(user_format_name($account));
@@ -2289,9 +2289,9 @@ class NodeTokenReplaceTestCase extends DrupalWebTestCase {
 
     // Generate and test unsanitized tokens.
     $tests['[node:title]'] = $node->title;
-    $tests['[node:body]'] = $node->body[$node->language][0]['value'];
-    $tests['[node:summary]'] = $node->body[$node->language][0]['summary'];
-    $tests['[node:language]'] = $node->language;
+    $tests['[node:body]'] = $node->body[$node->langcode][0]['value'];
+    $tests['[node:summary]'] = $node->body[$node->langcode][0]['summary'];
+    $tests['[node:langcode]'] = $node->langcode;
     $tests['[node:author:name]'] = user_format_name($account);
 
     foreach ($tests as $input => $expected) {
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index abe864a..1b37fc8 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -50,9 +50,9 @@ function node_token_info() {
     'name' => t("Summary"),
     'description' => t("The summary of the node's main body text."),
   );
-  $node['language'] = array(
-    'name' => t("Language"),
-    'description' => t("The language the node is written in."),
+  $node['langcode'] = array(
+    'name' => t('Language code'),
+    'description' => t('The language code of the language the node is written in.'),
   );
   $node['url'] = array(
     'name' => t("URL"),
@@ -143,8 +143,8 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
           }
           break;
 
-        case 'language':
-          $replacements[$original] = $sanitize ? check_plain($node->language) : $node->language;
+        case 'langcode':
+          $replacements[$original] = $sanitize ? check_plain($node->langcode) : $node->langcode;
           break;
 
         case 'url':
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 9d7b2b1..8127a91 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -97,8 +97,8 @@ function path_form_node_form_alter(&$form, $form_state) {
   $path = array();
   if (!empty($form['#node']->nid)) {
     $conditions = array('source' => 'node/' . $form['#node']->nid);
-    if ($form['#node']->language != LANGUAGE_NONE) {
-      $conditions['langcode'] = $form['#node']->language;
+    if ($form['#node']->langcode != LANGUAGE_NONE) {
+      $conditions['langcode'] = $form['#node']->langcode;
     }
     $path = path_load($conditions);
     if ($path === FALSE) {
@@ -109,7 +109,7 @@ function path_form_node_form_alter(&$form, $form_state) {
     'pid' => NULL,
     'source' => isset($form['#node']->nid) ? 'node/' . $form['#node']->nid : NULL,
     'alias' => '',
-    'langcode' => isset($form['#node']->language) ? $form['#node']->language : LANGUAGE_NONE,
+    'langcode' => isset($form['#node']->langcode) ? $form['#node']->langcode : LANGUAGE_NONE,
   );
 
   $form['path'] = array(
@@ -157,8 +157,8 @@ function path_form_element_validate($element, &$form_state, $complete_form) {
     // originally assigned URL alias language.
     // @todo Remove this after converting Path module to a field, and, after
     //   stopping Locale module from abusing the content language system.
-    if (isset($form_state['values']['language'])) {
-      form_set_value($element['langcode'], $form_state['values']['language'], $form_state);
+    if (isset($form_state['values']['langcode'])) {
+      form_set_value($element['langcode'], $form_state['values']['langcode'], $form_state);
     }
 
     $path = $form_state['values']['path'];
@@ -189,7 +189,7 @@ function path_node_insert($node) {
     if (!empty($path['alias'])) {
       // Ensure fields for programmatic executions.
       $path['source'] = 'node/' . $node->nid;
-      $path['langcode'] = isset($node->language) ? $node->language : LANGUAGE_NONE;
+      $path['langcode'] = isset($node->langcode) ? $node->langcode : LANGUAGE_NONE;
       path_save($path);
     }
   }
@@ -210,7 +210,7 @@ function path_node_update($node) {
     if (!empty($path['alias'])) {
       // Ensure fields for programmatic executions.
       $path['source'] = 'node/' . $node->nid;
-      $path['langcode'] = isset($node->language) ? $node->language : LANGUAGE_NONE;
+      $path['langcode'] = isset($node->langcode) ? $node->langcode : LANGUAGE_NONE;
       path_save($path);
     }
   }
diff --git a/core/modules/path/path.test b/core/modules/path/path.test
index ba86b79..5a2532a 100644
--- a/core/modules/path/path.test
+++ b/core/modules/path/path.test
@@ -267,7 +267,7 @@ class PathLanguageTestCase extends DrupalWebTestCase {
 
     // Edit the node to set language and path.
     $edit = array();
-    $edit['language'] = 'en';
+    $edit['langcode'] = 'en';
     $edit['path[alias]'] = $english_alias;
     $this->drupalPost('node/' . $english_node->nid . '/edit', $edit, t('Save'));
 
@@ -303,7 +303,7 @@ class PathLanguageTestCase extends DrupalWebTestCase {
     drupal_static_reset('locale_url_outbound_alter');
     drupal_static_reset('locale_language_url_rewrite_url');
     $languages = language_list();
-    $url = url('node/' . $french_node->nid, array('language' => $languages[$french_node->language]));
+    $url = url('node/' . $french_node->nid, array('language' => $languages[$french_node->langcode]));
     $this->assertTrue(strpos($url, $edit['path[alias]']), t('URL contains the path alias.'));
 
     // Confirm that the alias works even when changing language negotiation
@@ -353,17 +353,17 @@ class PathLanguageTestCase extends DrupalWebTestCase {
     // drupal_lookup_path() has an internal static cache. Check to see that
     // it has the appropriate contents at this point.
     drupal_lookup_path('wipe');
-    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
+    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->langcode);
     $this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path works.'));
     // Second call should return the same path.
-    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->language);
+    $french_node_path = drupal_lookup_path('source', $french_alias, $french_node->langcode);
     $this->assertEqual($french_node_path, 'node/' . $french_node->nid, t('Normal path is the same.'));
 
     // Confirm that the alias works.
-    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
+    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->langcode);
     $this->assertEqual($french_node_alias, $french_alias, t('Alias works.'));
     // Second call should return the same alias.
-    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->language);
+    $french_node_alias = drupal_lookup_path('alias', 'node/' . $french_node->nid, $french_node->langcode);
     $this->assertEqual($french_node_alias, $french_alias, t('Alias is the same.'));
   }
 }
diff --git a/core/modules/poll/poll.test b/core/modules/poll/poll.test
index 0c406f0..af21636 100644
--- a/core/modules/poll/poll.test
+++ b/core/modules/poll/poll.test
@@ -853,7 +853,7 @@ class PollTranslateTestCase extends PollTestCase {
     // Set the poll's first choice count to 200.
     $edit['choice[chid:1][chvotes]'] = 200;
     // Set the language to Dutch.
-    $edit['language'] = 'nl';
+    $edit['langcode'] = 'nl';
     $this->drupalPost(NULL, $edit, t('Save'));
 
     // Translate the Dutch poll.
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index c9fc562..c835d59 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -932,7 +932,7 @@ class DrupalWebTestCase extends DrupalTestCase {
       'sticky'    => 0,
       'type'      => 'page',
       'revisions' => NULL,
-      'language'  => LANGUAGE_NONE,
+      'langcode'  => LANGUAGE_NONE,
     );
 
     // Use the original node's created time for existing nodes.
@@ -957,7 +957,7 @@ class DrupalWebTestCase extends DrupalTestCase {
       'value' => $this->randomName(32),
       'format' => filter_default_format(),
     );
-    $settings['body'][$settings['language']][0] += $body;
+    $settings['body'][$settings['langcode']][0] += $body;
 
     $node = (object) $settings;
     node_save($node);
diff --git a/core/modules/simpletest/tests/form_test.module b/core/modules/simpletest/tests/form_test.module
index e1e2435..a2f1290 100644
--- a/core/modules/simpletest/tests/form_test.module
+++ b/core/modules/simpletest/tests/form_test.module
@@ -1617,7 +1617,7 @@ function form_test_two_instances() {
     'uid' => $user->uid,
     'name' => (isset($user->name) ? $user->name : ''),
     'type' => 'page',
-    'language' => LANGUAGE_NONE,
+    'langcode' => LANGUAGE_NONE,
   );
   $node2 = clone($node1);
   $return['node_form_1'] = drupal_get_form('page_node_form', $node1);
diff --git a/core/modules/simpletest/tests/upgrade/drupal-7.language.database.php b/core/modules/simpletest/tests/upgrade/drupal-7.language.database.php
index 67d51e2..84d02f8 100644
--- a/core/modules/simpletest/tests/upgrade/drupal-7.language.database.php
+++ b/core/modules/simpletest/tests/upgrade/drupal-7.language.database.php
@@ -512,11 +512,11 @@ db_insert('variable')->fields(array(
 ))
 ->values(array(
   'name' => 'language_content_type_article',
-  'value' => 's:1:"1";',
+  'value' => 's:1:"2";',
 ))
 ->execute();
 
-// Enable the locale module.
+// Enable Locale and Translation module.
 db_update('system')->fields(array(
   'status' => 1,
   'schema_version' => '7001',
@@ -524,3 +524,159 @@ db_update('system')->fields(array(
 ->condition('type', 'module')
 ->condition('name', 'locale')
 ->execute();
+db_update('system')->fields(array(
+  'status' => 1,
+  'schema_version' => '7001',
+))
+->condition('type', 'module')
+->condition('name', 'translation')
+->execute();
+
+// Add nodes for testing.
+db_insert('node')->fields(array(
+  'nid',
+  'vid',
+  'type',
+  'language',
+  'title',
+  'uid',
+  'status',
+  'created',
+  'changed',
+  'comment',
+  'promote',
+  'sticky',
+  'tnid',
+  'translate',
+))
+// Add a sample node with LANGUAGE_NONE as language.
+->values(array(
+  'nid' => '38',
+  'vid' => '50',
+  'type' => 'article',
+  'language' => 'und',
+  'title' => 'Node title 38',
+  'uid' => '6',
+  'status' => '1',
+  'created' => '1263769200',
+  'changed' => '1263769200',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+  'tnid' => '0',
+  'translate' => '0',
+))
+// Add a sample node with 'ca' as language code.
+->values(array(
+  'nid' => '39',
+  'vid' => '55',
+  'type' => 'article',
+  'language' => 'ca',
+  'title' => 'Node title 39',
+  'uid' => '6',
+  'status' => '1',
+  'created' => '1263769300',
+  'changed' => '1263769300',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+  'tnid' => '0',
+  'translate' => '0',
+))
+// Add a translation set, consisting of a 'en' node and an 'cv' node.
+->values(array(
+  'nid' => '40',
+  'vid' => '60',
+  'type' => 'article',
+  'language' => 'en',
+  'title' => 'Node title 40',
+  'uid' => '6',
+  'status' => '1',
+  'created' => '1263769534',
+  'changed' => '1263769534',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+  'tnid' => '40',
+  'translate' => '0',
+))
+->values(array(
+  'nid' => '41',
+  'vid' => '65',
+  'type' => 'article',
+  'language' => 'cv',
+  'title' => 'Node title 41',
+  'uid' => '6',
+  'status' => '1',
+  'created' => '1263770064',
+  'changed' => '1263770064',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+  'tnid' => '40',
+  'translate' => '0',
+))
+->execute();
+
+// Add node revision information.
+db_insert('node_revision')->fields(array(
+  'nid',
+  'vid',
+  'uid',
+  'title',
+  'log',
+  'timestamp',
+  'status',
+  'comment',
+  'promote',
+  'sticky',
+))
+->values(array(
+  'nid' => '38',
+  'vid' => '50',
+  'uid' => '6',
+  'title' => 'Node title 38',
+  'log' => 'Created a LANGUAGE_NONE node.',
+  'timestamp' => '1263769200',
+  'status' => '1',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '39',
+  'vid' => '55',
+  'uid' => '6',
+  'title' => 'Node title 39',
+  'log' => 'Created a Catalan node.',
+  'timestamp' => '1263769300',
+  'status' => '1',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '40',
+  'vid' => '60',
+  'uid' => '6',
+  'title' => 'Node title 40',
+  'log' => 'Created source translation in English.',
+  'timestamp' => '1263769534',
+  'status' => '1',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->values(array(
+  'nid' => '41',
+  'vid' => '65',
+  'uid' => '6',
+  'title' => 'Node title 41',
+  'log' => 'Created Chuvash translation.',
+  'timestamp' => '1263770064',
+  'status' => '1',
+  'comment' => '0',
+  'promote' => '0',
+  'sticky' => '0',
+))
+->execute();
diff --git a/core/modules/simpletest/tests/upgrade/upgrade.language.test b/core/modules/simpletest/tests/upgrade/upgrade.language.test
index ee77fa7..bc73530 100644
--- a/core/modules/simpletest/tests/upgrade/upgrade.language.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade.language.test
@@ -41,10 +41,26 @@ class LanguageUpgradePathTestCase extends UpgradePathTestCase {
       $this->assertTrue($language->default == ($language->langcode == 'ca'), t('@language default property properly set', array('@language' => $language->name)));
     }
 
+    // Test that the 'language' property was properly renamed to 'langcode'.
+    $language_none_nid = 38;
+    $spanish_nid = 39;
+    $translation_source_nid = 40;
+    $translation_nid = 41;
+    // Check directly for the $node->langcode property.
+    $this->assertEqual(node_load($language_none_nid)->langcode, LANGUAGE_NONE, "'language' property was renamed to 'langcode' for LANGUAGE_NONE node.");
+    $this->assertEqual(node_load($spanish_nid)->langcode, 'ca', "'language' property was renamed to 'langcode' for Catalan node.");
+    // Check that the translation table works correctly.
+    $this->drupalGet("node/$translation_source_nid/translate");
+    $this->assertResponse(200, 'The translated node has a proper translation table.');
+    $this->assertRaw('<td><strong>English</strong> (source)</td>', 'English is the source node of the translation.');
+    $this->assertRaw('<td>Chuvash</td>', 'There is a Chuvash translation of the node.');
+    $this->assertLinkByHref("node/$translation_nid", 0, 'The translation table links to the Chuvash translation.');
+    $this->assertRaw('<td>Catalan</td><td>n/a</td><td>Not translated</td>', 'There is no Catalan translation of this node.');
+
     // Check for node content type settings upgrade.
     $this->drupalGet('node/add/article');
-    $this->assertFieldByName('language');
+    $this->assertFieldByName('langcode');
     $this->drupalGet('node/add/page');
-    $this->assertNoFieldByName('language');
+    $this->assertNoFieldByName('langcode');
   }
 }
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index 2b2a6ff..e1de320 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -77,7 +77,7 @@ function translation_menu() {
  * all languages).
  */
 function _translation_tab_access($node) {
-  if ($node->language != LANGUAGE_NONE && translation_supported_type($node->type) && node_access('view', $node)) {
+  if ($node->langcode != LANGUAGE_NONE && translation_supported_type($node->type) && node_access('view', $node)) {
     return user_access('translate content');
   }
   return FALSE;
@@ -147,26 +147,26 @@ function translation_form_node_form_alter(&$form, &$form_state) {
           $options[$group][$langcode] = $language->name;
         }
       }
-      $form['language']['#options'] = $options;
+      $form['langcode']['#options'] = $options;
     }
     if (!empty($node->translation_source)) {
       // We are creating a translation. Add values and lock language field.
       $form['translation_source'] = array('#type' => 'value', '#value' => $node->translation_source);
-      $form['language']['#disabled'] = TRUE;
+      $form['langcode']['#disabled'] = TRUE;
     }
     elseif (!empty($node->nid) && !empty($node->tnid)) {
       // Disable languages for existing translations, so it is not possible to switch this
       // node to some language which is already in the translation set. Also remove the
       // language neutral option.
-      unset($form['language']['#options'][LANGUAGE_NONE]);
+      unset($form['langcode']['#options'][LANGUAGE_NONE]);
       foreach (translation_node_get_translations($node->tnid) as $langcode => $translation) {
         if ($translation->nid != $node->nid) {
           if ($translator_widget) {
             $group = $groups[(int)!isset($disabled_languages[$langcode])];
-            unset($form['language']['#options'][$group][$langcode]);
+            unset($form['langcode']['#options'][$group][$langcode]);
           }
           else {
-            unset($form['language']['#options'][$langcode]);
+            unset($form['langcode']['#options'][$langcode]);
           }
         }
       }
@@ -229,7 +229,7 @@ function translation_node_view($node, $view_mode) {
     foreach ($translations as $langcode => $translation) {
       // Do not show links to the same node, to unpublished translations or to
       // translations in disabled languages.
-      if ($translation->status && isset($languages[$langcode]) && $langcode != $node->language) {
+      if ($translation->status && isset($languages[$langcode]) && $langcode != $node->langcode) {
         $language = $languages[$langcode];
         $key = "translation_$langcode";
 
@@ -288,7 +288,7 @@ function translation_node_prepare($node) {
 
     $language_list = language_list();
     $langcode = $_GET['target'];
-    if (!isset($language_list[$langcode]) || ($source_node->language == $langcode)) {
+    if (!isset($language_list[$langcode]) || ($source_node->langcode == $langcode)) {
       // If not supported language, or same language as source node, break.
       return;
     }
@@ -303,13 +303,13 @@ function translation_node_prepare($node) {
     }
 
     // Populate fields based on source node.
-    $node->language = $langcode;
+    $node->langcode = $langcode;
     $node->translation_source = $source_node;
     $node->title = $source_node->title;
 
     // Add field translations and let other modules module add custom translated
     // fields.
-    field_attach_prepare_translation('node', $node, $node->language, $source_node, $source_node->language);
+    field_attach_prepare_translation('node', $node, $node->langcode, $source_node, $source_node->langcode);
   }
 }
 
@@ -354,7 +354,7 @@ function translation_node_insert($node) {
 function translation_node_update($node) {
   // Only act if we are dealing with a content type supporting translations.
   if (translation_supported_type($node->type)) {
-    if (isset($node->translation) && $node->translation && !empty($node->language) && $node->tnid) {
+    if (isset($node->translation) && $node->translation && !empty($node->langcode) && $node->tnid) {
       // Update translation information.
       db_update('node')
         ->fields(array(
@@ -385,8 +385,8 @@ function translation_node_validate($node, $form) {
   if (translation_supported_type($node->type) && (!empty($node->tnid) || !empty($form['#node']->translation_source->nid))) {
     $tnid = !empty($node->tnid) ? $node->tnid : $form['#node']->translation_source->nid;
     $translations = translation_node_get_translations($tnid);
-    if (isset($translations[$node->language]) && $translations[$node->language]->nid != $node->nid ) {
-      form_set_error('language', t('There is already a translation in this language.'));
+    if (isset($translations[$node->langcode]) && $translations[$node->langcode]->nid != $node->nid ) {
+      form_set_error('langcode', t('There is already a translation in this language.'));
     }
   }
 }
@@ -443,7 +443,7 @@ function translation_remove_from_set($node) {
  *   The translation source nid of the translation set, the identifier
  *   of the node used to derive all translations in the set.
  * @return
- *   Array of partial node objects (nid, title, language) representing
+ *   Array of partial node objects (nid, title, langcode) representing
  *   all nodes in the translation set, in effect all translations
  *   of node $tnid, including node $tnid itself. Because these are
  *   partial nodes, you need to node_load() the full node, if you
@@ -456,13 +456,13 @@ function translation_node_get_translations($tnid) {
     if (!isset($translations[$tnid])) {
       $translations[$tnid] = array();
       $result = db_select('node', 'n')
-        ->fields('n', array('nid', 'type', 'uid', 'status', 'title', 'language'))
+        ->fields('n', array('nid', 'type', 'uid', 'status', 'title', 'langcode'))
         ->condition('n.tnid', $tnid)
         ->addTag('node_access')
         ->execute();
 
       foreach ($result as $node) {
-        $translations[$tnid][$node->language] = $node;
+        $translations[$tnid][$node->langcode] = $node;
       }
     }
     return $translations[$tnid];
@@ -516,10 +516,10 @@ function translation_language_switch_links_alter(array &$links, $type, $path) {
       // have translations it might be a language neutral node, in which case we
       // must leave the language switch links unaltered. This is true also for
       // nodes not having translation support enabled.
-      if (empty($node) || $node->language == LANGUAGE_NONE || !translation_supported_type($node->type)) {
+      if (empty($node) || $node->langcode == LANGUAGE_NONE || !translation_supported_type($node->type)) {
         return;
       }
-      $translations = array($node->language => $node);
+      $translations = array($node->langcode => $node);
     }
     else {
       $translations = translation_node_get_translations($node->tnid);
diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc
index 8c09850..fd69d34 100644
--- a/core/modules/translation/translation.pages.inc
+++ b/core/modules/translation/translation.pages.inc
@@ -22,7 +22,7 @@ function translation_node_overview($node) {
   else {
     // We have no translation source nid, this could be a new set, emulate that.
     $tnid = $node->nid;
-    $translations = array($node->language => $node);
+    $translations = array($node->langcode => $node);
   }
 
   $type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE);
diff --git a/core/modules/translation/translation.test b/core/modules/translation/translation.test
index 64fede4..4a089bf 100644
--- a/core/modules/translation/translation.test
+++ b/core/modules/translation/translation.test
@@ -62,7 +62,6 @@ class TranslationTestCase extends DrupalWebTestCase {
     $node_title = $this->randomName();
     $node_body =  $this->randomName();
     $node = $this->createPage($node_title, $node_body, 'en');
-
     // Unpublish the original node to check that this has no impact on the
     // translation overview page, publish it again afterwards.
     $this->drupalLogin($this->admin_user);
@@ -126,14 +125,14 @@ class TranslationTestCase extends DrupalWebTestCase {
     // Confirm that disabled languages are an option for translators when
     // creating nodes.
     $this->drupalGet('node/add/page');
-    $this->assertFieldByXPath('//select[@name="language"]//option', 'it', t('Italian (disabled) is available in language selection.'));
+    $this->assertFieldByXPath('//select[@name="langcode"]//option', 'it', t('Italian (disabled) is available in language selection.'));
     $translation_it = $this->createTranslation($node, $this->randomName(), $this->randomName(), 'it');
     $this->assertRaw($translation_it->body[LANGUAGE_NONE][0]['value'], t('Content created in Italian (disabled).'));
 
     // Confirm that language neutral is an option for translators when there are
     // disabled languages.
     $this->drupalGet('node/add/page');
-    $this->assertFieldByXPath('//select[@name="language"]//option', LANGUAGE_NONE, t('Language neutral is available in language selection with disabled languages.'));
+    $this->assertFieldByXPath('//select[@name="langcode"]//option', LANGUAGE_NONE, t('Language neutral is available in language selection with disabled languages.'));
     $node2 = $this->createPage($this->randomName(), $this->randomName(), LANGUAGE_NONE);
     $this->assertRaw($node2->body[LANGUAGE_NONE][0]['value'], t('Language neutral content created with disabled languages available.'));
 
@@ -221,9 +220,9 @@ class TranslationTestCase extends DrupalWebTestCase {
     // Create a language neutral node and check that the language switcher is
     // left untouched.
     $node2 = $this->createPage($this->randomName(), $this->randomName(), LANGUAGE_NONE);
-    $node2_en = (object) array('nid' => $node2->nid, 'language' => 'en');
-    $node2_es = (object) array('nid' => $node2->nid, 'language' => 'es');
-    $node2_it = (object) array('nid' => $node2->nid, 'language' => 'it');
+    $node2_en = (object) array('nid' => $node2->nid, 'langcode' => 'en');
+    $node2_es = (object) array('nid' => $node2->nid, 'langcode' => 'es');
+    $node2_it = (object) array('nid' => $node2->nid, 'langcode' => 'it');
     $this->assertLanguageSwitchLinks($node2_en, $node2_en, TRUE, $type);
     $this->assertLanguageSwitchLinks($node2_en, $node2_es, TRUE, $type);
     $this->assertLanguageSwitchLinks($node2_en, $node2_it, TRUE, $type);
@@ -244,8 +243,8 @@ class TranslationTestCase extends DrupalWebTestCase {
     // Check that new nodes with a language assigned do not trigger language
     // switcher alterations when translation support is disabled.
     $node = $this->createPage($this->randomName(), $this->randomName());
-    $node_es = (object) array('nid' => $node->nid, 'language' => 'es');
-    $node_it = (object) array('nid' => $node->nid, 'language' => 'it');
+    $node_es = (object) array('nid' => $node->nid, 'langcode' => 'es');
+    $node_it = (object) array('nid' => $node->nid, 'langcode' => 'it');
     $this->assertLanguageSwitchLinks($node, $node, TRUE, $type);
     $this->assertLanguageSwitchLinks($node, $node_es, TRUE, $type);
     $this->assertLanguageSwitchLinks($node, $node_it, TRUE, $type);
@@ -264,7 +263,7 @@ class TranslationTestCase extends DrupalWebTestCase {
    * Return an empty node data structure.
    */
   function emptyNode($langcode) {
-    return (object) array('nid' => NULL, 'language' => $langcode);
+    return (object) array('nid' => NULL, 'langcode' => $langcode);
   }
 
   /**
@@ -312,16 +311,16 @@ class TranslationTestCase extends DrupalWebTestCase {
    *   Title of basic page in specified language.
    * @param $body
    *   Body of basic page in specified language.
-   * @param
-   *   $language Language code.
+   * @param $langcode
+   *   (optional) Language code.
    */
-  function createPage($title, $body, $language = NULL) {
+  function createPage($title, $body, $langcode = NULL) {
     $edit = array();
-    $langcode = LANGUAGE_NONE;
+    $field_langcode = LANGUAGE_NONE;
     $edit["title"] = $title;
-    $edit["body[$langcode][0][value]"] = $body;
-    if (!empty($language)) {
-      $edit['language'] = $language;
+    $edit["body[$field_langcode][0][value]"] = $body;
+    if (!empty($langcode)) {
+      $edit['langcode'] = $langcode;
     }
     $this->drupalPost('node/add/page', $edit, t('Save'));
     $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
@@ -343,14 +342,14 @@ class TranslationTestCase extends DrupalWebTestCase {
    *   Title of basic page in specified language.
    * @param $body
    *   Body of basic page in specified language.
-   * @param $language
+   * @param $langcode
    *   Language code.
    */
-  function createTranslation($node, $title, $body, $language) {
-    $this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $language)));
+  function createTranslation($node, $title, $body, $langcode) {
+    $this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'target' => $langcode)));
 
-    $langcode = LANGUAGE_NONE;
-    $body_key = "body[$langcode][0][value]";
+    $field_langcode = LANGUAGE_NONE;
+    $body_key = "body[$field_langcode][0][value]";
     $this->assertFieldByXPath('//input[@id="edit-title"]', $node->title, "Original title value correctly populated.");
     $this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[LANGUAGE_NONE][0]['value'], "Original body value correctly populated.");
 
@@ -417,8 +416,8 @@ class TranslationTestCase extends DrupalWebTestCase {
 
     $result = TRUE;
     $languages = language_list();
-    $page_language = $languages[$node->language];
-    $translation_language = $languages[$translation->language];
+    $page_language = $languages[$node->langcode];
+    $translation_language = $languages[$translation->langcode];
     $url = url("node/$translation->nid", array('language' => $translation_language));
 
     $this->drupalGet("node/$node->nid", array('language' => $page_language));
