Index: block_api.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/block_api/block_api.api.php,v
retrieving revision 1.4
diff -u -p -r1.4 block_api.api.php
--- block_api.api.php	12 Dec 2010 19:23:35 -0000	1.4
+++ block_api.api.php	12 Dec 2010 20:23:03 -0000
@@ -26,6 +26,7 @@
  *     block instances of the block type by default. These default settings are
  *     only applied upon (re-)saving the block instance configuration through
  *     the UI.
+ *   - ...: Any other properties to pass through to hook_block_info().
  */
 function hook_block_api_info() {
   $types['html'] = array(
Index: block_api.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/block_api/block_api.install,v
retrieving revision 1.6
diff -u -p -r1.6 block_api.install
--- block_api.install	12 Dec 2010 17:12:52 -0000	1.6
+++ block_api.install	12 Dec 2010 19:32:21 -0000
@@ -1,6 +1,14 @@
 <?php
 // $Id: block_api.install,v 1.6 2010/12/12 17:12:52 sun Exp $
 
+/**
+ * @file
+ * Installation functions for Block API module.
+ */
+
+/**
+ * Implements hook_field_schema().
+ */
 function block_api_schema() {
   $schema['block_api'] = array(
     'description' => 'Stores Block API block instances.',
Index: block_api.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/block_api/block_api.module,v
retrieving revision 1.9
diff -u -p -r1.9 block_api.module
--- block_api.module	12 Dec 2010 19:23:35 -0000	1.9
+++ block_api.module	12 Dec 2010 21:35:51 -0000
@@ -53,11 +53,28 @@ function block_api_get_info() {
  * Implements hook_block_info().
  */
 function block_api_block_info() {
+  $block_info = block_api_get_info();
   $blocks = array();
   foreach (block_api_load_multiple(FALSE) as $instance) {
-    $blocks[$instance->delta] = array(
-      'info' => $instance->admin_title,
-    );
+    // If a block type module is disabled, no type information exists.
+    if (!isset($block_info[$instance->type])) {
+      $block_info[$instance->type]['title'] = $instance->type;
+    }
+
+    $blocks[$instance->delta]['info'] = t('!type: !title', array(
+      '!type' => $block_info[$instance->type]['title'],
+      '!title' => $instance->admin_title,
+    ));
+    // Add any other Block module properties defined by the block type, but
+    // exclude all Block API properties.
+    $blocks[$instance->delta] += array_diff_key($block_info[$instance->type], array(
+      'title',
+      'description',
+      'module',
+      'type',
+      'storage',
+      'settings',
+    ));
   }
   return $blocks;
 }
@@ -106,7 +123,11 @@ function block_api_block_configure($delt
  */
 function block_api_block_save($delta, $edit = array()) {
   $instance = $edit['block_api'];
-  $instance->settings = $edit['settings'];
+  // In case the block type module is disabled, the block configuration form
+  // does not contain any block type settings, so retain the existing.
+  if (isset($edit['settings'])) {
+    $instance->settings = $edit['settings'];
+  }
 
   // Allow the block type module to perform changes in $instance and $edit
   // before saving.
@@ -304,3 +325,13 @@ function block_api_form_block_admin_disp
     );
   }
 }
+
+/**
+ * Implements hook_modules_uninstalled().
+ */
+function block_api_modules_uninstalled($modules) {
+  $deltas = db_query('SELECT delta FROM {block_api} WHERE module IN (:modules)', array(':modules' => $modules))->fetchCol();
+  if ($deltas) {
+    block_api_delete_multiple($deltas);
+  }
+}
Index: tests/block_api.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/block_api/tests/block_api.test,v
retrieving revision 1.3
diff -u -p -r1.3 block_api.test
--- tests/block_api.test	12 Dec 2010 19:23:35 -0000	1.3
+++ tests/block_api.test	12 Dec 2010 21:33:53 -0000
@@ -92,3 +92,81 @@ class BlockApiAdministrationWebTestCase 
     $this->assertNoRaw(check_plain($edit['title']), t('Block title not found.'));
   }
 }
+
+/**
+ * Tests module system integration.
+ */
+class BlockApiModuleWebTestCase extends BlockApiTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Module system integration',
+      'description' => 'Tests module system integration.',
+      'group' => 'Block API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp(array('block_api_test'));
+
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer blocks',
+    ));
+    $this->drupalLogin($this->admin_user);
+  }
+
+  /**
+   * Tests behavior of block instances when block type modules are disabled.
+   */
+  function testBlockTypeDisabled() {
+    $this->drupalGet('admin/structure/block/add-module-block');
+
+    // Create a new block type instance.
+    $edit = array(
+      'admin_title' => $this->randomString(),
+      'delta' => drupal_strtolower($this->randomName()),
+      'type' => 'html',
+    );
+    $this->drupalPost(NULL, $edit, t('Add block'));
+    $this->assertText(t('Block body'));
+
+    $instance = (object) $edit;
+    $theme = variable_get('theme_default', 'bartik');
+    // Use randomName() to simplify assertions below, as check_markup() should
+    // not filter or escape any characters of the string.
+    $body = $this->randomName();
+    $edit = array(
+      'title' => $this->randomName(),
+      'settings[body][value]' => $body,
+      "regions[$theme]" => 'sidebar_first',
+    );
+    $this->drupalPost(NULL, $edit, t('Save block'));
+
+    // Verify that the block is shown.
+    $this->drupalGet('');
+    $this->assertText($body, t('Block found.'));
+
+    // block_api_test module cannot be disabled through the UI, since it is
+    // hidden, so disable it programmatically.
+    module_disable(array('block_api_test'));
+    system_list_reset();
+
+    // Verify that the block is no longer shown.
+    $this->drupalGet('');
+    $this->assertNoText($body, t('Block of disabled block type module not found.'));
+
+    // Verify that the block type module's settings form elements are not
+    // output, but we can save the block.
+    $this->drupalGet('admin/structure/block/manage/block_api/' . $instance->delta);
+    $this->assertNoText(t('Block body'), t('Block type module settings not found.'));
+    $this->drupalPost(NULL, array(), t('Save block'));
+
+    // Re-enable block_api_test module.
+    module_enable(array('block_api_test'));
+    system_list_reset();
+
+    // Verify that the block still contains the last saved settings.
+    $this->drupalGet('');
+    $this->assertText($body, t('Block found.'));
+  }
+}
+
