diff --git a/mollom.module b/mollom.module
index 93fdd3c..fd6c7be 100644
--- a/mollom.module
+++ b/mollom.module
@@ -740,8 +740,8 @@ function mollom_form_alter(&$form, &$form_state, $form_id) {
       // Form-level validation handlers are required, since we need access to
       // all validated and submitted form values. _form_validate() invokes
       // #element_validate handlers while it is recursing into the form.
-      $form['#validate'][] = 'mollom_validate_analysis';
       $form['#validate'][] = 'mollom_validate_captcha';
+      $form['#validate'][] = 'mollom_validate_analysis';
       $form['#validate'][] = 'mollom_validate_post';
 
       // Append a submit handler to store Mollom session data. Requires that
@@ -1743,6 +1743,12 @@ function mollom_process_mollom($element, &$form_state, $complete_form) {
  *   The current state of the form. Passed by reference.
  */
 function mollom_form_add_captcha(&$element, &$form_state) {
+  // Only add a CAPTCHA once to a form within a single request.
+  if (!empty($form_state['temporary']['mollom']['captcha'])) {
+    return;
+  }
+  $form_state['temporary']['mollom']['captcha'] = TRUE;
+
   // Prevent the page cache from storing a form containing a CAPTCHA element.
   drupal_page_is_cacheable(FALSE);
 
@@ -1879,7 +1885,11 @@ function mollom_validate_analysis(&$form, &$form_state) {
         else {
           $form_state['mollom']['require_captcha'] = TRUE;
           $form_state['mollom']['passed_captcha'] = FALSE;
+
+          // Retrieve a new CAPTCHA and throw an error.
+          mollom_form_add_captcha($form['mollom'], $form_state);
           $form['mollom']['captcha']['#access'] = TRUE;
+          form_error($form['mollom']['captcha'], t('To complete this form, please complete the word verification below.'));
         }
         mollom_log(array(
           'message' => 'Unsure: %teaser',
@@ -1910,15 +1920,21 @@ function mollom_validate_analysis(&$form, &$form_state) {
  * text analysis result is "unsure".
  */
 function mollom_validate_captcha(&$form, &$form_state) {
-  if (!$form_state['mollom']['require_captcha']) {
-    return;
+  if ($form_state['mollom']['require_analysis']) {
+    if (empty($form_state['values']['mollom']['captchaId'])) {
+      return;
+    }
   }
-
-  // If there is no CAPTCHA ID yet, retrieve one and throw an error.
-  if (empty($form_state['values']['mollom']['captchaId'])) {
-    mollom_form_add_captcha($form['mollom'], $form_state);
-    form_error($form['mollom']['captcha'], t('To complete this form, please complete the word verification below.'));
-    return;
+  else {
+    if (!$form_state['mollom']['require_captcha']) {
+      return;
+    }
+    // If there is no CAPTCHA ID yet, retrieve one and throw an error.
+    if (empty($form_state['values']['mollom']['captchaId'])) {
+      mollom_form_add_captcha($form['mollom'], $form_state);
+      form_error($form['mollom']['captcha'], t('To complete this form, please complete the word verification below.'));
+      return;
+    }
   }
 
   // $form_state['mollom']['passed_captcha'] may only ever be set by this
@@ -1974,8 +1990,17 @@ function mollom_validate_captcha(&$form, &$form_state) {
   // form_set_value() is effectless, as this is not a element-level but a
   // form-level validation handler.
   $form['mollom']['captchaId']['#value'] = $result['captchaId'];
+//  if (!$form_state['mollom']['require_analysis']) {
+//    $form['mollom']['captchaId']['#value'] = $result['captchaId'];
+//  }
+//  else {
+//    $form['mollom']['captchaId']['#value'] = '';
+//  }
 
   if (!empty($result['solved'])) {
+    if ($form_state['mollom']['require_analysis']) {
+      $form['mollom']['captchaId']['#value'] = '';
+    }
     $form_state['mollom']['passed_captcha'] = TRUE;
     $form['mollom']['captcha']['#access'] = FALSE;
     $form['mollom']['captcha']['#solved'] = TRUE;
@@ -2019,8 +2044,8 @@ function mollom_pre_render_mollom($element) {
   $element['captcha']['#value'] = '';
 
   // DX: Debugging helpers.
-//  $element['captcha']['#suffix'] = 'contentId: ' . $element['contentId']['#value'];
-//  $element['captcha']['#suffix'] .= '<br />captchaId: ' . $element['captchaId']['#value'];
+  $element['#suffix'] = 'contentId: ' . $element['contentId']['#value'] . '<br>';
+  $element['#suffix'] .= 'captchaId: ' . $element['captchaId']['#value'] . '<br>';
 
   return $element;
 }
diff --git a/tests/mollom.test b/tests/mollom.test
index 81ff136..82fa46e 100644
--- a/tests/mollom.test
+++ b/tests/mollom.test
@@ -3966,14 +3966,12 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-    $this->assertResponseIDInForm('captchaId');
     $this->assertNoCaptchaField();
     $edit = array(
       'body' => 'unsure unsure unsure',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-    $this->assertResponseIDInForm('captchaId');
     $this->assertNoCaptchaField();
     $edit = array(
       'title' => 'unsure',
@@ -3986,14 +3984,11 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
 
   /**
    * Tests unsure posts turning into ham.
-   *
-   * @todo CAPTCHA ID should stay the same.
-   * @see http://drupal.org/node/1959904
    */
   function subtestUnsureHam() {
     $this->drupalGet('mollom-test/form');
     $this->assertNoCaptchaField();
-    // Posting ham as title would submit the form, so post as body instead.
+    // Posting unsure as title would submit the form, so post as body instead.
     $edit = array(
       'body' => 'unsure',
     );
@@ -4004,10 +3999,10 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     // Turn the post into ham.
     $edit = array(
       'body' => 'ham',
+      'mollom[captcha]' => 'correct',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-//    $this->assertResponseIDInForm('captchaId');
     $this->assertNoCaptchaField();
     // Turn the post back into unsure.
     $edit = array(
@@ -4015,12 +4010,10 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-//    $this->assertResponseIDInForm('captchaId');
-    $this->assertCaptchaField();
+    $this->assertNoCaptchaField();
 
     $edit = array(
       'title' => 'irrelevant',
-      'mollom[captcha]' => 'correct',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertNoCaptchaField();
@@ -4037,31 +4030,33 @@ class MollomAnalysisTestCase extends MollomWebTestCase {
     $this->drupalGet('mollom-test/form');
     $this->assertNoCaptchaField();
     $edit = array(
-      'title' => 'unsure',
+      'body' => 'unsure',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId', TRUE);
     $this->assertResponseIDInForm('captchaId', TRUE);
     $this->assertCaptchaField();
-    // Turn the post into spam.
+
     $edit = array(
-      'title' => 'spam',
+      'mollom[captcha]' => 'correct',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-//    $this->assertResponseIDInForm('captchaId');
     $this->assertNoCaptchaField();
-    // Turn the post back into unsure.
+
+    // Turn the post into spam.
     $edit = array(
-      'title' => 'unsure',
+      'title' => 'spam',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertResponseIDInForm('contentId');
-//    $this->assertResponseIDInForm('captchaId');
-    $this->assertCaptchaField();
+    $this->assertNoCaptchaField();
+    $this->assertText($this->spam_message);
+    $this->assertNoText('Successful form submission.');
 
+    // Turn the post back into unsure.
     $edit = array(
-      'mollom[captcha]' => 'correct',
+      'title' => 'unsure',
     );
     $this->drupalPost(NULL, $edit, 'Submit');
     $this->assertNoCaptchaField();
