diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 390d976..199263b 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -536,52 +536,6 @@ function entity_get_form(EntityInterface $entity, $operation = 'default', array
 }
 
 /**
- * Copies submitted values to entity properties for simple entity forms.
- *
- * During the submission handling of an entity form's "Save", "Preview", and
- * possibly other buttons, the form state's entity needs to be updated with the
- * submitted form values. Each entity form implements its own builder function
- * for doing this, appropriate for the particular entity and form, whereas
- * modules may specify additional builder functions in $form['#entity_builders']
- * for copying the form values of added form elements to entity properties.
- * Many of the main entity builder functions can call this helper function to
- * re-use its logic of copying $form_state['values'][PROPERTY] values to
- * $entity->PROPERTY for all entries in $form_state['values'] that are not
- * field data, and calling field_attach_extract_form_values() to copy field
- * data. Apart from that this helper invokes any additional builder functions
- * that have been specified in $form['#entity_builders'].
- *
- * For some entity forms (e.g., forms with complex non-field data and forms that
- * simultaneously edit multiple entities), this behavior may be inappropriate,
- * so the builder function for such forms needs to implement the required
- * functionality instead of calling this function.
- */
-function entity_form_submit_build_entity($entity_type, $entity, $form, &$form_state, array $options = array()) {
-  $info = entity_get_info($entity_type);
-
-  // Copy top-level form values that are not for fields to entity properties,
-  // without changing existing entity properties that are not being edited by
-  // this form. Copying field values must be done using
-  // field_attach_extract_form_values().
-  $values_excluding_fields = $info['fieldable'] ? array_diff_key($form_state['values'], field_info_instances($entity_type, $entity->bundle())) : $form_state['values'];
-  foreach ($values_excluding_fields as $key => $value) {
-    $entity->set($key, $value);
-  }
-
-  // Invoke all specified builders for copying form values to entity properties.
-  if (isset($form['#entity_builders'])) {
-    foreach ($form['#entity_builders'] as $function) {
-      call_user_func_array($function, array($entity_type, $entity, &$form, &$form_state));
-    }
-  }
-
-  // Copy field values to the entity.
-  if ($info['fieldable']) {
-    field_attach_extract_form_values($entity, $form, $form_state, $options);
-  }
-}
-
-/**
  * Returns an entity list controller for a given entity type.
  *
  * @param string $entity_type
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
index aa1cb34..c0fe632 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -74,24 +74,16 @@ public function isNew() {
   }
 
   /**
-   * Overrides Entity::get().
-   *
-   * EntityInterface::get() implements support for fieldable entities, but
-   * configuration entities are not fieldable.
+   * {@inheritdoc}
    */
-  public function get($property_name, $langcode = NULL) {
-    // @todo: Add support for translatable properties being not fields.
+  public function get($property_name) {
     return isset($this->{$property_name}) ? $this->{$property_name} : NULL;
   }
 
   /**
-   * Overrides Entity::set().
-   *
-   * EntityInterface::set() implements support for fieldable entities, but
-   * configuration entities are not fieldable.
+   * {@inheritdoc}
    */
-  public function set($property_name, $value, $langcode = NULL, $notify = TRUE) {
-    // @todo: Add support for translatable properties being not fields.
+  public function set($property_name, $value) {
     $this->{$property_name} = $value;
   }
 
@@ -149,7 +141,7 @@ public static function sort($a, $b) {
   }
 
   /**
-   * Overrides \Drupal\Core\Entity\Entity::getExportProperties().
+   * {@inheritdoc}
    */
   public function getExportProperties() {
     // Configuration objects do not have a schema. Extract all key names from
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
index 0d9bd71..d1adc69 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php
@@ -76,6 +76,27 @@ public function setStatus($status);
   public function status();
 
   /**
+   * Returns the value of a property.
+   *
+   * @param string $property_name
+   *   The name of the property that should be returned.
+   *
+   * @return mixed
+   *   The property, if existing, NULL otherwise.
+   */
+  public function get($property_name);
+
+  /**
+   * Sets the value of a property.
+   *
+   * @param string $property_name
+   *   The name of the property that should be set.
+   * @param mixed $value
+   *   The value the property should be set to.
+   */
+  public function set($property_name, $value);
+
+  /**
    * Retrieves the exportable properties of the entity.
    *
    * These are the values that get saved into config.
diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
similarity index 83%
rename from core/lib/Drupal/Core/Entity/EntityNG.php
rename to core/lib/Drupal/Core/Entity/ContentEntityBase.php
index df1ea79..389bf8b 100644
--- a/core/lib/Drupal/Core/Entity/EntityNG.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -2,27 +2,20 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\EntityNG.
+ * Contains \Drupal\Core\Entity\ContentEntityBase.
  */
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Core\Entity\Plugin\DataType\EntityReference;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
 
 /**
  * Implements Entity Field API specific enhancements to the Entity class.
- *
- * Entity(..)NG classes are variants of the Entity(...) classes that implement
- * the next generation (NG) entity field API. They exist during conversion to
- * the new API only and changes will be merged into the respective original
- * classes once the conversion is complete.
- *
- * @todo: Once all entity types have been converted, merge improvements into the
- * Entity class and overhaul the EntityInterface.
  */
-class EntityNG extends Entity {
+abstract class ContentEntityBase extends Entity implements \IteratorAggregate, ContentEntityInterface {
 
   /**
    * Status code indentifying a removed translation.
@@ -85,7 +78,7 @@ class EntityNG extends Entity {
   /**
    * Local cache for field definitions.
    *
-   * @see EntityNG::getPropertyDefinitions()
+   * @see ContentEntityBase::getPropertyDefinitions()
    *
    * @var array
    */
@@ -127,6 +120,20 @@ class EntityNG extends Entity {
   protected $translationInitialize = FALSE;
 
   /**
+   * Boolean indicating whether a new revision should be created on save.
+   *
+   * @var bool
+   */
+  protected $newRevision = FALSE;
+
+  /**
+   * Indicates whether this is the default revision.
+   *
+   * @var bool
+   */
+  protected $isDefaultRevision = TRUE;
+
+  /**
    * Overrides Entity::__construct().
    */
   public function __construct(array $values, $entity_type, $bundle = FALSE, $translations = array()) {
@@ -160,6 +167,154 @@ public function __construct(array $values, $entity_type, $bundle = FALSE, $trans
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function setNewRevision($value = TRUE) {
+    $this->newRevision = $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isNewRevision() {
+    $info = $this->entityInfo();
+    return $this->newRevision || (!empty($info['entity_keys']['revision']) && !$this->getRevisionId());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isDefaultRevision($new_value = NULL) {
+    $return = $this->isDefaultRevision;
+    if (isset($new_value)) {
+      $this->isDefaultRevision = (bool) $new_value;
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionId() {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isTranslatable() {
+    // @todo Inject the entity manager and retrieve bundle info from it.
+    $bundles = entity_get_bundles($this->entityType);
+    return !empty($bundles[$this->bundle()]['translatable']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefinition() {
+    // @todo: This does not make much sense, so remove once TypedDataInterface
+    // is removed. See https://drupal.org/node/2002138.
+    if ($this->bundle() != $this->entityType()) {
+      $type = 'entity:' . $this->entityType() . ':' . $this->bundle();
+    }
+    else {
+      $type = 'entity:' . $this->entityType();
+    }
+    return array('type' => $type);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue() {
+    // @todo: This does not make much sense, so remove once TypedDataInterface
+    // is removed. See https://drupal.org/node/2002138.
+    return $this->getPropertyValues();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setValue($value, $notify = TRUE) {
+    // @todo: This does not make much sense, so remove once TypedDataInterface
+    // is removed. See https://drupal.org/node/2002138.
+    $this->setPropertyValues($value);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getString() {
+    return $this->label();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate() {
+    // @todo: Add the typed data manager as proper dependency.
+    return \Drupal::typedData()->getValidator()->validate($this);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applyDefaultValue($notify = TRUE) {
+    foreach ($this->getProperties() as $property) {
+      $property->applyDefaultValue(FALSE);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConstraints() {
+    return array();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getName() {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRoot() {
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyPath() {
+    return '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getParent() {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setContext($name = NULL, TypedDataInterface $parent = NULL) {
+    // As entities are always the root of the tree of typed data, we do not need
+    // to set any parent or name.
+  }
+
+  /**
    * Initialize the object. Invoked upon construction and wake up.
    */
   protected function init() {
@@ -188,14 +343,14 @@ public function __wakeup() {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::id().
+   * {@inheritdoc}
    */
   public function id() {
     return $this->id->value;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::bundle().
+   * {@inheritdoc}
    */
   public function bundle() {
     return $this->bundle;
@@ -209,7 +364,7 @@ public function uuid() {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::get().
+   * {@inheritdoc}
    */
   public function get($property_name) {
     if (!isset($this->fields[$property_name][$this->activeLangcode])) {
@@ -254,14 +409,14 @@ protected function getTranslatedField($property_name, $langcode) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
+   * {@inheritdoc}
    */
   public function set($property_name, $value, $notify = TRUE) {
     $this->get($property_name)->setValue($value, FALSE);
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getProperties().
+   * {@inheritdoc}
    */
   public function getProperties($include_computed = FALSE) {
     $properties = array();
@@ -274,14 +429,14 @@ public function getProperties($include_computed = FALSE) {
   }
 
   /**
-   * Implements \IteratorAggregate::getIterator().
+   * {@inheritdoc}
    */
   public function getIterator() {
     return new \ArrayIterator($this->getProperties());
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition().
+   * {@inheritdoc}
    */
   public function getPropertyDefinition($name) {
     if (!isset($this->fieldDefinitions)) {
@@ -296,7 +451,7 @@ public function getPropertyDefinition($name) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   * {@inheritdoc}
    */
   public function getPropertyDefinitions() {
     if (!isset($this->fieldDefinitions)) {
@@ -307,7 +462,7 @@ public function getPropertyDefinitions() {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyValues().
+   * {@inheritdoc}
    */
   public function getPropertyValues() {
     $values = array();
@@ -318,7 +473,7 @@ public function getPropertyValues() {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::setPropertyValues().
+   * {@inheritdoc}
    */
   public function setPropertyValues($values) {
     foreach ($values as $name => $value) {
@@ -327,7 +482,7 @@ public function setPropertyValues($values) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty().
+   * {@inheritdoc}
    */
   public function isEmpty() {
     if (!$this->isNew()) {
@@ -378,7 +533,7 @@ public function language() {
    */
   protected function getDefaultLanguage() {
     // Keep a local cache of the language object and clear it if the langcode
-    // gets changed, see EntityNG::onChange().
+    // gets changed, see ContentEntityBase::onChange().
     if (!isset($this->language)) {
       // Get the language code if the property exists.
       if ($this->getPropertyDefinition('langcode') && ($item = $this->get('langcode')) && isset($item->language)) {
@@ -404,7 +559,7 @@ public function onChange($property_name) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslation().
+   * {@inheritdoc}
    *
    * @return \Drupal\Core\Entity\EntityInterface
    */
@@ -768,4 +923,25 @@ public function label($langcode = NULL) {
     return $label;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function referencedEntities() {
+    $referenced_entities = array();
+
+    // Gather a list of referenced entities.
+    foreach ($this->getProperties() as $field_items) {
+      foreach ($field_items as $field_item) {
+        // Loop over all properties of a field item.
+        foreach ($field_item->getProperties(TRUE) as $property) {
+          if ($property instanceof EntityReference && $entity = $property->getTarget()) {
+            $referenced_entities[] = $entity;
+          }
+        }
+      }
+    }
+
+    return $referenced_entities;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php b/core/lib/Drupal/Core/Entity/ContentEntityConfirmFormBase.php
similarity index 91%
rename from core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php
rename to core/lib/Drupal/Core/Entity/ContentEntityConfirmFormBase.php
index d0bf4ef..c43cd9c 100644
--- a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityConfirmFormBase.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\Core\Entity\EntityNGConfirmFormBase.
+ * Contains \Drupal\Core\Entity\ContentEntityConfirmFormBase.
  */
 
 namespace Drupal\Core\Entity;
@@ -13,7 +13,7 @@
 /**
  * Provides a generic base class for an entity-based confirmation form.
  */
-abstract class EntityNGConfirmFormBase extends EntityFormControllerNG implements ConfirmFormInterface {
+abstract class ContentEntityConfirmFormBase extends ContentEntityFormController implements ConfirmFormInterface {
 
   /**
    * {@inheritdoc}
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityFormController.php b/core/lib/Drupal/Core/Entity/ContentEntityFormController.php
new file mode 100644
index 0000000..c12683b
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/ContentEntityFormController.php
@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\ContentEntityFormController.
+ */
+
+namespace Drupal\Core\Entity;
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Entity form controller variant for content entity types.
+ *
+ * @see \Drupal\Core\ContentEntityBase
+ */
+class ContentEntityFormController extends EntityFormController {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, array &$form_state) {
+    $entity = $this->entity;
+    // @todo Exploit the Field API to generate the default widgets for the
+    // entity fields.
+    $info = $entity->entityInfo();
+    if (!empty($info['fieldable'])) {
+      field_attach_form($entity, $form, $form_state, $this->getFormLangcode($form_state));
+    }
+
+    // Add a process callback so we can assign weights and hide extra fields.
+    $form['#process'][] = array($this, 'processForm');
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate(array $form, array &$form_state) {
+    $entity = $this->buildEntity($form, $form_state);
+    $entity_type = $entity->entityType();
+    $entity_langcode = $entity->language()->id;
+
+    $violations = array();
+    foreach ($entity as $field_name => $field) {
+      $field_violations = $field->validate();
+      if (count($field_violations)) {
+        $violations[$field_name] = $field_violations;
+      }
+    }
+
+    // Map errors back to form elements.
+    if ($violations) {
+      foreach ($violations as $field_name => $field_violations) {
+        $langcode = field_is_translatable($entity_type, field_info_field($entity_type, $field_name)) ? $entity_langcode : Language::LANGCODE_NOT_SPECIFIED;
+        $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
+        $field_state['constraint_violations'] = $field_violations;
+        field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
+      }
+
+      field_invoke_method('flagErrors', _field_invoke_widget_target($form_state['form_display']), $entity, $form, $form_state);
+    }
+
+    // @todo Remove this.
+    // Execute legacy global validation handlers.
+    unset($form_state['validate_handlers']);
+    form_execute_handlers('validate', $form, $form_state);
+  }
+
+  /**
+   * Initialize the form state and the entity before the first form build.
+   */
+  protected function init(array &$form_state) {
+    // Ensure we act on the translation object corresponding to the current form
+    // language.
+    $this->entity = $this->getTranslatedEntity($form_state);
+    parent::init($form_state);
+  }
+
+  /**
+   * Returns the translation object corresponding to the form language.
+   *
+   * @param array $form_state
+   *   A keyed array containing the current state of the form.
+   */
+  protected function getTranslatedEntity(array $form_state) {
+    $langcode = $this->getFormLangcode($form_state);
+    $translation = $this->entity->getTranslation($langcode);
+    // Ensure that the entity object is a BC entity if the original one is.
+    return $this->entity instanceof EntityBCDecorator ? $translation->getBCEntity() : $translation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormLangcode(array $form_state) {
+    $entity = $this->entity;
+    if (!empty($form_state['langcode'])) {
+      $langcode = $form_state['langcode'];
+    }
+    else {
+      // If no form langcode was provided we default to the current content
+      // language and inspect existing translations to find a valid fallback,
+      // if any.
+      $translations = $entity->getTranslationLanguages();
+      $languageManager = \Drupal::languageManager();
+      $langcode = $languageManager->getLanguage(Language::TYPE_CONTENT)->id;
+      $fallback = $languageManager->isMultilingual() ? language_fallback_get_candidates() : array();
+      while (!empty($langcode) && !isset($translations[$langcode])) {
+        $langcode = array_shift($fallback);
+      }
+    }
+
+    // If the site is not multilingual or no translation for the given form
+    // language is available, fall back to the entity language.
+    if (!empty($langcode))  {
+      return $langcode;
+    }
+    else {
+      // If the entity is translatable, return the original language.
+      return $entity->getUntranslated()->language()->id;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isDefaultFormLangcode(array $form_state) {
+    return $this->getFormLangcode($form_state) == $this->entity->getUntranslated()->language()->id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildEntity(array $form, array &$form_state) {
+    $entity = clone $this->entity;
+    $entity_type = $entity->entityType();
+    $info = entity_get_info($entity_type);
+    // @todo Exploit the Field API to process the submitted entity fields.
+
+    // Copy top-level form values that are entity fields but not handled by
+    // field API without changing existing entity fields that are not being
+    // edited by this form. Values of fields handled by field API are copied
+    // by field_attach_extract_form_values() below.
+    $values_excluding_fields = $info['fieldable'] ? array_diff_key($form_state['values'], field_info_instances($entity_type, $entity->bundle())) : $form_state['values'];
+    $definitions = $entity->getPropertyDefinitions();
+    foreach ($values_excluding_fields as $key => $value) {
+      if (isset($definitions[$key])) {
+        $entity->$key = $value;
+      }
+    }
+
+    // Invoke all specified builders for copying form values to entity fields.
+    if (isset($form['#entity_builders'])) {
+      foreach ($form['#entity_builders'] as $function) {
+        call_user_func_array($function, array($entity_type, $entity, &$form, &$form_state));
+      }
+    }
+
+    // Invoke field API for copying field values.
+    if ($info['fieldable']) {
+      field_attach_extract_form_values($entity, $form, $form_state, array('langcode' => $this->getFormLangcode($form_state)));
+    }
+    return $entity;
+  }
+}
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
index 9f2186f..93f28b8 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
@@ -7,9 +7,52 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Core\TypedData\ComplexDataInterface;
+use Drupal\Core\TypedData\TranslatableInterface;
+
 /**
  * Defines a common interface for all content entity objects.
+ *
+ * This interface builds upon the general interfaces provided by the typed data
+ * API, while extending them with content entity-specific additions. I.e., a
+ * content entity implements the ComplexDataInterface among others, thus is
+ * complex data containing fields as its data properties. The contained fields
+ * have to implement \Drupal\Core\Entity\Field\FieldItemListInterface,
+ * which builds upon typed data interfaces as well.
+ *
+ * When implementing this interface which extends Traversable, make sure to list
+ * IteratorAggregate or Iterator before this interface in the implements clause.
+ *
+ * @see \Drupal\Core\TypedData\TypedDataManager
+ * @see \Drupal\Core\Entity\Field\FieldItemListInterface
  */
-interface ContentEntityInterface extends EntityInterface {
+interface ContentEntityInterface extends EntityInterface, RevisionableInterface, TranslatableInterface, ComplexDataInterface {
+
+  /**
+   * Marks the translation identified by the given language code as existing.
+   *
+   * @param string $langcode
+   *   The language code identifying the translation to be initialized.
+   *
+   * @todo Remove this as soon as translation metadata have been converted to
+   *    regular fields.
+   */
+  public function initTranslation($langcode);
+
+  /**
+   * Defines the base fields of the entity type.
+   *
+   * @param string $entity_type
+   *   The entity type to return properties for. Useful when a single class is
+   *   used for multiple, possibly dynamic entity types.
+   *
+   * @return array
+   *   An array of entity field definitions as specified by
+   *   \Drupal\Core\Entity\EntityManager::getFieldDefinitions(), keyed by field
+   *   name.
+   *
+   * @see \Drupal\Core\Entity\EntityManager::getFieldDefinitions()
+   */
+  public static function baseFieldDefinitions($entity_type);
 
 }
diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
index 02b9978..3fe24c2 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
@@ -22,9 +22,7 @@
  * @todo: Once all entity types have been converted, merge improvements into the
  * DatabaseStorageController class.
  *
- * See the EntityNG documentation for an explanation of "NG".
- *
- * @see \Drupal\Core\EntityNG
+ * @see \Drupal\Core\ContentEntityBase
  */
 class DatabaseStorageControllerNG extends DatabaseStorageController {
 
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index fd1dc38..34aa09d 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -9,19 +9,12 @@
 
 use Drupal\Core\Entity\Plugin\DataType\EntityReferenceItem;
 use Drupal\Core\Language\Language;
-use Drupal\Core\TypedData\TranslatableInterface;
-use Drupal\Core\TypedData\TypedDataInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
  * Defines a base entity class.
- *
- * Default implementation of EntityInterface.
- *
- * This class can be used as-is by simple entity types. Entity types requiring
- * special handling can extend the class.
  */
-class Entity implements \IteratorAggregate, EntityInterface {
+abstract class Entity implements EntityInterface {
 
   /**
    * The language code of the entity's default language.
@@ -45,20 +38,6 @@ class Entity implements \IteratorAggregate, EntityInterface {
   protected $enforceIsNew;
 
   /**
-   * Boolean indicating whether a new revision should be created on save.
-   *
-   * @var bool
-   */
-  protected $newRevision = FALSE;
-
-  /**
-   * Indicates whether this is the default revision.
-   *
-   * @var bool
-   */
-  protected $isDefaultRevision = TRUE;
-
-  /**
    * Constructs an Entity object.
    *
    * @param array $values
@@ -76,64 +55,49 @@ public function __construct(array $values, $entity_type) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::id().
+   * {@inheritdoc}
    */
   public function id() {
     return isset($this->id) ? $this->id : NULL;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::uuid().
+   * {@inheritdoc}
    */
   public function uuid() {
     return isset($this->uuid) ? $this->uuid : NULL;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isNew().
+   * {@inheritdoc}
    */
   public function isNew() {
     return !empty($this->enforceIsNew) || !$this->id();
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isNewRevision().
-   */
-  public function isNewRevision() {
-    $info = $this->entityInfo();
-    return $this->newRevision || (!empty($info['entity_keys']['revision']) && !$this->getRevisionId());
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::enforceIsNew().
+   * {@inheritdoc}
    */
   public function enforceIsNew($value = TRUE) {
     $this->enforceIsNew = $value;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::setNewRevision().
-   */
-  public function setNewRevision($value = TRUE) {
-    $this->newRevision = $value;
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::entityType().
+   * {@inheritdoc}
    */
   public function entityType() {
     return $this->entityType;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::bundle().
+   * {@inheritdoc}
    */
   public function bundle() {
     return $this->entityType;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::label().
+   * {@inheritdoc}
    */
   public function label($langcode = NULL) {
     $label = NULL;
@@ -269,83 +233,9 @@ public function uriRelationships() {
     return isset($entity_info['links']) ? array_keys($entity_info['links']) : array();
   }
 
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::get().
-   */
-  public function get($property_name, $langcode = NULL) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-    return isset($this->{$property_name}) ? $this->{$property_name} : NULL;
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
-   */
-  public function set($property_name, $value, $notify = TRUE) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-    $this->{$property_name} = $value;
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getProperties().
-   */
-  public function getProperties($include_computed = FALSE) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyValues().
-   */
-  public function getPropertyValues() {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::setPropertyValues().
-   */
-  public function setPropertyValues($values) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition().
-   */
-  public function getPropertyDefinition($name) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
-   */
-  public function getPropertyDefinitions() {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty().
-   */
-  public function isEmpty() {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getIterator().
-   */
-  public function getIterator() {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-    return new \ArrayIterator(array());
-  }
 
   /**
-   * Implements \Drupal\Core\TypedData\AccessibleInterface::access().
+   * {@inheritdoc}
    */
   public function access($operation = 'view', AccountInterface $account = NULL) {
     if ($operation == 'create') {
@@ -359,11 +249,9 @@ public function access($operation = 'view', AccountInterface $account = NULL) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::language().
+   * {@inheritdoc}
    */
   public function language() {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
     $language = language_load($this->langcode);
     if (!$language) {
       // Make sure we return a proper language object.
@@ -373,66 +261,14 @@ public function language() {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslation().
-   *
-   * @return \Drupal\Core\Entity\EntityInterface
-   */
-  public function getTranslation($langcode) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-    return $this;
-  }
-
-  /**
-   * Returns the languages the entity is translated to.
-   *
-   * @todo: Remove once all entity types implement the entity field API.
-   *   This is deprecated by
-   *   \Drupal\Core\TypedData\TranslatableInterface::getTranslationLanguages().
-   */
-  public function translations() {
-    return $this->getTranslationLanguages(FALSE);
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslationLanguages().
-   */
-  public function getTranslationLanguages($include_default = TRUE) {
-    // @todo: Replace by EntityNG implementation once all entity types have been
-    // converted to use the entity field API.
-    $default_language = $this->language();
-    $languages = array($default_language->id => $default_language);
-    $entity_info = $this->entityInfo();
-
-    if ($entity_info['fieldable']) {
-      // Go through translatable properties and determine all languages for
-      // which translated values are available.
-      foreach (field_info_instances($this->entityType, $this->bundle()) as $field_name => $instance) {
-        if (field_is_translatable($this->entityType, $instance->getField()) && isset($this->$field_name)) {
-          foreach (array_filter($this->$field_name) as $langcode => $value)  {
-            $languages[$langcode] = TRUE;
-          }
-        }
-      }
-      $languages = array_intersect_key(language_list(Language::STATE_ALL), $languages);
-    }
-
-    if (empty($include_default)) {
-      unset($languages[$default_language->id]);
-    }
-
-    return $languages;
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::save().
+   * {@inheritdoc}
    */
   public function save() {
     return \Drupal::entityManager()->getStorageController($this->entityType)->save($this);
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::delete().
+   * {@inheritdoc}
    */
   public function delete() {
     if (!$this->isNew()) {
@@ -441,7 +277,7 @@ public function delete() {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::createDuplicate().
+   * {@inheritdoc}
    */
   public function createDuplicate() {
     $duplicate = clone $this;
@@ -457,154 +293,13 @@ public function createDuplicate() {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::entityInfo().
+   * {@inheritdoc}
    */
   public function entityInfo() {
     return \Drupal::entityManager()->getDefinition($this->entityType());
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::getRevisionId().
-   */
-  public function getRevisionId() {
-    return NULL;
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isDefaultRevision().
-   */
-  public function isDefaultRevision($new_value = NULL) {
-    $return = $this->isDefaultRevision;
-    if (isset($new_value)) {
-      $this->isDefaultRevision = (bool) $new_value;
-    }
-    return $return;
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::getExportProperties().
-   */
-  public function getExportProperties() {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefinition() {
-    // @todo: This does not make much sense, so remove once TypedDataInterface
-    // is removed. See https://drupal.org/node/2002138.
-    if ($this->bundle() != $this->entityType()) {
-      $type = 'entity:' . $this->entityType() . ':' . $this->bundle();
-    }
-    else {
-      $type = 'entity:' . $this->entityType();
-    }
-    return array('type' => $type);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getValue() {
-    // @todo: This does not make much sense, so remove once TypedDataInterface
-    // is removed. See https://drupal.org/node/2002138.
-    return $this->getPropertyValues();
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::setValue().
-   */
-  public function setValue($value, $notify = TRUE) {
-    // @todo: This does not make much sense, so remove once TypedDataInterface
-    // is removed. See https://drupal.org/node/2002138.
-    $this->setPropertyValues($value);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getString() {
-    return $this->label();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConstraints() {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validate() {
-    // @todo: Add the typed data manager as proper dependency.
-    return \Drupal::typedData()->getValidator()->validate($this);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyDefaultValue($notify = TRUE) {
-    foreach ($this->getProperties() as $property) {
-      $property->applyDefaultValue(FALSE);
-    }
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange().
-   */
-  public function onChange($property_name) {
-    // Nothing to do.
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::getName().
-   */
-  public function getName() {
-    return NULL;
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::getRoot().
-   */
-  public function getRoot() {
-    return $this;
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::getPropertyPath().
-   */
-  public function getPropertyPath() {
-    return '';
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::getParent().
-   */
-  public function getParent() {
-    return NULL;
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TypedDataInterface::setContext().
-   */
-  public function setContext($name = NULL, TypedDataInterface $parent = NULL) {
-    // As entities are always the root of the tree of typed data, we do not need
-    // to set any parent or name.
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isTranslatable().
-   */
-  public function isTranslatable() {
-    // @todo Inject the entity manager and retrieve bundle info from it.
-    $bundles = entity_get_bundles($this->entityType);
-    return !empty($bundles[$this->bundle()]['translatable']);
-  }
-
-  /**
    * {@inheritdoc}
    */
   public function preSave(EntityStorageControllerInterface $storage_controller) {
@@ -653,80 +348,8 @@ public static function postLoad(EntityStorageControllerInterface $storage_contro
   /**
    * {@inheritdoc}
    */
-  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) {
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getUntranslated() {
-    return $this->getTranslation(Language::LANGCODE_DEFAULT);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasTranslation($langcode) {
-    $translations = $this->getTranslationLanguages();
-    return isset($translations[$langcode]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addTranslation($langcode, array $values = array()) {
-    // @todo Config entities do not support entity translation hence we need to
-    //   move the TranslatableInterface implementation to EntityNG. See
-    //   http://drupal.org/node/2004244
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function removeTranslation($langcode) {
-    // @todo Config entities do not support entity translation hence we need to
-    //   move the TranslatableInterface implementation to EntityNG. See
-    //   http://drupal.org/node/2004244
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initTranslation($langcode) {
-    // @todo Config entities do not support entity translation hence we need to
-    //   move the TranslatableInterface implementation to EntityNG. See
-    //   http://drupal.org/node/2004244
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function baseFieldDefinitions($entity_type) {
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function referencedEntities() {
-    $referenced_entities = array();
-
-    // @todo Remove when all entities are converted to EntityNG.
-    if (!$this->getPropertyDefinitions()) {
-      return $referenced_entities;
-    }
-
-    // Gather a list of referenced entities.
-    foreach ($this->getProperties() as $name => $definition) {
-      $field_items = $this->get($name);
-      foreach ($field_items as $offset => $field_item) {
-        if ($field_item instanceof EntityReferenceItem && $entity = $field_item->entity) {
-          $referenced_entities[] = $entity;
-        }
-      }
-    }
-
-    return $referenced_entities;
+    return array();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index d59ace3..7dcd16a 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Entity;
 
 use Drupal\Core\Form\FormBase;
+use Drupal\Core\TypedData\TranslatableInterface;
 use Drupal\entity\EntityFormDisplayInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\Language;
@@ -120,10 +121,6 @@ protected function init(array &$form_state) {
     // module-provided form handlers there.
     $form_state['controller'] = $this;
 
-    // Ensure we act on the translation object corresponding to the current form
-    // language.
-    $this->entity = $this->getTranslatedEntity($form_state);
-
     // Prepare the entity to be presented in the entity form.
     $this->prepareEntity();
 
@@ -167,7 +164,7 @@ public function form(array $form, array &$form_state) {
       // new entities.
       $form['langcode'] = array(
         '#type' => 'value',
-        '#value' => !$entity->isNew() ? $entity->getUntranslated()->language()->id : language_default()->id,
+        '#value' => !$entity->isNew() ? $entity->language()->id : language_default()->id,
       );
     }
     return $form;
@@ -269,33 +266,9 @@ protected function actions(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::validate().
+   * {@inheritdoc}
    */
   public function validate(array $form, array &$form_state) {
-    $entity = $this->buildEntity($form, $form_state);
-    $entity_type = $entity->entityType();
-    $entity_langcode = $entity->language()->id;
-
-    $violations = array();
-
-    foreach ($entity as $field_name => $field) {
-      $field_violations = $field->validate();
-      if (count($field_violations)) {
-        $violations[$field_name] = $field_violations;
-      }
-    }
-
-    // Map errors back to form elements.
-    if ($violations) {
-      foreach ($violations as $field_name => $field_violations) {
-        $field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
-        $field_state['constraint_violations'] = $field_violations;
-        field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
-      }
-
-      field_invoke_method('flagErrors', _field_invoke_widget_target($form_state['form_display']), $entity, $form, $form_state);
-    }
-
     // @todo Remove this.
     // Execute legacy global validation handlers.
     unset($form_state['validate_handlers']);
@@ -303,7 +276,7 @@ public function validate(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::submit().
+   * {@inheritdoc}
    *
    * This is the default entity object builder function. It is called before any
    * other submit handler to build the new entity object to be passed to the
@@ -350,36 +323,18 @@ public function delete(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::getFormLangcode().
+   * {@inheritdoc}
    */
   public function getFormLangcode(array $form_state) {
-    $entity = $this->entity;
-
-    if (!empty($form_state['langcode'])) {
-      $langcode = $form_state['langcode'];
-    }
-    else {
-      // If no form langcode was provided we default to the current content
-      // language and inspect existing translations to find a valid fallback,
-      // if any.
-      $translations = $entity->getTranslationLanguages();
-      $langcode = language(Language::TYPE_CONTENT)->id;
-      $fallback = language_multilingual() ? language_fallback_get_candidates() : array();
-      while (!empty($langcode) && !isset($translations[$langcode])) {
-        $langcode = array_shift($fallback);
-      }
-    }
-
-    // If the site is not multilingual or no translation for the given form
-    // language is available, fall back to the entity language.
-    return !empty($langcode) ? $langcode : $entity->getUntranslated()->language()->id;
+    return $this->entity->language()->id;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::isDefaultFormLangcode().
+   * {@inheritdoc}
    */
   public function isDefaultFormLangcode(array $form_state) {
-    return $this->getFormLangcode($form_state) == $this->entity->getUntranslated()->language()->id;
+    // The entity is not translatable, this is always the default language.
+    return TRUE;
   }
 
   /**
@@ -396,7 +351,7 @@ protected function updateFormLangcode(array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::buildEntity().
+   * {@inheritdoc}
    */
   public function buildEntity(array $form, array &$form_state) {
     $entity = clone $this->entity;
@@ -404,32 +359,37 @@ public function buildEntity(array $form, array &$form_state) {
     // the controller to be the one before caching. Ensure to have the
     // controller of the current request.
     $form_state['controller'] = $this;
-    // @todo Move entity_form_submit_build_entity() here.
-    // @todo Exploit the Field API to process the submitted entity field.
-    entity_form_submit_build_entity($entity->entityType(), $entity, $form, $form_state, array('langcode' => $this->getFormLangcode($form_state)));
+
+    // Copy top-level form values to entity properties, without changing
+    // existing entity properties that are not being edited by
+    // this form.
+    // @todo: This relies on a method that only exists for config and content
+    //   entities, in a different way. Consider moving this logic to a config
+    //   entity specific implementation.
+    foreach ($form_state['values'] as $key => $value) {
+      $entity->set($key, $value);
+    }
+
+    // Invoke all specified builders for copying form values to entity
+    // properties.
+    if (isset($form['#entity_builders'])) {
+      foreach ($form['#entity_builders'] as $function) {
+        call_user_func_array($function, array($entity->entityType(), $entity, &$form, &$form_state));
+      }
+    }
+
     return $entity;
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::getEntity().
+   * {@inheritdoc}
    */
   public function getEntity() {
     return $this->entity;
   }
 
   /**
-   * Returns the translation object corresponding to the form language.
-   *
-   * @param array $form_state
-   *   A keyed array containing the current state of the form.
-   */
-  protected function getTranslatedEntity(array $form_state) {
-    $langcode = $this->getFormLangcode($form_state);
-    return $this->entity->getTranslation($langcode);
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::setEntity().
+   * {@inheritdoc}
    */
   public function setEntity(EntityInterface $entity) {
     $this->entity = $entity;
@@ -456,7 +416,7 @@ protected function prepareInvokeAll($hook, array &$form_state) {
       if (function_exists($function)) {
         // Ensure we pass an updated translation object and form display at
         // each invocation, since they depend on form state which is alterable.
-        $args = array($this->getTranslatedEntity($form_state), $this->getFormDisplay($form_state), $this->operation, &$form_state);
+        $args = array($this->entity, $this->getFormDisplay($form_state), $this->operation, &$form_state);
         call_user_func_array($function, $args);
       }
     }
@@ -478,7 +438,7 @@ public function setFormDisplay(EntityFormDisplayInterface $form_display, array &
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityFormControllerInterface::getOperation().
+   * {@inheritdoc}
    */
   public function getOperation() {
     return $this->operation;
diff --git a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php b/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php
deleted file mode 100644
index 11396d9..0000000
--- a/core/lib/Drupal/Core/Entity/EntityFormControllerNG.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Entity\EntityFormControllerNG.
- */
-
-namespace Drupal\Core\Entity;
-
-/**
- * Entity form controller variant for entity types using the new property API.
- *
- * @todo: Merge with EntityFormController and overhaul once all entity types
- * are converted to the new entity field API.
- *
- * See the EntityNG documentation for an explanation of "NG".
- *
- * @see \Drupal\Core\EntityNG
- */
-class EntityFormControllerNG extends EntityFormController {
-
-  /**
-   * Overrides EntityFormController::form().
-   */
-  public function form(array $form, array &$form_state) {
-    $entity = $this->entity;
-    // @todo Exploit the Field API to generate the default widgets for the
-    // entity fields.
-    $info = $entity->entityInfo();
-    if (!empty($info['fieldable'])) {
-      field_attach_form($entity, $form, $form_state, $this->getFormLangcode($form_state));
-    }
-
-    // Add a process callback so we can assign weights and hide extra fields.
-    $form['#process'][] = array($this, 'processForm');
-
-    return $form;
-  }
-
-  /**
-   * Overrides EntityFormController::buildEntity().
-   */
-  public function buildEntity(array $form, array &$form_state) {
-    $entity = clone $this->entity;
-    $entity_type = $entity->entityType();
-    $info = entity_get_info($entity_type);
-    // @todo Exploit the Field API to process the submitted entity fields.
-
-    // Copy top-level form values that are entity fields but not handled by
-    // field API without changing existing entity fields that are not being
-    // edited by this form. Values of fields handled by field API are copied
-    // by field_attach_extract_form_values() below.
-    $values_excluding_fields = $info['fieldable'] ? array_diff_key($form_state['values'], field_info_instances($entity_type, $entity->bundle())) : $form_state['values'];
-    $definitions = $entity->getPropertyDefinitions();
-    foreach ($values_excluding_fields as $key => $value) {
-      if (isset($definitions[$key])) {
-        $entity->$key = $value;
-      }
-    }
-
-    // Invoke all specified builders for copying form values to entity fields.
-    if (isset($form['#entity_builders'])) {
-      foreach ($form['#entity_builders'] as $function) {
-        call_user_func_array($function, array($entity_type, $entity, &$form, &$form_state));
-      }
-    }
-
-    // Invoke field API for copying field values.
-    if ($info['fieldable']) {
-      field_attach_extract_form_values($entity, $form, $form_state, array('langcode' => $this->getFormLangcode($form_state)));
-    }
-    return $entity;
-  }
-}
diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php
index 7fb1d24..06e412a 100644
--- a/core/lib/Drupal/Core/Entity/EntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityInterface.php
@@ -8,26 +8,11 @@
 namespace Drupal\Core\Entity;
 
 use Drupal\Core\TypedData\AccessibleInterface;
-use Drupal\Core\TypedData\ComplexDataInterface;
-use Drupal\Core\TypedData\TranslatableInterface;
 
 /**
  * Defines a common interface for all entity objects.
- *
- * This interface builds upon the general interfaces provided by the typed data
- * API, while extending them with entity-specific additions. I.e., an entity
- * implements the ComplexDataInterface among others, thus is complex data
- * containing fields as its data properties. The contained fields have to
- * implement the \Drupal\Core\Entity\Field\FieldItemListInterface, which builds upon
- * typed data interfaces as well.
- *
- * When implementing this interface which extends Traversable, make sure to list
- * IteratorAggregate or Iterator before this interface in the implements clause.
- *
- * @see \Drupal\Core\TypedData\TypedDataManager
- * @see \Drupal\Core\Field\FieldItemListInterface
  */
-interface EntityInterface extends ComplexDataInterface, AccessibleInterface, TranslatableInterface {
+interface EntityInterface extends AccessibleInterface {
 
   /**
    * Returns the entity UUID (Universally Unique Identifier).
@@ -50,6 +35,14 @@ public function uuid();
   public function id();
 
   /**
+   * Returns the language of the entity.
+   *
+   * @return \Drupal\Core\Language\Language
+   *   The language object.
+   */
+  public function language();
+
+  /**
    * Returns whether the entity is new.
    *
    * Usually an entity is new if no ID exists for it yet. However, entities may
@@ -63,26 +56,6 @@ public function id();
   public function isNew();
 
   /**
-   * Returns whether a new revision should be created on save.
-   *
-   * @return bool
-   *   TRUE if a new revision should be created.
-   *
-   * @see \Drupal\Core\Entity\EntityInterface::setNewRevision()
-   */
-  public function isNewRevision();
-
-  /**
-   * Enforces an entity to be saved as a new revision.
-   *
-   * @param bool $value
-   *   (optional) Whether a new revision should be saved.
-   *
-   * @see \Drupal\Core\Entity\EntityInterface::isNewRevision()
-   */
-  public function setNewRevision($value = TRUE);
-
-  /**
    * Enforces an entity to be new.
    *
    * Allows migrations to create entities with pre-defined IDs by forcing the
@@ -176,16 +149,6 @@ public function delete();
   public function preSave(EntityStorageControllerInterface $storage_controller);
 
   /**
-   * Acts on a revision before it gets saved.
-   *
-   * @param EntityStorageControllerInterface $storage_controller
-   *   The entity storage controller object.
-   * @param \stdClass $record
-   *   The revision object.
-   */
-  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record);
-
-  /**
    * Acts on a saved entity before the insert or update hook is invoked.
    *
    * Used after the entity is saved, but before invoking the insert or update
@@ -270,70 +233,6 @@ public function createDuplicate();
   public function entityInfo();
 
   /**
-   * Returns the revision identifier of the entity.
-   *
-   * @return
-   *   The revision identifier of the entity, or NULL if the entity does not
-   *   have a revision identifier.
-   */
-  public function getRevisionId();
-
-  /**
-   * Checks if this entity is the default revision.
-   *
-   * @param bool $new_value
-   *   (optional) A Boolean to (re)set the isDefaultRevision flag.
-   *
-   * @return bool
-   *   TRUE if the entity is the default revision, FALSE otherwise. If
-   *   $new_value was passed, the previous value is returned.
-   */
-  public function isDefaultRevision($new_value = NULL);
-
-  /**
-   * Retrieves the exportable properties of the entity.
-   *
-   * @return array
-   *   An array of exportable properties and their values.
-   */
-  public function getExportProperties();
-
-  /**
-   * Returns the translation support status.
-   *
-   * @return bool
-   *   TRUE if the entity bundle has translation support enabled.
-   */
-  public function isTranslatable();
-
-  /**
-   * Marks the translation identified by the given language code as existing.
-   *
-   * @todo Remove this as soon as translation metadata have been converted to
-   *    regular fields.
-   *
-   * @param string $langcode
-   *   The language code identifying the translation to be initialized.
-   */
-  public function initTranslation($langcode);
-
-  /**
-   * Defines the base fields of the entity type.
-   *
-   * @param string $entity_type
-   *   The entity type to return properties for. Useful when a single class is
-   *   used for multiple, possibly dynamic entity types.
-   *
-   * @return array
-   *   An array of entity field definitions as specified by
-   *   \Drupal\Core\Entity\EntityManager::getFieldDefinitions(), keyed by field
-   *   name.
-   *
-   * @see \Drupal\Core\Entity\EntityManager::getFieldDefinitions()
-   */
-  public static function baseFieldDefinitions($entity_type);
-
-  /**
    * Returns a list of entities referenced by this entity.
    *
    * @return array
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 67e5690..e9808d2 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -442,14 +442,15 @@ public function getAdminRouteInfo($entity_type, $bundle) {
   }
 
   /**
-   * Gets an array of entity field definitions.
+   * Gets an array of content entity field definitions.
    *
    * If a bundle is passed, fields specific to this bundle are included. Entity
    * fields are always multi-valued, so 'list' is TRUE for each returned field
    * definition.
    *
    * @param string $entity_type
-   *   The entity type to get field definitions for.
+   *   The entity type to get field definitions for. Only entity types that
+   *   implement \Drupal\Core\Entity\ContentEntityInterface are supported.
    * @param string $bundle
    *   (optional) The entity bundle for which to get field definitions. If NULL
    *   is passed, no bundle-specific fields are included. Defaults to NULL.
diff --git a/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php b/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php
index 43ff5f1..e54372f 100644
--- a/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityStorageControllerBase.php
@@ -140,35 +140,15 @@ protected function cacheSet($entities) {
    * {@inheritdoc}
    */
   public function invokeFieldMethod($method, EntityInterface $entity) {
-    foreach (array_keys($entity->getTranslationLanguages()) as $langcode) {
-      // @todo getTranslation() only works on NG entities. Remove the condition
-      // and the second code branch when all core entity types are converted.
-      if ($translation = $entity->getTranslation($langcode)) {
-        foreach ($translation as $field) {
-          $field->$method();
-        }
-      }
-      else {
-        // For BC entities, iterate through fields and instantiate NG items
-        // objects manually.
-        $definitions = \Drupal::entityManager()->getFieldDefinitions($entity->entityType(), $entity->bundle());
-        foreach ($definitions as $field_name => $definition) {
-          if (!empty($definition['configurable'])) {
-            // Create the items object.
-            $itemsBC = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
-            // @todo Exception : this calls setValue(), tries to set the
-            // 'formatted' property. For now, this is worked around by
-            // commenting out the Exception in TextProcessed::setValue().
-            $items = \Drupal::typedData()->create($definition, $itemsBC, $field_name, $entity);
-            $items->$method();
+    // Only act on content entities.
+    if (!($entity instanceof ContentEntityInterface)) {
+      return;
+    }
 
-            // Put back the items values in the entity.
-            $itemsBC = $items->getValue(TRUE);
-            if ($itemsBC !== array() || isset($entity->{$field_name}[$langcode])) {
-              $entity->{$field_name}[$langcode] = $itemsBC;
-            }
-          }
-        }
+    foreach (array_keys($entity->getTranslationLanguages()) as $langcode) {
+      $translation = $entity->getTranslation($langcode);
+      foreach ($translation as $field) {
+        $field->$method();
       }
     }
   }
@@ -177,57 +157,27 @@ public function invokeFieldMethod($method, EntityInterface $entity) {
    * {@inheritdoc}
    */
   public function invokeFieldItemPrepareCache(EntityInterface $entity) {
+    // Only act on content entities.
+    if (!($entity instanceof ContentEntityInterface)) {
+      return;
+    }
     foreach (array_keys($entity->getTranslationLanguages()) as $langcode) {
-      // @todo getTranslation() only works on NG entities. Remove the condition
-      // and the second code branch when all core entity types are converted.
-      if ($translation = $entity->getTranslation($langcode)) {
-        foreach ($translation->getPropertyDefinitions() as $property => $definition) {
-          $type_definition = \Drupal::typedData()->getDefinition($definition['type']);
-          // Only create the item objects if needed.
-          if (is_subclass_of($type_definition['class'], '\Drupal\Core\Entity\Field\PrepareCacheInterface')
-            // Prevent legacy field types from skewing performance too much by
-            // checking the existence of the legacy function directly, instead
-            // of making LegacyConfigFieldItem implement PrepareCacheInterface.
-            // @todo Remove once all core field types have been converted (see
-            // http://drupal.org/node/2014671).
-            || (is_subclass_of($type_definition['class'], '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem')
-              && isset($type_definition['provider']) && function_exists($type_definition['provider'] . '_field_load'))) {
-
-            // Call the prepareCache() method directly on each item
-            // individually.
-            foreach ($translation->get($property) as $item) {
-              $item->prepareCache();
-            }
-          }
-        }
-      }
-      else {
-        // For BC entities, iterate through the fields and instantiate NG items
-        // objects manually.
-        $definitions = \Drupal::entityManager()->getFieldDefinitions($entity->entityType(), $entity->bundle());
-        foreach ($definitions as $field_name => $definition) {
-          if (!empty($definition['configurable'])) {
-            $type_definition = \Drupal::typedData()->getDefinition($definition['type']);
-            // Only create the item objects if needed.
-            if (is_subclass_of($type_definition['class'], '\Drupal\Core\Entity\Field\PrepareCacheInterface')
-              // @todo Remove once all core field types have been converted
-              // (see http://drupal.org/node/2014671).
-              || (is_subclass_of($type_definition['class'], '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem') && function_exists($type_definition['provider'] . '_field_load'))) {
-
-              // Create the items object.
-              $items = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array();
-              $itemsNG = \Drupal::typedData()->create($definition, $items, $field_name, $entity);
-
-              foreach ($itemsNG as $item) {
-                $item->prepareCache();
-              }
-
-              // Put back the items values in the entity.
-              $items = $itemsNG->getValue(TRUE);
-              if ($items !== array() || isset($entity->{$field_name}[$langcode])) {
-                $entity->{$field_name}[$langcode] = $items;
-              }
-            }
+      $translation = $entity->getTranslation($langcode);
+      foreach ($translation->getPropertyDefinitions() as $property => $definition) {
+        $type_definition = \Drupal::typedData()->getDefinition($definition['type']);
+        // Only create the item objects if needed.
+        if (is_subclass_of($type_definition['class'], '\Drupal\Core\Entity\Field\PrepareCacheInterface')
+          // Prevent legacy field types from skewing performance too much by
+          // checking the existence of the legacy function directly, instead
+          // of making LegacyConfigFieldItem implement PrepareCacheInterface.
+          // @todo Remove once all core field types have been converted (see
+          // http://drupal.org/node/2014671).
+          || (is_subclass_of($type_definition['class'], '\Drupal\field\Plugin\field\field_type\LegacyConfigFieldItem') && function_exists($type_definition['provider'] . '_field_load'))) {
+
+          // Call the prepareCache() method directly on each item
+          // individually.
+          foreach ($translation->get($property) as $item) {
+            $item->prepareCache();
           }
         }
       }
@@ -257,6 +207,10 @@ protected function invokeHook($hook, EntityInterface $entity) {
    *   The entity being saved.
    */
   protected function invokeTranslationHooks(EntityInterface $entity) {
+    // Only act on content entities.
+    if (!($entity instanceof ContentEntityInterface)) {
+      return;
+    }
     $translations = $entity->getTranslationLanguages(FALSE);
     $original_translations = $entity->original->getTranslationLanguages(FALSE);
     $all_translations = array_keys($translations + $original_translations);
diff --git a/core/lib/Drupal/Core/Entity/RevisionableInterface.php b/core/lib/Drupal/Core/Entity/RevisionableInterface.php
new file mode 100644
index 0000000..d246d24
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/RevisionableInterface.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\RevisionableInterface.
+ */
+
+namespace Drupal\Core\Entity;
+
+/**
+ * Provides methods for an entity to support revisions.
+ */
+interface RevisionableInterface {
+
+  /**
+   * Returns whether a new revision should be created on save.
+   *
+   * @return bool
+   *   TRUE if a new revision should be created.
+   *
+   * @see \Drupal\Core\Entity\EntityInterface::setNewRevision()
+   */
+  public function isNewRevision();
+
+  /**
+   * Enforces an entity to be saved as a new revision.
+   *
+   * @param bool $value
+   *   (optional) Whether a new revision should be saved.
+   *
+   * @see \Drupal\Core\Entity\EntityInterface::isNewRevision()
+   */
+  public function setNewRevision($value = TRUE);
+
+  /**
+   * Returns the revision identifier of the entity.
+   *
+   * @return
+   *   The revision identifier of the entity, or NULL if the entity does not
+   *   have a revision identifier.
+   */
+  public function getRevisionId();
+
+  /**
+   * Checks if this entity is the default revision.
+   *
+   * @param bool $new_value
+   *   (optional) A Boolean to (re)set the isDefaultRevision flag.
+   *
+   * @return bool
+   *   TRUE if the entity is the default revision, FALSE otherwise. If
+   *   $new_value was passed, the previous value is returned.
+   */
+  public function isDefaultRevision($new_value = NULL);
+
+  /**
+   * Acts on a revision before it gets saved.
+   *
+   * @param EntityStorageControllerInterface $storage_controller
+   *   The entity storage controller object.
+   * @param \stdClass $record
+   *   The revision object.
+   */
+  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record);
+
+}
diff --git a/core/lib/Drupal/Core/TypedData/TranslatableInterface.php b/core/lib/Drupal/Core/TypedData/TranslatableInterface.php
index 0d5332b..f94aa0b 100644
--- a/core/lib/Drupal/Core/TypedData/TranslatableInterface.php
+++ b/core/lib/Drupal/Core/TypedData/TranslatableInterface.php
@@ -90,4 +90,12 @@ public function addTranslation($langcode, array $values = array());
    */
   public function removeTranslation($langcode);
 
+  /**
+   * Returns the translation support status.
+   *
+   * @return bool
+   *   TRUE if the object has translation support enabled.
+   */
+  public function isTranslatable();
+
 }
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
index 104cf28..b293f82 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Feed.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Symfony\Component\DependencyInjection\Container;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Entity\Annotation\EntityType;
@@ -38,7 +38,7 @@
  *   }
  * )
  */
-class Feed extends EntityNG implements FeedInterface {
+class Feed extends ContentEntityBase implements FeedInterface {
 
   /**
    * The feed ID.
@@ -135,7 +135,7 @@ class Feed extends EntityNG implements FeedInterface {
   public $modified;
 
   /**
-   * Overrides Drupal\Core\Entity\EntityNG::init().
+   * {@inheritdoc}
    */
   public function init() {
     parent::init();
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
index f06bf06..d87a34f 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Entity/Item.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
@@ -32,7 +32,7 @@
  *   }
  * )
  */
-class Item extends EntityNG implements ItemInterface {
+class Item extends ContentEntityBase implements ItemInterface {
 
   /**
    * The feed item ID.
@@ -102,7 +102,7 @@ class Item extends EntityNG implements ItemInterface {
   public $guid;
 
   /**
-   * Overrides Drupal\Core\Entity\EntityNG::init().
+   * {@inheritdoc}
    */
   public function init() {
     parent::init();
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
index 3ba86ac..1b29d85 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/FeedFormController.php
@@ -8,13 +8,13 @@
 namespace Drupal\aggregator;
 
 use Drupal\Component\Utility\String;
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the aggregator feed edit forms.
  */
-class FeedFormController extends EntityFormControllerNG {
+class FeedFormController extends ContentEntityFormController {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedDeleteForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedDeleteForm.php
index 6916d025e..adad1ee 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedDeleteForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedDeleteForm.php
@@ -7,12 +7,12 @@
 
 namespace Drupal\aggregator\Form;
 
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 
 /**
  * Provides a form for deleting a feed.
  */
-class FeedDeleteForm extends EntityNGConfirmFormBase {
+class FeedDeleteForm extends ContentEntityConfirmFormBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedItemsRemoveForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedItemsRemoveForm.php
index 3886048..54b7d5a 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedItemsRemoveForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/FeedItemsRemoveForm.php
@@ -7,12 +7,12 @@
 
 namespace Drupal\aggregator\Form;
 
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 
 /**
  * Provides a deletion confirmation form for items that belong to a feed.
  */
-class FeedItemsRemoveForm extends EntityNGConfirmFormBase {
+class FeedItemsRemoveForm extends ContentEntityConfirmFormBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
index d64e3de..fb818fc 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php
@@ -8,13 +8,13 @@
 namespace Drupal\custom_block;
 
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the custom block edit forms.
  */
-class CustomBlockFormController extends EntityFormControllerNG {
+class CustomBlockFormController extends ContentEntityFormController {
 
   /**
    * Overrides \Drupal\Core\Entity\EntityFormController::prepareEntity().
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTranslationController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTranslationController.php
index 4436f57..08d8935 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTranslationController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTranslationController.php
@@ -8,12 +8,12 @@
 namespace Drupal\custom_block;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\content_translation\ContentTranslationControllerNG;
+use Drupal\content_translation\ContentTranslationController;
 
 /**
  * Defines the translation controller class for custom blocks.
  */
-class CustomBlockTranslationController extends ContentTranslationControllerNG {
+class CustomBlockTranslationController extends ContentTranslationController {
 
   /**
    * Overrides ContentTranslationController::entityFormAlter().
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
index b012a4f..524acd4 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\custom_block\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
@@ -53,7 +53,7 @@
  *   }
  * )
  */
-class CustomBlock extends EntityNG implements CustomBlockInterface {
+class CustomBlock extends ContentEntityBase implements CustomBlockInterface {
 
   /**
    * The block ID.
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
index 16d22b4..e259313 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.php
@@ -7,13 +7,13 @@
 
 namespace Drupal\custom_block\Form;
 
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Provides a confirmation form for deleting a custom block entity.
  */
-class CustomBlockDeleteForm extends EntityNGConfirmFormBase {
+class CustomBlockDeleteForm extends ContentEntityConfirmFormBase {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php
index f921834..7f5c895 100644
--- a/core/modules/block/lib/Drupal/block/Entity/Block.php
+++ b/core/modules/block/lib/Drupal/block/Entity/Block.php
@@ -126,11 +126,11 @@ public function label($langcode = NULL) {
   }
 
   /**
-   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::get();
+   * {@inheritdoc}
    */
-  public function get($property_name, $langcode = NULL) {
+  public function get($property_name) {
     // The theme is stored in the entity ID.
-    $value = parent::get($property_name, $langcode);
+    $value = parent::get($property_name);
     if ($property_name == 'theme' && !$value) {
       list($value) = explode('.', $this->id());
     }
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index 4555e8f..ecbe5b2 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -11,7 +11,7 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Entity\EntityManager;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
@@ -21,7 +21,7 @@
 /**
  * Base for controller for comment forms.
  */
-class CommentFormController extends EntityFormControllerNG {
+class CommentFormController extends ContentEntityFormController {
 
   /**
    * The entity manager service.
diff --git a/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php b/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
index df70b15..4812798 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentTranslationController.php
@@ -9,12 +9,12 @@
 namespace Drupal\comment;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\content_translation\ContentTranslationControllerNG;
+use Drupal\content_translation\ContentTranslationController;
 
 /**
  * Defines the translation controller class for comments.
  */
-class CommentTranslationController extends ContentTranslationControllerNG {
+class CommentTranslationController extends ContentTranslationController {
 
   /**
    * Overrides ContentTranslationController::entityFormTitle().
diff --git a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
index 617d4ad..65531de 100644
--- a/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
+++ b/core/modules/comment/lib/Drupal/comment/Entity/Comment.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\comment\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
 use Drupal\comment\CommentInterface;
@@ -53,7 +53,7 @@
  *   }
  * )
  */
-class Comment extends EntityNG implements CommentInterface {
+class Comment extends ContentEntityBase implements CommentInterface {
 
   /**
    * The comment ID.
diff --git a/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php b/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php
index 05fbed5..2c13db5 100644
--- a/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php
+++ b/core/modules/comment/lib/Drupal/comment/Form/DeleteForm.php
@@ -9,13 +9,13 @@
 
 use Drupal\comment\CommentManager;
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides the comment delete confirmation form.
  */
-class DeleteForm extends EntityNGConfirmFormBase {
+class DeleteForm extends ContentEntityConfirmFormBase {
 
   /**
    * The comment manager.
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
index 2b16c9d..0588ab8 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php
@@ -59,11 +59,9 @@ function testCRUD() {
     $this->assertIdentical($empty->get('langcode'), $default_langcode);
 
     // Verify Entity properties/methods on the newly created empty entity.
-    $this->assertIdentical($empty->isNewRevision(), FALSE);
     $this->assertIdentical($empty->entityType(), 'config_test');
     $uri = $empty->uri();
     $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage');
-    $this->assertIdentical($empty->isDefaultRevision(), TRUE);
 
     // Verify that an empty entity cannot be saved.
     try {
@@ -108,10 +106,8 @@ function testCRUD() {
     $expected['uuid'] = $config_test->uuid();
     $this->assertIdentical($config_test->label(), $expected['label']);
 
-    $this->assertIdentical($config_test->isNewRevision(), FALSE);
     $uri = $config_test->uri();
     $this->assertIdentical($uri['path'], 'admin/structure/config_test/manage/' . $expected['id']);
-    $this->assertIdentical($config_test->isDefaultRevision(), TRUE);
 
     // Verify that the entity can be saved.
     try {
diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Message.php b/core/modules/contact/lib/Drupal/contact/Entity/Message.php
index f81b456..1d0f5cd 100644
--- a/core/modules/contact/lib/Drupal/contact/Entity/Message.php
+++ b/core/modules/contact/lib/Drupal/contact/Entity/Message.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\contact\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\contact\MessageInterface;
 
 /**
@@ -34,7 +34,7 @@
  *   }
  * )
  */
-class Message extends EntityNG implements MessageInterface {
+class Message extends ContentEntityBase implements MessageInterface {
 
   /**
    * Overrides Drupal\Core\Entity\Entity::id().
diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
index d41c959..b056dc6 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
@@ -7,14 +7,14 @@
 
 namespace Drupal\contact;
 
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 use Drupal\user\UserInterface;
 
 /**
  * Form controller for contact message forms.
  */
-class MessageFormController extends EntityFormControllerNG {
+class MessageFormController extends ContentEntityFormController {
 
   /**
    * Overrides Drupal\Core\Entity\EntityFormController::form().
diff --git a/core/modules/contact/lib/Drupal/contact/MessageInterface.php b/core/modules/contact/lib/Drupal/contact/MessageInterface.php
index bf797e4..f4efb1c 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageInterface.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageInterface.php
@@ -7,12 +7,12 @@
 
 namespace Drupal\contact;
 
-use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
 
 /**
  * Provides an interface defining a contant message entity
  */
-interface MessageInterface extends EntityInterface {
+interface MessageInterface extends ContentEntityInterface {
 
   /**
    * Returns the category this contact message belongs to.
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index a6cf31c..2b6a611 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -5,11 +5,12 @@
  * Allows entities to be translated into different languages.
  */
 
-use Drupal\Core\Language\Language;
-use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityFormControllerInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Language\Language;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\TypedData\TranslatableInterface;
 
 /**
  * Implements hook_help().
@@ -264,8 +265,7 @@ function _content_translation_menu_strip_loaders($path) {
  *   The entity whose translation overview should be displayed.
  */
 function content_translation_translate_access(EntityInterface $entity) {
-  $entity_type = $entity->entityType();
-  return empty($entity->getUntranslated()->language()->locked) && language_multilingual() && $entity->isTranslatable() &&
+  return $entity instanceof ContentEntityInterface && empty($entity->getUntranslated()->language()->locked) && language_multilingual() && $entity->isTranslatable() &&
     (user_access('create content translations') || user_access('update content translations') || user_access('delete content translations'));
 }
 
@@ -586,7 +586,7 @@ function content_translation_permission() {
  * Implements hook_form_alter().
  */
 function content_translation_form_alter(array &$form, array &$form_state) {
-  if (($form_controller = content_translation_form_controller($form_state)) && ($entity = $form_controller->getEntity()) && !$entity->isNew() && $entity->isTranslatable()) {
+  if (($form_controller = content_translation_form_controller($form_state)) && ($entity = $form_controller->getEntity()) && !$entity->isNew() && $entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
     $controller = content_translation_controller($entity->entityType());
     $controller->entityFormAlter($form, $form_state, $entity);
 
@@ -617,7 +617,7 @@ function content_translation_field_language_alter(&$display_language, $context)
   $entity = $context['entity'];
   $entity_type = $entity->entityType();
 
-  if (isset($entity->translation[$context['langcode']]) && $entity->isTranslatable() && !content_translation_view_access($entity, $context['langcode'])) {
+  if ($entity instanceof ContentEntityInterface && isset($entity->translation[$context['langcode']]) && $entity->isTranslatable() && !content_translation_view_access($entity, $context['langcode'])) {
     $instances = field_info_instances($entity_type, $entity->bundle());
     // Avoid altering the real entity.
     $entity = clone($entity);
@@ -642,7 +642,7 @@ function content_translation_entity_load(array $entities, $entity_type) {
 
   if (content_translation_enabled($entity_type)) {
     foreach ($entities as $entity) {
-      if ($entity->isTranslatable()) {
+      if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
         $enabled_entities[$entity->id()] = $entity;
       }
     }
@@ -685,7 +685,7 @@ function content_translation_load_translation_metadata(array $entities, $entity_
  */
 function content_translation_entity_insert(EntityInterface $entity) {
   // Only do something if translation support for the given entity is enabled.
-  if (!$entity->isTranslatable()) {
+  if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) {
     return;
   }
 
@@ -725,7 +725,7 @@ function content_translation_entity_insert(EntityInterface $entity) {
  */
 function content_translation_entity_delete(EntityInterface $entity) {
   // Only do something if translation support for the given entity is enabled.
-  if (!$entity->isTranslatable()) {
+  if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) {
     return;
   }
 
@@ -740,7 +740,7 @@ function content_translation_entity_delete(EntityInterface $entity) {
  */
 function content_translation_entity_update(EntityInterface $entity) {
   // Only do something if translation support for the given entity is enabled.
-  if (!$entity->isTranslatable()) {
+  if (!($entity instanceof ContentEntityInterface) || !$entity->isTranslatable()) {
     return;
   }
 
@@ -835,7 +835,7 @@ function content_translation_field_info_alter(&$info) {
  * Implements hook_entity_presave().
  */
 function content_translation_entity_presave(EntityInterface $entity) {
-  if ($entity->isTranslatable()) {
+  if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
     // @todo Avoid using request attributes once translation metadata become
     //   regular fields.
     $attributes = \Drupal::request()->attributes;
diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc
index be151b9..f4eba85 100644
--- a/core/modules/content_translation/content_translation.pages.inc
+++ b/core/modules/content_translation/content_translation.pages.inc
@@ -7,7 +7,7 @@
 
 use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityInterface;
 
 /**
  * Translations overview page callback.
@@ -242,8 +242,10 @@ function content_translation_edit_page(EntityInterface $entity, Language $langua
  *   The language to be used as target.
  */
 function content_translation_prepare_translation(EntityInterface $entity, Language $source, Language $target) {
-  $source_translation = $entity->getTranslation($source->id);
-  $entity->addTranslation($target->id, $source_translation->getPropertyValues());
+  if ($entity instanceof ContentEntityInterface) {
+    $source_translation = $entity->getTranslation($source->id);
+    $entity->addTranslation($target->id, $source_translation->getPropertyValues());
+  }
 }
 
 /**
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
index 77ac782..acdafb0 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
@@ -43,18 +43,10 @@ public function __construct($entity_type, $entity_info) {
   }
 
   /**
-   * Implements ContentTranslationControllerInterface::removeTranslation().
+   * {@inheritdoc}
    */
   public function removeTranslation(EntityInterface $entity, $langcode) {
-    // @todo Handle properties.
-    // Remove field translations.
-    foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) {
-      $field_name = $instance['field_name'];
-      $field = $instance->getField();
-      if ($field['translatable']) {
-        $entity->{$field_name}[$langcode] = array();
-      }
-    }
+    $entity->removeTranslation($langcode);
   }
 
   /**
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerNG.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerNG.php
deleted file mode 100644
index 61e490d..0000000
--- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationControllerNG.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\content_translation\ContentTranslationControllerNG.
- */
-
-namespace Drupal\content_translation;
-
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Test content translation controller.
- */
-class ContentTranslationControllerNG extends ContentTranslationController {
-
-  /**
-   * Overrides \Drupal\content_translation\ContentTranslationControllerInterface::removeTranslation().
-   */
-  public function removeTranslation(EntityInterface $entity, $langcode) {
-    $entity->removeTranslation($langcode);
-  }
-
-}
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
index 46a5b89..64bacdc 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\content_translation;
 
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\EntityNG;
 
 /**
  * Provides field translation synchronization capabilities.
@@ -36,7 +36,7 @@ public function __construct(EntityManager $entityManager) {
   /**
    * {@inheritdoc}
    */
-  public function synchronizeFields(EntityInterface $entity, $sync_langcode, $original_langcode = NULL) {
+  public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode, $original_langcode = NULL) {
     $translations = $entity->getTranslationLanguages();
 
     // If we have no information about what to sync to, if we are creating a new
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizerInterface.php b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizerInterface.php
index 7c73b33..0c60b18 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizerInterface.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizerInterface.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\content_translation;
 
-use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
 
 /**
  * Provides field translation synchronization capabilities.
@@ -26,7 +26,7 @@
    * instance to translate the "alt" and "title" textual elements of an image
    * field, while keeping the same image on every translation.
    *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
    *   The entity whose values should be synchronized.
    * @param string $sync_langcode
    *   The language of the translation whose values should be used as source for
@@ -35,7 +35,7 @@
    *   (optional) If a new translation is being created, this should be the
    *   language code of the original values. Defaults to NULL.
    */
-  public function synchronizeFields(EntityInterface $entity, $sync_langcode, $original_langcode = NULL);
+  public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode, $original_langcode = NULL);
 
   /**
    * Synchronize the items of a single field.
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php
index ef579b2..956e6dd 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php
@@ -8,7 +8,7 @@
 namespace Drupal\content_translation\Tests;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Language\Language;
 
 /**
diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module
index e843c2d..8282d07 100644
--- a/core/modules/editor/editor.module
+++ b/core/modules/editor/editor.module
@@ -5,7 +5,7 @@
  * Adds bindings for client-side "text editors" to text formats.
  */
 
-use Drupal\file\Entity\File;
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\editor\Entity\Editor;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Entity\EntityInterface;
@@ -393,6 +393,10 @@ function editor_pre_render_format($element) {
  * Implements hook_entity_insert().
  */
 function editor_entity_insert(EntityInterface $entity) {
+  // Only act on content entities.
+  if (!($entity instanceof ContentEntityInterface)) {
+    return;
+  }
   $referenced_files_by_field = _editor_get_file_uuids_by_field($entity);
   foreach ($referenced_files_by_field as $field => $uuids) {
     _editor_record_file_usage($uuids, $entity);
@@ -403,6 +407,11 @@ function editor_entity_insert(EntityInterface $entity) {
  * Implements hook_entity_update().
  */
 function editor_entity_update(EntityInterface $entity) {
+  // Only act on content entities.
+  if (!($entity instanceof ContentEntityInterface)) {
+    return;
+  }
+
   // On new revisions, all files are considered to be a new usage and no
   // deletion of previous file usages are necessary.
   if (!empty($entity->original) && $entity->getRevisionId() != $entity->original->getRevisionId()) {
@@ -437,6 +446,10 @@ function editor_entity_update(EntityInterface $entity) {
  * Implements hook_entity_delete().
  */
 function editor_entity_delete(EntityInterface $entity) {
+  // Only act on content entities.
+  if (!($entity instanceof ContentEntityInterface)) {
+    return;
+  }
   $referenced_files_by_field = _editor_get_file_uuids_by_field($entity);
   foreach ($referenced_files_by_field as $field => $uuids) {
     _editor_delete_file_usage($uuids, $entity, 0);
@@ -447,6 +460,10 @@ function editor_entity_delete(EntityInterface $entity) {
  * Implements hook_entity_revision_delete().
  */
 function editor_entity_revision_delete(EntityInterface $entity) {
+  // Only act on content entities.
+  if (!($entity instanceof ContentEntityInterface)) {
+    return;
+  }
   $referenced_files_by_field = _editor_get_file_uuids_by_field($entity);
   foreach ($referenced_files_by_field as $field => $uuids) {
     _editor_delete_file_usage($uuids, $entity, 1);
@@ -524,7 +541,7 @@ function _editor_get_file_uuids_by_field(EntityInterface $entity) {
  * @return array
  *   The names of the fields on this entity that have text processing enabled.
  */
-function _editor_get_processed_text_fields(EntityInterface $entity) {
+function _editor_get_processed_text_fields(ContentEntityInterface $entity) {
   $properties = $entity->getPropertyDefinitions();
   if (empty($properties)) {
     return array();
diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc
index e33b150..0de7e5d 100644
--- a/core/modules/field/field.deprecated.inc
+++ b/core/modules/field/field.deprecated.inc
@@ -6,7 +6,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Field\PrepareCacheInterface;
 use Drupal\Core\Language\Language;
 use Drupal\entity\Entity\EntityDisplay;
@@ -597,7 +597,7 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc
  * elements. Fieldable entity types should call this function during their own
  * form validation function.
  *
- * @param \Drupal\Core\Entity\EntityInterface $entity
+ * @param \Drupal\Core\Entity\ContentEntityInterface $entity
  *   The entity being submitted. The actual field values will be read
  *   from $form_state['values'].
  * @param $form
@@ -611,7 +611,7 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc
  *
  * @deprecated as of Drupal 8.0. Use the entity system instead.
  */
-function field_attach_form_validate(EntityInterface $entity, $form, &$form_state, array $options = array()) {
+function field_attach_form_validate(ContentEntityInterface $entity, $form, &$form_state, array $options = array()) {
   $has_violations = FALSE;
   foreach ($entity as $field_name => $field) {
     $definition = $field->getDefinition();
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 01c9181..c15fa3a 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -5,7 +5,6 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Language\Language;
 use Drupal\Core\Template\Attribute;
 use Drupal\field\FieldInterface;
 use Drupal\field\FieldInstanceInterface;
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
index e46622f..f5febd5 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php
@@ -49,8 +49,8 @@ public function isEmpty() {
     // Make sure the array received by the legacy callback includes computed
     // properties.
     $item = $this->getValue(TRUE);
-    // The previous hook was never called on an empty item, but EntityNG always
-    // creates a FieldItem element for an empty field.
+    // The previous hook was never called on an empty item, but
+    // ContentEntityBase always creates a FieldItem element for an empty field.
     return empty($item) || $callback($item, $this->getFieldDefinition()->getFieldType());
   }
 
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
index 4f0a5d9..67fa7d6 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php
@@ -7,9 +7,8 @@
 
 namespace Drupal\field_ui\Form;
 
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\TypedData\TypedDataManager;
 use Drupal\field\FieldInfo;
@@ -161,7 +160,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     // FieldItem.
     $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
     $entity = _field_create_entity_from_ids($ids);
-    $form['field']['settings'] += $this->getFieldItem($entity, $field['field_name'])->settingsForm($form, $form_state, $field->hasData());
+    $form['field']['settings'] += $entity->get($field['field_name'])->offsetGet(0)->settingsForm($form, $form_state, $field->hasData());
 
     $form['actions'] = array('#type' => 'actions');
     $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings'));
@@ -217,21 +216,4 @@ public function submitForm(array &$form, array &$form_state) {
     }
   }
 
-  /**
-   * Returns a FieldItem object for an entity.
-   *
-   * @todo Remove when all entity types extend EntityNG.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   An entity.
-   * @param string $field_name
-   *   The field name.
-   *
-   * @return \Drupal\field\Plugin\Type\FieldType\ConfigFieldItemInterface
-   *   The field item object.
-   */
-  protected function getFieldItem(EntityInterface $entity, $field_name) {
-    return $entity->get($field_name)->offsetGet(0);
-  }
-
 }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
index 68c5bfb..b5b7e62 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php
@@ -7,9 +7,7 @@
 
 namespace Drupal\field_ui\Form;
 
-use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManager;
-use Drupal\Core\Entity\EntityNG;
 use Drupal\Core\Form\FormBase;
 use Drupal\field\FieldInstanceInterface;
 use Drupal\field_ui\FieldUI;
@@ -80,7 +78,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
     // Create an arbitrary entity object (used by the 'default value' widget).
     $ids = (object) array('entity_type' => $this->instance['entity_type'], 'bundle' => $this->instance['bundle'], 'entity_id' => NULL);
     $form['#entity'] = _field_create_entity_from_ids($ids);
-    $items = $this->getFieldItems($form['#entity'], $this->instance['field_name']);
+    $items = $form['#entity']->get($this->instance['field_name']);
 
     if (!empty($field['locked'])) {
       $form['locked'] = array(
@@ -165,7 +163,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceInterfac
    */
   public function validateForm(array &$form, array &$form_state) {
     if (isset($form['instance']['default_value'])) {
-      $items = $this->getFieldItems($form['#entity'], $this->instance['field_name']);
+      $items = $form['#entity']->get($this->instance['field_name']);
       $items->defaultValuesFormValidate($form['instance']['default_value'], $form, $form_state);
     }
   }
@@ -177,7 +175,7 @@ public function submitForm(array &$form, array &$form_state) {
     // Handle the default value.
     $default_value = array();
     if (isset($form['instance']['default_value'])) {
-      $items = $this->getFieldItems($form['#entity'], $this->instance['field_name']);
+      $items = $form['#entity']->get($this->instance['field_name']);
       $default_value = $items->defaultValuesFormSubmit($form['instance']['default_value'], $form, $form_state);
     }
     $this->instance['default_value'] = $default_value;
@@ -207,21 +205,6 @@ public function delete(array &$form, array &$form_state) {
   }
 
   /**
-   * Returns a Field object for an entity.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   An entity.
-   * @param string $field_name
-   *   The field name.
-   *
-   * @return \Drupal\field\Plugin\Type\FieldType\ConfigFieldItemListInterface
-   *   The field object.
-   */
-  protected function getFieldItems(EntityInterface $entity, $field_name) {
-    return $entity->get($field_name);
-  }
-
-  /**
    * Returns the next redirect path in a multipage sequence.
    *
    * @return string|array
diff --git a/core/modules/file/lib/Drupal/file/Entity/File.php b/core/modules/file/lib/Drupal/file/Entity/File.php
index b891253..b8823e3 100644
--- a/core/modules/file/lib/Drupal/file/Entity/File.php
+++ b/core/modules/file/lib/Drupal/file/Entity/File.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\file\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Annotation\Translation;
@@ -34,7 +34,7 @@
  *   }
  * )
  */
-class File extends EntityNG implements FileInterface {
+class File extends ContentEntityBase implements FileInterface {
 
   /**
    * The plain data values of the contained properties.
diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php
index 5a3f2ce..a3aa448 100644
--- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php
+++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php
@@ -8,7 +8,7 @@
 namespace Drupal\hal\Normalizer;
 
 use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Language\Language;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
index 0fc739a..a238ad6 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\menu_link\Entity;
 
+use Drupal\Core\Language\Language;
 use Drupal\menu_link\MenuLinkInterface;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
@@ -269,6 +270,56 @@ class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
   protected $routeObject;
 
   /**
+   * Boolean indicating whether a new revision should be created on save.
+   *
+   * @var bool
+   */
+  protected $newRevision = FALSE;
+
+  /**
+   * Indicates whether this is the default revision.
+   *
+   * @var bool
+   */
+  protected $isDefaultRevision = TRUE;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setNewRevision($value = TRUE) {
+    $this->newRevision = $value;
+  }
+  /**
+   * {@inheritdoc}
+   */
+  public function isNewRevision() {
+    $info = $this->entityInfo();
+    return $this->newRevision || (!empty($info['entity_keys']['revision']) && !$this->getRevisionId());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionId() {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isTranslatable() {
+    // @todo Inject the entity manager and retrieve bundle info from it.
+    $bundles = entity_get_bundles($this->entityType);
+    return !empty($bundles[$this->bundle()]['translatable']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) {
+  }
+
+  /**
    * Overrides Entity::id().
    */
   public function id() {
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
index 4f437ec..3222a68 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php
@@ -241,6 +241,35 @@ public function validate(array $form, array &$form_state) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function buildEntity(array $form, array &$form_state) {
+    // @todo: Remove this when menu links are converted to content entities in
+    //   http://drupal.org/node/1842858.
+    $entity = clone $this->entity;
+    // If you submit a form, the form state comes from caching, which forces
+    // the controller to be the one before caching. Ensure to have the
+    // controller of the current request.
+    $form_state['controller'] = $this;
+
+    // Copy top-level form values to entity properties, without changing
+    // existing entity properties that are not being edited by
+    // this form.
+    foreach ($form_state['values'] as $key => $value) {
+      $entity->$key = $value;
+    }
+
+    // Invoke all specified builders for copying form values to entity properties.
+    if (isset($form['#entity_builders'])) {
+      foreach ($form['#entity_builders'] as $function) {
+        call_user_func_array($function, array($entity->entityType(), $entity, &$form, &$form_state));
+      }
+    }
+
+    return $entity;
+  }
+
+  /**
    * Overrides EntityFormController::submit().
    */
   public function submit(array $form, array &$form_state) {
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
index b8e639e..fcf5415 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
@@ -15,7 +15,7 @@
 /**
  * Provides an interface defining a menu link entity.
  */
-interface MenuLinkInterface extends ContentEntityInterface {
+interface MenuLinkInterface extends EntityInterface {
 
   /**
    * Returns the Route object associated with this link, if any.
diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php
index 1d13b76..3ae8aca 100644
--- a/core/modules/node/lib/Drupal/node/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Entity/Node.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\node\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
@@ -58,7 +58,7 @@
  *   }
  * )
  */
-class Node extends EntityNG implements NodeInterface {
+class Node extends ContentEntityBase implements NodeInterface {
 
   /**
    * Implements Drupal\Core\Entity\EntityInterface::id().
diff --git a/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php
index 29db847..e6e469a 100644
--- a/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php
+++ b/core/modules/node/lib/Drupal/node/Form/NodeDeleteForm.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\node\Form;
 
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -15,7 +15,7 @@
 /**
  * Provides a form for deleting a node.
  */
-class NodeDeleteForm extends EntityNGConfirmFormBase {
+class NodeDeleteForm extends ContentEntityConfirmFormBase {
 
   /**
    * The URL generator.
diff --git a/core/modules/node/lib/Drupal/node/NodeAccessController.php b/core/modules/node/lib/Drupal/node/NodeAccessController.php
index 9b5a403..0f06917 100644
--- a/core/modules/node/lib/Drupal/node/NodeAccessController.php
+++ b/core/modules/node/lib/Drupal/node/NodeAccessController.php
@@ -13,7 +13,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\EntityAccessController;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\user\Entity\User;
 use Symfony\Component\DependencyInjection\ContainerInterface;
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index f0c0ae8..a787175 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -9,13 +9,13 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the node edit forms.
  */
-class NodeFormController extends EntityFormControllerNG {
+class NodeFormController extends ContentEntityFormController {
 
   /**
    * Default settings for this content/node type.
diff --git a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
index fba9847..8dcc8f3 100644
--- a/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
+++ b/core/modules/node/lib/Drupal/node/NodeGrantDatabaseStorage.php
@@ -10,7 +10,7 @@
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\user\Entity\User;
diff --git a/core/modules/node/lib/Drupal/node/NodeTranslationController.php b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
index 9436996..29a2734 100644
--- a/core/modules/node/lib/Drupal/node/NodeTranslationController.php
+++ b/core/modules/node/lib/Drupal/node/NodeTranslationController.php
@@ -8,12 +8,12 @@
 namespace Drupal\node;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\content_translation\ContentTranslationControllerNG;
+use Drupal\content_translation\ContentTranslationController;
 
 /**
  * Defines the translation controller class for nodes.
  */
-class NodeTranslationController extends ContentTranslationControllerNG {
+class NodeTranslationController extends ContentTranslationController {
 
   /**
    * Overrides ContentTranslationController::entityFormAlter().
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 984650a..1cdcc49 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -7,6 +7,7 @@
 
 use Drupal\Core\Language\Language;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
 
 /**
  * Implements hook_help().
@@ -231,7 +232,7 @@ function path_entity_field_info($entity_type) {
  * @todo: Move this to methods on the FieldItem class.
  */
 function path_entity_insert(EntityInterface $entity) {
-  if ($entity->getPropertyDefinition('path')) {
+  if ($entity instanceof ContentEntityInterface && $entity->getPropertyDefinition('path')) {
     $entity->path->alias = trim($entity->path->alias);
     // Only save a non-empty alias.
     if (!empty($entity->path->alias)) {
@@ -247,7 +248,7 @@ function path_entity_insert(EntityInterface $entity) {
  * Implements hook_entity_update().
  */
 function path_entity_update(EntityInterface $entity) {
-  if ($entity->getPropertyDefinition('path')) {
+  if ($entity instanceof ContentEntityInterface && $entity->getPropertyDefinition('path')) {
     $entity->path->alias = trim($entity->path->alias);
     // Delete old alias if user erased it.
     if ($entity->path->pid && !$entity->path->alias) {
@@ -268,7 +269,7 @@ function path_entity_update(EntityInterface $entity) {
  * Implements hook_entity_predelete().
  */
 function path_entity_predelete(EntityInterface $entity) {
-  if ($entity->getPropertyDefinition('path')) {
+  if ($entity instanceof ContentEntityInterface && $entity->getPropertyDefinition('path')) {
     // Delete all aliases associated with this term.
     $uri = $entity->uri();
     \Drupal::service('path.crud')->delete(array('source' => $uri['path']));
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php
index 8fdaef3..dd77f6a 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/FieldRdfaTestBase.php
@@ -34,7 +34,7 @@
   /**
    * The entity to render for testing.
    *
-   * @var \Drupal\Core\Entity\EntityNG
+   * @var \Drupal\Core\Entity\ContentEntityBase
    */
   protected $entity;
 
@@ -93,7 +93,7 @@ protected function createTestField() {
   /**
    * Gets the absolute URI of an entity.
    *
-   * @param \Drupal\Core\Entity\EntityNG $entity
+   * @param \Drupal\Core\Entity\ContentEntityBase $entity
    *   The entity for which to generate the URI.
    *
    * @return string
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
index 74d6082..184e811 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php
@@ -137,8 +137,7 @@ public function testCreate() {
     $this->assertResponse(404);
     $this->assertFalse(entity_load_multiple($entity_type, NULL, TRUE), 'No entity has been created in the database.');
 
-    // @todo Once EntityNG is implemented for other entity types add a security
-    // test. It should not be possible for example to create a test entity on a
-    // node resource route.
+    // @todo Add a security test. It should not be possible for example to
+    //   create a test entity on a node resource route.
   }
 }
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/ReadTest.php b/core/modules/rest/lib/Drupal/rest/Tests/ReadTest.php
index 7c84cfd..a22174e 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/ReadTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/ReadTest.php
@@ -34,8 +34,7 @@ public static function getInfo() {
    * Tests several valid and invalid read requests on all entity types.
    */
   public function testRead() {
-    // @todo once EntityNG is implemented for other entity types expand this at
-    // least to users.
+    // @todo Expand this at least to users.
     // Define the entity types we want to test.
     $entity_types = array('entity_test', 'node');
     foreach ($entity_types as $entity_type) {
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
index a30e615..11359b4 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php
@@ -34,8 +34,7 @@ public static function getInfo() {
    */
   public function testPatchUpdate() {
     $serializer = $this->container->get('serializer');
-    // @todo once EntityNG is implemented for other entity types test all other
-    // entity types here as well.
+    // @todo Test all other entity types here as well.
     $entity_type = 'entity_test';
 
     $this->enableService('entity:' . $entity_type, 'PATCH');
diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php
index c8a4862..2b08044 100644
--- a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php
+++ b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php
@@ -29,7 +29,7 @@ class EntitySerializationTest extends NormalizerTestBase {
   /**
    * The test entity.
    *
-   * @var \Drupal\Core\Entity\EntityNG
+   * @var \Drupal\Core\Entity\ContentEntityBase
    */
   protected $entity;
 
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index 342f2e6..b798903 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -5,6 +5,8 @@
  * Hooks provided the Entity module.
  */
 
+use Drupal\Core\Entity\ContentEntityInterface;
+
 /**
  * @addtogroup hooks
  * @{
@@ -251,9 +253,7 @@ function hook_entity_info_alter(&$entity_info) {
  *   The entity object.
  */
 function hook_entity_create(\Drupal\Core\Entity\EntityInterface $entity) {
-  // @todo Remove the check for EntityNG once all entity types have been
-  //   converted to it.
-  if (!isset($entity->foo) && ($entity instanceof \Drupal\Core\Entity\EntityNG)) {
+  if ($entity instanceof ContentEntityInterface && !$entity->foo->value) {
     $entity->foo->value = 'some_initial_value';
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
index c92cf2c..9302dd8 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php
@@ -521,9 +521,9 @@ public function testUserHooks() {
   }
 
   /**
-   * Tests rollback from failed insert in EntityNG.
+   * Tests rollback from failed entity save.
    */
-  function testEntityNGRollback() {
+  function testEntityRollback() {
     // Create a block.
     try {
       $entity = entity_create('entity_test', array('name' => 'fail_insert'))->save();
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
index 06a7fe7..392b564 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\entity_test\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Annotation\Translation;
 use Drupal\Core\Language\Language;
@@ -26,7 +26,7 @@
  *     "form" = {
  *       "default" = "Drupal\entity_test\EntityTestFormController"
  *     },
- *     "translation" = "Drupal\content_translation\ContentTranslationControllerNG"
+ *     "translation" = "Drupal\content_translation\ContentTranslationController"
  *   },
  *   base_table = "entity_test",
  *   fieldable = TRUE,
@@ -39,7 +39,7 @@
  *   menu_base_path = "entity-test/manage/%entity_test"
  * )
  */
-class EntityTest extends EntityNG {
+class EntityTest extends ContentEntityBase {
 
   /**
    * The entity ID.
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestCache.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestCache.php
index 37dccb6..a1c66cd 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestCache.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestCache.php
@@ -24,7 +24,7 @@
  *     "form" = {
  *       "default" = "Drupal\entity_test\EntityTestFormController"
  *     },
- *     "translation" = "Drupal\content_translation\ContentTranslationControllerNG"
+ *     "translation" = "Drupal\content_translation\ContentTranslationController"
  *   },
  *   base_table = "entity_test",
  *   fieldable = TRUE,
@@ -39,64 +39,4 @@
  */
 class EntityTestCache extends EntityTest {
 
-  /**
-   * The entity ID.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldItemListInterface
-   */
-  public $id;
-
-  /**
-   * The entity UUID.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldItemListInterface
-   */
-  public $uuid;
-
-  /**
-   * The bundle of the test entity.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldItemListInterface
-   */
-  public $type;
-
-  /**
-   * The name of the test entity.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldItemListInterface
-   */
-  public $name;
-
-  /**
-   * The associated user.
-   *
-   * @var \Drupal\Core\Entity\Field\FieldItemListInterface
-   */
-  public $user_id;
-
-  /**
-   * Initialize the object. Invoked upon construction and wake up.
-   */
-  protected function init() {
-    parent::init();
-    // We unset all defined properties, so magic getters apply.
-    unset($this->id);
-    unset($this->uuid);
-    unset($this->name);
-    unset($this->user_id);
-    unset($this->type);
-  }
-
-  /**
-   * Overrides Drupal\entity\Entity::label().
-   */
-  public function label($langcode = Language::LANGCODE_DEFAULT) {
-    $info = $this->entityInfo();
-    if (isset($info['entity_keys']['label']) && $info['entity_keys']['label'] == 'name') {
-      return $this->getTranslation($langcode)->name->value;
-    }
-    else {
-      return parent::label($langcode);
-    }
-  }
 }
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php
index 3f7e833..2081873 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMul.php
@@ -24,7 +24,7 @@
  *     "form" = {
  *       "default" = "Drupal\entity_test\EntityTestFormController"
  *     },
- *     "translation" = "Drupal\content_translation\ContentTranslationControllerNG"
+ *     "translation" = "Drupal\content_translation\ContentTranslationController"
  *   },
  *   base_table = "entity_test_mul",
  *   data_table = "entity_test_mul_property_data",
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php
index 4a578e2..b8efe1c 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestMulRev.php
@@ -24,7 +24,7 @@
  *     "form" = {
  *       "default" = "Drupal\entity_test\EntityTestFormController"
  *     },
- *     "translation" = "Drupal\content_translation\ContentTranslationControllerNG"
+ *     "translation" = "Drupal\content_translation\ContentTranslationController"
  *   },
  *   base_table = "entity_test_mulrev",
  *   data_table = "entity_test_mulrev_property_data",
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestRev.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestRev.php
index 57e3531..1c2c882 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestRev.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Entity/EntityTestRev.php
@@ -24,7 +24,7 @@
  *     "form" = {
  *       "default" = "Drupal\entity_test\EntityTestFormController"
  *     },
- *     "translation" = "Drupal\content_translation\ContentTranslationControllerNG"
+ *     "translation" = "Drupal\content_translation\ContentTranslationController"
  *   },
  *   base_table = "entity_test_rev",
  *   revision_table = "entity_test_rev_revision",
@@ -48,7 +48,7 @@ class EntityTestRev extends EntityTest {
   public $revision_id;
 
   /**
-   * Overrides EntityNG::init().
+   * {@inheritdoc}
    */
   public function init() {
     parent::init();
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
index 1dbb859..e54520c 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php
@@ -6,13 +6,13 @@
 
 namespace Drupal\entity_test;
 
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the test entity edit forms.
  */
-class EntityTestFormController extends EntityFormControllerNG {
+class EntityTestFormController extends ContentEntityFormController {
 
   /**
    * Overrides Drupal\Core\Entity\EntityFormController::form().
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
index 6b3659d..066e8f2 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\taxonomy\Entity;
 
-use Drupal\Core\Entity\EntityNG;
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\Annotation\EntityType;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Annotation\Translation;
@@ -54,7 +54,7 @@
  *   permission_granularity = "bundle"
  * )
  */
-class Term extends EntityNG implements TermInterface {
+class Term extends ContentEntityBase implements TermInterface {
 
   /**
    * The taxonomy term ID.
@@ -130,7 +130,7 @@ public function id() {
   }
 
   /**
-   * Overides \Drupal\Core\Entity\EntityNG::init().
+   * {@inheritdoc}
    */
   protected function init() {
     parent::init();
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/TermDeleteForm.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/TermDeleteForm.php
index c8a1237..0d47081 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Form/TermDeleteForm.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Form/TermDeleteForm.php
@@ -9,13 +9,13 @@
 
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\taxonomy\VocabularyStorageControllerInterface;
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 use Drupal\Core\Cache\Cache;
 
 /**
  * Provides a deletion confirmation form for taxonomy term.
  */
-class TermDeleteForm extends EntityNGConfirmFormBase {
+class TermDeleteForm extends ContentEntityConfirmFormBase {
 
   /**
    * The taxonomy vocabulary storage controller.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
index b6bbb41..8821b09 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermFormController.php
@@ -9,14 +9,14 @@
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigFactory;
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Base for controller for taxonomy term edit forms.
  */
-class TermFormController extends EntityFormControllerNG {
+class TermFormController extends ContentEntityFormController {
 
   /**
    * The vocabulary storage.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
index 3b50d17..f7c704a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermTranslationController.php
@@ -8,12 +8,12 @@
 namespace Drupal\taxonomy;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\content_translation\ContentTranslationControllerNG;
+use Drupal\content_translation\ContentTranslationController;
 
 /**
  * Defines the translation controller class for terms.
  */
-class TermTranslationController extends ContentTranslationControllerNG {
+class TermTranslationController extends ContentTranslationController {
 
   /**
    * Overrides ContentTranslationController::entityFormAlter().
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index b20474b..85bfafa 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -655,7 +655,7 @@ function toolbar_modules_uninstalled($modules) {
  * Implements hook_ENTITY_TYPE_update().
  */
 function toolbar_menu_link_update(MenuLinkInterface $menu_link) {
-  if ($menu_link->get('menu_name') === 'admin') {
+  if ($menu_link->menu_name === 'admin') {
     _toolbar_clear_user_cache();
   }
 }
diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php
index 138b86e..b9fe6e3 100644
--- a/core/modules/user/lib/Drupal/user/AccountFormController.php
+++ b/core/modules/user/lib/Drupal/user/AccountFormController.php
@@ -7,13 +7,13 @@
 
 namespace Drupal\user;
 
-use Drupal\Core\Entity\EntityFormControllerNG;
+use Drupal\Core\Entity\ContentEntityFormController;
 use Drupal\Core\Language\Language;
 
 /**
  * Form controller for the user account forms.
  */
-abstract class AccountFormController extends EntityFormControllerNG {
+abstract class AccountFormController extends ContentEntityFormController {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php
index d975177..d8dc8e4 100644
--- a/core/modules/user/lib/Drupal/user/Entity/User.php
+++ b/core/modules/user/lib/Drupal/user/Entity/User.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\user\Entity;
 
+use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\Core\Entity\EntityMalformedException;
-use Drupal\Core\Entity\EntityNG;
 use Drupal\user\UserInterface;
 
 /**
@@ -46,7 +46,7 @@
  *   }
  * )
  */
-class User extends EntityNG implements UserInterface {
+class User extends ContentEntityBase implements UserInterface {
 
   /**
    * {@inheritdoc}
diff --git a/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php b/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php
index 5b460c9..973c84e 100644
--- a/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php
+++ b/core/modules/user/lib/Drupal/user/Form/UserCancelForm.php
@@ -8,13 +8,13 @@
 namespace Drupal\user\Form;
 
 use Drupal\Core\Config\ConfigFactory;
-use Drupal\Core\Entity\EntityNGConfirmFormBase;
+use Drupal\Core\Entity\ContentEntityConfirmFormBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a confirmation form for cancelling user account.
  */
-class UserCancelForm extends EntityNGConfirmFormBase {
+class UserCancelForm extends ContentEntityConfirmFormBase {
 
   /**
    * Available account cancellation methods.
diff --git a/core/modules/user/lib/Drupal/user/ProfileTranslationController.php b/core/modules/user/lib/Drupal/user/ProfileTranslationController.php
index 3392754..499f28c 100644
--- a/core/modules/user/lib/Drupal/user/ProfileTranslationController.php
+++ b/core/modules/user/lib/Drupal/user/ProfileTranslationController.php
@@ -8,12 +8,12 @@
 namespace Drupal\user;
 
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\content_translation\ContentTranslationControllerNG;
+use Drupal\content_translation\ContentTranslationController;
 
 /**
- * Defines the translation controller class for terms.
+ * Defines the translation controller class for users.
  */
-class ProfileTranslationController extends ContentTranslationControllerNG {
+class ProfileTranslationController extends ContentTranslationController {
 
   /**
    * Overrides ContentTranslationController::entityFormAlter().
diff --git a/core/modules/user/lib/Drupal/user/UserInterface.php b/core/modules/user/lib/Drupal/user/UserInterface.php
index 3400abf..4fbe5b3 100644
--- a/core/modules/user/lib/Drupal/user/UserInterface.php
+++ b/core/modules/user/lib/Drupal/user/UserInterface.php
@@ -7,13 +7,13 @@
 
 namespace Drupal\user;
 
-use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
  * Provides an interface defining a user entity.
  */
-interface UserInterface extends EntityInterface, AccountInterface {
+interface UserInterface extends ContentEntityInterface, AccountInterface {
 
   /**
    * Returns a list of roles.
diff --git a/core/modules/views/lib/Drupal/views/ViewStorageInterface.php b/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
index 7009bae..089f428 100644
--- a/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
+++ b/core/modules/views/lib/Drupal/views/ViewStorageInterface.php
@@ -12,7 +12,7 @@
 /**
  * Defines an interface for View storage classes.
  */
-interface ViewStorageInterface extends \IteratorAggregate, ConfigEntityInterface {
+interface ViewStorageInterface extends ConfigEntityInterface {
 
   /**
    * Retrieves a specific display's configuration by reference.
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
index 7d88791..3de8091 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -793,13 +793,6 @@ public function &getDisplay($display_id) {
   }
 
   /**
-   * Implements \IteratorAggregate::getIterator().
-   */
-  public function getIterator() {
-    return $this->storage->getIterator();
-  }
-
-  /**
    * Implements \Drupal\Core\Entity\EntityInterface::id().
    */
   public function id() {
@@ -835,20 +828,6 @@ public function bundle() {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isDefaultRevision().
-   */
-  public function isDefaultRevision($new_value = NULL) {
-    return $this->storage->isDefaultRevision($new_value);
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::getRevisionId().
-   */
-  public function getRevisionId() {
-    return $this->storage->getRevisionId();
-  }
-
-  /**
    * Implements \Drupal\Core\Entity\EntityInterface::entityInfo().
    */
   public function entityInfo() {
@@ -891,20 +870,6 @@ public function label($langcode = NULL) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\EntityInterface::isNewRevision().
-   */
-  public function isNewRevision() {
-    return $this->storage->isNewRevision();
-  }
-
-  /**
-   * Implements \Drupal\Core\Entity\EntityInterface::setNewRevision().
-   */
-  public function setNewRevision($value = TRUE) {
-    return $this->storage->setNewRevision($value);
-  }
-
-  /**
    * Implements \Drupal\Core\Entity\EntityInterface::enforceIsNew().
    */
   public function enforceIsNew($value = TRUE) {
@@ -918,23 +883,9 @@ public function getExportProperties() {
     return $this->storage->getExportProperties();
   }
 
-  /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslation().
-   */
-  public function getTranslation($langcode) {
-    // @todo Revisit this once config entities are converted to NG.
-    return $this;
-  }
 
   /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::getTranslationLanguages().
-   */
-  public function getTranslationLanguages($include_default = TRUE) {
-    return $this->storage->getTranslationLanguages($include_default);
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\TranslatableInterface::language)().
+   * {@inheritdoc}
    */
   public function language() {
     return $this->storage->language();
@@ -948,48 +899,6 @@ public function access($operation = 'view', AccountInterface $account = NULL) {
   }
 
   /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::isEmpty)().
-   */
-  public function isEmpty() {
-    return $this->storage->isEmpty();
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyValues().
-   */
-  public function getPropertyValues() {
-    return $this->storage->getPropertyValues();
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
-   */
-  public function getPropertyDefinitions() {
-    return $this->storage->getPropertyDefinitions();
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinition().
-   */
-  public function getPropertyDefinition($name) {
-    return $this->storage->getPropertyDefinition($name);
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::setPropertyValues().
-   */
-  public function setPropertyValues($values) {
-    return $this->storage->setPropertyValues($values);
-  }
-
-  /**
-   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getProperties().
-   */
-  public function getProperties($include_computed = FALSE) {
-    return $this->storage->getProperties($include_computed);
-  }
-
-  /**
    * Implements \Drupal\Core\Config\Entity\ConfigEntityInterface::enable().
    */
   public function enable() {
@@ -1205,13 +1114,6 @@ public static function postLoad(EntityStorageControllerInterface $storage_contro
   /**
    * {@inheritdoc}
    */
-  public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) {
-    $this->storage->preSaveRevision($storage_controller, $record);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function mergeDefaultDisplaysOptions() {
     $this->storage->mergeDefaultDisplaysOptions();
   }
@@ -1226,16 +1128,6 @@ public function uriRelationships() {
   /**
    * {@inheritdoc}
    */
-  public static function baseFieldDefinitions($entity_type) {
-    // @todo: This class is not directly defined as an entity type and does
-    //   not have base definitions but has to implement this method. Remove in
-    //   https://drupal.org/node/2004244.
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
    public function referencedEntities() {
      return $this->storage->referencedEntities();
    }
diff --git a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewUIObjectTest.php b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewUIObjectTest.php
index 172d6ef..3c42487 100644
--- a/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewUIObjectTest.php
+++ b/core/modules/views_ui/tests/Drupal/views_ui/Tests/ViewUIObjectTest.php
@@ -35,10 +35,8 @@ public function testEntityDecoration() {
     $method_args = array();
     $method_args['setOriginalID'] = array(12);
     $method_args['setStatus'] = array(TRUE);
-    $method_args['setNewRevision'] = array(FALSE);
     $method_args['enforceIsNew'] = array(FALSE);
     $method_args['label'] = array(Language::LANGCODE_NOT_SPECIFIED);
-    $method_args['isDefaultRevision'] = array(TRUE);
 
     $reflection = new \ReflectionClass('Drupal\Core\Config\Entity\ConfigEntityInterface');
     $interface_methods = array();
