diff --git a/core/includes/common.inc b/core/includes/common.inc
index ab11ddf..97afe45 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3895,7 +3895,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
   // Collect all #post_render_cache callbacks associated with this element when:
   // - about to store this element in the render cache, or when;
   // - about to apply #post_render_cache callbacks.
-  if (isset($elements['#cache']) || !$is_recursive_call) {
+  if (isset($elements['#cache'])) {
     $post_render_cache = drupal_render_collect_post_render_cache($elements);
     if ($post_render_cache) {
       $elements['#post_render_cache'] = $post_render_cache;
@@ -4020,7 +4020,11 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) {
   // Only the case of a cache hit when #cache is enabled, is not handled here,
   // that is handled earlier in drupal_render().
   if (!$is_recursive_call) {
-    _drupal_render_process_post_render_cache($elements);
+    $post_render_cache = drupal_render_collect_post_render_cache($elements);
+    if ($post_render_cache) {
+      $elements['#post_render_cache'] = $post_render_cache;
+      _drupal_render_process_post_render_cache($elements);
+    }
   }
 
   $elements['#printed'] = TRUE;
diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
index 7f86532..bb375ad 100644
--- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\TypedData\TranslatableInterface;
 use Drupal\entity\Entity\EntityViewDisplay;
+use Drupal\Core\Render\Element;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -92,8 +93,10 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
     $entities_by_bundle = array();
     foreach ($entities as $id => $entity) {
-      // Remove previously built content, if exists.
-      $entity->content = array(
+      if (empty($entity->content)) {
+        $entity->content = array();
+      }
+      $entity->content += array(
         '#view_mode' => $view_mode,
       );
       // Initialize the field item attributes for the fields being displayed.
@@ -120,7 +123,9 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
     foreach ($entities_by_bundle as $bundle => $bundle_entities) {
       $build = $displays[$bundle]->buildMultiple($bundle_entities);
       foreach ($bundle_entities as $id => $entity) {
-        $entity->content += $build[$id];
+        $entity->content += array(
+          '#view_mode' => $view_mode,
+        ) + $build[$id];
       }
     }
   }
@@ -144,6 +149,7 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
       "#{$this->entityTypeId}" => $entity,
       '#view_mode' => $view_mode,
       '#langcode' => $langcode,
+      '#pre_render' => array(array($this, 'entityViewBuilderPreRender')),
     );
 
     // Cache the rendered output if permitted by the view mode and global entity
@@ -168,6 +174,64 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
   }
 
   /**
+   * Performs pre-render tasks on an entity view.
+   *
+   * This function is assigned as a #pre_render callback in
+   * \Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults().
+   *
+   * @param array $elements
+   *   A structured array containing build information and context for an
+   *   entity view.
+   *
+   * @see drupal_render()
+   */
+  public function entityViewBuilderPreRender(array $elements) {
+    $entity = $elements['#entity'];
+    $bundle = $entity->bundle();
+    $view_hook = "{$this->entityTypeId}_view";
+    $view_mode = $elements['#view_mode'];
+    $langcode = $elements['#langcode'];
+    $context = array('langcode' => $langcode);
+
+    // Allow modules to change the view mode.
+    $this->moduleHandler->alter('entity_view_mode', $view_mode, $entity, $context);
+
+    // Get the corresponding display settings.
+    $display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode);
+
+    // Build field renderables.
+    $entity->content = $elements;
+    $this->buildContent(array($entity->id() => $entity), array($bundle => $display), $view_mode, $langcode);
+    $view_mode = isset($entity->content['#view_mode']) ? $entity->content['#view_mode'] : $view_mode;
+
+    $this->moduleHandler()->invokeAll($view_hook, array($entity, $display, $view_mode, $langcode));
+    $this->moduleHandler()->invokeAll('entity_view', array($entity, $display, $view_mode, $langcode));
+
+    // Do not override $build = $elements because hook_view implementations
+    // are expected to add content, not alter it. For example, mymodule_view
+    // should not change the #theme key.
+    $build = $entity->content;
+    // We don't need duplicate rendering info in $entity->content.
+    unset($entity->content);
+
+    $this->alterBuild($build, $entity, $display, $view_mode, $langcode);
+
+    // Assign the weights configured in the display.
+    // @todo: Once https://drupal.org/node/1875974 provides the missing API,
+    //   only do it for 'extra fields', since other components have been taken
+    //   care of in EntityViewDisplay::buildMultiple().
+    foreach ($display->getComponents() as $name => $options) {
+      if (isset($build[$name])) {
+        $build[$name]['#weight'] = $options['weight'];
+      }
+    }
+
+    // Allow modules to modify the render array.
+    \Drupal::moduleHandler()->alter(array($view_hook, 'entity_view'), $build, $entity, $display);
+    return $build;
+  }
+
+  /**
    * Specific per-entity building.
    *
    * @param array $build
@@ -202,58 +266,24 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
     }
 
     // Build the view modes and display objects.
-    $view_modes = array();
-    $context = array('langcode' => $langcode);
-    foreach ($entities as $key => $entity) {
-      $bundle = $entity->bundle();
+    $build = array('#sorted' => TRUE);
+    $weight = 0;
 
+    foreach ($entities as $key => $entity) {
       // Ensure that from now on we are dealing with the proper translation
       // object.
       $entity = $this->entityManager->getTranslationFromContext($entity, $langcode);
       $entities[$key] = $entity;
 
-      // Allow modules to change the view mode.
-      $entity_view_mode = $view_mode;
-      $this->moduleHandler->alter('entity_view_mode', $entity_view_mode, $entity, $context);
-      // Store entities for rendering by view_mode.
-      $view_modes[$entity_view_mode][$entity->id()] = $entity;
-    }
-
-    foreach ($view_modes as $mode => $view_mode_entities) {
-      $displays[$mode] = EntityViewDisplay::collectRenderDisplays($view_mode_entities, $mode);
-      $this->buildContent($view_mode_entities, $displays[$mode], $mode, $langcode);
-    }
+      //$build[$key] = $entity->content;
+      $build[$key] = array(
+        '#entity' => $entity
+      );
 
-    $view_hook = "{$this->entityTypeId}_view";
-    $build = array('#sorted' => TRUE);
-    $weight = 0;
-    foreach ($entities as $key => $entity) {
-      $entity_view_mode = isset($entity->content['#view_mode']) ? $entity->content['#view_mode'] : $view_mode;
-      $display = $displays[$entity_view_mode][$entity->bundle()];
-      \Drupal::moduleHandler()->invokeAll($view_hook, array($entity, $display, $entity_view_mode, $langcode));
-      \Drupal::moduleHandler()->invokeAll('entity_view', array($entity, $display, $entity_view_mode, $langcode));
-
-      $build[$key] = $entity->content;
-      // We don't need duplicate rendering info in $entity->content.
-      unset($entity->content);
-
-      $build[$key] += $this->getBuildDefaults($entity, $entity_view_mode, $langcode);
-      $this->alterBuild($build[$key], $entity, $display, $entity_view_mode, $langcode);
-
-      // Assign the weights configured in the display.
-      // @todo: Once https://drupal.org/node/1875974 provides the missing API,
-      //   only do it for 'extra fields', since other components have been taken
-      //   care of in EntityViewDisplay::buildMultiple().
-      foreach ($display->getComponents() as $name => $options) {
-        if (isset($build[$key][$name])) {
-          $build[$key][$name]['#weight'] = $options['weight'];
-        }
-      }
+      // Set defaults for #pre_render.
+      $build[$key] += $this->getBuildDefaults($entity, $view_mode, $langcode);
 
       $build[$key]['#weight'] = $weight++;
-
-      // Allow modules to modify the render array.
-      $this->moduleHandler->alter(array($view_hook, 'entity_view'), $build[$key], $entity, $display);
     }
 
     return $build;
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 0070378..51d0561 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1312,17 +1312,14 @@ function comment_preview(CommentInterface $comment, array &$form_state) {
     // includes the comment reply form, which contains the comment preview and
     // therefore the rendered parent entity. This results in an infinite loop of
     // parent entity output rendering the comment form and the comment form
-    // rendering the parent entity. To prevent this infinite loop we temporarily
-    // set the value of the comment field on the rendered entity to hidden
+    // rendering the parent entity. To prevent this infinite loop we clone
+    // the commented entity and change the value of the comment field to hidden
     // before calling entity_view(). That way when the output of the commented
-    // entity is rendered, it excludes the comment field output. As objects are
-    // always addressed by reference we ensure changes are not lost by setting
-    // the value back to its original state after the call to entity_view().
+    // entity is rendered, it excludes the comment field output.
+    $entity = clone $entity;
     $field_name = $comment->getFieldName();
-    $original_status = $entity->get($field_name)->status;
     $entity->get($field_name)->status = COMMENT_HIDDEN;
     $build = entity_view($entity, 'full');
-    $entity->get($field_name)->status = $original_status;
   }
 
   $preview_build['comment_output_below'] = $build;
