From 53d8c24d94fe3e85a318862f39781df45b2d61c0 Mon Sep 17 00:00:00 2001
From: webchick <webchick@24967.no-reply.drupal.org>
Date: Fri, 26 Apr 2013 09:10:49 -0700
Subject: [PATCH] Issue #1818560 by Berdir, fago, Wim Leers, jessebeach,
 dawehner, YesCT: Convert taxonomy entities to the new Entity Field API.

---
 .../Entity/DatabaseStorageControllerNG.php    |  10 +-
 .../Tests/EntityReferenceItemTest.php         |   8 +-
 core/modules/forum/forum.admin.inc            |  88 ++++-----
 core/modules/forum/forum.module               |  41 ++---
 core/modules/forum/forum.pages.inc            |  10 +-
 .../lib/Drupal/forum/Tests/ForumTest.php      |   8 +-
 .../forum/templates/forum-list.tpl.php        |   4 +-
 core/modules/options/options.api.php          |   2 +-
 .../path/lib/Drupal/path/Type/PathItem.php    |  43 +++++
 core/modules/path/path.module                 |  62 +++++--
 .../rdf/Tests/TaxonomyAttributesTest.php      |   4 +-
 core/modules/rdf/rdf.module                   |   2 +-
 .../Tests/Entity/EntityCrudHookTest.php       |   4 +-
 .../Entity/EntityQueryRelationshipTest.php    |   8 +-
 .../system/Tests/Menu/BreadcrumbTest.php      |  10 +-
 .../Tests/Path/UrlAlterFunctionalTest.php     |  15 +-
 .../Tests/Theme/EntityFilteringThemeTest.php  |   4 +-
 core/modules/system/system.api.php            |   2 +-
 .../taxonomy_test/taxonomy_test.module        |  36 ++--
 .../taxonomy/Plugin/Core/Entity/Term.php      |  48 +++--
 .../selection/TermSelection.php               |   2 +-
 .../widget/TaxonomyAutocompleteWidget.php     |   2 +-
 .../Plugin/views/argument/IndexTidDepth.php   |   2 +-
 .../Plugin/views/argument/Taxonomy.php        |   2 +-
 .../Plugin/views/argument_validator/Term.php  |   6 +-
 .../Plugin/views/field/TaxonomyIndexTid.php   |   4 +-
 .../Drupal/taxonomy/TermFormController.php    |  51 +++---
 .../Drupal/taxonomy/TermRenderController.php  |   4 +-
 .../Drupal/taxonomy/TermStorageController.php |  80 +++++++--
 .../taxonomy/TermTranslationController.php    |   4 +-
 .../lib/Drupal/taxonomy/Tests/EfqTest.php     |   8 +-
 .../lib/Drupal/taxonomy/Tests/HooksTest.php   |  18 +-
 .../taxonomy/Tests/LoadMultipleTest.php       |  10 +-
 .../lib/Drupal/taxonomy/Tests/RssTest.php     |   8 +-
 .../Tests/TaxonomyTermReferenceItemTest.php   |  16 +-
 .../Tests/TermFieldMultipleVocabularyTest.php |  12 +-
 .../Drupal/taxonomy/Tests/TermFieldTest.php   |   6 +-
 .../Drupal/taxonomy/Tests/TermIndexTest.php   |  40 ++---
 .../taxonomy/Tests/TermLanguageTest.php       |   8 +-
 .../lib/Drupal/taxonomy/Tests/TermTest.php    | 170 +++++++++---------
 .../Drupal/taxonomy/Tests/TermUnitTest.php    |  10 +-
 .../lib/Drupal/taxonomy/Tests/ThemeTest.php   |   4 +-
 .../taxonomy/Tests/TokenReplaceTest.php       |  32 ++--
 .../Views/RelationshipNodeTermDataTest.php    |   2 +-
 .../Views/RelationshipRepresentativeNode.php  |   4 +-
 .../taxonomy/Tests/Views/TaxonomyTestBase.php |   4 +-
 .../Tests/VocabularyPermissionsTest.php       |   6 +-
 .../taxonomy/Tests/VocabularyUnitTest.php     |   4 +-
 core/modules/taxonomy/taxonomy.admin.inc      | 103 +++++------
 core/modules/taxonomy/taxonomy.api.php        |  10 +-
 core/modules/taxonomy/taxonomy.module         |  31 ++--
 core/modules/taxonomy/taxonomy.pages.inc      |  19 +-
 core/modules/taxonomy/taxonomy.tokens.inc     |  14 +-
 core/modules/taxonomy/taxonomy.views.inc      |   6 +-
 .../taxonomy/templates/taxonomy-term.tpl.php  |   2 +-
 .../Drupal/views/Tests/DefaultViewsTest.php   |   2 +-
 core/modules/views/views_ui/admin.inc         |   2 +-
 core/scripts/generate-d7-content.sh           |   6 +-
 58 files changed, 628 insertions(+), 495 deletions(-)
 create mode 100644 core/modules/path/lib/Drupal/path/Type/PathItem.php

diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
index 46efdc883328..1771f50e049b 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
@@ -96,9 +96,13 @@ public function __construct($entityType) {
    */
   public function create(array $values) {
     // We have to determine the bundle first.
-    // @todo Throw an exception if no bundle is passed and we have a bundle key
-    //   defined.
-    $bundle = $this->bundleKey ? $values[$this->bundleKey] : FALSE;
+    $bundle = FALSE;
+    if ($this->bundleKey) {
+      if (!isset($values[$this->bundleKey])) {
+        throw new EntityStorageException(t('Missing bundle for entity type @type', array('@type' => $this->entityType)));
+      }
+      $bundle = $values[$this->bundleKey];
+    }
     $entity = new $this->entityClass(array(), $this->entityType, $bundle);
 
     // Set all other given values.
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php
index cc089fb4b933..c8bed9ac5050 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceItemTest.php
@@ -74,7 +74,7 @@ public function testEntityReferenceItem() {
     $this->assertTrue($entity->field_test_taxonomy instanceof FieldInterface, 'Field implements interface.');
     $this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.');
     $this->assertEqual($entity->field_test_taxonomy->target_id, $tid);
-    $this->assertEqual($entity->field_test_taxonomy->entity->name, $this->term->name);
+    $this->assertEqual($entity->field_test_taxonomy->entity->name->value, $this->term->name->value);
     $this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid);
     $this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid());
 
@@ -84,18 +84,18 @@ public function testEntityReferenceItem() {
     $entity->field_test_taxonomy->entity->save();
     // Verify it is the correct name.
     $term = entity_load('taxonomy_term', $tid);
-    $this->assertEqual($term->name, $new_name);
+    $this->assertEqual($term->name->value, $new_name);
 
     // Make sure the computed term reflects updates to the term id.
     $term2 = entity_create('taxonomy_term', array(
       'name' => $this->randomName(),
-      'vid' => $this->term->vid,
+      'vid' => $this->term->bundle(),
       'langcode' => LANGUAGE_NOT_SPECIFIED,
     ));
     $term2->save();
 
     $entity->field_test_taxonomy->target_id = $term2->id();
     $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id());
-    $this->assertEqual($entity->field_test_taxonomy->entity->name, $term2->name);
+    $this->assertEqual($entity->field_test_taxonomy->entity->name->value, $term2->name->value);
   }
 }
diff --git a/core/modules/forum/forum.admin.inc b/core/modules/forum/forum.admin.inc
index 001dd97b0140..559749b27f4a 100644
--- a/core/modules/forum/forum.admin.inc
+++ b/core/modules/forum/forum.admin.inc
@@ -5,28 +5,32 @@
  * Administrative page callbacks for the Forum module.
  */
 
+use Drupal\taxonomy\Plugin\Core\Entity\Term;
+
 /**
  * Page callback: Returns a form for creating a new forum or container.
  *
  * @param $type
  *   What is being added. Possible values are 'forum' and 'container'.
- * @param $edit
- *   (optional) Associative array containing a forum term to be edited.
- *   Defaults to an empty array.
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
+ *   (optional) A forum or container term to be edited. Defaults to NULL.
  *
  * @return
  *   A form for creating a new forum or container.
  *
  * @see forum_menu()
  */
-function forum_form_main($type, $edit = array()) {
-  $edit = (array) $edit;
+function forum_form_main($type, Term $term = NULL) {
+  if (!$term) {
+    $term = entity_create('taxonomy_term', array('vid' => config('forum.settings')->get('vocabulary')));
+  }
+
   switch ($type) {
     case 'forum':
-      return drupal_get_form('forum_form_forum', $edit);
+      return drupal_get_form('forum_form_forum', $term);
       break;
     case 'container':
-      return drupal_get_form('forum_form_container', $edit);
+      return drupal_get_form('forum_form_container', $term);
       break;
   }
 }
@@ -34,37 +38,30 @@ function forum_form_main($type, $edit = array()) {
 /**
  * Form constructor for adding and editing a forum.
  *
- * @param $edit
- *   (optional) Associative array containing a forum term to be added or edited.
- *   Defaults to an empty array.
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
+ *   A forum term to be edited.
  *
  * @see forum_form_submit()
  * @ingroup forms
  */
-function forum_form_forum($form, &$form_state, $edit = array()) {
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'tid' => NULL,
-    'weight' => 0,
-  );
+function forum_form_forum($form, &$form_state, Term $term) {
   $form['name'] = array('#type' => 'textfield',
     '#title' => t('Forum name'),
-    '#default_value' => $edit['name'],
+    '#default_value' => $term->name->value,
     '#maxlength' => 255,
     '#description' => t('Short but meaningful name for this collection of threaded discussions.'),
     '#required' => TRUE,
   );
   $form['description'] = array('#type' => 'textarea',
     '#title' => t('Description'),
-    '#default_value' => $edit['description'],
+    '#default_value' => $term->description->value,
     '#description' => t('Description and guidelines for discussions within this forum.'),
   );
   $form['parent']['#tree'] = TRUE;
-  $form['parent'][0] = _forum_parent_select($edit['tid'], t('Parent'), 'forum');
+  $form['parent'][0] = _forum_parent_select($term->id(), t('Parent'), 'forum');
   $form['weight'] = array('#type' => 'weight',
     '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
+    '#default_value' => $term->weight->value,
     '#description' => t('Forums are displayed in ascending order by weight (forums with equal weights are displayed alphabetically).'),
   );
 
@@ -76,13 +73,13 @@ function forum_form_forum($form, &$form_state, $edit = array()) {
     '#button_type' => 'primary',
     '#submit' => array('forum_form_submit')
   );
-  if ($edit['tid']) {
+  if (!$term->isNew()) {
     $form['actions']['delete'] = array(
       '#type' => 'submit',
       '#value' => t('Delete'),
       '#submit' => array('forum_forum_delete'),
     );
-    $form['tid'] = array('#type' => 'value', '#value' => $edit['tid']);
+    $form['tid'] = array('#type' => 'value', '#value' => $term->id());
   }
   $form['#theme'] = 'forum_form';
 
@@ -111,10 +108,10 @@ function forum_form_submit($form, &$form_state) {
     case SAVED_NEW:
       if ($container) {
         $containers = $config->get('containers');
-        $containers[] = $term->tid;
+        $containers[] = $term->id();
         $config->set('containers', $containers)->save();
       }
-      $form_state['values']['tid'] = $term->tid;
+      $form_state['values']['tid'] = $term->id();
       drupal_set_message(t('Created new @type %term.', array('%term' => $form_state['values']['name'], '@type' => $type)));
       break;
     case SAVED_UPDATED:
@@ -145,26 +142,19 @@ function theme_forum_form($variables) {
 /**
  * Form constructor for adding and editing forum containers.
  *
- * @param $edit
- *   (optional) Associative array containing a container term to be added or edited.
- *   Defaults to an empty array.
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
+ *   A container term to be edited.
  *
  * @see forum_form_submit()
  * @ingroup forms
  */
-function forum_form_container($form, &$form_state, $edit = array()) {
+function forum_form_container($form, &$form_state, Term $term) {
   $config = config('forum.settings');
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'tid' => NULL,
-    'weight' => 0,
-  );
   // Handle a delete operation.
   $form['name'] = array(
     '#title' => t('Container name'),
     '#type' => 'textfield',
-    '#default_value' => $edit['name'],
+    '#default_value' => $term->name->value,
     '#maxlength' => 255,
     '#description' => t('Short but meaningful name for this collection of related forums.'),
     '#required' => TRUE
@@ -173,15 +163,15 @@ function forum_form_container($form, &$form_state, $edit = array()) {
   $form['description'] = array(
     '#type' => 'textarea',
     '#title' => t('Description'),
-    '#default_value' => $edit['description'],
+    '#default_value' => $term->description->value,
     '#description' => t('Description and guidelines for forums within this container.')
   );
   $form['parent']['#tree'] = TRUE;
-  $form['parent'][0] = _forum_parent_select($edit['tid'], t('Parent'), 'container');
+  $form['parent'][0] = _forum_parent_select($term->id(), t('Parent'), 'container');
   $form['weight'] = array(
     '#type' => 'weight',
     '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
+    '#default_value' => $term->weight->value,
     '#description' => t('Containers are displayed in ascending order by weight (containers with equal weights are displayed alphabetically).')
   );
 
@@ -196,13 +186,13 @@ function forum_form_container($form, &$form_state, $edit = array()) {
     '#button_type' => 'primary',
     '#submit' => array('forum_form_submit'),
   );
-  if ($edit['tid']) {
+  if (!$term->isNew()) {
     $form['actions']['delete'] = array(
       '#type' => 'submit',
       '#value' => t('Delete'),
       '#submit' => array('forum_forum_delete'),
     );
-    $form['tid'] = array('#type' => 'value', '#value' => $edit['tid']);
+    $form['tid'] = array('#type' => 'value', '#value' => $term->id());
   }
   $form['#theme'] = 'forum_form';
 
@@ -240,18 +230,18 @@ function forum_overview($form, &$form_state) {
   foreach (element_children($form['terms']) as $key) {
     if (isset($form['terms'][$key]['#term'])) {
       $term = $form['terms'][$key]['#term'];
-      $form['terms'][$key]['term']['#href'] = 'forum/' . $term['tid'];
+      $form['terms'][$key]['term']['#href'] = 'forum/' . $term->id();
       unset($form['terms'][$key]['operations']['#links']['delete']);
-      if (in_array($form['terms'][$key]['#term']['tid'], $config->get('containers'))) {
+      if (in_array($form['terms'][$key]['#term']->id(), $config->get('containers'))) {
         $form['terms'][$key]['operations']['#links']['edit']['title'] = t('edit container');
-        $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/container/' . $term['tid'];
+        $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/container/' . $term->id();
         // We don't want the redirect from the link so we can redirect the
         // delete action.
         unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']);
       }
       else {
         $form['terms'][$key]['operations']['#links']['edit']['title'] = t('edit forum');
-        $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/forum/' . $term['tid'];
+        $form['terms'][$key]['operations']['#links']['edit']['href'] = 'admin/structure/forum/edit/forum/' . $term->id();
         // We don't want the redirect from the link so we can redirect the
         // delete action.
         unset($form['terms'][$key]['operations']['#links']['edit']['query']['destination']);
@@ -286,7 +276,7 @@ function _forum_parent_select($tid, $title, $child_type) {
   $parents = taxonomy_term_load_parents($tid);
   if ($parents) {
     $parent = array_shift($parents);
-    $parent = $parent->tid;
+    $parent = $parent->id();
   }
   else {
     $parent = 0;
@@ -297,7 +287,7 @@ function _forum_parent_select($tid, $title, $child_type) {
 
   // A term can't be the child of itself, nor of its children.
   foreach ($children as $child) {
-    $exclude[] = $child->tid;
+    $exclude[] = $child->id();
   }
   $exclude[] = $tid;
 
@@ -305,8 +295,8 @@ function _forum_parent_select($tid, $title, $child_type) {
   $options[0] = '<' . t('root') . '>';
   if ($tree) {
     foreach ($tree as $term) {
-      if (!in_array($term->tid, $exclude)) {
-        $options[$term->tid] = str_repeat(' -- ', $term->depth) . $term->label();
+      if (!in_array($term->id(), $exclude)) {
+        $options[$term->id()] = str_repeat(' -- ', $term->depth) . $term->label();
       }
     }
   }
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index eb2c1ec91e77..164897447b59 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -168,7 +168,7 @@ function forum_menu_local_tasks(&$data, $router_item, $root_path) {
 
   // Add action link to 'node/add/forum' on 'forum' sub-pages.
   if ($root_path == 'forum' || $root_path == 'forum/%') {
-    $tid = (isset($router_item['page_arguments'][0]) ? $router_item['page_arguments'][0]->tid : 0);
+    $tid = (isset($router_item['page_arguments'][0]) ? $router_item['page_arguments'][0]->id() : 0);
     $forum_term = forum_forum_load($tid);
     if ($forum_term) {
       $links = array();
@@ -180,7 +180,7 @@ function forum_menu_local_tasks(&$data, $router_item, $root_path) {
             '#theme' => 'menu_local_action',
             '#link' => array(
               'title' => t('Add new @node_type', array('@node_type' => node_type_get_label($type))),
-              'href' => 'node/add/' . $type . '/' . $forum_term->tid,
+              'href' => 'node/add/' . $type . '/' . $forum_term->id(),
             ),
           );
         }
@@ -242,7 +242,7 @@ function forum_entity_bundle_info_alter(&$bundles) {
  */
 function forum_uri($forum) {
   return array(
-    'path' => 'forum/' . $forum->tid,
+    'path' => 'forum/' . $forum->id(),
   );
 }
 
@@ -275,7 +275,7 @@ function forum_node_view(EntityInterface $node, EntityDisplay $display, $view_mo
       if ($parents = taxonomy_term_load_parents_all($node->forum_tid)) {
         $parents = array_reverse($parents);
         foreach ($parents as $parent) {
-          $breadcrumb[] = l($parent->label(), 'forum/' . $parent->tid);
+          $breadcrumb[] = l($parent->label(), 'forum/' . $parent->id());
         }
       }
       drupal_set_breadcrumb($breadcrumb);
@@ -310,10 +310,10 @@ function forum_node_validate(EntityInterface $node, $form) {
           continue;
         }
         $used = db_query_range('SELECT 1 FROM {taxonomy_term_data} WHERE tid = :tid AND vid = :vid', 0, 1, array(
-          ':tid' => $term->tid,
+          ':tid' => $term->id(),
           ':vid' => $term->bundle(),
         ))->fetchField();
-        if ($used && in_array($term->tid, $containers)) {
+        if ($used && in_array($term->id(), $containers)) {
           form_set_error('taxonomy_forums', t('The item %forum is a forum container, not a forum. Select one of the forums below instead.', array('%forum' => $term->label())));
         }
       }
@@ -479,7 +479,7 @@ function forum_taxonomy_term_delete(Term $term) {
   // For containers, remove the tid from the forum_containers variable.
   $config = config('forum.settings');
   $containers = $config->get('containers');
-  $key = array_search($term->tid, $containers);
+  $key = array_search($term->id(), $containers);
   if ($key !== FALSE) {
     unset($containers[$key]);
   }
@@ -722,16 +722,17 @@ function forum_forum_load($tid = NULL) {
   elseif ($tid === 0) {
     $forum_term = entity_create('taxonomy_term', array(
       'tid' => 0,
+      'vid' => $vid,
     ));
   }
 
   // Determine if the requested term is a container.
-  if (!$forum_term->tid || in_array($forum_term->tid, $config->get('containers'))) {
+  if (!$forum_term->id() || in_array($forum_term->id(), $config->get('containers'))) {
     $forum_term->container = 1;
   }
 
   // Load parent terms.
-  $forum_term->parents = taxonomy_term_load_parents_all($forum_term->tid);
+  $forum_term->parents = taxonomy_term_load_parents_all($forum_term->id());
 
   // Load the tree below.
   $forums = array();
@@ -754,14 +755,14 @@ function forum_forum_load($tid = NULL) {
 
   foreach ($_forums as $forum) {
     // Determine if the child term is a container.
-    if (in_array($forum->tid, $config->get('containers'))) {
+    if (in_array($forum->id(), $config->get('containers'))) {
       $forum->container = 1;
     }
 
     // Merge in the topic and post counters.
-    if (!empty($counts[$forum->tid])) {
-      $forum->num_topics = $counts[$forum->tid]->topic_count;
-      $forum->num_posts = $counts[$forum->tid]->topic_count + $counts[$forum->tid]->comment_count;
+    if (!empty($counts[$forum->id()])) {
+      $forum->num_topics = $counts[$forum->id()]->topic_count;
+      $forum->num_posts = $counts[$forum->id()]->topic_count + $counts[$forum->id()]->comment_count;
     }
     else {
       $forum->num_topics = 0;
@@ -770,7 +771,7 @@ function forum_forum_load($tid = NULL) {
 
     // Query "Last Post" information for this forum.
     $query = db_select('node', 'n');
-    $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $forum->tid));
+    $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $forum->id()));
     $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
     $query->join('users', 'u', 'ncs.last_comment_uid = u.uid');
     $query->addExpression('CASE ncs.last_comment_uid WHEN 0 THEN ncs.last_comment_name ELSE u.name END', 'last_comment_name');
@@ -793,7 +794,7 @@ function forum_forum_load($tid = NULL) {
     }
     $forum->last_post = $last_post;
 
-    $forums[$forum->tid] = $forum;
+    $forums[$forum->id()] = $forum;
   }
 
   // Cache the result, and return the tree.
@@ -1054,8 +1055,8 @@ function template_preprocess_forum_list(&$variables) {
   $row = 0;
   // Sanitize each forum so that the template can safely print the data.
   foreach ($variables['forums'] as $id => $forum) {
-    $variables['forums'][$id]->description = !empty($forum->description) ? filter_xss_admin($forum->description) : '';
-    $variables['forums'][$id]->link = url("forum/$forum->tid");
+    $variables['forums'][$id]->description = filter_xss_admin($forum->description->value);
+    $variables['forums'][$id]->link = url("forum/" . $forum->id());
     $variables['forums'][$id]->name = check_plain($forum->label());
     $variables['forums'][$id]->is_container = !empty($forum->container);
     $variables['forums'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
@@ -1068,10 +1069,10 @@ function template_preprocess_forum_list(&$variables) {
     $variables['forums'][$id]->icon_class = 'default';
     $variables['forums'][$id]->icon_title = t('No new posts');
     if ($user->uid) {
-      $variables['forums'][$id]->new_topics = _forum_topics_unread($forum->tid, $user->uid);
+      $variables['forums'][$id]->new_topics = _forum_topics_unread($forum->id(), $user->uid);
       if ($variables['forums'][$id]->new_topics) {
-        $variables['forums'][$id]->new_text = format_plural($variables['forums'][$id]->new_topics, '1 new post<span class="element-invisible"> in forum %title</span>', '@count new posts<span class="element-invisible"> in forum %title</span>', array('%title' => $variables['forums'][$id]->name));
-        $variables['forums'][$id]->new_url = url("forum/$forum->tid", array('fragment' => 'new'));
+        $variables['forums'][$id]->new_text = format_plural($variables['forums'][$id]->new_topics, '1 new post<span class="element-invisible"> in forum %title</span>', '@count new posts<span class="element-invisible"> in forum %title</span>', array('%title' => $variables['forums'][$id]->label()));
+        $variables['forums'][$id]->new_url = url('forum/' . $forum->id(), array('fragment' => 'new'));
         $variables['forums'][$id]->icon_class = 'new';
         $variables['forums'][$id]->icon_title = t('New posts');
       }
diff --git a/core/modules/forum/forum.pages.inc b/core/modules/forum/forum.pages.inc
index 78eabbd7f6a9..422d92efc2ba 100644
--- a/core/modules/forum/forum.pages.inc
+++ b/core/modules/forum/forum.pages.inc
@@ -30,21 +30,21 @@ function forum_page($forum_term = NULL) {
 
   // Breadcrumb navigation.
   $breadcrumb[] = l(t('Home'), NULL);
-  if ($forum_term->tid) {
+  if ($forum_term->id()) {
     // Parent of all forums is the vocabulary name.
     $breadcrumb[] = l($vocabulary->label(), 'forum');
   }
   // Add all parent forums to breadcrumbs.
   if ($forum_term->parents) {
     foreach (array_reverse($forum_term->parents) as $parent) {
-      if ($parent->id() != $forum_term->tid) {
+      if ($parent->id() != $forum_term->id()) {
         $breadcrumb[] = l($parent->label(), 'forum/' . $parent->id());
       }
     }
   }
   drupal_set_breadcrumb($breadcrumb);
 
-  if ($forum_term->tid && array_search($forum_term->tid, $config->get('containers')) === FALSE) {
+  if ($forum_term->id() && array_search($forum_term->id(), $config->get('containers')) === FALSE) {
     // Add RSS feed for forums.
     drupal_add_feed('taxonomy/term/' . $forum_term->id() . '/feed', 'RSS - ' . $forum_term->label());
   }
@@ -58,7 +58,7 @@ function forum_page($forum_term = NULL) {
   $sort_by = $config->get('topics.order');
 
   if (empty($forum_term->container)) {
-    $topics = forum_get_topics($forum_term->tid, $sort_by, $forum_per_page);
+    $topics = forum_get_topics($forum_term->id(), $sort_by, $forum_per_page);
   }
   else {
     $topics = '';
@@ -69,7 +69,7 @@ function forum_page($forum_term = NULL) {
     '#forums' => $forum_term->forums,
     '#topics' => $topics,
     '#parents' => $forum_term->parents,
-    '#tid' => $forum_term->tid,
+    '#tid' => $forum_term->id(),
     '#sortby' => $sort_by,
     '#forums_per_page' => $forum_per_page,
   );
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index c17dc2b18b18..a2264dd98a75 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -240,10 +240,10 @@ function testForum() {
   function testAddOrphanTopic() {
     // Must remove forum topics to test creating orphan topics.
     $vid = config('forum.settings')->get('vocabulary');
-    $tree = taxonomy_get_tree($vid);
-    foreach ($tree as $term) {
-      taxonomy_term_delete($term->tid);
-    }
+    $tids = \Drupal::entityQuery('taxonomy_term')
+      ->condition('vid', $vid)
+      ->execute();
+    taxonomy_term_delete_multiple($tids);
 
     // Create an orphan forum item.
     $this->drupalLogin($this->admin_user);
diff --git a/core/modules/forum/templates/forum-list.tpl.php b/core/modules/forum/templates/forum-list.tpl.php
index b1694930f68e..da8a12de0271 100644
--- a/core/modules/forum/templates/forum-list.tpl.php
+++ b/core/modules/forum/templates/forum-list.tpl.php
@@ -55,8 +55,8 @@
             <span class="element-invisible"><?php print $forum->icon_title; ?></span>
           </div>
           <div class="name"><a href="<?php print $forum->link; ?>"><?php print $forum->label(); ?></a></div>
-          <?php if ($forum->description): ?>
-            <div class="description"><?php print $forum->description; ?></div>
+          <?php if ($forum->description->value): ?>
+            <div class="description"><?php print $forum->description->value; ?></div>
           <?php endif; ?>
         <?php print str_repeat('</div>', $forum->depth); ?>
       </td>
diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php
index e92768ff78d3..f3d0f7d72417 100644
--- a/core/modules/options/options.api.php
+++ b/core/modules/options/options.api.php
@@ -61,7 +61,7 @@ function hook_options_list($field, $instance, $entity) {
     $terms = taxonomy_get_tree($tree['vid'], $tree['parent'], NULL, TRUE);
     if ($terms) {
       foreach ($terms as $term) {
-        $options[$term->tid] = str_repeat('-', $term->depth) . $term->label();
+        $options[$term->id()] = str_repeat('-', $term->depth) . $term->label();
       }
     }
   }
diff --git a/core/modules/path/lib/Drupal/path/Type/PathItem.php b/core/modules/path/lib/Drupal/path/Type/PathItem.php
new file mode 100644
index 000000000000..9b8abd1cf385
--- /dev/null
+++ b/core/modules/path/lib/Drupal/path/Type/PathItem.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\path\Type\PathItem.
+ */
+
+namespace Drupal\path\Type;
+
+use Drupal\Core\Entity\Field\FieldItemBase;
+
+/**
+ * Defines the 'path_field' entity field item.
+ */
+class PathItem extends FieldItemBase {
+
+  /**
+   * Definitions of the contained properties.
+   *
+   * @see PathItem::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   */
+  public function getPropertyDefinitions() {
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['alias'] = array(
+        'type' => 'string',
+        'label' => t('Path alias'),
+      );
+      static::$propertyDefinitions['pid'] = array(
+        'type' => 'integer',
+        'label' => t('Path id'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+}
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index cee17ed595f7..6cfb64a349d8 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -232,13 +232,13 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
   // Make sure this does not show up on the delete confirmation form.
   if (empty($form_state['confirm_delete'])) {
     $term = $form_state['controller']->getEntity($form_state);
-    $path = (isset($term->tid) ? drupal_container()->get('path.crud')->load(array('source' => 'taxonomy/term/' . $term->tid)) : array());
+    $path = ($term->id() ? Drupal::service('path.crud')->load(array('source' => 'taxonomy/term/' . $term->id())) : array());
     if ($path === FALSE) {
       $path = array();
     }
     $path += array(
       'pid' => NULL,
-      'source' => isset($term->tid) ? 'taxonomy/term/' . $term->tid : NULL,
+      'source' => $term->id() ? 'taxonomy/term/' . $term->id() : NULL,
       'alias' => '',
       'langcode' => LANGUAGE_NOT_SPECIFIED,
     );
@@ -261,19 +261,46 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
   }
 }
 
+/**
+ * Implements hook_data_type_info().
+ */
+function path_data_type_info() {
+  $info['path_field'] = array(
+    'label' => t('Path field item'),
+    'description' => t('An entity field containing a path alias and related data.'),
+    'class' => '\Drupal\path\Type\PathItem',
+    'list class' => '\Drupal\Core\Entity\Field\Type\Field',
+  );
+  return $info;
+}
+
+/**
+ * Implements hook_entity_field_info().
+ */
+function path_entity_field_info($entity_type) {
+  if ($entity_type === 'taxonomy_term') {
+    $info['definitions']['path'] = array(
+      'type' => 'path_field',
+      'label' => t('The path alias'),
+      'computed' => TRUE,
+      'list' => TRUE,
+    );
+    return $info;
+  }
+}
+
 /**
  * Implements hook_taxonomy_term_insert().
  */
 function path_taxonomy_term_insert(Term $term) {
   if (isset($term->path)) {
-    $path = $term->path;
-    $path['alias'] = trim($path['alias']);
+    $term->path->alias = trim($term->path->alias);
     // Only save a non-empty alias.
-    if (!empty($path['alias'])) {
+    if (!empty($term->path->alias)) {
       // Ensure fields for programmatic executions.
-      $path['source'] = 'taxonomy/term/' . $term->tid;
-      $path['langcode'] = LANGUAGE_NOT_SPECIFIED;
-      drupal_container()->get('path.crud')->save($path['source'], $path['alias'], $path['langcode']);
+      $source = 'taxonomy/term/' . $term->id();
+      $langcode = LANGUAGE_NOT_SPECIFIED;
+      Drupal::service('path.crud')->save($source, $term->path->alias, $langcode);
     }
   }
 }
@@ -283,19 +310,18 @@ function path_taxonomy_term_insert(Term $term) {
  */
 function path_taxonomy_term_update(Term $term) {
   if (isset($term->path)) {
-    $path = $term->path;
-    $path['alias'] = trim($path['alias']);
+    $term->path->alias = trim($term->path->alias);
     // Delete old alias if user erased it.
-    if (!empty($path['pid']) && empty($path['alias'])) {
-      drupal_container()->get('path.crud')->delete(array('pid' => $path['pid']));
+    if (!empty($term->path->pid) && empty($term->path->alias)) {
+      Drupal::service('path.crud')->delete(array('pid' => $term->path->pid));
     }
     // Only save a non-empty alias.
-    if (!empty($path['alias'])) {
-      $pid = (!empty($path['pid']) ? $path['pid'] : NULL);
+    if ($term->path->alias) {
+      $pid = (!empty($term->path->pid) ? $term->path->pid  : NULL);
       // Ensure fields for programmatic executions.
-      $path['source'] = 'taxonomy/term/' . $term->tid;
-      $path['langcode'] = LANGUAGE_NOT_SPECIFIED;
-      drupal_container()->get('path.crud')->save($path['source'], $path['alias'], $path['langcode'], $pid);
+      $source = 'taxonomy/term/' . $term->id();
+      $langcode = LANGUAGE_NOT_SPECIFIED;
+      Drupal::service('path.crud')->save($source, $term->path->alias, $langcode, $pid);
     }
   }
 }
@@ -305,7 +331,7 @@ function path_taxonomy_term_update(Term $term) {
  */
 function path_taxonomy_term_delete(Term $term) {
   // Delete all aliases associated with this term.
-  drupal_container()->get('path.crud')->delete(array('source' => 'taxonomy/term/' . $term->tid));
+  Drupal::service('path.crud')->delete(array('source' => 'taxonomy/term/' . $term->id()));
 }
 
 /**
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
index 83e6ec992260..4b26a04aea5d 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/TaxonomyAttributesTest.php
@@ -35,13 +35,13 @@ public static function getInfo() {
   function testTaxonomyTermRdfaAttributes() {
     $vocabulary = $this->createVocabulary();
     $term = $this->createTerm($vocabulary);
-    $term_uri = url('taxonomy/term/' . $term->tid, array('absolute' => TRUE));
+    $term_uri = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE));
 
     // Parses the term's page and checks that the RDF output is correct.
     $parser = new \EasyRdf_Parser_Rdfa();
     $graph = new \EasyRdf_Graph();
     $base_uri = url('<front>', array('absolute' => TRUE));
-    $parser->parse($graph, $this->drupalGet('taxonomy/term/' . $term->tid), 'rdfa', $base_uri);
+    $parser->parse($graph, $this->drupalGet('taxonomy/term/' . $term->id()), 'rdfa', $base_uri);
 
     // Inspects RDF graph output.
     // Term type.
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 547075a58673..a2f74a33e878 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -767,7 +767,7 @@ function rdf_preprocess_taxonomy_term(&$variables) {
   $term_label_meta = array(
       '#tag' => 'meta',
       '#attributes' => array(
-        'about' => url('taxonomy/term/' . $term->tid),
+        'about' => url('taxonomy/term/' . $term->id()),
         'typeof' => $term->rdf_mapping['rdftype'],
         'property' => $term->rdf_mapping['name']['predicates'],
         'content' => $term->label(),
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
index 985fefba81c6..784ced93ea02 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
@@ -373,7 +373,7 @@ public function testTaxonomyTermHooks() {
     ));
 
     $_SESSION['entity_crud_hook_test'] = array();
-    $term = taxonomy_term_load($term->tid);
+    $term = taxonomy_term_load($term->id());
 
     $this->assertHookMessageOrder(array(
       'entity_crud_hook_test_entity_load called for type taxonomy_term',
@@ -392,7 +392,7 @@ public function testTaxonomyTermHooks() {
     ));
 
     $_SESSION['entity_crud_hook_test'] = array();
-    taxonomy_term_delete($term->tid);
+    taxonomy_term_delete($term->id());
 
     $this->assertHookMessageOrder(array(
       'entity_crud_hook_test_taxonomy_term_predelete called',
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php
index e6d796e5f3c7..f36fca7613b5 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php
@@ -111,7 +111,7 @@ public function setUp() {
       $entity->name->value = $this->randomName();
       $index = $i ? 1 : 0;
       $entity->user_id->target_id = $this->accounts[$index]->uid;
-      $entity->{$this->fieldName}->tid = $this->terms[$index]->tid;
+      $entity->{$this->fieldName}->tid = $this->terms[$index]->id();
       $entity->save();
       $this->entities[] = $entity;
     }
@@ -147,18 +147,18 @@ public function testQuery() {
     // This returns the 0th entity as that's only one pointing to the 0th
     // term (test without specifying the field column).
     $this->queryResults = $this->factory->get('entity_test')
-      ->condition("$this->fieldName.entity.name", $this->terms[0]->name)
+      ->condition("$this->fieldName.entity.name", $this->terms[0]->name->value)
       ->execute();
     $this->assertResults(array(0));
     // This returns the 0th entity as that's only one pointing to the 0th
     // term (test with specifying the column name).
     $this->queryResults = $this->factory->get('entity_test')
-      ->condition("$this->fieldName.tid.entity.name", $this->terms[0]->name)
+      ->condition("$this->fieldName.tid.entity.name", $this->terms[0]->name->value)
       ->execute();
     $this->assertResults(array(0));
     // This returns the 1st and 2nd entity as those point to the 1st term.
     $this->queryResults = $this->factory->get('entity_test')
-      ->condition("$this->fieldName.entity.name", $this->terms[0]->name, '<>')
+      ->condition("$this->fieldName.entity.name", $this->terms[0]->name->value, '<>')
       ->execute();
     $this->assertResults(array(1, 2));
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
index 07c38aee4a27..6ebcfdaa1027 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php
@@ -323,16 +323,16 @@ function testBreadCrumbs() {
         $edit = array(
           'parent[]' => array($parent_tid),
         );
-        $this->drupalPost("taxonomy/term/{$term->tid}/edit", $edit, t('Save'));
+        $this->drupalPost("taxonomy/term/{$term->id()}/edit", $edit, t('Save'));
       }
-      $parent_tid = $term->tid;
+      $parent_tid = $term->id();
     }
     $parent_mlid = 0;
     foreach ($tags as $name => $data) {
       $term = $data['term'];
       $edit = array(
         'link_title' => "$name link",
-        'link_path' => "taxonomy/term/{$term->tid}",
+        'link_path' => "taxonomy/term/{$term->id()}",
         'parent' => "$menu:{$parent_mlid}",
       );
       $this->drupalPost("admin/structure/menu/manage/$menu/add", $edit, t('Save'));
@@ -352,7 +352,7 @@ function testBreadCrumbs() {
       $tree += array(
         $link['link_path'] => $link['link_title'],
       );
-      $this->assertBreadcrumb($link['link_path'], $trail, $term->name, $tree);
+      $this->assertBreadcrumb($link['link_path'], $trail, $term->label(), $tree);
       $this->assertRaw(check_plain($parent->title), 'Tagged node found.');
 
       // Additionally make sure that this link appears only once; i.e., the
@@ -368,7 +368,7 @@ function testBreadCrumbs() {
       // Next iteration should expect this tag as parent link.
       // Note: Term name, not link name, due to taxonomy_term_page().
       $trail += array(
-        $link['link_path'] => $term->name,
+        $link['link_path'] => $term->label(),
       );
     }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
index b9877398d177..6b53b2246c30 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAlterFunctionalTest.php
@@ -69,15 +69,14 @@ function testUrlAlter() {
     $this->assertUrlOutboundAlter('forum', 'community');
     $forum_vid = config('forum.settings')->get('vocabulary');
     $term_name = $this->randomName();
-    $tid = db_insert('taxonomy_term_data')
-      ->fields(array(
-        'name' => $term_name,
-        'vid' => $forum_vid,
-      ))
-      ->execute();
-    $this->drupalGet("community/$tid");
+    $term = entity_create('taxonomy_term', array(
+      'name' => $term_name,
+      'vid' => $forum_vid,
+    ));
+    $term->save();
+    $this->drupalGet("community/" . $term->id());
     $this->assertText($term_name, 'The community/{tid} path gets resolved correctly');
-    $this->assertUrlOutboundAlter("forum/$tid", "community/$tid");
+    $this->assertUrlOutboundAlter("forum/" . $term->id(), "community/" . $term->id());
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
index 1f0f2ee4632f..703515af2f08 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/EntityFilteringThemeTest.php
@@ -102,7 +102,7 @@ function setUp() {
       'title' => $this->xss_label,
       'type' => 'article',
       'promote' => NODE_PROMOTED,
-      'field_tags' => array(array('tid' => $this->term->tid)),
+      'field_tags' => array(array('tid' => $this->term->id())),
     ));
 
     // Create a test comment on the test node.
@@ -125,7 +125,7 @@ function testThemedEntity() {
       'user',
       'node',
       'node/' . $this->node->nid,
-      'taxonomy/term/' . $this->term->tid,
+      'taxonomy/term/' . $this->term->id(),
     );
 
     // Check each path in all available themes.
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 339cdba00bd6..ecd63d380194 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1906,7 +1906,7 @@ function hook_mail($key, &$message, $params) {
     $variables += array(
       '%term_name' => $entity->name,
       '%term_description' => $entity->description,
-      '%term_id' => $entity->tid,
+      '%term_id' => $entity->id(),
       '%vocabulary_name' => $vocabulary->name,
       '%vocabulary_description' => $vocabulary->description,
       '%vocabulary_id' => $vocabulary->id(),
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
index 2c6c00af8a83..019b679bc486 100644
--- a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
+++ b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
@@ -10,14 +10,26 @@
 use Drupal\taxonomy\Plugin\Core\Entity\Term;
 use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
+/**
+ * Implements hook_entity_field_alter()
+ */
+function taxonomy_test_entity_field_info_alter(&$info, $entity_type) {
+  $info['definitions']['antonym'] = array(
+    'label' => t('Antonym'),
+    'description' => t('The term antonym.'),
+    'type' => 'string_field',
+    'computed' => TRUE,
+  );
+}
+
 /**
  * Implements hook_taxonomy_term_load().
  */
 function taxonomy_test_taxonomy_term_load(array $terms) {
   foreach ($terms as $term) {
-    $antonym = taxonomy_test_get_antonym($term->tid);
+    $antonym = taxonomy_test_get_antonym($term->id());
     if ($antonym) {
-      $term->antonym = $antonym;
+      $term->antonym->value = $antonym;
     }
   }
 }
@@ -26,11 +38,11 @@ function taxonomy_test_taxonomy_term_load(array $terms) {
  * Implements hook_taxonomy_term_insert().
  */
 function taxonomy_test_taxonomy_term_insert(Term $term) {
-  if (!empty($term->antonym)) {
+  if (!empty($term->antonym->value)) {
     db_insert('taxonomy_term_antonym')
       ->fields(array(
-        'tid' => $term->tid,
-        'name' => trim($term->antonym)
+        'tid' => $term->id(),
+        'name' => trim($term->antonym->value)
       ))
       ->execute();
   }
@@ -40,11 +52,11 @@ function taxonomy_test_taxonomy_term_insert(Term $term) {
  * Implements hook_taxonomy_term_update().
  */
 function taxonomy_test_taxonomy_term_update(Term $term) {
-  if (!empty($term->antonym)) {
+  if (!empty($term->antonym->value)) {
     db_merge('taxonomy_term_antonym')
-      ->key(array('tid' => $term->tid))
+      ->key(array('tid' => $term->id()))
       ->fields(array(
-        'name' => trim($term->antonym)
+        'name' => trim($term->antonym->value)
       ))
       ->execute();
   }
@@ -55,7 +67,7 @@ function taxonomy_test_taxonomy_term_update(Term $term) {
  */
 function taxonomy_test_taxonomy_term_delete(Term $term) {
   db_delete('taxonomy_term_antonym')
-    ->condition('tid', $term->tid)
+    ->condition('tid', $term->id())
     ->execute();
 }
 
@@ -66,7 +78,7 @@ function taxonomy_test_taxonomy_term_view(Term $term, EntityDisplay $display, $v
   if ($view_mode == 'full') {
     $term->content['taxonomy_test_term_view_check'] = array(
       '#prefix' => '<div>',
-      '#markup' => t('The antonym is %antonym', array('%antonym' => $term->antonym)),
+      '#markup' => t('The antonym is %antonym', array('%antonym' => $term->antonym->value)),
       '#suffix' => '</div>',
       '#weight' => 10,
     );
@@ -80,7 +92,7 @@ function taxonomy_test_entity_view($entity, EntityDisplay $display, $view_mode,
   if ($entity->entityType() == 'taxonomy_term' && $view_mode == 'full') {
     $entity->content['taxonomy_test_entity_view_check'] = array(
       '#prefix' => '<div>',
-      '#markup' => t('The antonym is %antonym', array('%antonym' => $entity->antonym)),
+      '#markup' => t('The antonym is %antonym', array('%antonym' => $entity->antonym->value)),
       '#suffix' => '</div>',
       '#weight' => 20,
     );
@@ -92,7 +104,7 @@ function taxonomy_test_entity_view($entity, EntityDisplay $display, $view_mode,
  */
 function taxonomy_test_form_taxonomy_term_form_alter(&$form, $form_state, $form_id) {
   $term = $form_state['controller']->getEntity($form_state);
-  $antonym = taxonomy_test_get_antonym($term->tid);
+  $antonym = taxonomy_test_get_antonym($term->id());
   $form['advanced']['antonym'] = array(
     '#type' => 'textfield',
     '#title' => t('Antonym'),
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
index 60811dbfe2fd..db9e033980d8 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/Core/Entity/Term.php
@@ -8,7 +8,7 @@
 namespace Drupal\taxonomy\Plugin\Core\Entity;
 
 use Drupal\Core\Entity\ContentEntityInterface;
-use Drupal\Core\Entity\Entity;
+use Drupal\Core\Entity\EntityNG;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
 
@@ -46,47 +46,47 @@
  *   permission_granularity = "bundle"
  * )
  */
-class Term extends Entity implements ContentEntityInterface {
+class Term extends EntityNG implements ContentEntityInterface {
 
   /**
    * The taxonomy term ID.
    *
-   * @var integer
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $tid;
 
   /**
    * The term UUID.
    *
-   * @var string
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $uuid;
 
   /**
    * The taxonomy vocabulary ID this term belongs to.
    *
-   * @var integer
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $vid;
 
   /**
    * Name of the term.
    *
-   * @var string
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $name;
 
   /**
    * Description of the term.
    *
-   * @var string
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $description;
 
   /**
    * The text format name for the term's description.
    *
-   * @var string
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $format;
 
@@ -96,9 +96,9 @@ class Term extends Entity implements ContentEntityInterface {
    * This property stores the weight of this term in relation to other terms of
    * the same vocabulary.
    *
-   * @var integer
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
-  public $weight = 0;
+  public $weight;
 
   /**
    * The parent term(s) for this term.
@@ -110,21 +110,39 @@ class Term extends Entity implements ContentEntityInterface {
    * term does not have any parents. When omitting this variable during an
    * update, the existing hierarchy for the term remains unchanged.
    *
-   * @var array
+   * @var \Drupal\Core\Entity\Field\FieldInterface
    */
   public $parent;
 
+  /**
+   * Default values for the term.
+   *
+   * @var array
+   */
+  protected $values = array(
+    'langcode' => array(LANGUAGE_DEFAULT => array(0 => array('value' => LANGUAGE_NOT_SPECIFIED))),
+    'weight' => array(LANGUAGE_DEFAULT => array(0 => array('value' => 0))),
+  );
+
   /**
    * Implements Drupal\Core\Entity\EntityInterface::id().
    */
   public function id() {
-    return $this->tid;
+    return $this->get('tid')->value;
   }
 
   /**
-   * Implements Drupal\Core\Entity\EntityInterface::bundle().
+   * Overides \Drupal\Core\Entity\EntityNG::init().
    */
-  public function bundle() {
-    return $this->vid;
+  protected function init() {
+    parent::init();
+    unset($this->tid);
+    unset($this->uuid);
+    unset($this->vid);
+    unset($this->name);
+    unset($this->weight);
+    unset($this->format);
+    unset($this->description);
+    unset($this->parent);
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php
index ab3d946f8c11..e49f31e50f3c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/entity_reference/selection/TermSelection.php
@@ -67,7 +67,7 @@ public function getReferencableEntities($match = NULL, $match_operator = 'CONTAI
       if ($vocabulary = entity_load('taxonomy_vocabulary', $bundle)) {
         if ($terms = taxonomy_get_tree($vocabulary->id(), 0)) {
           foreach ($terms as $term) {
-            $options[$vocabulary->id()][$term->tid] = str_repeat('-', $term->depth) . check_plain($term->name);
+            $options[$vocabulary->id()][$term->id()] = str_repeat('-', $term->depth) . check_plain($term->name);
           }
         }
       }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
index 3457126945f6..9624d43361b5 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
@@ -89,7 +89,7 @@ public function massageFormValues(array $values, array $form, array &$form_state
       // otherwise, create a new 'autocreate' term for insert/update.
       if ($possibilities = entity_load_multiple_by_properties('taxonomy_term', array('name' => trim($value), 'vid' => array_keys($vocabularies)))) {
         $term = array_pop($possibilities);
-        $item = array('tid' => $term->tid);
+        $item = array('tid' => $term->id());
       }
       else {
         $vocabulary = reset($vocabularies);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/IndexTidDepth.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/IndexTidDepth.php
index a08190c0e0ce..7c5a0ebebe90 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/IndexTidDepth.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/IndexTidDepth.php
@@ -149,7 +149,7 @@ public function query($group_by = FALSE) {
   function title() {
     $term = taxonomy_term_load($this->argument);
     if (!empty($term)) {
-      return check_plain($term->name);
+      return check_plain($term->label());
     }
     // TODO review text
     return t('No name');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/Taxonomy.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/Taxonomy.php
index 3a132ddeda2c..6bff5acb38ce 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/Taxonomy.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument/Taxonomy.php
@@ -27,7 +27,7 @@ function title() {
     if ($this->argument) {
       $term = taxonomy_term_load($this->argument);
       if (!empty($term)) {
-        return check_plain($term->name);
+        return check_plain($term->label());
       }
     }
     // TODO review text
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
index 0dbcd4c9d3e4..fafe15de29fa 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/argument_validator/Term.php
@@ -109,7 +109,7 @@ function validate_argument($argument) {
         if (!$term) {
           return FALSE;
         }
-        $this->argument->validated_title = check_plain($term->name);
+        $this->argument->validated_title = check_plain($term->label());
         return empty($vocabularies) || !empty($vocabularies[$term->bundle()]);
 
       case 'tids':
@@ -151,7 +151,7 @@ function validate_argument($argument) {
               return FALSE;
             }
 
-            $titles[] = $validated_cache[$term->id()] = check_plain($term->name);
+            $titles[] = $validated_cache[$term->id()] = check_plain($term->label());
             unset($test[$term->id()]);
           }
         }
@@ -175,7 +175,7 @@ function validate_argument($argument) {
           if ($type == 'convert') {
             $this->argument->argument = $term->id();
           }
-          $this->argument->validated_title = check_plain($term->name);
+          $this->argument->validated_title = check_plain($term->label());
           return TRUE;
         }
         return FALSE;
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/TaxonomyIndexTid.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/TaxonomyIndexTid.php
index 2880252b3376..44faa7f8742b 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/field/TaxonomyIndexTid.php
@@ -119,8 +119,8 @@ function pre_render(&$values) {
       foreach ($result as $term) {
         $this->items[$term->node_nid][$term->tid]['name'] = check_plain($term->name);
         $this->items[$term->node_nid][$term->tid]['tid'] = $term->tid;
-        $this->items[$term->node_nid][$term->tid]['vocabulary_vid'] = $term->bundle();
-        $this->items[$term->node_nid][$term->tid]['vocabulary'] = check_plain($vocabularies[$term->bundle()]->label());
+        $this->items[$term->node_nid][$term->tid]['vocabulary_vid'] = $term->vid;
+        $this->items[$term->node_nid][$term->tid]['vocabulary'] = check_plain($vocabularies[$term->vid]->label());
 
         if (!empty($this->options['link_to_taxonomy'])) {
           $this->items[$term->node_nid][$term->tid]['make_link'] = TRUE;
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
index 3735ad6c70a0..167befa95855 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
@@ -8,12 +8,12 @@
 namespace Drupal\taxonomy;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityFormControllerNG;
 
 /**
  * Base for controller for taxonomy term edit forms.
  */
-class TermFormController extends EntityFormController {
+class TermFormController extends EntityFormControllerNG {
 
   /**
    * Overrides Drupal\Core\Entity\EntityFormController::form().
@@ -21,14 +21,14 @@ class TermFormController extends EntityFormController {
   public function form(array $form, array &$form_state, EntityInterface $term) {
     $vocabulary = taxonomy_vocabulary_load($term->bundle());
 
-    $parent = array_keys(taxonomy_term_load_parents($term->tid));
+    $parent = array_keys(taxonomy_term_load_parents($term->id()));
     $form_state['taxonomy']['parent'] = $parent;
     $form_state['taxonomy']['vocabulary'] = $vocabulary;
 
     $form['name'] = array(
       '#type' => 'textfield',
       '#title' => t('Name'),
-      '#default_value' => $term->name,
+      '#default_value' => $term->name->value,
       '#maxlength' => 255,
       '#required' => TRUE,
       '#weight' => -5,
@@ -37,8 +37,8 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
     $form['description'] = array(
       '#type' => 'text_format',
       '#title' => t('Description'),
-      '#default_value' => $term->description,
-      '#format' => $term->format,
+      '#default_value' => $term->description->value,
+      '#format' => $term->format->value,
       '#weight' => 0,
     );
     $language_configuration = module_invoke('language', 'get_default_configuration', 'taxonomy_term', $vocabulary->id());
@@ -46,7 +46,7 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
       '#type' => 'language_select',
       '#title' => t('Language'),
       '#languages' => LANGUAGE_ALL,
-      '#default_value' => $term->langcode,
+      '#default_value' => $term->langcode->value,
       '#access' => !is_null($language_configuration['language_show']) && $language_configuration['language_show'],
     );
 
@@ -62,14 +62,14 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
     // before loading the full vocabulary. Contrib modules can then intercept
     // before hook_form_alter to provide scalable alternatives.
     if (!config('taxonomy.settings')->get('override_selector')) {
-      $parent = array_keys(taxonomy_term_load_parents($term->tid));
-      $children = taxonomy_get_tree($vocabulary->id(), $term->tid);
+      $parent = array_keys(taxonomy_term_load_parents($term->id()));
+      $children = taxonomy_get_tree($vocabulary->id(), $term->id());
 
       // A term can't be the child of itself, nor of its children.
       foreach ($children as $child) {
         $exclude[] = $child->tid;
       }
-      $exclude[] = $term->tid;
+      $exclude[] = $term->id();
 
       $tree = taxonomy_get_tree($vocabulary->id());
       $options = array('<' . t('root') . '>');
@@ -95,7 +95,7 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
       '#type' => 'textfield',
       '#title' => t('Weight'),
       '#size' => 6,
-      '#default_value' => $term->weight,
+      '#default_value' => $term->weight->value,
       '#description' => t('Terms are displayed in ascending order by weight.'),
       '#required' => TRUE,
     );
@@ -107,10 +107,10 @@ public function form(array $form, array &$form_state, EntityInterface $term) {
 
     $form['tid'] = array(
       '#type' => 'value',
-      '#value' => $term->tid,
+      '#value' => $term->id(),
     );
 
-    if (empty($term->tid)) {
+    if ($term->isNew()) {
       $form_state['redirect'] = current_path();
     }
 
@@ -130,18 +130,21 @@ public function validate(array $form, array &$form_state) {
   }
 
   /**
-   * Overrides Drupal\Core\Entity\EntityFormController::submit().
+   * Overrides Drupal\Core\Entity\EntityFormController::buildEntity().
    */
-  public function submit(array $form, array &$form_state) {
-    $term = parent::submit($form, $form_state);
+  public function buildEntity(array $form, array &$form_state) {
+    $term = parent::buildEntity($form, $form_state);
 
     // Prevent leading and trailing spaces in term names.
-    $term->name = trim($term->name);
+    $term->name->value = trim($term->name->value);
 
     // Convert text_format field into values expected by taxonomy_term_save().
     $description = $form_state['values']['description'];
-    $term->description = $description['value'];
-    $term->format = $description['format'];
+    $term->description->value = $description['value'];
+    $term->format->value = $description['format'];
+
+    // Assign parents with proper delta values starting from 0.
+    $term->parent = array_keys($form_state['values']['parent']);
 
     return $term;
   }
@@ -156,11 +159,11 @@ public function save(array $form, array &$form_state) {
     switch ($status) {
       case SAVED_NEW:
         drupal_set_message(t('Created new term %term.', array('%term' => $term->label())));
-        watchdog('taxonomy', 'Created new term %term.', array('%term' => $term->label()), WATCHDOG_NOTICE, l(t('edit'), 'taxonomy/term/' . $term->tid . '/edit'));
+        watchdog('taxonomy', 'Created new term %term.', array('%term' => $term->label()), WATCHDOG_NOTICE, l(t('edit'), 'taxonomy/term/' . $term->id() . '/edit'));
         break;
       case SAVED_UPDATED:
         drupal_set_message(t('Updated term %term.', array('%term' => $term->label())));
-        watchdog('taxonomy', 'Updated term %term.', array('%term' => $term->label()), WATCHDOG_NOTICE, l(t('edit'), 'taxonomy/term/' . $term->tid . '/edit'));
+        watchdog('taxonomy', 'Updated term %term.', array('%term' => $term->label()), WATCHDOG_NOTICE, l(t('edit'), 'taxonomy/term/' . $term->id() . '/edit'));
         // Clear the page and block caches to avoid stale data.
         cache_invalidate_tags(array('content' => TRUE));
         break;
@@ -186,8 +189,8 @@ public function save(array $form, array &$form_state) {
       taxonomy_vocabulary_save($form_state['taxonomy']['vocabulary']);
     }
 
-    $form_state['values']['tid'] = $term->tid;
-    $form_state['tid'] = $term->tid;
+    $form_state['values']['tid'] = $term->id();
+    $form_state['tid'] = $term->id();
   }
 
   /**
@@ -200,6 +203,6 @@ public function delete(array $form, array &$form_state) {
       unset($_GET['destination']);
     }
     $term = $this->getEntity($form_state);
-    $form_state['redirect'] = array('taxonomy/term/' . $term->tid . '/delete', array('query' => $destination));
+    $form_state['redirect'] = array('taxonomy/term/' . $term->id() . '/delete', array('query' => $destination));
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
index ce8cb0361401..60728b4b489d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
@@ -25,9 +25,9 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
     foreach ($entities as $entity) {
       // Add the description if enabled.
       $display = $displays[$entity->bundle()];
-      if (!empty($entity->description) && $display->getComponent('description')) {
+      if (!empty($entity->description->value) && $display->getComponent('description')) {
         $entity->content['description'] = array(
-          '#markup' => check_markup($entity->description, $entity->format, '', TRUE),
+          '#markup' => check_markup($entity->description->value, $entity->format->value, '', TRUE),
           '#prefix' => '<div class="taxonomy-term-description">',
           '#suffix' => '</div>',
         );
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
index c7dbd975927f..bea79763d45d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorageController.php
@@ -9,12 +9,12 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
-use Drupal\Core\Entity\DatabaseStorageController;
+use Drupal\Core\Entity\DatabaseStorageControllerNG;
 
 /**
  * Defines a Controller class for taxonomy terms.
  */
-class TermStorageController extends DatabaseStorageController {
+class TermStorageController extends DatabaseStorageControllerNG {
 
   /**
    * Overrides Drupal\Core\Entity\DatabaseStorageController::create().
@@ -24,11 +24,11 @@ class TermStorageController extends DatabaseStorageController {
    *   vocabulary ID ('vid') is required.
    */
   public function create(array $values) {
-    $entity = parent::create($values);
     // Save new terms with no parents by default.
-    if (!isset($entity->parent)) {
-      $entity->parent = array(0);
+    if (empty($values['parent'])) {
+      $values['parent'] = array(0);
     }
+    $entity = parent::create($values);
     return $entity;
   }
 
@@ -53,11 +53,11 @@ protected function postDelete($entities) {
       if ($children = taxonomy_term_load_children($tid)) {
         foreach ($children as $child) {
           // If the term has multiple parents, we don't delete it.
-          $parents = taxonomy_term_load_parents($child->tid);
+          $parents = taxonomy_term_load_parents($child->id());
           // Because the parent has already been deleted, the parent count might
           // be 0.
           if (count($parents) <= 1) {
-            $orphans[] = $child->tid;
+            $orphans[] = $child->id();
           }
         }
       }
@@ -78,9 +78,11 @@ protected function postDelete($entities) {
    * Overrides Drupal\Core\Entity\DatabaseStorageController::postSave().
    */
   protected function postSave(EntityInterface $entity, $update) {
-    if (isset($entity->parent)) {
+    // Only change the parents if a value is set, keep the existing values if
+    // not.
+    if (isset($entity->parent->value)) {
       db_delete('taxonomy_term_hierarchy')
-        ->condition('tid', $entity->tid)
+        ->condition('tid', $entity->id())
         ->execute();
 
       $query = db_insert('taxonomy_term_hierarchy')
@@ -88,8 +90,8 @@ protected function postSave(EntityInterface $entity, $update) {
 
       foreach ($entity->parent as $parent) {
         $query->values(array(
-          'tid' => $entity->tid,
-          'parent' => $parent
+          'tid' => $entity->id(),
+          'parent' => (int) $parent->value,
         ));
       }
       $query->execute();
@@ -109,4 +111,60 @@ public function resetCache(array $ids = NULL) {
     drupal_static_reset('taxonomy_term_load_children');
     parent::resetCache($ids);
   }
+
+  /**
+   * Overrides \Drupal\Core\Entity\DatabaseStorageControllerNG::baseFieldDefintions().
+   */
+  public function baseFieldDefinitions() {
+    $properties['tid'] = array(
+      'label' => t('Term ID'),
+      'description' => t('The term ID.'),
+      'type' => 'integer_field',
+      'read-only' => TRUE,
+    );
+    $properties['uuid'] = array(
+      'label' => t('UUID'),
+      'description' => t('The term UUID.'),
+      'type' => 'string_field',
+      'read-only' => TRUE,
+    );
+    $properties['vid'] = array(
+      'label' => t('Vocabulary ID'),
+      'description' => t('The ID of the vocabulary to which the term is assigned.'),
+      'type' => 'string_field',
+    );
+    $properties['langcode'] = array(
+      'label' => t('Language code'),
+      'description' => t('The term language code.'),
+      'type' => 'language_field',
+    );
+    $properties['name'] = array(
+      'label' => t('Name'),
+      'description' => t('The term name.'),
+      'type' => 'string_field',
+    );
+    $properties['description'] = array(
+      'label' => t('Description'),
+      'description' => t('A description of the term'),
+      'type' => 'string_field',
+    );
+    // @todo Combine with description.
+    $properties['format'] = array(
+      'label' => t('Description format'),
+      'description' => t('The filter format ID of the description.'),
+      'type' => 'string_field',
+    );
+    $properties['weight'] = array(
+      'label' => t('Weight'),
+      'description' => t('The weight of this term in relation to other terms.'),
+      'type' => 'integer_field',
+    );
+    $properties['parent'] = array(
+      'label' => t('Term Parents'),
+      'description' => t('The parents of this term.'),
+      'type' => 'integer_field',
+      'computed' => TRUE,
+    );
+    return $properties;
+  }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
index ab36a799e008..0d4fcc58e96d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
@@ -8,12 +8,12 @@
 namespace Drupal\taxonomy;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\translation_entity\EntityTranslationController;
+use Drupal\translation_entity\EntityTranslationControllerNG;
 
 /**
  * Defines the translation controller class for terms.
  */
-class TermTranslationController extends EntityTranslationController {
+class TermTranslationController extends EntityTranslationControllerNG {
 
   /**
    * Overrides EntityTranslationController::entityFormAlter().
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/EfqTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/EfqTest.php
index b3ce285e7935..bc219ee42152 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/EfqTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/EfqTest.php
@@ -35,7 +35,7 @@ function testTaxonomyEfq() {
     $terms = array();
     for ($i = 0; $i < 5; $i++) {
       $term = $this->createTerm($this->vocabulary);
-      $terms[$term->tid] = $term;
+      $terms[$term->id()] = $term;
     }
     $result = \Drupal::entityQuery('taxonomy_term')->execute();
     sort($result);
@@ -47,14 +47,14 @@ function testTaxonomyEfq() {
       'bundle' => $this->vocabulary->id(),
     );
     $term = _field_create_entity_from_ids($ids);
-    $this->assertEqual($term->tid, $tid, 'Taxonomy term can be created based on the IDs');
+    $this->assertEqual($term->id(), $tid, 'Taxonomy term can be created based on the IDs');
 
     // Create a second vocabulary and five more terms.
     $vocabulary2 = $this->createVocabulary();
     $terms2 = array();
     for ($i = 0; $i < 5; $i++) {
       $term = $this->createTerm($vocabulary2);
-      $terms2[$term->tid] = $term;
+      $terms2[$term->id()] = $term;
     }
 
     $result = \Drupal::entityQuery('taxonomy_term')
@@ -69,6 +69,6 @@ function testTaxonomyEfq() {
       'bundle' => $vocabulary2->id(),
     );
     $term = _field_create_entity_from_ids($ids);
-    $this->assertEqual($term->tid, $tid, 'Taxonomy term can be created based on the IDs');
+    $this->assertEqual($term->id(), $tid, 'Taxonomy term can be created based on the IDs');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/HooksTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/HooksTest.php
index edddd1aae64c..88d7871aadcf 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/HooksTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/HooksTest.php
@@ -53,29 +53,29 @@ function testTaxonomyTermHooks() {
     $this->drupalPost('admin/structure/taxonomy/' . $vocabulary->id() . '/add', $edit, t('Save'));
     $terms = taxonomy_term_load_multiple_by_name($edit['name']);
     $term = reset($terms);
-    $this->assertEqual($term->antonym, $edit['antonym'], 'Antonym was loaded into the term object.');
+    $this->assertEqual($term->antonym->value, $edit['antonym'], 'Antonym was loaded into the term object.');
 
     // Update the term with a different antonym.
     $edit = array(
       'name' => $this->randomName(),
       'antonym' => 'Short',
     );
-    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
+    $this->drupalPost('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save'));
     taxonomy_terms_static_reset();
-    $term = taxonomy_term_load($term->tid);
-    $this->assertEqual($edit['antonym'], $term->antonym, 'Antonym was successfully edited.');
+    $term = taxonomy_term_load($term->id());
+    $this->assertEqual($edit['antonym'], $term->antonym->value, 'Antonym was successfully edited.');
 
     // View the term and ensure that hook_taxonomy_term_view() and
     // hook_entity_view() are invoked.
-    $term = taxonomy_term_load($term->tid);
+    $term = taxonomy_term_load($term->id());
     module_load_include('inc', 'taxonomy', 'taxonomy.pages');
     $term_build = taxonomy_term_page($term);
-    $this->assertFalse(empty($term_build['taxonomy_terms'][$term->tid]['taxonomy_test_term_view_check']), 'hook_taxonomy_term_view() was invoked when viewing the term.');
-    $this->assertFalse(empty($term_build['taxonomy_terms'][$term->tid]['taxonomy_test_entity_view_check']), 'hook_entity_view() was invoked when viewing the term.');
+    $this->assertFalse(empty($term_build['taxonomy_terms'][$term->id()]['taxonomy_test_term_view_check']), 'hook_taxonomy_term_view() was invoked when viewing the term.');
+    $this->assertFalse(empty($term_build['taxonomy_terms'][$term->id()]['taxonomy_test_entity_view_check']), 'hook_entity_view() was invoked when viewing the term.');
 
     // Delete the term.
-    taxonomy_term_delete($term->tid);
-    $antonym = db_query('SELECT tid FROM {taxonomy_term_antonym} WHERE tid = :tid', array(':tid' => $term->tid))->fetchField();
+    $term->delete();
+    $antonym = db_query('SELECT tid FROM {taxonomy_term_antonym} WHERE tid = :tid', array(':tid' => $term->id()))->fetchField();
     $this->assertFalse($antonym, 'The antonym were deleted from the database.');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LoadMultipleTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LoadMultipleTest.php
index d05f033aeddb..501c26cadc0b 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LoadMultipleTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LoadMultipleTest.php
@@ -52,20 +52,20 @@ function testTaxonomyTermMultipleLoad() {
 
     // Remove one term from the array, then delete it.
     $deleted = array_shift($terms2);
-    taxonomy_term_delete($deleted->tid);
-    $deleted_term = taxonomy_term_load($deleted->tid);
+    $deleted->delete();
+    $deleted_term = taxonomy_term_load($deleted->id());
     $this->assertFalse($deleted_term);
 
     // Load terms from the vocabulary by vid.
     $terms3 = entity_load_multiple_by_properties('taxonomy_term', array('vid' => $vocabulary->id()));
     $this->assertEqual(count($terms3), 4, 'Correct number of terms were loaded.');
-    $this->assertFalse(isset($terms3[$deleted->tid]));
+    $this->assertFalse(isset($terms3[$deleted->id()]));
 
     // Create a single term and load it by name.
     $term = $this->createTerm($vocabulary);
-    $loaded_terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $term->name));
+    $loaded_terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => $term->name->value));
     $this->assertEqual(count($loaded_terms), 1, 'One term was loaded.');
     $loaded_term = reset($loaded_terms);
-    $this->assertEqual($term->tid, $loaded_term->tid, 'Term loaded by name successfully.');
+    $this->assertEqual($term->id(), $loaded_term->id(), 'Term loaded by name successfully.');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
index 4c3e3d32bbd2..ca775e9b31ac 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -92,22 +92,22 @@ function testTaxonomyRss() {
     $edit = array();
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $edit["title"] = $this->randomName();
-    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->tid;
+    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->id();
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when the RSS feed is viewed.
     $this->drupalGet('rss.xml');
     $test_element = array(
       'key' => 'category',
-      'value' => $term1->name,
+      'value' => $term1->name->value,
       'attributes' => array(
-        'domain' => url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE)),
+        'domain' => url('taxonomy/term/' . $term1->id(), array('absolute' => TRUE)),
       ),
     );
     $this->assertRaw(format_xml_elements(array($test_element)), 'Term is displayed when viewing the rss feed.');
 
     // Test that the feed page exists for the term.
-    $this->drupalGet("taxonomy/term/{$term1->tid}/feed");
+    $this->drupalGet("taxonomy/term/{$term1->id()}/feed");
     $this->assertRaw('<rss version="2.0"', "Feed page is RSS.");
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
index ea9bc3eb2419..abb5893e830a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
@@ -80,15 +80,15 @@ public function testTaxonomyTermReferenceItem() {
     $tid = $this->term->id();
     // Just being able to create the entity like this verifies a lot of code.
     $entity = entity_create('entity_test', array());
-    $entity->field_test_taxonomy->tid = $this->term->tid;
+    $entity->field_test_taxonomy->tid = $this->term->id();
     $entity->name->value = $this->randomName();
     $entity->save();
 
     $entity = entity_load('entity_test', $entity->id());
     $this->assertTrue($entity->field_test_taxonomy instanceof FieldInterface, 'Field implements interface.');
     $this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.');
-    $this->assertEqual($entity->field_test_taxonomy->tid, $this->term->tid);
-    $this->assertEqual($entity->field_test_taxonomy->entity->name, $this->term->name);
+    $this->assertEqual($entity->field_test_taxonomy->tid, $this->term->id());
+    $this->assertEqual($entity->field_test_taxonomy->entity->name->value, $this->term->name->value);
     $this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid);
     $this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid());
 
@@ -98,19 +98,19 @@ public function testTaxonomyTermReferenceItem() {
     $entity->field_test_taxonomy->entity->save();
     // Verify it is the correct name.
     $term = entity_load('taxonomy_term', $tid);
-    $this->assertEqual($term->name, $new_name);
+    $this->assertEqual($term->name->value, $new_name);
 
     // Make sure the computed term reflects updates to the term id.
     $term2 = entity_create('taxonomy_term', array(
       'name' => $this->randomName(),
-      'vid' => $this->term->vid,
+      'vid' => $this->term->vid->value,
       'langcode' => LANGUAGE_NOT_SPECIFIED,
     ));
     $term2->save();
 
-    $entity->field_test_taxonomy->tid = $term2->tid;
-    $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->tid);
-    $this->assertEqual($entity->field_test_taxonomy->entity->name, $term2->name);
+    $entity->field_test_taxonomy->tid = $term2->id();
+    $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id());
+    $this->assertEqual($entity->field_test_taxonomy->entity->name->value, $term2->name->value);
   }
 
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
index 8c5571ca8880..4f71f5383e02 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldMultipleVocabularyTest.php
@@ -88,7 +88,7 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     $this->drupalGet('test-entity/add/test_bundle');
     $this->assertFieldByName("{$this->field_name}[$langcode][]", '', 'Widget is displayed');
     $edit = array(
-      "{$this->field_name}[$langcode][]" => array($term1->tid, $term2->tid),
+      "{$this->field_name}[$langcode][]" => array($term1->id(), $term2->id()),
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
@@ -102,8 +102,8 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     field_attach_prepare_view('test_entity', $entities, array($entity->bundle() => $display));
     $entity->content = field_attach_view($entity, $display);
     $this->content = drupal_render($entity->content);
-    $this->assertText($term1->name, 'Term 1 name is displayed.');
-    $this->assertText($term2->name, 'Term 2 name is displayed.');
+    $this->assertText($term1->label(), 'Term 1 name is displayed.');
+    $this->assertText($term2->label(), 'Term 2 name is displayed.');
 
     // Delete vocabulary 2.
     taxonomy_vocabulary_delete($this->vocabulary2->id());
@@ -118,8 +118,8 @@ function testTaxonomyTermFieldMultipleVocabularies() {
     $this->content = drupal_render($entity->content);
 
     // Term 1 should still be displayed; term 2 should not be.
-    $this->assertText($term1->name, 'Term 1 name is displayed.');
-    $this->assertNoText($term2->name, 'Term 2 name is not displayed.');
+    $this->assertText($term1->label(), 'Term 1 name is displayed.');
+    $this->assertNoText($term2->label(), 'Term 2 name is not displayed.');
 
     // Verify that field and instance settings are correct.
     $field_info = field_info_field($this->field_name);
@@ -131,7 +131,7 @@ function testTaxonomyTermFieldMultipleVocabularies() {
 
     // Term 1 should still pass validation.
     $edit = array(
-      "{$this->field_name}[$langcode][]" => array($term1->tid),
+      "{$this->field_name}[$langcode][]" => array($term1->id()),
     );
     $this->drupalPost(NULL, $edit, t('Save'));
   }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
index d5de5fa5afb9..363d3269dabb 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermFieldTest.php
@@ -78,7 +78,7 @@ function testTaxonomyTermFieldValidation() {
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $entity = field_test_create_entity();
     $term = $this->createTerm($this->vocabulary);
-    $entity->{$this->field_name}[$langcode][0]['tid'] = $term->tid;
+    $entity->{$this->field_name}[$langcode][0]['tid'] = $term->id();
     try {
       field_attach_validate($entity);
       $this->pass('Correct term does not cause validation error.');
@@ -89,7 +89,7 @@ function testTaxonomyTermFieldValidation() {
 
     $entity = field_test_create_entity();
     $bad_term = $this->createTerm($this->createVocabulary());
-    $entity->{$this->field_name}[$langcode][0]['tid'] = $bad_term->tid;
+    $entity->{$this->field_name}[$langcode][0]['tid'] = $bad_term->id();
     try {
       field_attach_validate($entity);
       $this->fail('Wrong term causes validation error.');
@@ -113,7 +113,7 @@ function testTaxonomyTermFieldWidgets() {
 
     // Submit with some value.
     $edit = array(
-      "{$this->field_name}[$langcode]" => array($term->tid),
+      "{$this->field_name}[$langcode]" => array($term->id()),
     );
     $this->drupalPost(NULL, $edit, t('Save'));
     preg_match('|test-entity/manage/(\d+)/edit|', $this->url, $match);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index f9cba0da262a..237f4b42359c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -104,47 +104,47 @@ function testTaxonomyIndex() {
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $edit["title"] = $this->randomName();
     $edit["body[$langcode][0][value]"] = $this->randomName();
-    $edit["{$this->field_name_1}[$langcode][]"] = $term_1->tid;
-    $edit["{$this->field_name_2}[$langcode][]"] = $term_1->tid;
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_1->id();
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_1->id();
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is indexed, and only once.
     $node = $this->drupalGetNodeByTitle($edit["title"]);
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
 
     // Update the article to change one term.
-    $edit["{$this->field_name_1}[$langcode][]"] = $term_2->tid;
+    $edit["{$this->field_name_1}[$langcode][]"] = $term_2->id();
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     // Check that both terms are indexed.
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_2->tid,
+      ':tid' => $term_2->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
 
     // Update the article to change another term.
-    $edit["{$this->field_name_2}[$langcode][]"] = $term_2->tid;
+    $edit["{$this->field_name_2}[$langcode][]"] = $term_2->id();
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     // Check that only one term is indexed.
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_2->tid,
+      ':tid' => $term_2->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
 
@@ -159,44 +159,44 @@ function testTaxonomyIndex() {
     // Check that the index was not changed.
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_2->tid,
+      ':tid' => $term_2->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
 
     // Update the article to change one term.
-    $node->{$this->field_name_1}[$langcode] = array(array('tid' => $term_1->tid));
+    $node->{$this->field_name_1}[$langcode] = array(array('tid' => $term_1->id()));
     $node->save();
 
     // Check that both terms are indexed.
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_2->tid,
+      ':tid' => $term_2->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
 
     // Update the article to change another term.
-    $node->{$this->field_name_2}[$langcode] = array(array('tid' => $term_1->tid));
+    $node->{$this->field_name_2}[$langcode] = array(array('tid' => $term_1->id()));
     $node->save();
 
     // Check that only one term is indexed.
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_1->tid,
+      ':tid' => $term_1->id(),
     ))->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->nid,
-      ':tid' => $term_2->tid,
+      ':tid' => $term_2->id(),
     ))->fetchField();
     $this->assertEqual(0, $index_count, 'Term 2 is not indexed.');
   }
@@ -208,11 +208,11 @@ function testTaxonomyTermHierarchyBreadcrumbs() {
     // Create two taxonomy terms and set term2 as the parent of term1.
     $term1 = $this->createTerm($this->vocabulary);
     $term2 = $this->createTerm($this->vocabulary);
-    $term1->parent = array($term2->tid);
+    $term1->parent = array($term2->id());
     taxonomy_term_save($term1);
 
     // Verify that the page breadcrumbs include a link to the parent term.
-    $this->drupalGet('taxonomy/term/' . $term1->tid);
-    $this->assertRaw(l($term2->name, 'taxonomy/term/' . $term2->tid), 'Parent term link is displayed when viewing the node.');
+    $this->drupalGet('taxonomy/term/' . $term1->id());
+    $this->assertRaw(l($term2->label(), 'taxonomy/term/' . $term2->id()), 'Parent term link is displayed when viewing the node.');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
index e2729dddefad..9bbc5a74e823 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermLanguageTest.php
@@ -63,18 +63,18 @@ function testTermLanguage() {
     $this->drupalPost(NULL, $edit, t('Save'));
     $terms = taxonomy_term_load_multiple_by_name($edit['name']);
     $term = reset($terms);
-    $this->assertEqual($term->langcode, $edit['langcode']);
+    $this->assertEqual($term->language()->langcode, $edit['langcode']);
 
     // Check if on the edit page the language is correct.
-    $this->drupalGet('taxonomy/term/' . $term->tid . '/edit');
+    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertOptionSelected('edit-langcode', $edit['langcode'], t('The term language was correctly selected.'));
 
     // Change the language of the term.
     $edit['langcode'] = 'bb';
-    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
+    $this->drupalPost('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save'));
 
     // Check again that on the edit page the language is correct.
-    $this->drupalGet('taxonomy/term/' . $term->tid . '/edit');
+    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertOptionSelected('edit-langcode', $edit['langcode'], t('The term language was correctly selected.'));
   }
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 6b8cff330086..705ff6006ea0 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -71,27 +71,27 @@ function testTaxonomyTermHierarchy() {
 
     // Edit $term2, setting $term1 as parent.
     $edit = array();
-    $edit['parent[]'] = array($term1->tid);
-    $this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
+    $edit['parent[]'] = array($term1->id());
+    $this->drupalPost('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save'));
 
     // Check the hierarchy.
-    $children = taxonomy_term_load_children($term1->tid);
-    $parents = taxonomy_term_load_parents($term2->tid);
-    $this->assertTrue(isset($children[$term2->tid]), 'Child found correctly.');
-    $this->assertTrue(isset($parents[$term1->tid]), 'Parent found correctly.');
+    $children = taxonomy_term_load_children($term1->id());
+    $parents = taxonomy_term_load_parents($term2->id());
+    $this->assertTrue(isset($children[$term2->id()]), 'Child found correctly.');
+    $this->assertTrue(isset($parents[$term1->id()]), 'Parent found correctly.');
 
     // Load and save a term, confirming that parents are still set.
-    $term = taxonomy_term_load($term2->tid);
+    $term = taxonomy_term_load($term2->id());
     taxonomy_term_save($term);
-    $parents = taxonomy_term_load_parents($term2->tid);
-    $this->assertTrue(isset($parents[$term1->tid]), 'Parent found correctly.');
+    $parents = taxonomy_term_load_parents($term2->id());
+    $this->assertTrue(isset($parents[$term1->id()]), 'Parent found correctly.');
 
     // Create a third term and save this as a parent of term2.
     $term3 = $this->createTerm($this->vocabulary);
-    $term2->parent = array($term1->tid, $term3->tid);
+    $term2->parent = array($term1->id(), $term3->id());
     taxonomy_term_save($term2);
-    $parents = taxonomy_term_load_parents($term2->tid);
-    $this->assertTrue(isset($parents[$term1->tid]) && isset($parents[$term3->tid]), 'Both parents found successfully.');
+    $parents = taxonomy_term_load_parents($term2->id());
+    $this->assertTrue(isset($parents[$term1->id()]) && isset($parents[$term3->id()]), 'Both parents found successfully.');
   }
 
   /**
@@ -109,31 +109,31 @@ function testTaxonomyNode() {
     $langcode = LANGUAGE_NOT_SPECIFIED;
     $edit["title"] = $this->randomName();
     $edit["body[$langcode][0][value]"] = $this->randomName();
-    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->tid;
+    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term1->id();
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when the node is viewed.
     $node = $this->drupalGetNodeByTitle($edit["title"]);
     $this->drupalGet('node/' . $node->nid);
-    $this->assertText($term1->name, 'Term is displayed when viewing the node.');
+    $this->assertText($term1->label(), 'Term is displayed when viewing the node.');
 
     $this->clickLink(t('Edit'));
-    $this->assertText($term1->name, 'Term is displayed when editing the node.');
+    $this->assertText($term1->label(), 'Term is displayed when editing the node.');
     $this->drupalPost(NULL, array(), t('Save'));
-    $this->assertText($term1->name, 'Term is displayed after saving the node with no changes.');
+    $this->assertText($term1->label(), 'Term is displayed after saving the node with no changes.');
 
     // Edit the node with a different term.
-    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->tid;
+    $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->id();
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     $this->drupalGet('node/' . $node->nid);
-    $this->assertText($term2->name, 'Term is displayed when viewing the node.');
+    $this->assertText($term2->label(), 'Term is displayed when viewing the node.');
 
     // Preview the node.
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Preview'));
-    $this->assertNoUniqueText($term2->name, 'Term is displayed when previewing the node.');
+    $this->assertNoUniqueText($term2->label(), 'Term is displayed when previewing the node.');
     $this->drupalPost(NULL, NULL, t('Preview'));
-    $this->assertNoUniqueText($term2->name, 'Term is displayed when previewing the node again.');
+    $this->assertNoUniqueText($term2->label(), 'Term is displayed when previewing the node again.');
   }
 
   /**
@@ -194,34 +194,34 @@ function testNodeTermCreationAndDeletion() {
     }
 
     // Delete term 1 from the term edit page.
-    $this->drupalPost('taxonomy/term/' . $term_objects['term1']->tid . '/edit', array(), t('Delete'));
+    $this->drupalPost('taxonomy/term/' . $term_objects['term1']->id() . '/edit', array(), t('Delete'));
     $this->drupalPost(NULL, NULL, t('Delete'));
 
     // Delete term 2 from the term delete page.
-    $this->drupalPost('taxonomy/term/' . $term_objects['term2']->tid . '/delete', array(), t('Delete'));
-    $term_names = array($term_objects['term3']->name, $term_objects['term4']->name);
+    $this->drupalPost('taxonomy/term/' . $term_objects['term2']->id() . '/delete', array(), t('Delete'));
+    $term_names = array($term_objects['term3']->label(), $term_objects['term4']->label());
 
     // Get the node.
     $node = $this->drupalGetNodeByTitle($edit["title"]);
     $this->drupalGet('node/' . $node->nid);
 
     foreach ($term_names as $term_name) {
-      $this->assertText($term_name, format_string('The term %name appears on the node page after two terms, %deleted1 and %deleted2, were deleted', array('%name' => $term_name, '%deleted1' => $term_objects['term1']->name, '%deleted2' => $term_objects['term2']->name)));
+      $this->assertText($term_name, format_string('The term %name appears on the node page after two terms, %deleted1 and %deleted2, were deleted', array('%name' => $term_name, '%deleted1' => $term_objects['term1']->label(), '%deleted2' => $term_objects['term2']->label())));
     }
-    $this->assertNoText($term_objects['term1']->name, format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->name)));
-    $this->assertNoText($term_objects['term2']->name, format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term2']->name)));
+    $this->assertNoText($term_objects['term1']->label(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term1']->label())));
+    $this->assertNoText($term_objects['term2']->label(), format_string('The deleted term %name does not appear on the node page.', array('%name' => $term_objects['term2']->label())));
 
     // Test autocomplete on term 3, which contains a comma.
     // The term will be quoted, and the " will be encoded in unicode (\u0022).
-    $input = substr($term_objects['term3']->name, 0, 3);
+    $input = substr($term_objects['term3']->label(), 0, 3);
     $json = $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->id(), array('query' => array('q' => $input)));
-    $this->assertEqual($json, '{"\u0022' . $term_objects['term3']->name . '\u0022":"' . $term_objects['term3']->name . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term3']->name)));
+    $this->assertEqual($json, '{"\u0022' . $term_objects['term3']->label() . '\u0022":"' . $term_objects['term3']->label() . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term3']->label())));
 
     // Test autocomplete on term 4 - it is alphanumeric only, so no extra
     // quoting.
-    $input = substr($term_objects['term4']->name, 0, 3);
+    $input = substr($term_objects['term4']->label(), 0, 3);
     $this->drupalGet('taxonomy/autocomplete/taxonomy_' . $this->vocabulary->id(), array('query' => array('q' => $input)));
-    $this->assertRaw('{"' . $term_objects['term4']->name . '":"' . $term_objects['term4']->name . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term4']->name)));
+    $this->assertRaw('{"' . $term_objects['term4']->label() . '":"' . $term_objects['term4']->label() . '"}', format_string('Autocomplete returns term %term_name after typing the first 3 letters.', array('%term_name' => $term_objects['term4']->label())));
 
     // Test taxonomy autocomplete with a nonexistent field.
     $field_name = $this->randomName();
@@ -256,27 +256,27 @@ function testTermAutocompletion() {
     // The result order is not guaranteed, so check each term separately.
     $result = $this->drupalGet($path, array('query' => array('q' => $input)));
     $data = drupal_json_decode($result);
-    $this->assertEqual($data[$first_term->name], check_plain($first_term->name), 'Autocomplete returned the first matching term');
-    $this->assertEqual($data[$second_term->name], check_plain($second_term->name), 'Autocomplete returned the second matching term');
+    $this->assertEqual($data[$first_term->label()], check_plain($first_term->label()), 'Autocomplete returned the first matching term');
+    $this->assertEqual($data[$second_term->label()], check_plain($second_term->label()), 'Autocomplete returned the second matching term');
 
     // Try to autocomplete a term name that matches first term.
     // We should only get the first term in a json encoded string.
     $input = '10/16';
     $path = 'taxonomy/autocomplete/taxonomy_' . $this->vocabulary->id();
     $this->drupalGet($path, array('query' => array('q' => $input)));
-    $target = array($first_term->name => check_plain($first_term->name));
+    $target = array($first_term->label() => check_plain($first_term->label()));
     $this->assertRaw(drupal_json_encode($target), 'Autocomplete returns only the expected matching term.');
 
     // Try to autocomplete a term name with both a comma and a slash.
     $input = '"term with, comma and / a';
     $path = 'taxonomy/autocomplete/taxonomy_' . $this->vocabulary->id();
     $this->drupalGet($path, array('query' => array('q' => $input)));
-    $n = $third_term->name;
+    $n = $third_term->label();
     // Term names containing commas or quotes must be wrapped in quotes.
-    if (strpos($third_term->name, ',') !== FALSE || strpos($third_term->name, '"') !== FALSE) {
-      $n = '"' . str_replace('"', '""', $third_term->name) . '"';
+    if (strpos($third_term->label(), ',') !== FALSE || strpos($third_term->label(), '"') !== FALSE) {
+      $n = '"' . str_replace('"', '""', $third_term->label()) . '"';
     }
-    $target = array($n => check_plain($third_term->name));
+    $target = array($n => check_plain($third_term->label()));
     $this->assertRaw(drupal_json_encode($target), 'Autocomplete returns a term containing a comma and a slash.');
   }
 
@@ -316,7 +316,7 @@ function testTermInterface() {
     );
 
     // Edit the term.
-    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', $edit, t('Save'));
+    $this->drupalPost('taxonomy/term/' . $term->id() . '/edit', $edit, t('Save'));
 
     // Check that the term is still present at admin UI after edit.
     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->id());
@@ -324,7 +324,7 @@ function testTermInterface() {
     $this->assertLink(t('edit'));
 
     // View the term and check that it is correct.
-    $this->drupalGet('taxonomy/term/' . $term->tid);
+    $this->drupalGet('taxonomy/term/' . $term->id());
     $this->assertText($edit['name'], 'The randomly generated term name is present.');
     $this->assertText($edit['description[value]'], 'The randomly generated term description is present.');
 
@@ -333,22 +333,22 @@ function testTermInterface() {
     // Check that it does NOT show a description when description is blank.
     $term->description = '';
     taxonomy_term_save($term);
-    $this->drupalGet('taxonomy/term/' . $term->tid);
+    $this->drupalGet('taxonomy/term/' . $term->id());
     $this->assertNoPattern('|class="taxonomy-term-description"|', 'Term page did not display the term description when description was blank.');
 
     // Check that the term feed page is working.
-    $this->drupalGet('taxonomy/term/' . $term->tid . '/feed');
+    $this->drupalGet('taxonomy/term/' . $term->id() . '/feed');
 
     // Check that the term edit page does not try to interpret additional path
     // components as arguments for taxonomy_term_form().
-    $this->drupalGet('taxonomy/term/' . $term->tid . '/edit/' . $this->randomName());
+    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit/' . $this->randomName());
 
     // Delete the term.
-    $this->drupalPost('taxonomy/term/' . $term->tid . '/edit', array(), t('Delete'));
+    $this->drupalPost('taxonomy/term/' . $term->id() . '/edit', array(), t('Delete'));
     $this->drupalPost(NULL, NULL, t('Delete'));
 
     // Assert that the term no longer exists.
-    $this->drupalGet('taxonomy/term/' . $term->tid);
+    $this->drupalGet('taxonomy/term/' . $term->id());
     $this->assertResponse(404, 'The taxonomy term page was not found.');
   }
 
@@ -365,7 +365,7 @@ function testTermReorder() {
     drupal_static_reset('taxonomy_get_tree');
     drupal_static_reset('taxonomy_get_treeparent');
     drupal_static_reset('taxonomy_get_treeterms');
-    list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->id());
+    list($term1, $term2, $term3) = taxonomy_get_tree($this->vocabulary->id(), 0, NULL, TRUE);
 
     $this->drupalGet('admin/structure/taxonomy/' . $this->vocabulary->id());
 
@@ -374,18 +374,18 @@ function testTermReorder() {
     // term3, term1 by setting weight property, make term3 a child of term2 by
     // setting the parent and depth properties, and update all hidden fields.
     $edit = array(
-      'terms[tid:' . $term2->tid . ':0][term][tid]' => $term2->tid,
-      'terms[tid:' . $term2->tid . ':0][term][parent]' => 0,
-      'terms[tid:' . $term2->tid . ':0][term][depth]' => 0,
-      'terms[tid:' . $term2->tid . ':0][weight]' => 0,
-      'terms[tid:' . $term3->tid . ':0][term][tid]' => $term3->tid,
-      'terms[tid:' . $term3->tid . ':0][term][parent]' => $term2->tid,
-      'terms[tid:' . $term3->tid . ':0][term][depth]' => 1,
-      'terms[tid:' . $term3->tid . ':0][weight]' => 1,
-      'terms[tid:' . $term1->tid . ':0][term][tid]' => $term1->tid,
-      'terms[tid:' . $term1->tid . ':0][term][parent]' => 0,
-      'terms[tid:' . $term1->tid . ':0][term][depth]' => 0,
-      'terms[tid:' . $term1->tid . ':0][weight]' => 2,
+      'terms[tid:' . $term2->id() . ':0][term][tid]' => $term2->id(),
+      'terms[tid:' . $term2->id() . ':0][term][parent]' => 0,
+      'terms[tid:' . $term2->id() . ':0][term][depth]' => 0,
+      'terms[tid:' . $term2->id() . ':0][weight]' => 0,
+      'terms[tid:' . $term3->id() . ':0][term][tid]' => $term3->id(),
+      'terms[tid:' . $term3->id() . ':0][term][parent]' => $term2->id(),
+      'terms[tid:' . $term3->id() . ':0][term][depth]' => 1,
+      'terms[tid:' . $term3->id() . ':0][weight]' => 1,
+      'terms[tid:' . $term1->id() . ':0][term][tid]' => $term1->id(),
+      'terms[tid:' . $term1->id() . ':0][term][parent]' => 0,
+      'terms[tid:' . $term1->id() . ':0][term][depth]' => 0,
+      'terms[tid:' . $term1->id() . ':0][weight]' => 2,
     );
     $this->drupalPost(NULL, $edit, t('Save'));
 
@@ -393,9 +393,9 @@ function testTermReorder() {
     drupal_static_reset('taxonomy_get_treeparent');
     drupal_static_reset('taxonomy_get_treeterms');
     $terms = taxonomy_get_tree($this->vocabulary->id());
-    $this->assertEqual($terms[0]->tid, $term2->tid, 'Term 2 was moved above term 1.');
-    $this->assertEqual($terms[1]->parents, array($term2->tid), 'Term 3 was made a child of term 2.');
-    $this->assertEqual($terms[2]->tid, $term1->tid, 'Term 1 was moved below term 2.');
+    $this->assertEqual($terms[0]->tid, $term2->id(), 'Term 2 was moved above term 1.');
+    $this->assertEqual($terms[1]->parents, array($term2->id()), 'Term 3 was made a child of term 2.');
+    $this->assertEqual($terms[2]->tid, $term1->id(), 'Term 1 was moved below term 2.');
 
     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->id(), array(), t('Reset to alphabetical'));
     // Submit confirmation form.
@@ -404,11 +404,11 @@ function testTermReorder() {
     drupal_static_reset('taxonomy_get_tree');
     drupal_static_reset('taxonomy_get_treeparent');
     drupal_static_reset('taxonomy_get_treeterms');
-    $terms = taxonomy_get_tree($this->vocabulary->id());
-    $this->assertEqual($terms[0]->tid, $term1->tid, 'Term 1 was moved to back above term 2.');
-    $this->assertEqual($terms[1]->tid, $term2->tid, 'Term 2 was moved to back below term 1.');
-    $this->assertEqual($terms[2]->tid, $term3->tid, 'Term 3 is still below term 2.');
-    $this->assertEqual($terms[2]->parents, array($term2->tid), 'Term 3 is still a child of term 2.' . var_export($terms[1]->tid, 1));
+    $terms = taxonomy_get_tree($this->vocabulary->id(), 0, NULL, TRUE);
+    $this->assertEqual($terms[0]->id(), $term1->id(), 'Term 1 was moved to back above term 2.');
+    $this->assertEqual($terms[1]->id(), $term2->id(), 'Term 2 was moved to back below term 1.');
+    $this->assertEqual($terms[2]->id(), $term3->id(), 'Term 3 is still below term 2.');
+    $this->assertEqual($terms[2]->parents, array($term2->id()), 'Term 3 is still a child of term 2.' . var_export($terms[1]->id(), 1));
   }
 
   /**
@@ -422,7 +422,7 @@ function testTermMultipleParentsInterface() {
     $edit = array(
       'name' => $this->randomName(12),
       'description[value]' => $this->randomName(100),
-      'parent[]' => array(0, $parent->tid),
+      'parent[]' => array(0, $parent->id()),
     );
     // Save the new term.
     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->id() . '/add', $edit, t('Save'));
@@ -431,13 +431,13 @@ function testTermMultipleParentsInterface() {
     $terms = taxonomy_term_load_multiple_by_name($edit['name']);
     $term = reset($terms);
     $this->assertNotNull($term, 'Term found in database.');
-    $this->assertEqual($edit['name'], $term->name, 'Term name was successfully saved.');
-    $this->assertEqual($edit['description[value]'], $term->description, 'Term description was successfully saved.');
+    $this->assertEqual($edit['name'], $term->label(), 'Term name was successfully saved.');
+    $this->assertEqual($edit['description[value]'], $term->description->value, 'Term description was successfully saved.');
     // Check that the parent tid is still there. The other parent (<root>) is
     // not added by taxonomy_term_load_parents().
-    $parents = taxonomy_term_load_parents($term->tid);
+    $parents = taxonomy_term_load_parents($term->id());
     $parent = reset($parents);
-    $this->assertEqual($edit['parent[]'][1], $parent->tid, 'Term parents were successfully saved.');
+    $this->assertEqual($edit['parent[]'][1], $parent->id(), 'Term parents were successfully saved.');
   }
 
   /**
@@ -447,56 +447,56 @@ function testTaxonomyGetTermByName() {
     $term = $this->createTerm($this->vocabulary);
 
     // Load the term with the exact name.
-    $terms = taxonomy_term_load_multiple_by_name($term->name);
-    $this->assertTrue(isset($terms[$term->tid]), 'Term loaded using exact name.');
+    $terms = taxonomy_term_load_multiple_by_name($term->label());
+    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded using exact name.');
 
     // Load the term with space concatenated.
-    $terms = taxonomy_term_load_multiple_by_name('  ' . $term->name . '   ');
-    $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with extra whitespace.');
+    $terms = taxonomy_term_load_multiple_by_name('  ' . $term->label() . '   ');
+    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with extra whitespace.');
 
     // Load the term with name uppercased.
-    $terms = taxonomy_term_load_multiple_by_name(strtoupper($term->name));
-    $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with uppercased name.');
+    $terms = taxonomy_term_load_multiple_by_name(strtoupper($term->label()));
+    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with uppercased name.');
 
     // Load the term with name lowercased.
-    $terms = taxonomy_term_load_multiple_by_name(strtolower($term->name));
-    $this->assertTrue(isset($terms[$term->tid]), 'Term loaded with lowercased name.');
+    $terms = taxonomy_term_load_multiple_by_name(strtolower($term->label()));
+    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded with lowercased name.');
 
     // Try to load an invalid term name.
     $terms = taxonomy_term_load_multiple_by_name('Banana');
     $this->assertFalse($terms);
 
     // Try to load the term using a substring of the name.
-    $terms = taxonomy_term_load_multiple_by_name(drupal_substr($term->name, 2));
+    $terms = taxonomy_term_load_multiple_by_name(drupal_substr($term->label(), 2));
     $this->assertFalse($terms);
 
     // Create a new term in a different vocabulary with the same name.
     $new_vocabulary = $this->createVocabulary();
     $new_term = entity_create('taxonomy_term', array(
-      'name' => $term->name,
+      'name' => $term->label(),
       'vid' => $new_vocabulary->id(),
     ));
     taxonomy_term_save($new_term);
 
     // Load multiple terms with the same name.
-    $terms = taxonomy_term_load_multiple_by_name($term->name);
+    $terms = taxonomy_term_load_multiple_by_name($term->label());
     $this->assertEqual(count($terms), 2, 'Two terms loaded with the same name.');
 
     // Load single term when restricted to one vocabulary.
-    $terms = taxonomy_term_load_multiple_by_name($term->name, $this->vocabulary->id());
+    $terms = taxonomy_term_load_multiple_by_name($term->label(), $this->vocabulary->id());
     $this->assertEqual(count($terms), 1, 'One term loaded when restricted by vocabulary.');
-    $this->assertTrue(isset($terms[$term->tid]), 'Term loaded using exact name and vocabulary machine name.');
+    $this->assertTrue(isset($terms[$term->id()]), 'Term loaded using exact name and vocabulary machine name.');
 
     // Create a new term with another name.
     $term2 = $this->createTerm($this->vocabulary);
 
     // Try to load a term by name that doesn't exist in this vocabulary but
     // exists in another vocabulary.
-    $terms = taxonomy_term_load_multiple_by_name($term2->name, $new_vocabulary->id());
+    $terms = taxonomy_term_load_multiple_by_name($term2->label(), $new_vocabulary->id());
     $this->assertFalse($terms, 'Invalid term name restricted by vocabulary machine name not loaded.');
 
     // Try to load terms filtering by a non-existing vocabulary.
-    $terms = taxonomy_term_load_multiple_by_name($term2->name, 'non_existing_vocabulary');
+    $terms = taxonomy_term_load_multiple_by_name($term2->label(), 'non_existing_vocabulary');
     $this->assertEqual(count($terms), 0, 'No terms loaded when restricted by a non-existing vocabulary.');
   }
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermUnitTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermUnitTest.php
index 86565055be08..166ab86eb661 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermUnitTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermUnitTest.php
@@ -24,7 +24,7 @@ function testTermDelete() {
     $vocabulary = $this->createVocabulary();
     $valid_term = $this->createTerm($vocabulary);
     // Delete a valid term.
-    taxonomy_term_delete($valid_term->tid);
+    taxonomy_term_delete($valid_term->id());
     $terms = entity_load_multiple_by_properties('taxonomy_term', array('vid' => $vocabulary->id()));
     $this->assertTrue(empty($terms), 'Vocabulary is empty after deletion');
 
@@ -44,13 +44,13 @@ function testTaxonomyVocabularyTree() {
     }
 
     // $term[2] is a child of 1 and 5.
-    $term[2]->parent = array($term[1]->tid, $term[5]->tid);
+    $term[2]->parent = array($term[1]->id(), $term[5]->id());
     taxonomy_term_save($term[2]);
     // $term[3] is a child of 2.
-    $term[3]->parent = array($term[2]->tid);
+    $term[3]->parent = array($term[2]->id());
     taxonomy_term_save($term[3]);
     // $term[5] is a child of 4.
-    $term[5]->parent = array($term[4]->tid);
+    $term[5]->parent = array($term[4]->id());
     taxonomy_term_save($term[5]);
 
     /**
@@ -65,7 +65,7 @@ function testTaxonomyVocabularyTree() {
      * ------ term[3] | depth: 3
      */
     // Count $term[1] parents with $max_depth = 1.
-    $tree = taxonomy_get_tree($vocabulary->id(), $term[1]->tid, 1);
+    $tree = taxonomy_get_tree($vocabulary->id(), $term[1]->id(), 1);
     $this->assertEqual(1, count($tree), 'We have one parent with depth 1.');
 
     // Count all vocabulary tree elements.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/ThemeTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/ThemeTest.php
index c14a5626ee49..62e18c6dc9e1 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/ThemeTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/ThemeTest.php
@@ -49,11 +49,11 @@ function testTaxonomyTermThemes() {
 
     // Viewing a taxonomy term should use the default theme.
     $term = $this->createTerm($vocabulary);
-    $this->drupalGet('taxonomy/term/' . $term->tid);
+    $this->drupalGet('taxonomy/term/' . $term->id());
     $this->assertRaw('bartik/css/style.css', t("The default theme's CSS appears on the page for viewing a taxonomy term."));
 
     // Editing a taxonomy term should use the same theme as adding one.
-    $this->drupalGet('taxonomy/term/' . $term->tid . '/edit');
+    $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertRaw('seven/style.css', t("The administrative theme's CSS appears on the page for editing a taxonomy term."));
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index a792aad913d2..0a45dd269deb 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -72,21 +72,21 @@ function testTaxonomyTokenReplacement() {
     // Edit $term2, setting $term1 as parent.
     $edit = array();
     $edit['name'] = '<blink>Blinking Text</blink>';
-    $edit['parent[]'] = array($term1->tid);
-    $this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
+    $edit['parent[]'] = array($term1->id());
+    $this->drupalPost('taxonomy/term/' . $term2->id() . '/edit', $edit, t('Save'));
 
     // Create node with term2.
     $edit = array();
     $node = $this->drupalCreateNode(array('type' => 'article'));
-    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term2->tid;
+    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term2->id();
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     // Generate and test sanitized tokens for term1.
     $tests = array();
-    $tests['[term:tid]'] = $term1->tid;
-    $tests['[term:name]'] = check_plain($term1->name);
-    $tests['[term:description]'] = check_markup($term1->description, $term1->format);
-    $tests['[term:url]'] = url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE));
+    $tests['[term:tid]'] = $term1->id();
+    $tests['[term:name]'] = check_plain($term1->name->value);
+    $tests['[term:description]'] = check_markup($term1->description->value, $term1->format->value);
+    $tests['[term:url]'] = url('taxonomy/term/' . $term1->id(), array('absolute' => TRUE));
     $tests['[term:node-count]'] = 0;
     $tests['[term:parent:name]'] = '[term:parent:name]';
     $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name);
@@ -98,13 +98,13 @@ function testTaxonomyTokenReplacement() {
 
     // Generate and test sanitized tokens for term2.
     $tests = array();
-    $tests['[term:tid]'] = $term2->tid;
-    $tests['[term:name]'] = check_plain($term2->name);
-    $tests['[term:description]'] = check_markup($term2->description, $term2->format);
-    $tests['[term:url]'] = url('taxonomy/term/' . $term2->tid, array('absolute' => TRUE));
+    $tests['[term:tid]'] = $term2->id();
+    $tests['[term:name]'] = check_plain($term2->name->value);
+    $tests['[term:description]'] = check_markup($term2->description->value, $term2->format->value);
+    $tests['[term:url]'] = url('taxonomy/term/' . $term2->id(), array('absolute' => TRUE));
     $tests['[term:node-count]'] = 1;
-    $tests['[term:parent:name]'] = check_plain($term1->name);
-    $tests['[term:parent:url]'] = url('taxonomy/term/' . $term1->tid, array('absolute' => TRUE));
+    $tests['[term:parent:name]'] = check_plain($term1->name->value);
+    $tests['[term:parent:url]'] = url('taxonomy/term/' . $term1->id(), array('absolute' => TRUE));
     $tests['[term:parent:parent:name]'] = '[term:parent:parent:name]';
     $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name);
 
@@ -117,9 +117,9 @@ function testTaxonomyTokenReplacement() {
     }
 
     // Generate and test unsanitized tokens.
-    $tests['[term:name]'] = $term2->name;
-    $tests['[term:description]'] = $term2->description;
-    $tests['[term:parent:name]'] = $term1->name;
+    $tests['[term:name]'] = $term2->name->value;
+    $tests['[term:description]'] = $term2->description->value;
+    $tests['[term:parent:name]'] = $term1->name->value;
     $tests['[term:vocabulary:name]'] = $this->vocabulary->name;
 
     foreach ($tests as $input => $expected) {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipNodeTermDataTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipNodeTermDataTest.php
index 0dbe0c263fa1..dfb3af48fc0c 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipNodeTermDataTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipNodeTermDataTest.php
@@ -29,7 +29,7 @@ public static function getInfo() {
 
   function testViewsHandlerRelationshipNodeTermData() {
     $view = views_get_view('test_taxonomy_node_term_data');
-    $this->executeView($view, array($this->term1->tid, $this->term2->tid));
+    $this->executeView($view, array($this->term1->id(), $this->term2->id()));
     $resultset = array(
       array(
         'nid' => $this->nodes[0]->nid,
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipRepresentativeNode.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipRepresentativeNode.php
index dbe4b3e7009e..c87a4372715d 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipRepresentativeNode.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/RelationshipRepresentativeNode.php
@@ -37,11 +37,11 @@ public function testRelationship() {
     $expected_result = array(
       array(
         'nid' => $this->nodes[1]->nid,
-        'tid' => $this->term2->tid,
+        'tid' => $this->term2->id(),
       ),
       array(
         'nid' => $this->nodes[1]->nid,
-        'tid' => $this->term1->tid,
+        'tid' => $this->term1->id(),
       ),
     );
     $this->assertIdenticalResultset($view, $expected_result, $map);
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
index 5f989907b9c4..6de1b17169a7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyTestBase.php
@@ -54,8 +54,8 @@ function setUp() {
 
     $node = array();
     $node['type'] = 'article';
-    $node['field_views_testing_tags'][]['tid'] = $this->term1->tid;
-    $node['field_views_testing_tags'][]['tid'] = $this->term2->tid;
+    $node['field_views_testing_tags'][]['tid'] = $this->term1->id();
+    $node['field_views_testing_tags'][]['tid'] = $this->term2->id();
     $this->nodes[] = $this->drupalCreateNode($node);
     $this->nodes[] = $this->drupalCreateNode($node);
   }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
index 941d6e8312c7..a863e9801921 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyPermissionsTest.php
@@ -80,7 +80,7 @@ function testVocabularyPermissionsTaxonomyTerm() {
     // Edit the term.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
     $this->assertResponse(200);
-    $this->assertText($term->name, 'Edit taxonomy term form opened successfully.');
+    $this->assertText($term->name->value, 'Edit taxonomy term form opened successfully.');
 
     $edit['name'] = $this->randomName();
     $this->drupalPost(NULL, $edit, t('Save'));
@@ -107,11 +107,11 @@ function testVocabularyPermissionsTaxonomyTerm() {
 
     // Delete the vocabulary.
     $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
-    $this->assertRaw(t('Are you sure you want to delete the term %name?', array('%name' => $term->name)), 'Delete taxonomy term form opened successfully.');
+    $this->assertRaw(t('Are you sure you want to delete the term %name?', array('%name' => $term->label())), 'Delete taxonomy term form opened successfully.');
 
     // Confirm deletion.
     $this->drupalPost(NULL, NULL, t('Delete'));
-    $this->assertRaw(t('Deleted term %name.', array('%name' => $term->name)), 'Term deleted.');
+    $this->assertRaw(t('Deleted term %name.', array('%name' => $term->label())), 'Term deleted.');
 
     // Test as user without proper permissions.
     $user = $this->drupalCreateUser();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
index b25ba51b6aeb..e427b4e68013 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyUnitTest.php
@@ -55,9 +55,9 @@ function testTaxonomyVocabularyDeleteWithTerms() {
     }
 
     // Set up hierarchy. term 2 is a child of 1 and 4 a child of 1 and 2.
-    $terms[2]->parent = array($terms[1]->tid);
+    $terms[2]->parent = array($terms[1]->id());
     taxonomy_term_save($terms[2]);
-    $terms[4]->parent = array($terms[1]->tid, $terms[2]->tid);
+    $terms[4]->parent = array($terms[1]->id(), $terms[2]->id());
     taxonomy_term_save($terms[4]);
 
     // Assert that there are now 5 terms.
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index d26501f9ef7a..929543d3a7fe 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -190,12 +190,12 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
 
     // Finally, if we've gotten down this far, we're rendering a term on this page.
     $page_entries++;
-    $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
-    $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];
+    $term_deltas[$term->id()] = isset($term_deltas[$term->id()]) ? $term_deltas[$term->id()] + 1 : 0;
+    $key = 'tid:' . $term->id() . ':' . $term_deltas[$term->id()];
 
     // Keep track of the first term displayed on this page.
     if ($page_entries == 1) {
-      $form['#first_tid'] = $term->tid;
+      $form['#first_tid'] = $term->id();
     }
     // Keep a variable to make sure at least 2 root elements are displayed.
     if ($term->parents[0] == 0) {
@@ -240,25 +240,18 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
     ),
   );
   foreach ($current_page as $key => $term) {
-    // Save the term for the current page so we don't have to load it a second
-    // time.
-    $form['terms'][$key]['#term'] = (array) $term;
-    if (isset($term->parents)) {
-      $form['terms'][$key]['#term']['parent'] = $term->parent = $term->parents[0];
-      unset($form['terms'][$key]['#term']['parents'], $term->parents);
-    }
-
+    $form['terms'][$key]['#term'] = $term;
     $form['terms'][$key]['term'] = array(
-      '#prefix' => isset($term->depth) && $term->depth > 0 ? theme('indentation', array('size' => $term->depth)) : '',
+      '#prefix' => isset($term->depth->value) && $term->depth->value > 0 ? theme('indentation', array('size' => $term->depth->value)) : '',
       '#type' => 'link',
       '#title' => $term->label(),
-      '#href' => "taxonomy/term/$term->tid",
+      '#href' => "taxonomy/term/$term->id()",
     );
     if ($vocabulary->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE && count($tree) > 1) {
       $parent_fields = TRUE;
       $form['terms'][$key]['term']['tid'] = array(
         '#type' => 'hidden',
-        '#value' => $term->tid,
+        '#value' => $term->id(),
         '#attributes' => array(
           'class' => array('term-id'),
         ),
@@ -267,7 +260,7 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
         '#type' => 'hidden',
         // Yes, default_value on a hidden. It needs to be changeable by the
         // javascript.
-        '#default_value' => $term->parent,
+        '#default_value' => $term->parent->value,
         '#attributes' => array(
           'class' => array('term-parent'),
         ),
@@ -287,7 +280,7 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
       '#delta' => $delta,
       '#title_display' => 'invisible',
       '#title' => t('Weight for added term'),
-      '#default_value' => $term->weight,
+      '#default_value' => $term->weight->value,
       '#attributes' => array(
         'class' => array('term-weight'),
       ),
@@ -295,19 +288,19 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
     $operations = array(
       'edit' => array(
         'title' => t('edit'),
-        'href' => 'taxonomy/term/' . $term->tid . '/edit',
+        'href' => 'taxonomy/term/' . $term->id() . '/edit',
         'query' => $destination,
       ),
       'delete' => array(
         'title' => t('delete'),
-        'href' => 'taxonomy/term/' . $term->tid . '/delete',
+        'href' => 'taxonomy/term/' . $term->id() . '/delete',
         'query' => $destination,
       ),
     );
     if (module_invoke('translation_entity', 'translate_access', $term)) {
       $operations['translate'] = array(
         'title' => t('translate'),
-        'href' => 'taxonomy/term/' . $term->tid . '/translations',
+        'href' => 'taxonomy/term/' . $term->id() . '/translations',
         'query' => $destination,
       );
     }
@@ -408,7 +401,7 @@ function taxonomy_overview_terms_submit($form, &$form_state) {
   $hierarchy = TAXONOMY_HIERARCHY_DISABLED;
 
   $changed_terms = array();
-  $tree = taxonomy_get_tree($vocabulary->id());
+  $tree = taxonomy_get_tree($vocabulary->id(), 0, NULL, TRUE);
 
   if (empty($tree)) {
     return;
@@ -416,16 +409,15 @@ function taxonomy_overview_terms_submit($form, &$form_state) {
 
   // Build a list of all terms that need to be updated on previous pages.
   $weight = 0;
-  $term = (array) $tree[0];
-  while ($term['tid'] != $form['#first_tid']) {
-    if ($term['parents'][0] == 0 && $term['weight'] != $weight) {
-      $term['parent'] = $term['parents'][0];
-      $term['weight'] = $weight;
-      $changed_terms[$term['tid']] = $term;
+  $term = $tree[0];
+  while ($term->id() != $form['#first_tid']) {
+    if ($term->parent->value == 0 && $term->weight->value != $weight) {
+      $term->weight->value = $weight;
+      $changed_terms[$term->id()] = $term;
     }
     $weight++;
-    $hierarchy = $term['parents'][0] != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
-    $term = (array) $tree[$weight];
+    $hierarchy = $term->parent->value != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
+    $term = $tree[$weight];
   }
 
   // Renumber the current page weights and assign any new parents.
@@ -434,53 +426,42 @@ function taxonomy_overview_terms_submit($form, &$form_state) {
     if (isset($form['terms'][$tid]['#term'])) {
       $term = $form['terms'][$tid]['#term'];
       // Give terms at the root level a weight in sequence with terms on previous pages.
-      if ($values['term']['parent'] == 0 && $term['weight'] != $weight) {
-        $term['weight'] = $weight;
-        $changed_terms[$term['tid']] = $term;
+      if ($values['term']['parent'] == 0 && $term->weight->value != $weight) {
+        $term->weight->value = $weight;
+        $changed_terms[$term->id()] = $term;
       }
       // Terms not at the root level can safely start from 0 because they're all on this page.
       elseif ($values['term']['parent'] > 0) {
-        $level_weights[$values['term']['parent']] = isset($level_weights[$values['term']['parent']]) ? $level_weights[$values['term']['parent']] + 1 : 0;
-        if ($level_weights[$values['term']['parent']] != $term['weight']) {
-          $term['weight'] = $level_weights[$values['term']['parent']];
-          $changed_terms[$term['tid']] = $term;
+        $level_weights[$values['term']['parent']] = isset($level_weights[$values['term']['parent']]) ? $level_weights[$values['term']->parent->value] + 1 : 0;
+        if ($level_weights[$values['term']['parent']] != $term->weight->value) {
+          $term->weight->value = $level_weights[$values['term']['parent']];
+          $changed_terms[$term->id()] = $term;
         }
       }
       // Update any changed parents.
-      if ($values['term']['parent'] != $term['parent']) {
-        $term['parent'] = $values['term']['parent'];
-        $changed_terms[$term['tid']] = $term;
+      if ($values['term']['parent'] != $term->parent->value) {
+        $term->parent->value = $values['term']['parent'];
+        $changed_terms[$term->id()] = $term;
       }
-      $hierarchy = $term['parent'] != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
+      $hierarchy = $term->parent->value != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
       $weight++;
     }
   }
 
   // Build a list of all terms that need to be updated on following pages.
   for ($weight; $weight < count($tree); $weight++) {
-    $term = (array) $tree[$weight];
-    if ($term['parents'][0] == 0 && $term['weight'] != $weight) {
-      $term['parent'] = $term['parents'][0];
-      $term['weight'] = $weight;
-      $changed_terms[$term['tid']] = $term;
+    $term = $tree[$weight];
+    if ($term->parent->value == 0 && $term->weight->value != $weight) {
+      $term->parent->value = $term->parent->value;
+      $term->weight->value = $weight;
+      $changed_terms[$term->id()] = $term;
     }
-    $hierarchy = $term['parents'][0] != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
+    $hierarchy = $term->parent->value != 0 ? TAXONOMY_HIERARCHY_SINGLE : $hierarchy;
   }
 
   // Save all updated terms.
-  foreach ($changed_terms as $changed) {
-    $term = (object) $changed;
-    // Update term_hierachy and term_data directly since we don't have a
-    // fully populated term object to save.
-    db_update('taxonomy_term_hierarchy')
-      ->fields(array('parent' => $term->parent))
-      ->condition('tid', $term->tid, '=')
-      ->execute();
-
-    db_update('taxonomy_term_data')
-      ->fields(array('weight' => $term->weight))
-      ->condition('tid', $term->tid, '=')
-      ->execute();
+  foreach ($changed_terms as $term) {
+    $term->save();
   }
 
   // Update the vocabulary hierarchy to flat or single hierarchy.
@@ -510,11 +491,11 @@ function taxonomy_term_add($vocabulary) {
  */
 function taxonomy_term_confirm_delete($form, &$form_state, Term $term) {
   // Always provide entity id in the same form key as in the entity edit form.
-  $form['tid'] = array('#type' => 'value', '#value' => $term->tid);
+  $form['tid'] = array('#type' => 'value', '#value' => $term->id());
 
-  $form_state['taxonomy']['vocabulary'] = taxonomy_vocabulary_load($term->bundle());;
+  $form_state['taxonomy']['vocabulary'] = taxonomy_vocabulary_load($term->bundle());
   $form['type'] = array('#type' => 'value', '#value' => 'term');
-  $form['name'] = array('#type' => 'value', '#value' => $term->name);
+  $form['name'] = array('#type' => 'value', '#value' => $term->label());
   $form['vid'] = array('#type' => 'value', '#value' => $term->bundle());
   $form['delete'] = array('#type' => 'value', '#value' => TRUE);
   return confirm_form($form,
diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php
index 1aa38f4a7133..941986bbcaa1 100644
--- a/core/modules/taxonomy/taxonomy.api.php
+++ b/core/modules/taxonomy/taxonomy.api.php
@@ -158,7 +158,7 @@ function hook_taxonomy_term_create(\Drupal\taxonomy\Plugin\Core\Entity\Term $ter
 function hook_taxonomy_term_load(array $terms) {
   $result = db_query('SELECT tid, foo FROM {mytable} WHERE tid IN (:tids)', array(':tids' => array_keys($terms)));
   foreach ($result as $record) {
-    $terms[$record->tid]->foo = $record->foo;
+    $terms[$record->id()]->foo = $record->foo;
   }
 }
 
@@ -190,7 +190,7 @@ function hook_taxonomy_term_insert(Drupal\taxonomy\Term $term) {
       if ($synonym) {
         db_insert('taxonomy_term_synonym')
         ->fields(array(
-          'tid' => $term->tid,
+          'tid' => $term->id(),
           'name' => rtrim($synonym),
         ))
         ->execute();
@@ -214,7 +214,7 @@ function hook_taxonomy_term_update(Drupal\taxonomy\Term $term) {
       if ($synonym) {
         db_insert('taxonomy_term_synonym')
         ->fields(array(
-          'tid' => $term->tid,
+          'tid' => $term->id(),
           'name' => rtrim($synonym),
         ))
         ->execute();
@@ -236,7 +236,7 @@ function hook_taxonomy_term_update(Drupal\taxonomy\Term $term) {
  * @see taxonomy_term_delete()
  */
 function hook_taxonomy_term_predelete(Drupal\taxonomy\Term $term) {
-  db_delete('term_synoynm')->condition('tid', $term->tid)->execute();
+  db_delete('term_synoynm')->condition('tid', $term->id())->execute();
 }
 
 /**
@@ -251,7 +251,7 @@ function hook_taxonomy_term_predelete(Drupal\taxonomy\Term $term) {
  * @see taxonomy_term_delete()
  */
 function hook_taxonomy_term_delete(Drupal\taxonomy\Term $term) {
-  db_delete('term_synoynm')->condition('tid', $term->tid)->execute();
+  db_delete('term_synoynm')->condition('tid', $term->id())->execute();
 }
 
 /**
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 89f334b496d4..2c50edbbdd63 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -142,7 +142,7 @@ function taxonomy_entity_bundle_info() {
  */
 function taxonomy_term_uri($term) {
   return array(
-    'path' => 'taxonomy/term/' . $term->tid,
+    'path' => 'taxonomy/term/' . $term->id(),
   );
 }
 
@@ -472,7 +472,7 @@ function taxonomy_check_vocabulary_hierarchy(Vocabulary $vocabulary, $changed_te
  *
  * @return
  *   Status constant indicating whether term was inserted (SAVED_NEW) or updated
- *   (SAVED_UPDATED). When inserting a new term, $term->tid will contain the
+ *   (SAVED_UPDATED). When inserting a new term, $term->id() will contain the
  *   term ID of the newly created term.
  */
 function taxonomy_term_save(Term $term) {
@@ -565,7 +565,7 @@ function template_preprocess_taxonomy_term(&$variables) {
   $variables['attributes']['class'][] = 'vocabulary-' . $vocabulary_name_css;
 
   $variables['theme_hook_suggestions'][] = 'taxonomy_term__' . $term->bundle();
-  $variables['theme_hook_suggestions'][] = 'taxonomy_term__' . $term->tid;
+  $variables['theme_hook_suggestions'][] = 'taxonomy_term__' . $term->id();
 }
 
 /**
@@ -576,7 +576,7 @@ function template_preprocess_taxonomy_term(&$variables) {
  */
 function taxonomy_term_is_page(Term $term) {
   $page_term = menu_get_object('taxonomy_term', 2);
-  return (!empty($page_term) ? $page_term->tid == $term->tid : FALSE);
+  return (!empty($page_term) ? $page_term->id() == $term->id() : FALSE);
 }
 
 /**
@@ -659,7 +659,7 @@ function taxonomy_term_load_parents_all($tid) {
   if ($term = taxonomy_term_load($tid)) {
     $parents[] = $term;
     $n = 0;
-    while ($parent = taxonomy_term_load_parents($parents[$n]->tid)) {
+    while ($parent = taxonomy_term_load_parents($parents[$n]->id())) {
       $parents = array_merge($parents, $parent);
       $n++;
     }
@@ -783,26 +783,27 @@ function taxonomy_get_tree($vid, $parent = 0, $max_depth = NULL, $load_entities
           break;
         }
         $term = $load_entities ? $term_entities[$child] : $terms[$vid][$child];
-        if (isset($parents[$vid][$term->tid])) {
+        if (isset($parents[$vid][$load_entities ? $term->id() : $term->tid])) {
           // Clone the term so that the depth attribute remains correct
           // in the event of multiple parents.
           $term = clone $term;
         }
         $term->depth = $depth;
         unset($term->parent);
-        $term->parents = $parents[$vid][$term->tid];
+        $tid = $load_entities ? $term->id() : $term->tid;
+        $term->parents = $parents[$vid][$tid];
         $tree[] = $term;
-        if (!empty($children[$vid][$term->tid])) {
+        if (!empty($children[$vid][$tid])) {
           $has_children = TRUE;
 
           // We have to continue with this parent later.
           $process_parents[] = $parent;
           // Use the current term as parent for the next iteration.
-          $process_parents[] = $term->tid;
+          $process_parents[] = $tid;
 
           // Reset pointers for child lists because we step in there more often
           // with multi parents.
-          reset($children[$vid][$term->tid]);
+          reset($children[$vid][$tid]);
           // Move pointer so that we get the correct term the next time.
           next($children[$vid][$parent]);
           break;
@@ -936,7 +937,7 @@ function taxonomy_term_load($tid) {
  * Helper function for array_map purposes.
  */
 function _taxonomy_get_tid_from_term(Term $term) {
-  return $term->tid;
+  return $term->id();
 }
 
 /**
@@ -1052,7 +1053,7 @@ function taxonomy_field_validate(EntityInterface $entity = NULL, $field, $instan
           elseif (!empty($settings['parent'])) {
             $ancestors = taxonomy_term_load_parents_all($item['tid']);
             foreach ($ancestors as $ancestor) {
-              if ($ancestor->tid == $settings['parent']) {
+              if ($ancestor->id() == $settings['parent']) {
                 $validate = TRUE;
                 break 2;
               }
@@ -1098,7 +1099,7 @@ function taxonomy_allowed_values($field, $instance, EntityInterface $entity) {
     if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) {
       if ($terms = taxonomy_get_tree($vocabulary->id(), $tree['parent'], NULL, TRUE)) {
         foreach ($terms as $term) {
-          $options[$term->tid] = str_repeat('-', $term->depth) . $term->label();
+          $options[$term->id()] = str_repeat('-', $term->depth) . $term->label();
         }
       }
     }
@@ -1238,7 +1239,7 @@ function taxonomy_field_presave(EntityInterface $entity, $field, $instance, $lan
     if (!$item['tid'] && isset($item['entity'])) {
       unset($item['tid']);
       taxonomy_term_save($item['entity']);
-      $items[$delta]['tid'] = $item['entity']->tid;
+      $items[$delta]['tid'] = $item['entity']->id();
     }
   }
 }
@@ -1355,7 +1356,7 @@ function taxonomy_delete_node_index(EntityInterface $node) {
 function taxonomy_taxonomy_term_delete(Term $term) {
   if (config('taxonomy.settings')->get('maintain_index_table')) {
     // Clean up the {taxonomy_index} table when terms are deleted.
-    db_delete('taxonomy_index')->condition('tid', $term->tid)->execute();
+    db_delete('taxonomy_index')->condition('tid', $term->id())->execute();
   }
 }
 
diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc
index b6f132916da9..72c1fb199513 100644
--- a/core/modules/taxonomy/taxonomy.pages.inc
+++ b/core/modules/taxonomy/taxonomy.pages.inc
@@ -19,21 +19,18 @@ function taxonomy_term_page(Term $term) {
   // Assign the term name as the page title.
   drupal_set_title($term->label());
 
-  // Build breadcrumb based on the hierarchy of the term.
-  $current = (object) array(
-    'tid' => $term->tid,
-  );
   // @todo This overrides any other possible breadcrumb and is a pure hard-coded
   //   presumption. Make this behavior configurable per vocabulary or term.
   $breadcrumb = array();
-  while ($parents = taxonomy_term_load_parents($current->tid)) {
+  $current = $term;
+  while ($parents = taxonomy_term_load_parents($current->id())) {
     $current = array_shift($parents);
-    $breadcrumb[] = l($current->label(), 'taxonomy/term/' . $current->tid);
+    $breadcrumb[] = l($current->label(), 'taxonomy/term/' . $current->id());
   }
   $breadcrumb[] = l(t('Home'), NULL);
   $breadcrumb = array_reverse($breadcrumb);
   drupal_set_breadcrumb($breadcrumb);
-  drupal_add_feed('taxonomy/term/' . $term->tid . '/feed', 'RSS - ' . $term->label());
+  drupal_add_feed('taxonomy/term/' . $term->id() . '/feed', 'RSS - ' . $term->label());
 
   $uri = $term->uri();
 
@@ -43,7 +40,7 @@ function taxonomy_term_page(Term $term) {
   drupal_add_html_head_link(array('rel' => 'shortlink', 'href' => url($uri['path'], array_merge($uri['options'], array('alias' => TRUE)))), TRUE);
 
   $build['taxonomy_terms'] = taxonomy_term_view_multiple(array($term->id() => $term));
-  if ($nids = taxonomy_select_nodes($term->tid, TRUE, config('node.settings')->get('items_per_page'))) {
+  if ($nids = taxonomy_select_nodes($term->id(), TRUE, config('node.settings')->get('items_per_page'))) {
     $nodes = node_load_multiple($nids);
     $build['nodes'] = node_view_multiple($nodes);
     $build['pager'] = array(
@@ -68,12 +65,12 @@ function taxonomy_term_page(Term $term) {
  *   The taxonomy term entity.
  */
 function taxonomy_term_feed(Term $term) {
-  $channel['link'] = url('taxonomy/term/' . $term->tid, array('absolute' => TRUE));
+  $channel['link'] = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE));
   $channel['title'] = config('system.site')->get('name') . ' - ' . $term->label();
   // Only display the description if we have a single term, to avoid clutter and confusion.
   // HTML will be removed from feed description.
-  $channel['description'] = check_markup($term->description, $term->format, '', TRUE);
-  $nids = taxonomy_select_nodes($term->tid, FALSE, config('system.rss')->get('items.limit'));
+  $channel['description'] = check_markup($term->description->value, $term->format->value, '', TRUE);
+  $nids = taxonomy_select_nodes($term->id(), FALSE, config('system.rss')->get('items.limit'));
 
   return node_feed($nids, $channel);
 }
diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc
index 00819f6c798b..f0818a69a375 100644
--- a/core/modules/taxonomy/taxonomy.tokens.inc
+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -100,15 +100,15 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
     foreach ($tokens as $name => $original) {
       switch ($name) {
         case 'tid':
-          $replacements[$original] = $term->tid;
+          $replacements[$original] = $term->id();
           break;
 
         case 'name':
-          $replacements[$original] = $sanitize ? check_plain($term->name) : $term->name;
+          $replacements[$original] = $sanitize ? check_plain($term->name->value) : $term->name->value;
           break;
 
         case 'description':
-          $replacements[$original] = $sanitize ? check_markup($term->description, $term->format, '', TRUE) : $term->description;
+          $replacements[$original] = $sanitize ? check_markup($term->description->value, $term->format->value, '', TRUE) : $term->description->value;
           break;
 
         case 'url':
@@ -118,7 +118,7 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
 
         case 'node-count':
           $query = db_select('taxonomy_index');
-          $query->condition('tid', $term->tid);
+          $query->condition('tid', $term->id());
           $query->addTag('term_node_count');
           $count = $query->countQuery()->execute()->fetchField();
           $replacements[$original] = $count;
@@ -130,9 +130,9 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
           break;
 
         case 'parent':
-          if ($parents = taxonomy_term_load_parents($term->tid)) {
+          if ($parents = taxonomy_term_load_parents($term->id())) {
             $parent = array_pop($parents);
-            $replacements[$original] = check_plain($parent->name);
+            $replacements[$original] = check_plain($parent->name->value);
           }
           break;
       }
@@ -143,7 +143,7 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
       $replacements += $token_service->generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options);
     }
 
-    if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->tid)) {
+    if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->id())) {
       $parent = array_pop($parents);
       $replacements += $token_service->generate('term', $vocabulary_tokens, array('term' => $parent), $options);
     }
diff --git a/core/modules/taxonomy/taxonomy.views.inc b/core/modules/taxonomy/taxonomy.views.inc
index 0644f82f5003..679deb5a641c 100644
--- a/core/modules/taxonomy/taxonomy.views.inc
+++ b/core/modules/taxonomy/taxonomy.views.inc
@@ -411,7 +411,7 @@ function views_taxonomy_set_breadcrumb(&$breadcrumb, &$argument) {
   $parents = taxonomy_get_parents_all($argument->argument);
   foreach (array_reverse($parents) as $parent) {
     // Unfortunately parents includes the current argument. Skip.
-    if ($parent->tid == $argument->argument) {
+    if ($parent->id() == $argument->argument) {
       continue;
     }
     if (!empty($argument->options['use_taxonomy_term_path'])) {
@@ -419,9 +419,9 @@ function views_taxonomy_set_breadcrumb(&$breadcrumb, &$argument) {
       $path = $path['path'];
     }
     else {
-      $args[$argument->position] = $parent->tid;
+      $args[$argument->position] = $parent->id();
       $path = $argument->view->getUrl($args);
     }
-    $breadcrumb[$path] = check_plain($parent->name);
+    $breadcrumb[$path] = check_plain($parent->label());
   }
 }
diff --git a/core/modules/taxonomy/templates/taxonomy-term.tpl.php b/core/modules/taxonomy/templates/taxonomy-term.tpl.php
index 0cd63d0e3e01..6f6cac19fa87 100644
--- a/core/modules/taxonomy/templates/taxonomy-term.tpl.php
+++ b/core/modules/taxonomy/templates/taxonomy-term.tpl.php
@@ -34,7 +34,7 @@
  * @ingroup themeable
  */
 ?>
-<div id="taxonomy-term-<?php print $term->tid; ?>"<?php print $attributes; ?>>
+<div id="taxonomy-term-<?php print $term->id(); ?>"<?php print $attributes; ?>>
 
   <?php if (!$page): ?>
     <h2><a href="<?php print $url; ?>"><?php print $label; ?></a></h2>
diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
index c4f90b83cd24..126e62d75375 100644
--- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php
@@ -96,7 +96,7 @@ protected function setUp() {
       $term = $this->createTerm($this->vocabulary);
 
       $values = array('created' => $time, 'type' => 'page');
-      $values[$this->field_name][]['tid'] = $term->tid;
+      $values[$this->field_name][]['tid'] = $term->id();
 
       // Make every other node promoted.
       if ($i % 2) {
diff --git a/core/modules/views/views_ui/admin.inc b/core/modules/views/views_ui/admin.inc
index df344d27988f..a723854f6588 100644
--- a/core/modules/views/views_ui/admin.inc
+++ b/core/modules/views/views_ui/admin.inc
@@ -238,7 +238,7 @@ function views_ui_taxonomy_autocomplete_validate($element, &$form_state) {
     foreach ($typed_terms as $typed_term) {
       if ($terms = entity_load_multiple_by_properties('taxonomy_term', array('name' => trim($typed_term), 'vid' => array_keys($vocabularies)))) {
         $term = array_pop($terms);
-        $value['tids'][] = $term->tid;
+        $value['tids'][] = $term->id();
       }
     }
     // Store the term IDs along with the name of the vocabulary. Currently
diff --git a/core/scripts/generate-d7-content.sh b/core/scripts/generate-d7-content.sh
index a19d329a89e5..c171271a13a2 100644
--- a/core/scripts/generate-d7-content.sh
+++ b/core/scripts/generate-d7-content.sh
@@ -151,9 +151,9 @@
       'weight' => $i * 3 + $j,
     ));
     taxonomy_term_save($term);
-    $terms[] = $term->tid;
-    $term_vocabs[$term->tid] = 'taxonomy_' . $vocabulary->machine_name;
-    $parents[] = $term->tid;
+    $terms[] = $term->id();
+    $term_vocabs[$term->id()] = 'taxonomy_' . $vocabulary->machine_name;
+    $parents[] = $term->id();
   }
 }
 $node_id = 0;
-- 
GitLab