diff --git a/core/lib/Drupal/Core/Updater/Module.php b/core/lib/Drupal/Core/Updater/Module.php
index acc3028..1c80f84 100644
--- a/core/lib/Drupal/Core/Updater/Module.php
+++ b/core/lib/Drupal/Core/Updater/Module.php
@@ -31,6 +31,14 @@ class Module extends Updater implements UpdaterInterface {
   public function getInstallDirectory() {
     if ($relative_path = drupal_get_path('module', $this->name)) {
       $relative_path = dirname($relative_path);
+      $project_name = $this->getProjectName($relative_path);
+      do {
+        // Some modules keep their .info file in a subdirectory of their root
+        // directory, e.g., modules/MODULE/MODULE/MODULE.info. To find
+        // the appropriate directory to install the module in, we repeatedly
+        // ascend to the parent directory until the project name differs.
+          $relative_path = dirname($relative_path);
+      } while ($this->getProjectName($relative_path) == $project_name);
     }
     else {
       $relative_path = 'modules';
diff --git a/core/lib/Drupal/Core/Updater/Theme.php b/core/lib/Drupal/Core/Updater/Theme.php
index 4bd716a..e94e814 100644
--- a/core/lib/Drupal/Core/Updater/Theme.php
+++ b/core/lib/Drupal/Core/Updater/Theme.php
@@ -31,6 +31,14 @@ class Theme extends Updater implements UpdaterInterface {
   public function getInstallDirectory() {
     if ($relative_path = drupal_get_path('theme', $this->name)) {
       $relative_path = dirname($relative_path);
+      $project_name = $this->getProjectName($relative_path);
+      do {
+        // Some themes keep their .info file in a subdirectory of their root
+        // directory, e.g., themes/THEME/THEME/THEME.info. To find
+        // the appropriate directory to install the theme in, we repeatedly
+        // ascend to the parent directory until the project name differs.
+          $relative_path = dirname($relative_path);
+      } while ($this->getProjectName($relative_path) == $project_name);
     }
     else {
       $relative_path = 'themes';
diff --git a/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php b/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
index af7d035..880d4fc 100644
--- a/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
+++ b/core/modules/update/lib/Drupal/update/Tests/UpdateContribTest.php
@@ -17,7 +17,7 @@ class UpdateContribTest extends UpdateTestBase {
    *
    * @var array
    */
-  public static $modules = array('update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test');
+  public static $modules = array('update_test', 'update', 'aaa_update_test', 'bbb_update_test', 'ccc_update_test', 'ddd_update_test', 'ddd_ui_update_test');
 
   public static function getInfo() {
     return array(
@@ -133,6 +133,20 @@ function testUpdateContribOrder() {
         'version' => '8.x-1.0',
         'hidden' => FALSE,
       ),
+
+      // This should be its own project, and listed third on the report.
+      'ddd_update_test' => array(
+        'project' => 'ddd_update_test',
+        'version' => '8.x-1.0',
+        'hidden' => FALSE,
+      ),
+
+      // This should be part of the "DDD Update test" project
+      'ddd_ui_update_test' => array(
+        'project' => 'ddd_update_test',
+        'version' => '8.x-1.0',
+        'hidden' => FALSE,
+      ),
     );
     config('update_test.settings')->set('system_info', $system_info)->save();
     $this->refreshUpdateStatus(array('drupal' => '0', '#all' => '1_0'));
@@ -140,17 +154,21 @@ function testUpdateContribOrder() {
     // We're expecting the report to say all projects are up to date.
     $this->assertText(t('Up to date'));
     $this->assertNoText(t('Update available'));
-    // We want to see all 3 module names listed, since they'll show up either
+    // We want to see all 5 module names listed, since they'll show up either
     // as project names or as modules under the "Includes" listing.
     $this->assertText(t('AAA Update test'));
     $this->assertText(t('BBB Update test'));
     $this->assertText(t('CCC Update test'));
+    $this->assertText(t('DDD Update test'));
+    $this->assertText(t('DDD UI Update test'));
     // We want aaa_update_test included in the ccc_update_test project, not as
     // its own project on the report.
     $this->assertNoRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'), 'Link to aaa_update_test project does not appear.');
-    // The other two should be listed as projects.
+    $this->assertNoRaw(l(t('DDD UI Update test'), 'http://example.com/project/ddd_ui_update_test'), 'Link to ddd_ui_update_test project does not appear.');
+    // The other three should be listed as projects.
     $this->assertRaw(l(t('BBB Update test'), 'http://example.com/project/bbb_update_test'), 'Link to bbb_update_test project appears.');
     $this->assertRaw(l(t('CCC Update test'), 'http://example.com/project/ccc_update_test'), 'Link to bbb_update_test project appears.');
+    $this->assertRaw(l(t('DDD Update test'), 'http://example.com/project/ddd_update_test'), 'Link to ddd_update_test project appears.');
 
     // We want to make sure we see the BBB project before the CCC project.
     // Instead of just searching for 'BBB Update test' or something, we want
@@ -285,6 +303,16 @@ function testUpdateBrokenFetchURL() {
         'version' => '8.x-1.0',
         'hidden' => FALSE,
       ),
+      'ddd_update_test' => array(
+        'project' => 'ddd_update_test',
+        'version' => '8.x-1.0',
+        'hidden' => FALSE,
+      ),
+      'ddd_ui_update_test' => array(
+        'project' => 'ddd_update_test',
+        'version' => '8.x-1.0',
+        'hidden' => FALSE,
+      ),
     );
     config('update_test.settings')->set('system_info', $system_info)->save();
 
@@ -293,6 +321,8 @@ function testUpdateBrokenFetchURL() {
       'aaa_update_test' => '1_0',
       'bbb_update_test' => 'does-not-exist',
       'ccc_update_test' => '1_0',
+      'ddd_update_test' => '1_0',
+      'ddd_ui_update_test' => '1_0',
     );
     $this->refreshUpdateStatus($xml_mapping);
 
@@ -309,13 +339,14 @@ function testUpdateBrokenFetchURL() {
     $this->assertRaw('<div class="version-status">' . t('Failed to get available update data'));
 
     // We should see the output messages from fetching manually.
-    $this->assertUniqueText(t('Checked available update data for 3 projects.'));
+    $this->assertUniqueText(t('Checked available update data for 4 projects.'));
     $this->assertUniqueText(t('Failed to get available update data for one project.'));
 
-    // The other two should be listed as projects.
+    // The other three should be listed as projects.
     $this->assertRaw(l(t('AAA Update test'), 'http://example.com/project/aaa_update_test'), 'Link to aaa_update_test project appears.');
     $this->assertNoRaw(l(t('BBB Update test'), 'http://example.com/project/bbb_update_test'), 'Link to bbb_update_test project does not appear.');
     $this->assertRaw(l(t('CCC Update test'), 'http://example.com/project/ccc_update_test'), 'Link to bbb_update_test project appears.');
+    $this->assertRaw(l(t('DDD Update test'), 'http://example.com/project/ddd_update_test'), 'Link to ddd_update_test project appears.');
   }
 
   /**
diff --git a/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.info b/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.info
new file mode 100644
index 0000000..eeb837d
--- /dev/null
+++ b/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.info
@@ -0,0 +1,5 @@
+name = DDD UI Update test
+description = Support module for update module testing.
+package = Testing
+core = 8.x
+hidden = TRUE
diff --git a/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.module b/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.module
new file mode 100644
index 0000000..4d67b8e
--- /dev/null
+++ b/core/modules/update/tests/modules/ddd_update_test/ddd_ui_update_test/ddd_ui_update_test.module
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Dummy module for testing Update status.
+ */
diff --git a/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.info b/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.info
new file mode 100644
index 0000000..09ddf8f
--- /dev/null
+++ b/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.info
@@ -0,0 +1,5 @@
+name = DDD Update test
+description = Support module for update module testing.
+package = Testing
+core = 8.x
+hidden = TRUE
diff --git a/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.module b/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.module
new file mode 100644
index 0000000..4d67b8e
--- /dev/null
+++ b/core/modules/update/tests/modules/ddd_update_test/ddd_update_test.module
@@ -0,0 +1,6 @@
+<?php
+
+/**
+ * @file
+ * Dummy module for testing Update status.
+ */
diff --git a/core/modules/update/tests/modules/update_test/ddd_ui_update_test.1_0.xml b/core/modules/update/tests/modules/update_test/ddd_ui_update_test.1_0.xml
new file mode 100644
index 0000000..ef945e9
--- /dev/null
+++ b/core/modules/update/tests/modules/update_test/ddd_ui_update_test.1_0.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project xmlns:dc="http://purl.org/dc/elements/1.1/">
+<title>DDD UI Update test</title>
+<short_name>ddd_ui_update_test</short_name>
+<dc:creator>Drupal</dc:creator>
+<api_version>8.x</api_version>
+<recommended_major>1</recommended_major>
+<supported_majors>1</supported_majors>
+<default_major>1</default_major>
+<project_status>published</project_status>
+<link>http://example.com/project/ddd_update_test/ddd_ui_update_test</link>
+  <terms>
+   <term><name>Projects</name><value>Modules</value></term>
+  </terms>
+<releases>
+ <release>
+  <name>ddd_ui_update_test 8.x-1.0</name>
+  <version>8.x-1.0</version>
+  <tag>DRUPAL-7--1-0</tag>
+  <version_major>1</version_major>
+  <version_patch>0</version_patch>
+  <status>published</status>
+  <release_link>http://example.com/ddd_update_test/ddd_ui_update_test-7-x-1-0-release</release_link>
+  <download_link>http://example.com/ddd_update_test/ddd_ui_update_test-8.x-1.0.tar.gz</download_link>
+  <date>1250424521</date>
+  <mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
+  <filesize>1073741824</filesize>
+  <terms>
+   <term><name>Release type</name><value>New features</value></term>
+   <term><name>Release type</name><value>Bug fixes</value></term>
+  </terms>
+ </release>
+</releases>
+</project>
diff --git a/core/modules/update/tests/modules/update_test/ddd_update_test.1_0.xml b/core/modules/update/tests/modules/update_test/ddd_update_test.1_0.xml
new file mode 100644
index 0000000..82c69bd
--- /dev/null
+++ b/core/modules/update/tests/modules/update_test/ddd_update_test.1_0.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project xmlns:dc="http://purl.org/dc/elements/1.1/">
+<title>DDD Update test</title>
+<short_name>ddd_update_test</short_name>
+<dc:creator>Drupal</dc:creator>
+<api_version>8.x</api_version>
+<recommended_major>1</recommended_major>
+<supported_majors>1</supported_majors>
+<default_major>1</default_major>
+<project_status>published</project_status>
+<link>http://example.com/project/ddd_update_test</link>
+  <terms>
+   <term><name>Projects</name><value>Modules</value></term>
+  </terms>
+<releases>
+ <release>
+  <name>ddd_update_test 8.x-1.0</name>
+  <version>8.x-1.0</version>
+  <tag>DRUPAL-7--1-0</tag>
+  <version_major>1</version_major>
+  <version_patch>0</version_patch>
+  <status>published</status>
+  <release_link>http://example.com/ddd_update_test-7-x-1-0-release</release_link>
+  <download_link>http://example.com/ddd_update_test-8.x-1.0.tar.gz</download_link>
+  <date>1250424521</date>
+  <mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
+  <filesize>1073741824</filesize>
+  <terms>
+   <term><name>Release type</name><value>New features</value></term>
+   <term><name>Release type</name><value>Bug fixes</value></term>
+  </terms>
+ </release>
+</releases>
+</project>
