diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index e91eda7..91cbc1e 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -708,6 +708,14 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) {
   $display = entity_get_display($entity_type, $bundle, $render_view_mode);
   $display->originalMode = $view_mode;
 
+  // Let modules alter the display.
+  $display_context = array(
+    'entity_type' => $entity_type,
+    'bundle' => $bundle,
+    'view_mode' => $view_mode,
+  );
+  drupal_alter('entity_display', $display, $display_context);
+
   return $display;
 }
 
@@ -808,6 +816,14 @@ function entity_get_render_form_display(EntityInterface $entity, $form_mode) {
   $form_display = entity_get_form_display($entity_type, $bundle, $render_form_mode);
   $form_display->originalMode = $form_mode;
 
+  // Let modules alter the form display.
+  $form_display_context = array(
+    'entity_type' => $entity_type,
+    'bundle' => $bundle,
+    'form_mode' => $form_mode,
+  );
+  drupal_alter('entity_form_display', $form_display, $form_display_context);
+
   return $form_display;
 }
 
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 54ee489..5b6a435 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -125,15 +125,6 @@ protected function init(array &$form_state) {
     $this->prepareEntity();
 
     $form_display = entity_get_render_form_display($this->entity, $this->getOperation());
-
-    // Let modules alter the form display.
-    $form_display_context = array(
-      'entity_type' => $this->entity->entityType(),
-      'bundle' => $this->entity->bundle(),
-      'form_mode' => $this->getOperation(),
-    );
-    $this->moduleHandler->alter('entity_form_display', $form_display, $form_display_context);
-
     $this->setFormDisplay($form_display, $form_state);
 
     // Invoke the prepare form hooks.
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 2680e6f..b9506cd 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -208,20 +208,9 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
       // Store entities for rendering by view_mode.
       $view_modes[$entity_view_mode][$entity->id()] = $entity;
 
-      // Load the corresponding display settings if not stored yet.
+      // Get the corresponding display settings.
       if (!isset($displays[$entity_view_mode][$bundle])) {
-        // Get the display object for this bundle and view mode.
-        $display = entity_get_render_display($entity, $entity_view_mode);
-
-        // Let modules alter the display.
-        $display_context = array(
-          'entity_type' => $this->entityType,
-          'bundle' => $bundle,
-          'view_mode' => $entity_view_mode,
-        );
-        drupal_alter('entity_display', $display, $display_context);
-
-        $displays[$entity_view_mode][$bundle] = $display;
+        $displays[$entity_view_mode][$bundle] = entity_get_render_display($entity, $entity_view_mode);
       }
     }
 
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php
index 7ad2cfd..32178bf 100644
--- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/AllowedValuesConstraintValidator.php
@@ -20,6 +20,9 @@ class AllowedValuesConstraintValidator extends ChoiceValidator {
    * {@inheritdoc}
    */
   public function validate($value, Constraint $constraint) {
+    if (!isset($value)) {
+      return;
+    }
     if ($this->context->getMetadata()->getTypedData() instanceof AllowedValuesInterface) {
       $account = \Drupal::currentUser();
       $allowed_values = $this->context->getMetadata()->getTypedData()->getSettableValues($account);
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php
index 7fb55b6..ed810fd 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Tests/AggregatorTestBase.php
@@ -359,7 +359,7 @@ function createSampleNodes($count = 5) {
     // Post $count article nodes.
     for ($i = 0; $i < $count; $i++) {
       $edit = array();
-      $edit['title'] = $this->randomName();
+      $edit['title[0][value]'] = $this->randomName();
       $edit['body[0][value]'] = $this->randomName();
       $this->drupalPostForm('node/add/article', $edit, t('Save'));
     }
diff --git a/core/modules/book/lib/Drupal/book/Tests/BookTest.php b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
index 5ea8b8d..4e96673 100644
--- a/core/modules/book/lib/Drupal/book/Tests/BookTest.php
+++ b/core/modules/book/lib/Drupal/book/Tests/BookTest.php
@@ -243,7 +243,7 @@ function createBookNode($book_nid, $parent = NULL) {
     static $number = 0; // Used to ensure that when sorted nodes stay in same order.
 
     $edit = array();
-    $edit["title"] = $number . ' - SimpleTest test node ' . $this->randomName(10);
+    $edit['title[0][value]'] = $number . ' - SimpleTest test node ' . $this->randomName(10);
     $edit['body[0][value]'] = 'SimpleTest test body ' . $this->randomName(32) . ' ' . $this->randomName(32);
     $edit['book[bid]'] = $book_nid;
 
@@ -258,7 +258,7 @@ function createBookNode($book_nid, $parent = NULL) {
     }
 
     // Check to make sure the book node was created.
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertNotNull(($node === FALSE ? NULL : $node), 'Book node found in database.');
     $number++;
 
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
index 8b885fe..9255b34 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLanguageTest.php
@@ -95,7 +95,7 @@ function testCommentLanguage() {
       // Create "Article" content.
       $title = $this->randomName();
       $edit = array(
-        'title' => $title,
+        'title[0][value]' => $title,
         'body[0][value]' => $this->randomName(),
         'langcode' => $node_langcode,
         'comment[0][status]' => COMMENT_OPEN,
diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
index 7fea145..c845b78 100644
--- a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
+++ b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
@@ -309,7 +309,7 @@ private function doNode($type) {
     // Create a node using the form in order to generate an add content event
     // (which is not triggered by drupalCreateNode).
     $edit = $this->getContent($type);
-    $title = $edit["title"];
+    $title = $edit['title[0][value]'];
     $this->drupalPostForm('node/add/' . $type, $edit, t('Save'));
     $this->assertResponse(200);
     // Retrieve the node object.
@@ -369,7 +369,7 @@ private function getContent($type) {
     switch ($type) {
       case 'forum':
         $content = array(
-          'title' => $this->randomName(8),
+          'title[0][value]' => $this->randomName(8),
           'taxonomy_forums' => array(1),
           'body[0][value]' => $this->randomName(32),
         );
@@ -377,7 +377,7 @@ private function getContent($type) {
 
       default:
         $content = array(
-          'title' => $this->randomName(8),
+          'title[0][value]' => $this->randomName(8),
           'body[0][value]' => $this->randomName(32),
         );
         break;
diff --git a/core/modules/edit/edit.services.yml b/core/modules/edit/edit.services.yml
index d71a196..73f7f25 100644
--- a/core/modules/edit/edit.services.yml
+++ b/core/modules/edit/edit.services.yml
@@ -4,7 +4,7 @@ services:
     arguments: ['@container.namespaces']
   access_check.edit.entity_field:
     class: Drupal\edit\Access\EditEntityFieldAccessCheck
-    arguments: ['@entity.manager', '@field.info']
+    arguments: ['@entity.manager']
     tags:
       - { name: access_check }
   access_check.edit.entity:
diff --git a/core/modules/edit/js/editors/directEditor.js b/core/modules/edit/js/editors/directEditor.js
index d87e5f0..d62aae3 100644
--- a/core/modules/edit/js/editors/directEditor.js
+++ b/core/modules/edit/js/editors/directEditor.js
@@ -21,7 +21,13 @@ Drupal.edit.editors.direct = Drupal.edit.EditorView.extend({
     var fieldModel = this.fieldModel;
 
     // Store the original value of this field. Necessary for reverting changes.
-    var $textElement = this.$textElement = this.$el.find('.field-item:first');
+    var $textElement;
+    if (this.$el.is(':has(.field-item)')) {
+      $textElement = this.$textElement = this.$el.find('.field-item:first');
+    }
+    else {
+     $textElement = this.$textElement = this.$el;
+    }
     editorModel.set('originalValue', $.trim(this.$textElement.text()));
 
     // Sets the state to 'changed' whenever the value changes
diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
index 413e9aa..2c5dd92 100644
--- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
+++ b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php
@@ -15,7 +15,6 @@
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\field\FieldInfo;
 
 /**
  * Access check for editing entity fields.
@@ -30,23 +29,13 @@ class EditEntityFieldAccessCheck implements StaticAccessCheckInterface, EditEnti
   protected $entityManager;
 
   /**
-   * The field info.
-   *
-   * @var \Drupal\field\FieldInfo
-   */
-  protected $fieldInfo;
-
-  /**
    * Constructs a EditEntityFieldAccessCheck object.
    *
    * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
    *   The entity manager.
-   * @param \Drupal\field\FieldInfo $field_info
-   *   The field info.
    */
-  public function __construct(EntityManagerInterface $entity_manager, FieldInfo $field_info) {
+  public function __construct(EntityManagerInterface $entity_manager) {
     $this->entityManager = $entity_manager;
-    $this->fieldInfo = $field_info;
   }
 
   /**
@@ -95,7 +84,7 @@ protected function validateAndUpcastRequestAttributes(Request $request) {
 
     // Validate the field name and language.
     $field_name = $request->attributes->get('field_name');
-    if (!$field_name || !$this->fieldInfo->getInstance($entity->entityType(), $entity->bundle(), $field_name)) {
+    if (!$field_name || !$entity->hasField($field_name)) {
       throw new NotFoundHttpException();
     }
     $langcode = $request->attributes->get('langcode');
diff --git a/core/modules/edit/lib/Drupal/edit/EditController.php b/core/modules/edit/lib/Drupal/edit/EditController.php
index c63b956..eb1ab84 100644
--- a/core/modules/edit/lib/Drupal/edit/EditController.php
+++ b/core/modules/edit/lib/Drupal/edit/EditController.php
@@ -145,7 +145,7 @@ public function metadata(Request $request) {
       }
 
       // Validate the field name and language.
-      if (!$field_name || !($instance = $this->fieldInfo->getInstance($entity->entityType(), $entity->bundle(), $field_name))) {
+      if (!$field_name || !$entity->hasField($field_name)) {
         throw new NotFoundHttpException();
       }
       if (!$langcode || (field_valid_language($langcode) !== $langcode)) {
@@ -158,7 +158,8 @@ public function metadata(Request $request) {
         $metadata[$entity_id] = $this->metadataGenerator->generateEntity($entity, $langcode);
       }
 
-      $metadata[$field] = $this->metadataGenerator->generateField($entity, $instance, $langcode, $view_mode);
+      $field_definition = $entity->get($field_name)->getFieldDefinition();
+      $metadata[$field] = $this->metadataGenerator->generateField($entity, $field_definition, $langcode, $view_mode);
     }
 
     return new JsonResponse($metadata);
diff --git a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
index f98f91e..45d2ff1 100644
--- a/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
+++ b/core/modules/edit/lib/Drupal/edit/Form/EditFieldForm.php
@@ -128,18 +128,8 @@ protected function init(array &$form_state, EntityInterface $entity, $field_name
     $form_state['field_name'] = $field_name;
 
     // @todo Allow the usage of different form modes by exposing a hook and the
-    // UI for them.
-    $form_display = entity_get_render_form_display($entity, 'default');
-
-    // Let modules alter the form display.
-    $form_display_context = array(
-      'entity_type' => $entity->entityType(),
-      'bundle' => $entity->bundle(),
-      'form_mode' => 'default',
-    );
-    $this->moduleHandler->alter('entity_form_display', $form_display, $form_display_context);
-
-    $form_state['form_display'] = $form_display;
+    //   UI for them.
+    $form_state['form_display'] = entity_get_render_form_display($entity, 'default');
   }
 
   /**
@@ -180,14 +170,14 @@ public function submitForm(array &$form, array &$form_state) {
    */
   protected function buildEntity(array $form, array &$form_state) {
     $entity = clone $form_state['entity'];
+    $field_name = $form_state['field_name'];
 
-    field_attach_extract_form_values($entity, $form, $form_state, array('field_name' =>  $form_state['field_name']));
+    field_attach_extract_form_values($entity, $form, $form_state, array('field_name' => $field_name));
 
     // @todo Refine automated log messages and abstract them to all entity
     //   types: http://drupal.org/node/1678002.
     if ($entity->entityType() == 'node' && $entity->isNewRevision() && !isset($entity->log)) {
-      $instance = field_info_instance($entity->entityType(), $form_state['field_name'], $entity->bundle());
-      $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $instance->getFieldLabel()));
+      $entity->log = t('Updated the %field-name field through in-place editing.', array('%field-name' => $entity->get($field_name)->getFieldDefinition()->getFieldLabel()));
     }
 
     return $entity;
diff --git a/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php b/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php
index 228b4b0..a745148 100644
--- a/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php
+++ b/core/modules/edit/tests/Drupal/edit/Tests/Access/EditEntityFieldAccessCheckTest.php
@@ -41,13 +41,6 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
   protected $entityManager;
 
   /**
-   * The mocked field info.
-   *
-   * @var \Drupal\field\FieldInfo|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $fieldInfo;
-
-  /**
    * The mocked entity storage controller.
    *
    * @var \Drupal\Core\Entity\EntityStorageControllerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -71,11 +64,7 @@ protected function setUp() {
       ->method('getStorageController')
       ->will($this->returnValue($this->entityStorageController));
 
-    $this->fieldInfo = $this->getMockBuilder('Drupal\field\FieldInfo')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $this->editAccessCheck = new EditEntityFieldAccessCheck($this->entityManager, $this->fieldInfo);
+    $this->editAccessCheck = new EditEntityFieldAccessCheck($this->entityManager);
   }
 
   /**
@@ -91,16 +80,12 @@ public function testAppliesTo() {
    * @see \Drupal\edit\Tests\edit\Access\EditEntityFieldAccessCheckTest::testAccess()
    */
   public function providerTestAccess() {
-    $editable_entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
+    $editable_entity = $this->createMockEntity();
     $editable_entity->expects($this->any())
       ->method('access')
       ->will($this->returnValue(TRUE));
 
-    $non_editable_entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
+    $non_editable_entity = $this->createMockEntity();
     $non_editable_entity->expects($this->any())
       ->method('access')
       ->will($this->returnValue(FALSE));
@@ -146,22 +131,15 @@ public function testAccess(EntityInterface $entity, FieldInterface $field = NULL
     $entity_with_field = clone $entity;
     $entity_with_field->expects($this->any())
       ->method('get')
+      ->with('valid')
       ->will($this->returnValue($field));
 
     // Prepare the request to be valid.
-    $request->attributes->set('entity', $entity_with_field);
     $request->attributes->set('entity_type', 'test_entity');
-    $request->attributes->set('field_name', 'example');
+    $request->attributes->set('entity', $entity_with_field);
+    $request->attributes->set('field_name', 'valid');
     $request->attributes->set('langcode', Language::LANGCODE_NOT_SPECIFIED);
 
-    $this->fieldInfo->expects($this->any())
-      ->method('getInstance')
-      ->will($this->returnValue(array(
-        'example' => array(
-          'field_name' => 'example',
-        )
-      )));
-
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
     $access = $this->editAccessCheck->access($route, $request, $account);
     $this->assertSame($expected_result, $access);
@@ -220,12 +198,7 @@ public function testAccessWithNotPassedFieldName() {
     $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
-
-    $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $request->attributes->set('entity', $entity);
+    $request->attributes->set('entity', $this->createMockEntity());
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
     $this->editAccessCheck->access($route, $request, $account);
@@ -240,25 +213,9 @@ public function testAccessWithNonExistingField() {
     $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
-
-    $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $entity->expects($this->any())
-      ->method('entityType')
-      ->will($this->returnValue('entity_test'));
-    $entity->expects($this->any())
-      ->method('bundle')
-      ->will($this->returnValue('test_bundle'));
-
-    $request->attributes->set('entity', $entity);
+    $request->attributes->set('entity', $this->createMockEntity());
     $request->attributes->set('field_name', 'not_valid');
 
-    $this->fieldInfo->expects($this->once())
-      ->method('getInstance')
-      ->with('entity_test', 'test_bundle', 'not_valid')
-      ->will($this->returnValue(NULL));
-
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
     $this->editAccessCheck->access($route, $request, $account);
   }
@@ -272,22 +229,9 @@ public function testAccessWithNotPassedLanguage() {
     $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
-
-    $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $request->attributes->set('entity', $entity);
-
+    $request->attributes->set('entity', $this->createMockEntity());
     $request->attributes->set('field_name', 'valid');
 
-    $field = $this->getMockBuilder('Drupal\field\Entity\Field')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $this->fieldInfo->expects($this->once())
-      ->method('getInstance')
-      ->will($this->returnValue($field));
-
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
     $this->editAccessCheck->access($route, $request, $account);
   }
@@ -301,25 +245,30 @@ public function testAccessWithInvalidLanguage() {
     $route = new Route('/edit/form/test_entity/1/body/und/full', array(), array('_access_edit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
-
-    $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $request->attributes->set('entity', $entity);
-
+    $request->attributes->set('entity', $this->createMockEntity());
     $request->attributes->set('field_name', 'valid');
     $request->attributes->set('langcode', 'xx-lolspeak');
 
-    $field = $this->getMockBuilder('Drupal\field\Entity\Field')
+    $account = $this->getMock('Drupal\Core\Session\AccountInterface');
+    $this->editAccessCheck->access($route, $request, $account);
+  }
+
+  /**
+   * Returns a mock entity.
+   */
+  protected function createMockEntity() {
+    $entity = $this->getMockBuilder('Drupal\entity_test\Entity\EntityTest')
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->fieldInfo->expects($this->once())
-      ->method('getInstance')
-      ->will($this->returnValue($field));
+    $entity->expects($this->any())
+      ->method('hasField')
+      ->will($this->returnValueMap(array(
+        array('valid', TRUE),
+        array('not_valid', FALSE),
+      )));
 
-    $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->editAccessCheck->access($route, $request, $account);
+    return $entity;
   }
 
 }
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
index e684a59..4c8cb72 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
@@ -51,10 +51,9 @@ public function getRenderer($field_name) {
     }
 
     // Instantiate the formatter object from the stored display properties.
-    if ($configuration = $this->getComponent($field_name)) {
-      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
+    if (($configuration = $this->getComponent($field_name)) && isset($configuration['type'])) {
       $formatter = $this->pluginManager->getInstance(array(
-        'field_definition' => $instance,
+        'field_definition' => $this->getFieldDefinition($field_name),
         'view_mode' => $this->originalMode,
         // No need to prepare, defaults have been merged in setComponent().
         'prepare' => FALSE,
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
index 461f7ce..5b111dc 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
@@ -51,10 +51,9 @@ public function getRenderer($field_name) {
     }
 
     // Instantiate the widget object from the stored display properties.
-    if ($configuration = $this->getComponent($field_name)) {
-      $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle);
+    if (($configuration = $this->getComponent($field_name)) && isset($configuration['type'])) {
       $widget = $this->pluginManager->getInstance(array(
-        'field_definition' => $instance,
+        'field_definition' => $this->getFieldDefinition($field_name),
         'form_mode' => $this->originalMode,
         // No need to prepare, defaults have been merged in setComponent().
         'prepare' => FALSE,
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index 0278c58..7657528 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\entity;
 
 use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Entity\ContentEntityInterface;
 
 /**
  * Base class for config entity types that store configuration for entity forms
@@ -44,6 +45,16 @@
   public $bundle;
 
   /**
+   * A partial entity, created via _field_create_entity_from_ids() from
+   * $targetEntityType and $bundle.
+   *
+   * @var \Drupal\Core\Entity\EntityInterface
+   *
+   * @todo Remove when getFieldDefinition() is fixed to not need it.
+   */
+  private $targetEntity;
+
+  /**
    * View or form mode to be displayed.
    *
    * @var string
@@ -194,9 +205,9 @@ public function getComponent($name) {
       // visibility.
       if (isset($this->content[$name])) {
         if ($this->content[$name]['visible']) {
-          return array(
-            'weight' => $this->content[$name]['weight'],
-          );
+          $options = $this->content[$name];
+          unset($options['visible']);
+          return $options;
         }
         else {
           return NULL;
@@ -231,8 +242,8 @@ public function setComponent($name, array $options = array()) {
       $options['weight'] = isset($max) ? $max + 1 : 0;
     }
 
-    if ($instance = field_info_instance($this->targetEntityType, $name, $this->bundle)) {
-      $options = $this->pluginManager->prepareConfiguration($instance->getFieldType(), $options);
+    if ($field_definition = $this->getFieldDefinition($name)) {
+      $options = $this->pluginManager->prepareConfiguration($field_definition->getFieldType(), $options);
 
       // Clear the persisted plugin, if any.
       unset($this->plugins[$name]);
@@ -290,4 +301,28 @@ public function getHighestWeight() {
     return $weights ? max($weights) : NULL;
   }
 
+  /**
+   * Returns the field definition of a field.
+   */
+  protected function getFieldDefinition($field_name) {
+    // @todo Replace this entire implementation with
+    //   \Drupal::entityManager()->getFieldDefinition() after [#2047229] lands.
+    if (!isset($this->targetEntity)) {
+      $this->targetEntity = _field_create_entity_from_ids((object) array('entity_type' => $this->targetEntityType, 'bundle' => $this->bundle, 'entity_id' => NULL));
+    }
+    if (($this->targetEntity instanceof ContentEntityInterface) && $this->targetEntity->hasField($field_name)) {
+      $field_definition = $this->targetEntity->get($field_name)->getFieldDefinition();
+
+      // @todo Nonconfigurable field types don't currently have default
+      //   formatters or widgets defined, but the formatter and plugin managers
+      //   require that, so until that's resolved, suppress returning field
+      //   definitions for those types.
+      $field_type = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field_definition->getFieldType());
+      if (!$field_type['configurable']) {
+        $field_definition = NULL;
+      }
+
+      return $field_definition;
+    }
+  }
 }
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
index b2879dc..2e0ad2d 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceAutoCreateTest.php
@@ -100,7 +100,7 @@ public function testAutoCreate() {
     $this->assertFalse($result, 'Referenced node does not exist yet.');
 
     $edit = array(
-      'title' => $this->randomName(),
+      'title[0][value]' => $this->randomName(),
       'test_field[0][target_id]' => $new_title,
     );
     $this->drupalPostForm("node/add/$this->referencing_type", $edit, 'Save');
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index 5567afd..385ebf3 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -6,7 +6,9 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\entity\Entity\EntityFormDisplay;
+use Drupal\field\FieldInstanceInterface;
 
 /**
  * @defgroup field_attach Field Attach API
@@ -63,7 +65,7 @@
  * @param string $method
  *   The name of the method to invoke.
  * @param callable $target_function
- *   A function that receives an $instance object and returns the object on
+ *   A function that receives a field definition and returns the object on
  *   which the method should be invoked.
  * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The fully formed $entity_type entity.
@@ -100,28 +102,32 @@ function field_invoke_method($method, $target_function, EntityInterface $entity,
   $options += $default_options;
 
   $entity_type = $entity->entityType();
-  // Determine the list of instances to iterate on.
-  $instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);
+  // Determine the list of fields to iterate on.
+  $field_definitions = _field_invoke_get_field_definitions($entity_type, $entity->bundle(), $options);
 
-  // Iterate through the instances and collect results.
+  // Iterate through the fields and collect results.
   $return = array();
-  foreach ($instances as $instance) {
+  foreach ($field_definitions as $field_definition) {
 
     // Let the function determine the target object on which the method should be
     // called.
-    $target = call_user_func($target_function, $instance);
+    $target = call_user_func($target_function, $field_definition);
 
     if (method_exists($target, $method)) {
-      $field = $instance->getField();
-      $field_name = $field->getFieldName();
-
       // Determine the list of languages to iterate on.
-      $available_langcodes = field_available_languages($entity_type, $field);
-      $langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_name);
+      // @todo Unify language fallback handling between configurable and base
+      //   fields.
+      if ($field_definition instanceof FieldInstanceInterface) {
+        $available_langcodes = field_available_languages($entity_type, $field_definition->getField());
+        $langcodes = _field_language_suggestion($available_langcodes, $options['langcode'], $field_definition->getFieldName());
+      }
+      else {
+        $langcodes = array($entity->language()->id);
+      }
 
       foreach ($langcodes as $langcode) {
         if ($entity->hasTranslation($langcode)) {
-          $items = $entity->getTranslation($langcode)->get($field_name);
+          $items = $entity->getTranslation($langcode)->get($field_definition->getFieldName());
           $items->filterEmptyValues();
 
           $result = $target->$method($items, $a, $b);
@@ -200,7 +206,7 @@ function field_invoke_method_multiple($method, $target_function, array $entities
     $entity_type = $entity->entityType();
 
     // Determine the list of instances to iterate on.
-    $entity_instances = _field_invoke_get_instances($entity_type, $entity->bundle(), $options);
+    $entity_instances = _field_invoke_get_field_definitions($entity_type, $entity->bundle(), $options);
 
     foreach ($entity_instances as $instance) {
       $instance_uuid = $instance->uuid();
@@ -264,7 +270,7 @@ function field_invoke_method_multiple($method, $target_function, array $entities
 }
 
 /**
- * Retrieves a list of instances to operate on.
+ * Retrieves a list of field definitions to operate on.
  *
  * Helper for field_invoke_method().
  *
@@ -281,9 +287,9 @@ function field_invoke_method_multiple($method, $target_function, array $entities
  *   See field_invoke_method() for details.
  *
  * @return
- *   The array of selected instance definitions.
+ *   The array of selected field definitions.
  */
-function _field_invoke_get_instances($entity_type, $bundle, $options) {
+function _field_invoke_get_field_definitions($entity_type, $bundle, $options) {
   if ($options['deleted']) {
     // Deleted fields are not included in field_info_instances(), and need to
     // be fetched from the database with field_read_instances().
@@ -294,12 +300,24 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
       // option.
       $params['field_id'] = $options['field_id'];
     }
-    $instances = field_read_instances($params, array('include_deleted' => TRUE));
+    $field_definitions = field_read_instances($params, array('include_deleted' => TRUE));
   }
   elseif (isset($options['field_name'])) {
-    // Single-field mode by field name: field_info_instance() does the
-    // filtering.
-    $instances = array(field_info_instance($entity_type, $options['field_name'], $bundle));
+    // @todo Replace with \Drupal::entityManager()->getFieldDefinition() after
+    //   [#2047229] lands.
+    $entity = _field_create_entity_from_ids((object) array('entity_type' => $entity_type, 'bundle' => $bundle, 'entity_id' => NULL));
+    $field_definitions = array($entity->get($options['field_name'])->getFieldDefinition());
+  }
+  elseif (isset($options['display'])) {
+    // @todo Replace with \Drupal::entityManager()->getFieldDefinitions() after
+    //   [#2047229] lands.
+    $entity = _field_create_entity_from_ids((object) array('entity_type' => $entity_type, 'bundle' => $bundle, 'entity_id' => NULL));
+    $field_definitions = array();
+    foreach ($options['display']->getComponents() as $name => $component_options) {
+      if ($entity->hasField($name)) {
+        $field_definitions[] = $entity->get($name)->getFieldDefinition();
+      }
+    }
   }
   else {
     $instances = field_info_instances($entity_type, $bundle);
@@ -313,15 +331,16 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
         }
       }
     }
+    $field_definitions = $instances;
   }
 
-  return $instances;
+  return $field_definitions;
 }
 
 /**
  * Defines a 'target function' for field_invoke_method().
  *
- * Used to invoke methods on an instance's widget.
+ * Used to invoke methods on a field's widget.
  *
  * @param \Drupal\entity\Entity\EntityFormDisplay $form_display
  *   An EntityFormDisplay object.
@@ -330,8 +349,8 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
  *   A 'target function' for field_invoke_method().
  */
 function _field_invoke_widget_target($form_display) {
-  return function ($instance) use ($form_display) {
-    return $form_display->getRenderer($instance->getFieldName());
+  return function (FieldDefinitionInterface $field_definition) use ($form_display) {
+    return $form_display->getRenderer($field_definition->getFieldName());
   };
 }
 
diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc
index 8ac2bc2..a8f08b2 100644
--- a/core/modules/field/field.deprecated.inc
+++ b/core/modules/field/field.deprecated.inc
@@ -8,10 +8,10 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Language\Language;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\entity\Entity\EntityDisplay;
 use Drupal\field\Field;
 
-
 /**
  * Returns information about field types.
  *
@@ -564,6 +564,7 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc
 
   // Get the entity_form_display object for this form.
   $form_display = $form_state['form_display'];
+  $options['display'] = $form_display;
 
   // If no language is provided use the default site language.
   $options['langcode'] = field_valid_language($langcode);
@@ -631,7 +632,9 @@ function field_attach_form_validate(ContentEntityInterface $entity, $form, &$for
 
   if ($has_violations) {
     // Map errors back to form elements.
-    field_invoke_method('flagErrors', _field_invoke_widget_target($form_state['form_display']), $entity, $form, $form_state, $options);
+    $form_display = $form_state['form_display'];
+    $options['display'] = $form_display;
+    field_invoke_method('flagErrors', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options);
   }
 }
 
@@ -658,6 +661,7 @@ function field_attach_form_validate(ContentEntityInterface $entity, $form, &$for
 function field_attach_extract_form_values(EntityInterface $entity, $form, &$form_state, array $options = array()) {
   // Extract field values from submitted values.
   $form_display = $form_state['form_display'];
+  $options['display'] = $form_display;
   field_invoke_method('extractFormValues', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options);
 
   // Let other modules act on submitting the entity.
@@ -757,14 +761,15 @@ function field_attach_prepare_view($entity_type, array $entities, array $display
  * @deprecated as of Drupal 8.0. Use the entity system instead.
  */
 function field_attach_view(EntityInterface $entity, EntityDisplay $display, $langcode = NULL, array $options = array()) {
+  $options['display'] = $display;
   // Determine the actual language code to display for each field, given the
   // language codes available in the field data.
   $options['langcode'] = field_language($entity, NULL, $langcode);
 
-  // For each instance, call the view() method on the formatter object handed
+  // For each field, call the view() method on the formatter object handed
   // by the entity display.
-  $target_function = function ($instance) use ($display) {
-    return $display->getRenderer($instance->getFieldName());
+  $target_function = function (FieldDefinitionInterface $field_definition) use ($display) {
+    return $display->getRenderer($field_definition->getFieldName());
   };
   $null = NULL;
   $output = field_invoke_method('view', $target_function, $entity, $null, $null, $options);
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 0d56a0a..5ec7580 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -4,6 +4,7 @@
  * Attach custom data fields to Drupal entities.
  */
 
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Template\Attribute;
 use Drupal\field\FieldInterface;
@@ -130,6 +131,9 @@ function field_theme() {
     'field' => array(
       'render element' => 'element',
     ),
+    'field__title' => array(
+      'base hook' => 'field',
+    ),
     'field_multiple_value_form' => array(
       'render element' => 'element',
     ),
@@ -470,7 +474,7 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display
  * The function takes care of invoking the prepare_view steps. It also respects
  * field access permissions.
  *
- * @param \Drupal\Core\Entity\EntityInterface $entity
+ * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity containing the field to display.
  * @param $field_name
  *   The name of the field to display.
@@ -503,16 +507,16 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display
  *
  * @see field_view_value()
  */
-function field_view_field(EntityInterface $entity, $field_name, $display_options = array(), $langcode = NULL) {
+function field_view_field(ContentEntityInterface $entity, $field_name, $display_options = array(), $langcode = NULL) {
   $output = array();
   $bundle = $entity->bundle();
   $entity_type = $entity->entityType();
 
   // Return nothing if the field doesn't exist.
-  $instance = field_info_instance($entity_type, $field_name, $bundle);
-  if (!$instance) {
+  if (!$entity->hasField($field_name)) {
     return $output;
   }
+  $field_definition = $entity->get($field_name)->getFieldDefinition();
 
   // Get the formatter object.
   if (is_string($display_options)) {
@@ -523,11 +527,10 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
     $view_mode = '_custom';
     // hook_field_attach_display_alter() needs to receive the 'prepared'
     // $display_options, so we cannot let preparation happen internally.
-    $field = field_info_field($entity_type, $field_name);
     $formatter_manager = Drupal::service('plugin.manager.field.formatter');
-    $display_options = $formatter_manager->prepareConfiguration($field->getFieldType(), $display_options);
+    $display_options = $formatter_manager->prepareConfiguration($field_definition->getFieldType(), $display_options);
     $formatter = $formatter_manager->getInstance(array(
-      'field_definition' => $instance,
+      'field_definition' => $field_definition,
       'view_mode' => $view_mode,
       'prepare' => FALSE,
       'configuration' => $display_options,
@@ -535,7 +538,14 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
   }
 
   if ($formatter) {
-    $display_langcode = field_language($entity, $field_name, $langcode);
+    // @todo Unify language fallback handling between configurable and base
+    //   fields.
+    if ($field_definition instanceof FieldInstanceInterface) {
+      $display_langcode = field_language($entity, $field_name, $langcode);
+    }
+    else {
+      $display_langcode = $entity->language()->id;
+    }
 
     // Invoke the formatter's prepareView() and view() methods.
     $items = $entity->getTranslation($display_langcode)->get($field_name);
@@ -778,6 +788,13 @@ function theme_field($variables) {
 }
 
 /**
+ * @todo Document.
+ */
+function theme_field__title($variables) {
+  return '<span' . $variables['attributes'] . '>' . drupal_render($variables['items']) . '</span>';
+}
+
+/**
  * Assembles a partial entity structure with initial IDs.
  *
  * @param object $ids
diff --git a/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php
index 928adbb..87e2347 100644
--- a/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/reEnableModuleFieldTest.php
@@ -85,8 +85,8 @@ function testReEnabledField() {
     // Submit an article node with a telephone field so data exist for the
     // field.
     $edit = array(
-      "title" => $this->randomName(),
-      "field_telephone[0][value]" => "123456789",
+      'title[0][value]' => $this->randomName(),
+      'field_telephone[0][value]' => "123456789",
     );
     $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->assertRaw('<a href="tel:123456789">');
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
index 7edeec7..0405c3a 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldTestBase.php
@@ -139,7 +139,7 @@ function updateFileField($name, $type_name, $instance_settings = array(), $widge
    */
   function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE, $extras = array()) {
     $edit = array(
-      "title" => $this->randomName(),
+      'title[0][value]' => $this->randomName(),
       'revision' => (string) (int) $new_revision,
     );
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
index d4e27f5..b6d6c48 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldValidateTest.php
@@ -37,7 +37,8 @@ function testRequired() {
     $test_file = $this->getTestFile('text');
 
     // Try to post a new node without uploading a file.
-    $edit = array("title" => $this->randomName());
+    $edit = array();
+    $edit['title[0][value]'] = $this->randomName();
     $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
     $this->assertRaw(t('!title field is required.', array('!title' => $instance->getFieldLabel())), 'Node save failed when required file field was empty.');
 
@@ -56,7 +57,8 @@ function testRequired() {
     $this->createFileField($field_name, 'node', $type_name, array('cardinality' => FieldDefinitionInterface::CARDINALITY_UNLIMITED), array('required' => '1'));
 
     // Try to post a new node without uploading a file in the multivalue field.
-    $edit = array('title' => $this->randomName());
+    $edit = array();
+    $edit['title[0][value]'] = $this->randomName();
     $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
     $this->assertRaw(t('!title field is required.', array('!title' => $instance->getFieldLabel())), 'Node save failed when required multiple value file field was empty.');
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
index d328bd5..bf80c17 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldWidgetTest.php
@@ -189,7 +189,7 @@ function testMultiValuedWidget() {
       $this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', array('%type' => $type)));
 
       // Save the node and ensure it does not have any files.
-      $this->drupalPostForm(NULL, array('title' => $this->randomName()), t('Save and publish'));
+      $this->drupalPostForm(NULL, array('title[0][value]' => $this->randomName()), t('Save and publish'));
       $matches = array();
       preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
       $nid = $matches[1];
@@ -267,10 +267,10 @@ function testPrivateFileComment() {
 
     // Create node.
     $edit = array(
-      'title' => $this->randomName(),
+      'title[0][value]' => $this->randomName(),
     );
     $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
 
     // Add a comment with a file.
     $text_file = $this->getTestFile('text');
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php
index bccc9f3..e10c5ca 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterAdminTest.php
@@ -232,13 +232,13 @@ function testFilterAdmin() {
     $text = $body . '<random>' . $extra_text . '</random>';
 
     $edit = array();
-    $edit["title"] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['body[0][value]'] = $text;
     $edit['body[0][format]'] = $basic;
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
-    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit["title"])), 'Filtered node created.');
+    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit['title[0][value]'])), 'Filtered node created.');
 
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue($node, 'Node found in database.');
 
     $this->drupalGet('node/' . $node->id());
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
index d18e7d5..cbf1661 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
@@ -211,11 +211,11 @@ function testFormatWidgetPermissions() {
     // Create node to edit.
     $this->drupalLogin($this->admin_user);
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit[$body_value_key] = $this->randomName(16);
     $edit[$body_format_key] = $this->disallowed_format->format;
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
 
     // Try to edit with a less privileged user.
     $this->drupalLogin($this->web_user);
@@ -227,14 +227,14 @@ function testFormatWidgetPermissions() {
 
     // Verify that title can be changed, but preview displays original body.
     $new_edit = array();
-    $new_edit['title'] = $this->randomName(8);
+    $new_edit['title[0][value]'] = $this->randomName(8);
     $this->drupalPostForm(NULL, $new_edit, t('Preview'));
     $this->assertText($edit[$body_value_key], 'Old body found in preview.');
 
     // Save and verify that only the title was changed.
     $this->drupalPostForm(NULL, $new_edit, t('Save'));
-    $this->assertNoText($edit['title'], 'Old title not found.');
-    $this->assertText($new_edit['title'], 'New title found.');
+    $this->assertNoText($edit['title[0][value]'], 'Old title not found.');
+    $this->assertText($new_edit['title[0][value]'], 'New title found.');
     $this->assertText($edit[$body_value_key], 'Old body found.');
 
     // Check that even an administrator with "administer filters" permission
@@ -266,9 +266,10 @@ function testFormatWidgetPermissions() {
 
     // Verify that trying to save the node without selecting a new text format
     // produces an error message, and does not result in the node being saved.
-    $old_title = $new_edit['title'];
+    $old_title = $new_edit['title[0][value]'];
     $new_title = $this->randomName(8);
-    $edit = array('title' => $new_title);
+    $edit = array();
+    $edit['title[0][value]'] = $new_title;
     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.');
     $this->drupalGet('node/' . $node->id());
@@ -302,7 +303,8 @@ function testFormatWidgetPermissions() {
     $this->drupalLogin($this->filter_admin_user);
     $old_title = $new_title;
     $new_title = $this->randomName(8);
-    $edit = array('title' => $new_title);
+    $edit = array();
+    $edit['title[0][value]'] = $new_title;
     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->assertText(t('!name field is required.', array('!name' => t('Text format'))), 'Error message is displayed.');
     $this->drupalGet('node/' . $node->id());
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php
index febf33d..b23ed88 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterHooksTest.php
@@ -65,11 +65,10 @@ function testFilterHooks() {
 
     // Use the format created.
     $title = $this->randomName(8);
-    $edit = array(
-      "title" => $title,
-      "body[0][value]" => $this->randomName(32),
-      "body[0][format]" => $format_id,
-    );
+    $edit = array();
+    $edit['title[0][value]'] = $title;
+    $edit['body[0][value]'] = $this->randomName(32);
+    $edit['body[0][format]'] = $format_id;
     $this->drupalPostForm("node/add/{$type->type}", $edit, t('Save and publish'));
     $this->assertText(t('@type @title has been created.', array('@type' => $type_name, '@title' => $title)));
 
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
index dda30f1..ab8feb9 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php
@@ -170,7 +170,7 @@ protected function createForumTopics($count = 5) {
       $date->modify('+1 minute');
 
       $edit = array(
-        'title' => $title,
+        'title[0][value]' => $title,
         'body[0][value]' => $body,
         // Forum posts are ordered by timestamp, so force a unique timestamp by
         // adding the index.
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php
index 3cc01d2..8c1f3ee 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php
@@ -47,7 +47,7 @@ function testForumIndexStatus() {
     // Create a test node.
     $title = $this->randomName(20);
     $edit = array(
-      'title' => $title,
+      'title[0][value]' => $title,
       'body[0][value]' => $this->randomName(200),
     );
 
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
index 489cc1b..99f8b25 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php
@@ -52,7 +52,7 @@ function testForumNodeAccess() {
     // Create a private node.
     $private_node_title = $this->randomName(20);
     $edit = array(
-      'title' => $private_node_title,
+      'title[0][value]' => $private_node_title,
       'body[0][value]' => $this->randomName(200),
       'private' => TRUE,
     );
@@ -63,7 +63,7 @@ function testForumNodeAccess() {
     // Create a public node.
     $public_node_title = $this->randomName(20);
     $edit = array(
-      'title' => $public_node_title,
+      'title[0][value]' => $public_node_title,
       'body[0][value]' => $this->randomName(200),
     );
     $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => 1)));
diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index 81d8d82..860e7c3 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -222,8 +222,11 @@ function testAddOrphanTopic() {
     entity_delete_multiple('taxonomy_term', $tids);
 
     // Create an orphan forum item.
+    $edit = array();
+    $edit['title[0][value]'] = $this->randomName(10);
+    $edit['body[0][value]'] = $this->randomName(120);
     $this->drupalLogin($this->admin_user);
-    $this->drupalPostForm('node/add/forum', array('title' => $this->randomName(10), 'body[0][value]' => $this->randomName(120)), t('Save'));
+    $this->drupalPostForm('node/add/forum', $edit, t('Save'));
 
     $nid_count = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
     $this->assertEqual(0, $nid_count, 'A forum node was not created when missing a forum vocabulary.');
@@ -481,7 +484,7 @@ function createForumTopic($forum, $container = FALSE) {
     $body = $this->randomName(200);
 
     $edit = array(
-      'title' => $title,
+      'title[0][value]' => $title,
       'body[0][value]' => $body,
     );
     $tid = $forum['tid'];
@@ -569,13 +572,13 @@ private function verifyForums($node_user, EntityInterface $node, $admin, $respon
     if ($response == 200) {
       // Edit forum node (including moving it to another forum).
       $edit = array();
-      $edit['title'] = 'node/' . $node->id();
+      $edit['title[0][value]'] = 'node/' . $node->id();
       $edit['body[0][value]'] = $this->randomName(256);
       // Assume the topic is initially associated with $forum.
       $edit['taxonomy_forums'] = $this->root_forum['tid'];
       $edit['shadow'] = TRUE;
       $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
-      $this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit["title"])), 'Forum node was edited');
+      $this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit['title[0][value]'])), 'Forum node was edited');
 
       // Verify topic was moved to a different forum.
       $forum_tid = db_query("SELECT tid FROM {forum} WHERE nid = :nid AND vid = :vid", array(
@@ -587,7 +590,7 @@ private function verifyForums($node_user, EntityInterface $node, $admin, $respon
       // Delete forum node.
       $this->drupalPostForm('node/' . $node->id() . '/delete', array(), t('Delete'));
       $this->assertResponse($response);
-      $this->assertRaw(t('Forum topic %title has been deleted.', array('%title' => $edit['title'])), 'Forum node was deleted');
+      $this->assertRaw(t('Forum topic %title has been deleted.', array('%title' => $edit['title[0][value]'])), 'Forum node was deleted');
     }
   }
 
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
index 64523a1..a000828 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldTestBase.php
@@ -114,7 +114,7 @@ function createImageField($name, $type_name, $field_settings = array(), $instanc
    */
   function uploadNodeImage($image, $field_name, $type) {
     $edit = array(
-      'title' => $this->randomName(),
+      'title[0][value]' => $this->randomName(),
     );
     $edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
     $this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php
index 39a9d43..d7dd52c 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuNodeTest.php
@@ -62,7 +62,7 @@ function testMenuNodeFormWidget() {
     // Create a node.
     $node_title = $this->randomName();
     $edit = array(
-      'title' => $node_title,
+      'title[0][value]' => $node_title,
       'body[0][value]' => $this->randomString(),
     );
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php
index d7b1f6a..9e1ea33 100644
--- a/core/modules/node/lib/Drupal/node/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Entity/Node.php
@@ -357,13 +357,13 @@ public static function baseFieldDefinitions($entity_type) {
     $properties['title'] = array(
       'label' => t('Title'),
       'description' => t('The title of this node, always treated as non-markup plain text.'),
-      'type' => 'string_field',
+      'type' => 'field_item:text',
+      'list_class' => '\Drupal\node\NodeTitleItemList',
       'required' => TRUE,
       'settings' => array(
         'default_value' => '',
-      ),
-      'property_constraints' => array(
-        'value' => array('Length' => array('max' => 255)),
+        'max_length' => 255,
+        'text_processing' => 0,
       ),
       'translatable' => TRUE,
     );
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index e14a662..705c355 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -101,18 +101,6 @@ public function form(array $form, array &$form_state) {
       '#default_value' => $node->getChangedTime(),
     );
 
-    $node_type = node_type_load($node->getType());
-    if ($node_type->has_title) {
-      $form['title'] = array(
-        '#type' => 'textfield',
-        '#title' => check_plain($node_type->title_label),
-        '#required' => TRUE,
-        '#default_value' => $node->title->value,
-        '#maxlength' => 255,
-        '#weight' => -5,
-      );
-    }
-
     $language_configuration = module_invoke('language', 'get_default_configuration', 'node', $node->getType());
     $form['langcode'] = array(
       '#title' => t('Language'),
diff --git a/core/modules/node/lib/Drupal/node/NodeTitleItemList.php b/core/modules/node/lib/Drupal/node/NodeTitleItemList.php
new file mode 100644
index 0000000..1295525
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/NodeTitleItemList.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\NodeTitleItemList.
+ */
+
+namespace Drupal\node;
+
+use Drupal\Core\Field\FieldItemList;
+
+/**
+ * @todo This class is a temporary hack for allowing the label of the node title
+ *   field to vary by node type. Remove it when https://drupal.org/node/2114707
+ *   is solved.
+ */
+class NodeTitleItemList extends FieldItemList {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $definition, $name, NodeInterface $node) {
+    $node_type = node_type_load($node->getType());
+    if (isset($node_type->title_label)) {
+      $definition['label'] = $node_type->title_label;
+    }
+    parent::__construct($definition, $name, $node);
+  }
+
+}
diff --git a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
index 25036b9..d8a67a0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/MultiStepNodeFormBasicOptionsTest.php
@@ -61,7 +61,7 @@ function testMultiStepNodeFormBasicOptions() {
       ->save();
 
     $edit = array(
-      'title' => 'a',
+      'title[0][value]' => 'a',
       'promote' => FALSE,
       'sticky' => 1,
       "{$this->field_name}[0][value]" => $this->randomString(32),
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
index 8fc72f6..e78b5bc 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
@@ -72,7 +72,7 @@ function testNodeAccessBasic() {
       $this->drupalLogin($this->webUser);
       foreach (array(0 => 'Public', 1 => 'Private') as $is_private => $type) {
         $edit = array(
-          'title' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->getUsername())),
+          'title[0][value]' => t('@private_public Article created by @user', array('@private_public' => $type, '@user' => $this->webUser->getUsername())),
         );
         if ($is_private) {
           $edit['private'] = TRUE;
@@ -85,13 +85,13 @@ function testNodeAccessBasic() {
         }
 
         $this->drupalPostForm('node/add/article', $edit, t('Save'));
-        $nid = db_query('SELECT nid FROM {node_field_data} WHERE title = :title', array(':title' => $edit['title']))->fetchField();
+        $nid = db_query('SELECT nid FROM {node_field_data} WHERE title = :title', array(':title' => $edit['title[0][value]']))->fetchField();
         $private_status = db_query('SELECT private FROM {node_access_test} where nid = :nid', array(':nid' => $nid))->fetchField();
         $this->assertTrue($is_private == $private_status, 'The private status of the node was properly set in the node_access_test table.');
         if ($is_private) {
           $private_nodes[] = $nid;
         }
-        $titles[$nid] = $edit['title'];
+        $titles[$nid] = $edit['title[0][value]'];
         $this->nodesByUser[$this->webUser->id()][$nid] = $is_private;
       }
     }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php
index 090a27e..5941fa7 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeCreationTest.php
@@ -45,15 +45,15 @@ function setUp() {
   function testNodeCreation() {
     // Create a node.
     $edit = array();
-    $edit["title"] = $this->randomName(8);
-    $edit["body[0][value]"] = $this->randomName(16);
+    $edit['title[0][value]'] = $this->randomName(8);
+    $edit['body[0][value]'] = $this->randomName(16);
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
     // Check that the Basic page has been created.
-    $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])), 'Basic page created.');
+    $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]'])), 'Basic page created.');
 
     // Check that the node exists in the database.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue($node, 'Node found in database.');
   }
 
@@ -110,7 +110,7 @@ function testUnpublishedNodeCreation() {
 
     // Create a node.
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
@@ -119,7 +119,7 @@ function testUnpublishedNodeCreation() {
     $this->assertText(t('Test page text'));
 
     // Confirm that the node was created.
-    $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])));
+    $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit['title[0][value]'])));
   }
 
   /**
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php
index 7a1ed97..2fb9918 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeEntityViewModeAlterTest.php
@@ -34,12 +34,12 @@ function testNodeViewModeChange() {
 
     // Create a node.
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = t('Data that should appear only in the body for the node.');
     $edit['body[0][summary]'] = t('Extra data that should appear only in the teaser for the node.');
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
 
     // Set the flag to alter the view mode and view the node.
     \Drupal::state()->set('node_test_change_view_mode', 'teaser');
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
index e6626ca..f535182 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php
@@ -70,7 +70,7 @@ function setUp() {
   function testMultilingualNodeForm() {
     // Create "Basic page" content.
     $langcode = language_get_default_langcode('node', 'page');
-    $title_key = "title";
+    $title_key = 'title[0][value]';
     $title_value = $this->randomName(8);
     $body_key = 'body[0][value]';
     $body_value = $this->randomName(16);
@@ -114,7 +114,7 @@ function testMultilingualNodeForm() {
    */
   function testMultilingualDisplaySettings() {
     // Create "Basic page" content.
-    $title_key = "title";
+    $title_key = 'title[0][value]';
     $title_value = $this->randomName(8);
     $body_key = 'body[0][value]';
     $body_value = $this->randomName(16);
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
index 539d695..1aa7dcd 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeFormButtonsTest.php
@@ -47,7 +47,7 @@ function testNodeFormButtons() {
 
     // Save the node and assert it's published after clicking
     // 'Save and publish'.
-    $edit = array('title' => $this->randomString());
+    $edit = array('title[0][value]' => $this->randomString());
     $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
 
     // Get the node.
@@ -83,7 +83,7 @@ function testNodeFormButtons() {
     $this->assertButtons(array(t('Save')), FALSE);
 
     // Create the node.
-    $edit = array('title' => $this->randomString());
+    $edit = array('title[0][value]' => $this->randomString());
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
     $node_2 = node_load(2);
     $this->assertTrue($node_2->isPublished(), 'Node is published');
@@ -118,7 +118,7 @@ function testNodeFormButtons() {
     // Verify the node is unpublished by default for a normal user.
     $this->drupalLogout();
     $this->drupalLogin($this->web_user);
-    $edit = array('title' => $this->randomString());
+    $edit = array('title[0][value]' => $this->randomString());
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
     $node_3 = node_load(3);
     $this->assertFalse($node_3->isPublished(), 'Node is unpublished');
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php
index 13d8ffd..bf23498 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeLastChangedTest.php
@@ -19,7 +19,7 @@ class NodeLastChangedTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('entity', 'user', 'node', 'field');
+  public static $modules = array('entity', 'user', 'node', 'field', 'text', 'filter');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php
index d213a69..1759837 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodePostSettingsTest.php
@@ -39,12 +39,12 @@ function testPagePostInfo() {
 
     // Create a node.
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
     // Check that the post information is displayed.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $elements = $this->xpath('//*[contains(@class,:class)]', array(':class' => 'submitted'));
     $this->assertEqual(count($elements), 1, 'Post information is displayed.');
     $node->delete();
@@ -56,7 +56,7 @@ function testPagePostInfo() {
 
     // Create a node.
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php
index 40015ec..9b503ff 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTitleTest.php
@@ -60,7 +60,7 @@ function testNodeTitle() {
     $this->assertEqual(current($this->xpath($xpath)), $node->label(), 'Node breadcrumb is equal to node title.', 'Node');
 
     // Test node title in comment preview.
-    $this->assertEqual(current($this->xpath('//article[@id=:id]/h2/a', array(':id' => 'node-' . $node->id()))), $node->label(), 'Node preview title is equal to node title.', 'Node');
+    $this->assertEqual(current($this->xpath('//article[@id=:id]/h2/a/span', array(':id' => 'node-' . $node->id()))), $node->label(), 'Node preview title is equal to node title.', 'Node');
 
     // Test node title is clickable on teaser list (/node).
     $this->drupalGet('node');
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php
index 3ec53b1..4eb58b7 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTitleXSSTest.php
@@ -29,7 +29,8 @@ function testNodeTitleXSS() {
 
     $xss = '<script>alert("xss")</script>';
     $title = $xss . $this->randomName();
-    $edit = array("title" => $title);
+    $edit = array();
+    $edit['title[0][value]'] = $title;
 
     $this->drupalPostForm('node/add/page', $edit, t('Preview'));
     $this->assertNoRaw($xss, 'Harmful tags are escaped when previewing a node.');
@@ -39,7 +40,7 @@ function testNodeTitleXSS() {
 
     $this->drupalGet('node/' . $node->id());
     // assertTitle() decodes HTML-entities inside the <title> element.
-    $this->assertTitle($edit["title"] . ' | Drupal', 'Title is diplayed when viewing a node.');
+    $this->assertTitle($title . ' | Drupal', 'Title is diplayed when viewing a node.');
     $this->assertNoRaw($xss, 'Harmful tags are escaped when viewing a node.');
 
     $this->drupalGet('node/' . $node->id() . '/edit');
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
index bab9996..96bfa86 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
@@ -56,7 +56,7 @@ protected function getTranslatorPermissions() {
    * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues().
    */
   protected function getNewEntityValues($langcode) {
-    return array('title' => $this->randomName()) + parent::getNewEntityValues($langcode);
+    return array('title' => array(array('value' => $this->randomName()))) + parent::getNewEntityValues($langcode);
   }
 
   /**
@@ -227,7 +227,7 @@ protected function doTestTranslations($path, array $values) {
     $languages = language_list();
     foreach ($this->langcodes as $langcode) {
       $this->drupalGet($path, array('language' => $languages[$langcode]));
-      $this->assertText($values[$langcode]['title'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode)));
+      $this->assertText($values[$langcode]['title'][0]['value'], format_string('The %langcode node translation is correctly displayed.', array('%langcode' => $langcode)));
     }
   }
 
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
index be9f1b8..dc655e7 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeInitialLanguageTest.php
@@ -101,11 +101,11 @@ function testNodeTypeInitialLanguageDefaults() {
   function testLanguageFieldVisibility() {
     // Creates a node to test Language field visibility feature.
     $edit = array(
-      'title' => $this->randomName(8),
+      'title[0][value]' => $this->randomName(8),
       'body[0][value]' => $this->randomName(16),
     );
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue($node, 'Node found in database.');
 
     // Loads node page and check if Language field is hidden by default.
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php
index 5e18494..7b0a0a0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php
@@ -54,13 +54,13 @@ public function testValidation() {
     $violations = $node->validate();
     $this->assertEqual(count($violations), 1, 'Violation found when title is too long.');
     $this->assertEqual($violations[0]->getPropertyPath(), 'title.0.value');
-    $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => 255)));
+    $this->assertEqual($violations[0]->getMessage(), '<em class="placeholder">Title</em>: the text may not be longer than 255 characters.');
 
     $node->set('title', NULL);
     $violations = $node->validate();
     $this->assertEqual(count($violations), 1, 'Violation found when title is not set.');
     $this->assertEqual($violations[0]->getPropertyPath(), 'title');
-    $this->assertEqual($violations[0]->getMessage(), t('This value should not be null.'));
+    $this->assertEqual($violations[0]->getMessage(), 'This value should not be null.');
 
     // Make the title valid again.
     $node->set('title', $this->randomString());
@@ -71,6 +71,6 @@ public function testValidation() {
     $violations = $node->validate();
     $this->assertEqual(count($violations), 1, 'Violation found when changed date is before the last changed date.');
     $this->assertEqual($violations[0]->getPropertyPath(), 'changed.0.value');
-    $this->assertEqual($violations[0]->getMessage(), t('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'));
+    $this->assertEqual($violations[0]->getMessage(), 'The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
   }
 }
diff --git a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
index 78bac8d..3e52eb0 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PageEditTest.php
@@ -35,7 +35,7 @@ function setUp() {
   function testPageEdit() {
     $this->drupalLogin($this->web_user);
 
-    $title_key = 'title';
+    $title_key = 'title[0][value]';
     $body_key = 'body[0][value]';
     // Create node to edit.
     $edit = array();
@@ -77,13 +77,13 @@ function testPageEdit() {
     // Edit the same node, creating a new revision.
     $this->drupalGet("node/" . $node->id() . "/edit");
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit[$body_key] = $this->randomName(16);
     $edit['revision'] = TRUE;
     $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
 
     // Ensure that the node revision has been created.
-    $revised_node = $this->drupalGetNodeByTitle($edit['title'], TRUE);
+    $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE);
     $this->assertNotIdentical($node->getRevisionId(), $revised_node->getRevisionId(), 'A new revision has been created.');
     // Ensure that the node author is preserved when it was not changed in the
     // edit form.
@@ -104,12 +104,12 @@ function testPageAuthoredBy() {
     // Create node to edit.
     $body_key = 'body[0][value]';
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit[$body_key] = $this->randomName(16);
     $this->drupalPostForm('node/add/page', $edit, t('Save and publish'));
 
     // Check that the node was authored by the currently logged in user.
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertIdentical($node->getAuthorId(), $this->admin_user->id(), 'Node authored by admin user.');
 
     // Try to change the 'authored by' field to an invalid user name.
diff --git a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
index 8bd1081..601dc54 100644
--- a/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/PagePreviewTest.php
@@ -110,7 +110,7 @@ function setUp() {
    * Checks the node preview functionality.
    */
   function testPagePreview() {
-    $title_key = "title";
+    $title_key = 'title[0][value]';
     $body_key = 'body[0][value]';
     $term_key = $this->field_name;
 
@@ -181,7 +181,7 @@ function testPagePreview() {
    * Checks the node preview functionality, when using revisions.
    */
   function testPagePreviewWithRevisions() {
-    $title_key = 'title';
+    $title_key = 'title[0][value]';
     $body_key = 'body[0][value]';
     $term_key = $this->field_name;
     // Force revision on "Basic page" content.
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 438104d..6282f2a 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -19,6 +19,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Template\Attribute;
 use Drupal\entity\Entity\EntityDisplay;
+use Drupal\entity\Entity\EntityFormDisplay;
 use Drupal\file\Entity\File;
 use Drupal\user\UserInterface;
 
@@ -191,14 +192,40 @@ function node_entity_bundle_info() {
  * Implements hook_entity_display_alter().
  */
 function node_entity_display_alter(EntityDisplay $display, $context) {
-  // Hide field labels in search index.
-  if ($context['entity_type'] == 'node' && $context['view_mode'] == 'search_index') {
-    foreach ($display->getComponents() as $name => $options) {
-      if (isset($options['label'])) {
-        $options['label'] = 'hidden';
-        $display->setComponent($name, $options);
+  if ($context['entity_type'] == 'node') {
+    // Hide field labels in search index.
+    if ($context['view_mode'] == 'search_index') {
+      foreach ($display->getComponents() as $name => $options) {
+        if (isset($options['label'])) {
+          $options['label'] = 'hidden';
+          $display->setComponent($name, $options);
+        }
       }
     }
+    // @todo Manage base field displays in the YAML.
+    $display->setComponent('title', array(
+      'label' => 'hidden',
+      'type' => 'text_default',
+    ));
+  }
+}
+
+/**
+ * Implements hook_entity_form_display_alter().
+ */
+function node_entity_form_display_alter(EntityFormDisplay $form_display, $context) {
+  if ($context['entity_type'] == 'node') {
+    // @todo Manage base field displays in the YAML.
+    $node_type = node_type_load($context['bundle']);
+    if ($node_type->has_title) {
+      // Title is also registered in node_field_extra_fields().
+      $options = $form_display->getComponent('title') ?: array('weight' => -5);
+      $options['type'] = 'text_textfield';
+      $form_display->setComponent('title', $options);
+    }
+    else {
+      $form_display->removeComponent('title');
+    }
   }
 }
 
@@ -648,7 +675,8 @@ function template_preprocess_node(&$variables) {
 
   $uri = $node->uri();
   $variables['node_url']  = url($uri['path'], $uri['options']);
-  $variables['label'] = check_plain($node->label());
+  $variables['label'] = $variables['elements']['title'];
+  unset($variables['elements']['title']);
   $variables['page'] = $variables['view_mode'] == 'full' && node_is_page($node);
 
   // Helpful $content variable for templates.
diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
index 8a1d9b2..dd476fe 100644
--- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
+++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php
@@ -199,7 +199,7 @@ function testNumberIntegerField() {
     // Create new content and check that prefix and suffix are shown.
     $rand_number = rand();
     $edit = array(
-      'title' => $this->randomName(),
+      'title[0][value]' => $this->randomName(),
       'field_' .$field_name . '[0][value]' => $rand_number,
     );
     $this->drupalPostForm("node/add/$type", $edit, t('Save'));
diff --git a/core/modules/overlay/lib/Drupal/overlay/Tests/OverlayCloseTest.php b/core/modules/overlay/lib/Drupal/overlay/Tests/OverlayCloseTest.php
index 406755c..46f021c 100644
--- a/core/modules/overlay/lib/Drupal/overlay/Tests/OverlayCloseTest.php
+++ b/core/modules/overlay/lib/Drupal/overlay/Tests/OverlayCloseTest.php
@@ -45,7 +45,7 @@ function testNodeCreation() {
 
     // Create a new node, with ?render=overlay in the query parameter to
     // simulate creating it inside the overlay.
-    $this->drupalPostForm('node/add/test', array('title' => 'Test node title'), t('Save'), array('query' => array('render' => 'overlay')));
+    $this->drupalPostForm('node/add/test', array('title[0][value]' => 'Test node title'), t('Save'), array('query' => array('render' => 'overlay')));
 
     // Make sure a bare minimum HTML page is displayed that contains the
     // JavaScript necessary to close the overlay.
diff --git a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
index 63ebf66..d4f7ec5 100644
--- a/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
+++ b/core/modules/path/lib/Drupal/path/Tests/PathLanguageTest.php
@@ -94,7 +94,7 @@ function testAliasTranslation() {
     $this->clickLink(t('Add'));
 
     $edit = array();
-    $edit['title'] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['body[0][value]'] = $this->randomName();
     $french_alias = $this->randomName();
     $edit['path[alias]'] = $french_alias;
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index a4c7b27..ab58a7f 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -2260,7 +2260,7 @@ protected function assertNoLinkByHref($href, $message = '', $group = 'Other') {
    */
   protected function clickLink($label, $index = 0) {
     $url_before = $this->getUrl();
-    $urls = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label));
+    $urls = $this->xpath('//a[normalize-space()=:label]', array(':label' => $label));
 
     if (isset($urls[$index])) {
       $url_target = $this->getAbsoluteUrl($urls[$index]['href']);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
index 78326e9..7530db1 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationFormTest.php
@@ -60,14 +60,14 @@ function testEntityFormLanguage() {
 
     // Create a node with language Language::LANGCODE_NOT_SPECIFIED.
     $edit = array();
-    $edit["title"] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
 
     $this->drupalGet('node/add/page');
     $form_langcode = \Drupal::state()->get('entity_test.form_langcode') ?: FALSE;
     $this->drupalPostForm(NULL, $edit, t('Save'));
 
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue($node->language()->id == $form_langcode, 'Form language is the same as the entity language.');
 
     // Edit the node and test the form language.
@@ -91,14 +91,14 @@ function testEntityFormLanguage() {
     // Create a node with language.
     $edit = array();
     $langcode = $this->langcodes[0];
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
     $edit['langcode'] = $langcode;
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
-    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit["title"])), 'Basic page created.');
+    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $edit['title[0][value]'])), 'Basic page created.');
 
     // Check to make sure the node was created.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue($node, 'Node found in database.');
 
     // Make body translatable.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php
index 262537b..6f3bd49 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/ContextPluginTest.php
@@ -17,7 +17,7 @@
  */
 class ContextPluginTest extends DrupalUnitTestBase {
 
-  public static $modules = array('system', 'user', 'node', 'field');
+  public static $modules = array('system', 'user', 'node', 'field', 'filter', 'text');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
index d08817d..bafa68d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php
@@ -71,16 +71,16 @@ function testTitleTags() {
     $this->assertTrue(strpos(drupal_get_title(), '<em>') !== FALSE, 'Tags in title are not converted to entities when $output is PASS_THROUGH.');
     // Generate node content.
     $edit = array(
-      'title' => '!SimpleTest! ' . $title . $this->randomName(20),
+      'title[0][value]' => '!SimpleTest! ' . $title . $this->randomName(20),
       'body[0][value]' => '!SimpleTest! test body' . $this->randomName(200),
     );
     // Create the node with HTML in the title.
     $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertNotNull($node, 'Node created and found in database');
     $this->drupalGet("node/" . $node->id());
-    $this->assertText(check_plain($edit["title"]), 'Check to make sure tags in the node title are converted.');
+    $this->assertText(check_plain($edit['title[0][value]']), 'Check to make sure tags in the node title are converted.');
   }
   /**
    * Test if the title of the site is XSS proof.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
index 76c3b06..20b4e54 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/FieldUpgradePathTest.php
@@ -285,7 +285,7 @@ function testFieldUpgradeToConfig() {
     // Check that creation of a new node works as expected.
     $value = $this->randomName();
     $edit = array(
-      'title' => 'Node after CMI conversion',
+      'title[0][value]' => 'Node after CMI conversion',
       'body[0][value]' => $value,
     );
     $this->drupalPostForm('node/add/article', $edit, 'Save and publish');
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
index 8c72ac0..9852d72 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
@@ -37,14 +37,14 @@ function testTaxonomyLegacyNode() {
     // Posts an article with a taxonomy term and a date prior to 1970.
     $date = new DrupalDateTime('1969-01-01 00:00:00');
     $edit = array();
-    $edit['title'] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['date[date]'] = $date->format('Y-m-d');
     $edit['date[time]'] = $date->format('H:i:s');
     $edit['body[0][value]'] = $this->randomName();
     $edit['field_tags'] = $this->randomName();
     $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
     // Checks that the node has been saved.
-    $node = $this->drupalGetNodeByTitle($edit['title']);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.');
   }
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
index e89c531..875fc59 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/RssTest.php
@@ -94,7 +94,7 @@ function testTaxonomyRss() {
 
     // Post an article.
     $edit = array();
-    $edit["title"] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit[$this->field_name . '[]'] = $term1->id();
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
index c7abc5c..c1e9bb2 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermIndexTest.php
@@ -105,14 +105,14 @@ function testTaxonomyIndex() {
 
     // Post an article.
     $edit = array();
-    $edit["title"] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['body[0][value]'] = $this->randomName();
     $edit["{$this->field_name_1}[]"] = $term_1->id();
     $edit["{$this->field_name_2}[]"] = $term_1->id();
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     // Check that the term is indexed, and only once.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $index_count = db_query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', array(
       ':nid' => $node->id(),
       ':tid' => $term_1->id(),
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 26f04ad..7664cf4 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -112,13 +112,13 @@ function testTaxonomyNode() {
 
     // Post an article.
     $edit = array();
-    $edit['title'] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['body[0][value]'] = $this->randomName();
     $edit[$this->instance->getFieldName() . '[]'] = $term1->id();
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when the node is viewed.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->drupalGet('node/' . $node->id());
     $this->assertText($term1->label(), 'Term is displayed when viewing the node.');
 
@@ -163,7 +163,7 @@ function testNodeTermCreationAndDeletion() {
     );
 
     $edit = array();
-    $edit['title'] = $this->randomName();
+    $edit['title[0][value]'] = $this->randomName();
     $edit['body[0][value]'] = $this->randomName();
     // Insert the terms in a comma separated list. Vocabulary 1 is a
     // free-tagging field created by the default profile.
@@ -186,7 +186,7 @@ function testNodeTermCreationAndDeletion() {
 
     // Save, creating the terms.
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit["title"])), 'The node was created successfully.');
+    $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title[0][value]'])), 'The node was created successfully.');
     foreach ($terms as $term) {
       $this->assertText($term, 'The term was saved and appears on the node page.');
     }
@@ -207,7 +207,7 @@ function testNodeTermCreationAndDeletion() {
     $term_names = array($term_objects['term3']->label(), $term_objects['term4']->label());
 
     // Get the node.
-    $node = $this->drupalGetNodeByTitle($edit["title"]);
+    $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->drupalGet('node/' . $node->id());
 
     foreach ($term_names as $term_name) {
@@ -520,7 +520,7 @@ function testReSavingTags() {
     // Create a term and a node using it.
     $term = $this->createTerm($this->vocabulary);
     $edit = array();
-    $edit['title'] = $this->randomName(8);
+    $edit['title[0][value]'] = $this->randomName(8);
     $edit['body[0][value]'] = $this->randomName(16);
     $edit[$this->instance->getFieldName()] = $term->label();
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
diff --git a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
index 1f5ab23..f66f6d9 100644
--- a/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
+++ b/core/modules/telephone/lib/Drupal/telephone/Tests/TelephoneFieldTest.php
@@ -87,8 +87,8 @@ function testTelephoneField() {
 
     // Test basic entery of telephone field.
     $edit = array(
-      "title" => $this->randomName(),
-      "field_telephone[0][value]" => "123456789",
+      'title[0][value]' => $this->randomName(),
+      'field_telephone[0][value]' => "123456789",
     );
 
     $this->drupalPostForm(NULL, $edit, t('Save'));
@@ -96,8 +96,8 @@ function testTelephoneField() {
 
     // Add number with a space in it. Need to ensure it is stripped on output.
     $edit = array(
-      "title" => $this->randomName(),
-      "field_telephone[0][value]" => "1234 56789",
+      'title[0][value]' => $this->randomName(),
+      'field_telephone[0][value]' => "1234 56789",
     );
 
     $this->drupalPostForm('node/add/article', $edit, t('Save'));
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
index 8a04604..a4dabc7 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -110,15 +110,15 @@ function testTaggedWith() {
 
     // Create three nodes, with different tags.
     $edit = array();
-    $edit['title'] = $node_tag1_title = $this->randomName();
+    $edit['title[0][value]'] = $node_tag1_title = $this->randomName();
     $edit[$this->tag_field->name] = 'tag1';
     $this->drupalPostForm($node_add_path, $edit, t('Save'));
     $edit = array();
-    $edit['title'] = $node_tag1_tag2_title = $this->randomName();
+    $edit['title[0][value]'] = $node_tag1_tag2_title = $this->randomName();
     $edit[$this->tag_field->name] = 'tag1, tag2';
     $this->drupalPostForm($node_add_path, $edit, t('Save'));
     $edit = array();
-    $edit['title'] = $node_no_tags_title = $this->randomName();
+    $edit['title[0][value]'] = $node_no_tags_title = $this->randomName();
     $this->drupalPostForm($node_add_path, $edit, t('Save'));
 
     // Create a view that filters by taxonomy term "tag1". It should show only
