diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 7ed3cbd..f3e1740 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -359,7 +359,15 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
     if (is_string(key($form_state->getValue('roles')))) {
       $form_state->setValue('roles', array_keys(array_filter($form_state->getValue('roles'))));
     }
-    return parent::buildEntity($form, $form_state);
+
+    /** @var \Drupal\user\UserInterface $account */
+    $account = parent::buildEntity($form, $form_state);
+
+    $signature = $form_state->getValue('signature');
+    $account->setSignature($signature['value']);
+    $account->setSignatureFormat($signature['format']);
+
+    return $account;
   }
 
   /**
@@ -368,64 +376,23 @@ public function buildEntity(array $form, FormStateInterface $form_state) {
   public function validate(array $form, FormStateInterface $form_state) {
     parent::validate($form, $form_state);
 
-    $account = $this->entity;
-    // Validate new or changing username.
-    if ($form_state->hasValue('name')) {
-      if ($error = user_validate_name($form_state->getValue('name'))) {
-        $form_state->setErrorByName('name', $error);
-      }
-      // Cast the user ID as an integer. It might have been set to NULL, which
-      // could lead to unexpected results.
-      else {
-        $name_taken = (bool) $this->entityQuery->get('user')
-          ->condition('uid', (int) $account->id(), '<>')
-          ->condition('name', $form_state->getValue('name'))
-          ->range(0, 1)
-          ->count()
-          ->execute();
-
-        if ($name_taken) {
-          $form_state->setErrorByName('name', $this->t('The username %name is already taken.', array('%name' => $form_state->getValue('name'))));
-        }
-      }
+    /** @var \Drupal\user\UserInterface $account */
+    $account = $this->buildEntity($form, $form_state);
+    // Customly trigger validation of manually added fields and add in
+    // violations.
+    $violations = $account->name->validate();
+    foreach ($violations as $violation) {
+      $form_state->setErrorByName('name', $violation->getMessage());
     }
 
-    $mail = $form_state->getValue('mail');
-
-    if (!empty($mail)) {
-      $mail_taken = (bool) $this->entityQuery->get('user')
-        ->condition('uid', (int) $account->id(), '<>')
-        ->condition('mail', $mail)
-        ->range(0, 1)
-        ->count()
-        ->execute();
-
-      if ($mail_taken) {
-        // Format error message dependent on whether the user is logged in or not.
-        if (\Drupal::currentUser()->isAuthenticated()) {
-          $form_state->setErrorByName('mail', $this->t('The email address %email is already taken.', array('%email' => $mail)));
-        }
-        else {
-          $form_state->setErrorByName('mail', $this->t('The email address %email is already registered. <a href="@password">Have you forgotten your password?</a>', array('%email' => $mail, '@password' => $this->url('user.pass'))));
-        }
-      }
+    $violations = $account->mail->validate();
+    foreach ($violations as $violation) {
+      $form_state->setErrorByName('mail', $violation->getMessage());
     }
 
-    // Make sure the signature isn't longer than the size of the database field.
-    // Signatures are disabled by default, so make sure it exists first.
-    if ($signature = $form_state->getValue('signature')) {
-      // Move text format for user signature into 'signature_format'.
-      $form_state->setValue('signature_format', $signature['format']);
-      // Move text value for user signature into 'signature'.
-      $form_state->setValue('signature', $signature['value']);
-
-      // @todo Make the user signature field use a widget to benefit from
-      //   automatic typed data validation in https://drupal.org/node/2227381.
-      $field_definitions = $this->entityManager->getFieldDefinitions('user', $this->getEntity()->bundle());
-      $max_length = $field_definitions['signature']->getSetting('max_length');
-      if (Unicode::strlen($form_state->getValue('signature')) > $max_length) {
-        $form_state->setErrorByName('signature', $this->t('The signature is too long: it must be %max characters or less.', array('%max' => $max_length)));
-      }
+    $violations = $account->signature->validate();
+    foreach ($violations as $violation) {
+      $form_state->setErrorByName('signature', $violation->getMessage());
     }
   }
 
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 22303e5..8cc2a09 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -291,6 +291,14 @@ public function getSignature() {
   /**
    * {@inheritdoc}
    */
+  public function setSignature($signature) {
+    $this->get('signature')->value = $signature;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getSignatureFormat() {
     return $this->get('signature_format')->value;
   }
@@ -298,6 +306,14 @@ public function getSignatureFormat() {
   /**
    * {@inheritdoc}
    */
+  public function setSignatureFormat($signature_format) {
+    $this->get('signature_format')->value = $signature_format;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getCreatedTime() {
     return $this->get('created')->value;
   }
diff --git a/core/modules/user/src/Tests/UserEditTest.php b/core/modules/user/src/Tests/UserEditTest.php
index 308fad9..0ee9599 100644
--- a/core/modules/user/src/Tests/UserEditTest.php
+++ b/core/modules/user/src/Tests/UserEditTest.php
@@ -16,12 +16,43 @@
  */
 class UserEditTest extends WebTestBase {
 
+  public static $modules = array('filter');
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->config('user.settings')->set('signatures', TRUE)->save();
+
+    // Prefetch and create text formats.
+    $this->filtered_html_format = entity_create('filter_format', array(
+      'format' => 'filtered_html_format',
+      'name' => 'Filtered HTML',
+      'weight' => -1,
+      'filters' => array(
+        'filter_html' => array(
+          'module' => 'filter',
+          'status' => TRUE,
+          'settings' => array(
+            'allowed_html' => '<a> <em> <strong>',
+          ),
+        ),
+      ),
+    ));
+    $this->filtered_html_format->save();
+
+    $this->full_html_format = entity_create('filter_format', array(
+      'format' => 'full_html',
+      'name' => 'Full HTML',
+    ));
+    $this->full_html_format->save();
+  }
+
   /**
    * Test user edit page.
    */
   function testUserEdit() {
     // Test user edit functionality.
-    $user1 = $this->drupalCreateUser(array('change own username'));
+    $user1 = $this->drupalCreateUser(array('change own username', $this->full_html_format->getPermissionName(), $this->filtered_html_format->getPermissionName()));
     $user2 = $this->drupalCreateUser(array());
     $this->drupalLogin($user1);
 
@@ -85,6 +116,11 @@ function testUserEdit() {
     $config->set('password_strength', FALSE)->save();
     $this->drupalPostForm("user/" . $user1->id() . "/edit", $edit, t('Save'));
     $this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.');
+
+    // Test user signature
+    $edit = array('signature[format]' => $this->full_html_format->id(), 'signature[value]' => $this->randomString(256));
+    $this->drupalPostForm('user/' . $user1->id() . '/edit', $edit, t('Save'));
+    $this->assertRaw(t("%name: may not be longer than @max characters.", array('%name' => t('Signature'), '@max' => 255)));
   }
 
   /**
diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/src/Tests/UserRegistrationTest.php
index 853891a..221667f 100644
--- a/core/modules/user/src/Tests/UserRegistrationTest.php
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -138,13 +138,13 @@ function testRegistrationEmailDuplicates() {
 
     // Attempt to create a new account using an existing email address.
     $this->drupalPostForm('user/register', $edit, t('Create new account'));
-    $this->assertText(t('The email address @email is already registered.', array('@email' => $duplicate_user->getEmail())), 'Supplying an exact duplicate email address displays an error message');
+    $this->assertText(t('The email address @email is already taken.', array('@email' => $duplicate_user->getEmail())), 'Supplying an exact duplicate email address displays an error message');
 
     // Attempt to bypass duplicate email registration validation by adding spaces.
     $edit['mail'] = '   ' . $duplicate_user->getEmail() . '   ';
 
     $this->drupalPostForm('user/register', $edit, t('Create new account'));
-    $this->assertText(t('The email address @email is already registered.', array('@email' => $duplicate_user->getEmail())), 'Supplying a duplicate email address with added whitespace displays an error message');
+    $this->assertText(t('The email address @email is already taken.', array('@email' => $duplicate_user->getEmail())), 'Supplying a duplicate email address with added whitespace displays an error message');
   }
 
   function testRegistrationDefaultValues() {
diff --git a/core/modules/user/src/UserInterface.php b/core/modules/user/src/UserInterface.php
index e2c44d0..6ccad91 100644
--- a/core/modules/user/src/UserInterface.php
+++ b/core/modules/user/src/UserInterface.php
@@ -97,6 +97,19 @@ public function setEmail($mail);
   public function getSignature();
 
   /**
+   * Set the user signature.
+   *
+   * @todo: Convert this to a configurable field.
+   *
+   * @param string $signature
+   *   The new signature text of the user.
+   *
+   * @return \Drupal\user\UserInterface
+   *   The called user entity.
+   */
+  public function setSignature($signature);
+
+  /**
    * Returns the signature format.
    *
    * @return string
@@ -105,6 +118,17 @@ public function getSignature();
   public function getSignatureFormat();
 
   /**
+   * Set the signature format.
+   *
+   * @param string
+   *   The name of the new filter format.
+   *
+   * @return \Drupal\user\UserInterface
+   *   The called user entity.
+   */
+  public function setSignatureFormat($signature_format);
+
+  /**
    * Returns the creation time of the user as a UNIX timestamp.
    *
    * @return int
