diff --git a/core/lib/Drupal/Core/Controller/AjaxController.php b/core/lib/Drupal/Core/Controller/AjaxController.php
index 55fef94..7fb31f9 100644
--- a/core/lib/Drupal/Core/Controller/AjaxController.php
+++ b/core/lib/Drupal/Core/Controller/AjaxController.php
@@ -48,6 +48,9 @@ public function content(Request $request, $_content) {
     // Remove the accept header so the subrequest does not end up back in this
     // controller.
     $request->headers->remove('accept');
+    // Remove the header in order to let the subrequest not think that it's an
+    // ajax request, see \Drupal\Core\ContentNegotiation.
+    $request->headers->remove('x-requested-with');
 
     $response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all());
     // For successful (HTTP status 200) responses.
diff --git a/core/lib/Drupal/Core/Controller/HtmlFormController.php b/core/lib/Drupal/Core/Controller/HtmlFormController.php
index 96530d5..2c2fa2c 100644
--- a/core/lib/Drupal/Core/Controller/HtmlFormController.php
+++ b/core/lib/Drupal/Core/Controller/HtmlFormController.php
@@ -63,8 +63,7 @@ public function content(Request $request, $_form) {
     $form_state['build_info']['args'] = $args;
 
     $form_id = _drupal_form_id($form_object, $form_state);
-    $form = drupal_build_form($form_id, $form_state);
-    return new Response(drupal_render_page($form));
+    return drupal_build_form($form_id, $form_state);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/HttpKernel.php b/core/lib/Drupal/Core/HttpKernel.php
index ca0c002..07c79c7 100644
--- a/core/lib/Drupal/Core/HttpKernel.php
+++ b/core/lib/Drupal/Core/HttpKernel.php
@@ -64,18 +64,21 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
     /**
      * Forwards the request to another controller.
      *
-     * @param string $controller The controller name (a string like BlogBundle:Post:index)
-     * @param array  $attributes An array of request attributes
-     * @param array  $query      An array of request query parameters
+     * @param string|NULL $controller
+     *   The controller name (a string like BlogBundle:Post:index).
+     * @param array $attributes
+     *   An array of request attributes.
+     * @param array $query
+     *   An array of request query parameters.
      *
-     * @return Response A Response instance
+     * @return Response
+     *   A Response instance
      */
     public function forward($controller, array $attributes = array(), array $query = array())
     {
-        $attributes['_controller'] = $controller;
-        $subRequest = $this->container->get('request')->duplicate($query, null, $attributes);
+      $subrequest = $this->setupSubrequest($controller, $attributes, $query);
 
-        return $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+      return $this->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
     }
 
     /**
@@ -240,4 +243,29 @@ public function hasEsiSupport()
     {
         return $this->esiSupport;
     }
+
+  /**
+   * Creates a request object for a subrequest.
+   *
+   * @param string $controller
+   *   The controller name (a string like BlogBundle:Post:index)
+   * @param array $attributes
+   *   An array of request attributes.
+   * @param array $query
+   *   An array of request query parameters.
+   *
+   * @return \Symfony\Component\HttpFoundation\Request
+   *   Returns the new request.
+   */
+  public function setupSubrequest($controller, array $attributes, array $query) {
+    // Don't override the controller if it's NULL.
+    if (isset($controller)) {
+      $attributes['_controller'] = $controller;
+    }
+    else {
+      unset($attributes['_controller']);
+    }
+    return $this->container->get('request')->duplicate($query, NULL, $attributes);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Routing/Enhancer/AjaxEnhancer.php b/core/lib/Drupal/Core/Routing/Enhancer/AjaxEnhancer.php
index 7d27783..47c5179 100644
--- a/core/lib/Drupal/Core/Routing/Enhancer/AjaxEnhancer.php
+++ b/core/lib/Drupal/Core/Routing/Enhancer/AjaxEnhancer.php
@@ -38,7 +38,7 @@ public function __construct(ContentNegotiation $negotiation) {
    */
   public function enhance(array $defaults, Request $request) {
     if (empty($defaults['_content']) && $this->negotiation->getContentType($request) == 'drupal_ajax') {
-      $defaults['_content'] = $defaults['_controller'];
+      $defaults['_content'] = isset($defaults['_controller']) ? $defaults['_controller'] : NULL;
       $defaults['_controller'] = '\Drupal\Core\Controller\AjaxController::content';
     }
     return $defaults;
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
index adb7425..791ea07 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Tests/PreviewTest.php
@@ -65,4 +65,18 @@ function testPreviewUI() {
     $this->assertEqual(count($elements), 0);
   }
 
+  /**
+   * Tests the actual preview response.
+   */
+  public function testPreviewController() {
+    $result = $this->drupalGetAJAX('admin/structure/views/view/test_preview/preview/default');
+
+    $result_commands = array();
+    // Build a list of the result commands keyed by the js command.
+    foreach ($result as $command) {
+      $result_commands[$command['command']] = $command;
+    }
+    $this->assertTrue(isset($result_commands['insert']));
+  }
+
 }
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php
index b18c471..b0efc08 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php
@@ -88,7 +88,7 @@ public function form(array $form, array &$form_state) {
       $args = explode('/', $form_state['values']['view_args']);
     }
 
-    if ($view->renderPreview) {
+    if (!empty($form_state['show_preview'])) {
       $form['preview'] = array(
         '#weight' => 110,
         '#theme_wrappers' => array('container'),
@@ -138,7 +138,6 @@ public function submitPreview($form, &$form_state) {
       $new_view = new ViewUI($view);
     }
     $form_state['build_info']['args'][0] = $new_view;
-    $view->renderPreview = TRUE;
     $form_state['show_preview'] = TRUE;
     $form_state['rebuild'] = TRUE;
   }
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 5877f28..42d58d9 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -534,6 +534,7 @@ public function renderPreview($display_id, $args = array()) {
     $output = '';
 
     $errors = $this->executable->validate();
+    $this->executable->destroy();
     if (empty($errors)) {
       $this->ajax = TRUE;
       $this->executable->live_preview = TRUE;
diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc
index a0a2630..465f618 100644
--- a/core/modules/views_ui/views_ui.theme.inc
+++ b/core/modules/views_ui/views_ui.theme.inc
@@ -461,5 +461,5 @@ function template_preprocess_views_ui_view_preview_section(&$vars) {
 function theme_views_ui_view_preview_section($vars) {
   return '<h1 class="section-title">' . $vars['title'] . '</h1>'
   . $vars['links']
-  . '<div class="preview-section">'. $vars['content'] . '</div>';
+  . '<div class="preview-section">'. render($vars['content']) . '</div>';
 }
diff --git a/core/tests/Drupal/Tests/Core/Controller/TestController.php b/core/tests/Drupal/Tests/Core/Controller/TestController.php
new file mode 100644
index 0000000..9513529
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Controller/TestController.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Controller\TestController.
+ */
+
+namespace Drupal\Tests\Core\Controller;
+
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Defines a test controller used by unit tests.
+ */
+class TestController {
+
+  /**
+   * Returns test content for unit tests.
+   */
+  public function content() {
+    return new Response('');
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/HttpKernelTest.php b/core/tests/Drupal/Tests/Core/HttpKernelTest.php
new file mode 100644
index 0000000..b51e108
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/HttpKernelTest.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\HttpKernelTest.
+ */
+
+namespace Drupal\Tests\Core;
+
+use Drupal\Core\Controller\ControllerResolver;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\HttpKernel;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
+use Symfony\Component\DependencyInjection\Scope;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Tests the custom http kernel of drupal.
+ *
+ * @see \Drupal\Core\HttpKernel
+ */
+class HttpKernelTest extends UnitTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'HttpKernel (Unit)',
+      'description' => 'Tests the HttpKernel.',
+      'group' => 'Routing',
+    );
+  }
+
+  /**
+   * Tests the forward method.
+   *
+   * @see \Drupal\Core\HttpKernel::setupSubrequest()
+   */
+  public function testSetupSubrequest() {
+    $container = new ContainerBuilder();
+
+    $request = new Request();
+    $container->addScope(new Scope('request'));
+    $container->enterScope('request');
+    $container->set('request', $request, 'request');
+
+    $dispatcher = new EventDispatcher();
+    $controller_resolver = new ControllerResolver($container);
+
+    $http_kernel = new HttpKernel($dispatcher, $container, $controller_resolver);
+
+    $test_controller = '\Drupal\Tests\Core\Controller\TestController';
+    $random_attribute = $this->randomName();
+    $subrequest = $http_kernel->setupSubrequest($test_controller, array('custom_attribute' => $random_attribute), array('custom_query' => $random_attribute));
+    $this->assertNotSame($subrequest, $request, 'The subrequest is not the same as the main request.');
+    $this->assertEquals($subrequest->attributes->get('custom_attribute'), $random_attribute, 'Attributes are set from the subrequest.');
+    $this->assertEquals($subrequest->query->get('custom_query'), $random_attribute, 'Query attributes are set from the subrequest.');
+    $this->assertEquals($subrequest->attributes->get('_controller'), $test_controller, 'Controller attribute got set.');
+
+    $subrequest = $http_kernel->setupSubrequest(NULL, array(), array());
+    $this->assertFalse($subrequest->attributes->has('_controller'), 'Ensure that _controller is not copied when no controller was set before.');
+  }
+
+}
