Index: modules/comment/comment.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.install,v
retrieving revision 1.73
diff -u -p -r1.73 comment.install
--- modules/comment/comment.install	28 Sep 2010 03:30:37 -0000	1.73
+++ modules/comment/comment.install	13 Dec 2010 04:50:23 -0000
@@ -7,35 +7,6 @@
  */
 
 /**
- * Implements hook_install().
- */
-function comment_install() {
-  // Create comment body field.
-  if (!field_info_field('comment_body')) {
-    $field = array(
-      'field_name' => 'comment_body',
-      'type' => 'text_long',
-      'entity_types' => array('comment'),
-    );
-    field_create_field($field);
-  }
-
-  // There is a separate comment bundle for each node type to allow for
-  // per-node-type customization of comment fields. Each one of these bundles
-  // needs a comment body field instance. A comment bundle is needed even for
-  // node types whose comments are disabled by default, because individual nodes
-  // may override that default.
-  // @todo This should be changed to call field_attach_create_bundle() instead,
-  //   and a comment_field_attach_create_bundle() function should be added to
-  //   handle the creation of the comment body field instance.
-  foreach (node_type_get_types() as $type => $info) {
-    if (!isset($info->is_new) && !isset($info->disabled) && !field_info_instance('comment', 'comment_body', 'comment_node_' . $info->type)) {
-      _comment_body_field_instance_create($info);
-    }
-  }
-}
-
-/**
  * Implements hook_uninstall().
  */
 function comment_uninstall() {
@@ -78,6 +49,22 @@ function comment_enable() {
 }
 
 /**
+ * Implements hook_modules_enabled().
+ */
+function comment_modules_enabled($modules) {
+  // There is a separate comment bundle for each node type to allow for
+  // per-node-type customization of comment fields. Each one of these bundles
+  // needs a comment body field instance. A comment bundle is needed even for
+  // node types whose comments are disabled by default, because individual nodes
+  // may override that default.
+  // Ensure that the list of node types reflects newly enabled modules.
+  node_types_rebuild();
+  foreach (node_type_get_types() as $type => $info) {
+    _comment_body_field_create($info);
+  }
+}
+
+/**
  * Implements hook_update_dependencies().
  */
 function comment_update_dependencies() {
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.927
diff -u -p -r1.927 comment.module
--- modules/comment/comment.module	9 Dec 2010 01:57:56 -0000	1.927
+++ modules/comment/comment.module	13 Dec 2010 04:50:24 -0000
@@ -316,10 +316,7 @@ function comment_count_unpublished() {
  * Implements hook_node_type_insert().
  */
 function comment_node_type_insert($info) {
-  field_attach_create_bundle('comment', 'comment_node_' . $info->type);
-  // @todo Create a comment_field_attach_create_bundle() function, and have that
-  //   function create the comment body field instance.
-  _comment_body_field_instance_create($info);
+  _comment_body_field_create($info);
 }
 
 /**
@@ -351,27 +348,43 @@ function comment_node_type_delete($info)
 }
 
  /**
- * Helper function which creates a comment body field instance for a given node
- * type.
+ * Creates a comment_body field instance for a given node type.
  */
-function _comment_body_field_instance_create($info) {
-  // Attaches the body field by default.
-  $instance = array(
-    'field_name' => 'comment_body',
-    'label' => 'Comment',
-    'entity_type' => 'comment',
-    'bundle' => 'comment_node_' . $info->type,
-    'settings' => array('text_processing' => 1),
-    'required' => TRUE,
-    'display' => array(
-      'default' => array(
-        'label' => 'hidden',
-        'type' => 'text_default',
-        'weight' => 0,
+function _comment_body_field_create($info) {
+  if (!module_exists('text')) {
+    // During an upgrade, this function may be called before text.module is
+    // enabled. If so, we can't create a text_long field yet.
+    return;
+  }
+  // Create the field if needed.
+  if (!field_read_field('comment_body', array('include_inactive' => TRUE))) {
+    $field = array(
+      'field_name' => 'comment_body',
+      'type' => 'text_long',
+      'entity_types' => array('comment'),
+    );
+    field_create_field($field);
+  }
+  if (!field_read_instance('comment', 'comment_body', 'comment_node_' . $info->type, array('include_inactive' => TRUE))) {
+    field_attach_create_bundle('comment', 'comment_node_' . $info->type);
+    // Attaches the body field by default.
+    $instance = array(
+      'field_name' => 'comment_body',
+      'label' => 'Comment',
+      'entity_type' => 'comment',
+      'bundle' => 'comment_node_' . $info->type,
+      'settings' => array('text_processing' => 1),
+      'required' => TRUE,
+      'display' => array(
+        'default' => array(
+          'label' => 'hidden',
+          'type' => 'text_default',
+          'weight' => 0,
+        ),
       ),
-    ),
-  );
-  field_create_instance($instance);
+    );
+    field_create_instance($instance);
+  }
 }
 
 /**
Index: modules/comment/comment.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.test,v
retrieving revision 1.95
diff -u -p -r1.95 comment.test
--- modules/comment/comment.test	9 Dec 2010 02:16:21 -0000	1.95
+++ modules/comment/comment.test	13 Dec 2010 04:50:24 -0000
@@ -1478,3 +1478,111 @@ class CommentActionsTestCase extends Com
     db_truncate('watchdog')->execute();
   }
 }
+
+/**
+ * Test that comment module works after being enabled after a content module.
+ */
+class CommentEnableTest extends CommentHelperCase {
+  protected $profile = 'testing';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment enable',
+      'description' => 'Test that comment module works after being enabled after a content module.',
+      'group' => 'Comment',
+    );
+  }
+
+  function setUp() {
+    // Do not call parent::setUp() because we selectively enable modules.
+    DrupalWebTestCase::setUp();
+  }
+
+  /**
+   * Test that comment module works after being enabled after a content module.
+   */
+  function testCommentEnable() {
+    // Create a user to do module administration.
+    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer modules'));
+    $this->drupalLogin($this->admin_user);
+
+    // Enable core content type modules (blog, book, and poll).
+    $edit = array();
+    $edit['modules[Core][blog][enable]'] = 'blog';
+    $edit['modules[Core][book][enable]'] = 'book';
+    $edit['modules[Core][poll][enable]'] = 'poll';
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->resetAll();
+
+    // Now enable the comment module.
+    $edit = array();
+    $edit['modules[Core][comment][enable]'] = 'comment';
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->resetAll();
+    $this->assertTrue(module_exists('comment'), t('Comment module installed.'));
+
+    // Create nodes of each type.
+    $blog_node = $this->drupalCreateNode(array('type' => 'blog'));
+    $book_node = $this->drupalCreateNode(array('type' => 'book'));
+    $poll_node = $this->drupalCreateNode(array('type' => 'poll', 'active' => 1, 'runtime' => 0, 'choice' => array(array('chtext' => ''))));
+
+    $this->drupalLogout();
+
+    // Try to post a comment on each node. An failure will be triggered if the
+    // comment body is missing on one of these forms.
+    $this->web_user = $this->drupalCreateUser(array('access content', 'access comments', 'post comments', 'skip comment approval'));
+    $this->drupalLogin($this->web_user);
+    $this->postComment($blog_node, $this->randomName(), $this->randomName());
+    $this->postComment($book_node, $this->randomName(), $this->randomName());
+    $this->postComment($poll_node, $this->randomName(), $this->randomName());
+  }
+}
+
+/**
+ * Test fields on comments.
+ */
+class CommentFields extends CommentHelperCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Comment fields',
+      'description' => 'Tests fields on comments.',
+      'group' => 'Comment',
+    );
+  }
+
+  /**
+   * Tests that the default 'comment_body' field is correctly added.
+   */
+  function testCommentDefaultFields() {
+    // Do not make assumptions on default node types created by the test
+    // install profile, and create our own.
+    $this->drupalCreateContentType(array('type' => 'test_node_type'));
+
+    // Check that the 'comment_body' field is present on all comment bundles.
+    $instances = field_info_instances('comment');
+    foreach (node_type_get_types() as $type_name => $info) {
+      $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+
+      // Delete the instance along the way.
+      field_delete_instance($instances['comment_node_' . $type_name]['comment_body']);
+    }
+
+    // @todo simulate http://drupal.org/node/915906
+    field_delete_field('comment_body');
+
+    // Check that the 'comment_body' field is deleted.
+    $field = field_info_field('comment_body');
+    $this->assertTrue(empty($field), t('The comment_body field was deleted'));
+
+    // Create a new content type.
+    $type_name = 'test_node_type_2';
+    $this->drupalCreateContentType(array('type' => $type_name));
+
+    // Check that the 'comment_body' field exists and has an instance on the
+    // new comment bundle.
+    $field = field_info_field('comment_body');
+    $this->assertTrue($field, t('The comment_body field exists'));
+    $instances = field_info_instances('comment');
+    $this->assertTrue(isset($instances['comment_node_' . $type_name]['comment_body']), t('The comment_body field is present for comments on type @type', array('@type' => $type_name)));
+  }
+}
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.254
diff -u -p -r1.254 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	5 Dec 2010 18:40:17 -0000	1.254
+++ modules/simpletest/drupal_web_test_case.php	13 Dec 2010 04:50:24 -0000
@@ -1327,6 +1327,10 @@ class DrupalWebTestCase extends DrupalTe
    */
   protected function resetAll() {
     // Rebuild caches.
+    system_list_reset();
+    module_list(TRUE);
+    module_implements('', FALSE, TRUE);
+    entity_info_cache_clear();
     drupal_static_reset();
     drupal_flush_all_caches();
 
Index: modules/taxonomy/taxonomy.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.install,v
retrieving revision 1.55
diff -u -p -r1.55 taxonomy.install
--- modules/taxonomy/taxonomy.install	7 Dec 2010 05:20:08 -0000	1.55
+++ modules/taxonomy/taxonomy.install	13 Dec 2010 04:50:24 -0000
@@ -247,21 +247,26 @@ function taxonomy_field_schema($field) {
  * Implements hook_update_dependencies().
  */
 function taxonomy_update_dependencies() {
-  // Taxonomy update 7002 creates comment Field API bundles and therefore must
-  // run after the Field module has been enabled, but before upgrading field
-  // data.
-  $dependencies['taxonomy'][7002] = array(
+  // Taxonomy update 7002 performs schema updates necessary before system
+  // update 7020, which indirectly invokes taxonomy_vocabulary_get_names()
+  // through module_enable() and comment_modules_enabled() field CRUD.
+  $dependencies['system'][7020] = array(
+    'taxonomy' => 7002,
+  );
+  // Taxonomy update 7004 performs field CRUD and therefore must run after the
+  // Field module has been enabled, but before upgrading field data.
+  $dependencies['taxonomy'][7004] = array(
     'system' => 7049,
   );
   $dependencies['user'][7006] = array(
-    'taxonomy' => 7002,
+    'taxonomy' => 7004,
   );
   $dependencies['system'][7050] = array(
-    'taxonomy' => 7002,
+    'taxonomy' => 7004,
   );
   // It also must run before nodes are upgraded to use the Field API.
   $dependencies['node'][7006] = array(
-    'taxonomy' => 7002,
+    'taxonomy' => 7004,
   );
   // Ensure that format columns are only changed after Filter module has changed
   // the primary records.
