diff --git a/resources/static/dialog/controllers/authenticate_controller.js b/resources/static/dialog/controllers/authenticate_controller.js
index 323fc4e1e3c4ca1132ca91a172723d296113665a..31e8a114566b07d442895ffb4b25a3f176782e79 100644
--- a/resources/static/dialog/controllers/authenticate_controller.js
+++ b/resources/static/dialog/controllers/authenticate_controller.js
@@ -76,7 +76,7 @@
 
     cancelEvent(event);
 
-    if(email) {
+    if (email) {
       dialogHelpers.createUser.call(self, email);
     }
   }
@@ -88,7 +88,7 @@
 
     cancelEvent(event);
 
-    if(email && pass) {
+    if (email && pass) {
       dialogHelpers.authenticateUser.call(self, email, pass, function(authenticated) {
         if (authenticated) {
           self.close("authenticated", {
@@ -99,16 +99,6 @@
     }
   }
 
-  function resetPassword(event) {
-    var email = getEmail();
-
-    cancelEvent(event);
-
-    if(email) {
-      dialogHelpers.resetPassword.call(this, email);
-    }
-  }
-
   function animateSwap(fadeOutSelector, fadeInSelector, callback) {
     // XXX instead of using jQuery here, think about using CSS animations.
     $(fadeOutSelector).fadeOut(ANIMATION_TIME, function() {
@@ -123,7 +113,7 @@
   function enterEmailState(el) {
     if (!el.is(":disabled")) {
       this.submit = checkEmail;
-      animateSwap(".returning:visible,.newuser:visible,.forgot:visible", ".start");
+      animateSwap(".returning:visible,.newuser:visible", ".start");
     }
   }
 
@@ -138,20 +128,12 @@
     });
   }
 
-  function forgotPasswordState(event) {
+  function forgotPassword(event) {
     cancelEvent(event);
-
-    this.submit = resetPassword;
-    dom.setAttr("#email", "disabled", "disabled");
-
-    animateSwap(".start:visible,.newuser:visible,.returning:visible", ".forgot");
-  }
-
-  function cancelForgotPassword(event) {
-    cancelEvent(event);
-
-    dom.removeAttr("#email", "disabled");
-    enterPasswordState.call(this);
+    var email = getEmail();
+    if (email) {
+      this.close("forgot_password", { email: email });
+    }
   }
 
   function createUserState(event) {
@@ -161,7 +143,7 @@
 
     self.publish("create_user");
     self.submit = createUser;
-    animateSwap(".start:visible,.returning:visible,.forgot:visible", ".newuser");
+    animateSwap(".start:visible,.returning:visible", ".newuser");
   }
 
 
@@ -188,8 +170,7 @@
 
 
       self.bind("#email", "keyup", emailKeyUp);
-      self.bind("#forgotPassword", "click", forgotPasswordState);
-      self.bind("#cancel_forgot_password", "click", cancelForgotPassword);
+      self.bind("#forgotPassword", "click", forgotPassword);
 
       self._super();
     },
@@ -197,7 +178,7 @@
     checkEmail: checkEmail,
     createUser: createUser,
     authenticate: authenticate,
-    resetPassword: resetPassword
+    forgotPassword: forgotPassword
   });
 
 }());
diff --git a/resources/static/dialog/controllers/dialog_controller.js b/resources/static/dialog/controllers/dialog_controller.js
index e19312e8dc4aa2f97f8d2b2a8dd298e885c5b9fe..82c2e7688e93586e577bce6e6e1105a7b76299b2 100644
--- a/resources/static/dialog/controllers/dialog_controller.js
+++ b/resources/static/dialog/controllers/dialog_controller.js
@@ -177,6 +177,15 @@
           self.syncEmails();
         });
 
+        subscribe("forgot_password", function(msg, info) {
+          self.doForgotPassword(info.email);
+        });
+
+        subscribe("cancel_forgot_password", function(msg, info) {
+          user.cancelUserValidation();
+          self.returnFromStageCancel();
+        });
+
         subscribe("reset_password", function(msg, info) {
           self.doConfirmUser(info.email);
         });
diff --git a/resources/static/dialog/controllers/forgotpassword_controller.js b/resources/static/dialog/controllers/forgotpassword_controller.js
new file mode 100644
index 0000000000000000000000000000000000000000..d1bdda2d765b1308f6974a93ef0a77b289cdae2b
--- /dev/null
+++ b/resources/static/dialog/controllers/forgotpassword_controller.js
@@ -0,0 +1,82 @@
+/*jshint browser:true, jQuery: true, forin: true, laxbreak:true */
+/*global BrowserID:true, PageController: true */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla BrowserID.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+(function() {
+  "use strict";
+
+  var ANIMATION_TIME = 250,
+      bid = BrowserID,
+      helpers = bid.Helpers,
+      dialogHelpers = helpers.Dialog,
+      dom = bid.DOM,
+      lastEmail = "";
+
+  function cancelEvent(event) {
+    if (event) event.preventDefault();
+  }
+
+  function resetPassword(event) {
+    cancelEvent(event);
+
+    var self=this;
+    dialogHelpers.resetPassword.call(self, self.email);
+  }
+
+  function cancelResetPassword(event) {
+    cancelEvent(event);
+
+    this.close("cancel_forgot_password");
+  }
+
+  PageController.extend("Forgotpassword", {}, {
+    start: function(options) {
+      var self=this;
+      self.email = options.email;
+      self.renderDialog("forgotpassword", {
+        email: options.email || ""
+      });
+
+      self.bind("#cancel_forgot_password", "click", cancelResetPassword);
+
+      self._super();
+    },
+
+    submit: resetPassword,
+    resetPassword: resetPassword,
+    cancelResetPassword: cancelResetPassword
+  });
+
+}());
diff --git a/resources/static/dialog/controllers/required_email_controller.js b/resources/static/dialog/controllers/required_email_controller.js
index c9acd8d5415aca9d13956a6fff52cdfa1ce547b7..eb49e0c32af1e9840c1fa4927d2fa57ec8c83ab4 100644
--- a/resources/static/dialog/controllers/required_email_controller.js
+++ b/resources/static/dialog/controllers/required_email_controller.js
@@ -102,7 +102,7 @@
     event && event.preventDefault();
 
     var self=this;
-    dialogHelpers.resetPassword.call(self, self.email);
+    self.close("forgot_password", { email: self.email });
   }
 
 
diff --git a/resources/static/dialog/dialog.js b/resources/static/dialog/dialog.js
index c1f5ad54aa0b99fa6bcd88950f200802e71cc12a..c84c1a7457661b209bbad3210b7c0de09ac49cc4 100644
--- a/resources/static/dialog/dialog.js
+++ b/resources/static/dialog/dialog.js
@@ -73,6 +73,7 @@ steal
 	.controllers('page',
                'dialog',
                'authenticate',
+               'forgotpassword',
                'checkregistration',
                'pickemail',
                'addemail',
diff --git a/resources/static/dialog/resources/helpers.js b/resources/static/dialog/resources/helpers.js
index c1f1a61cb3c435e2716e4e2a005d08b6dca2c7e6..f0cec248daf32dd9fb1e26bfd21355dc8d5a1fa0 100644
--- a/resources/static/dialog/resources/helpers.js
+++ b/resources/static/dialog/resources/helpers.js
@@ -34,21 +34,6 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-
-// The way this works, when the dialog is opened from a web page, it opens
-// the window with a #host=<requesting_host_name> parameter in its URL.
-// window.setupChannel is called automatically when the dialog is opened. We
-// assume that navigator.id.getVerifiedEmail was the function called, we will
-// keep this assumption until we start experimenting.  Since IE has some
-// serious problems iwth postMessage from a window to a child window, we are now
-// communicating not directly with the calling window, but with an iframe
-// on the same domain as us that we place into the calling window.  We use a
-// function within this iframe to relay messages back to the calling window.
-// We do so by searching for the frame within the calling window, and then
-// getting a reference to the proxy function.  When getVerifiedEmail is
-// complete, it calls the proxy function in the iframe, which then sends a
-// message back to the calling window.
-
 (function() {
   "use strict";
 
diff --git a/resources/static/dialog/views/authenticate.ejs b/resources/static/dialog/views/authenticate.ejs
index 41e3c4fc6cd580330912fbea270c6aa7deecde09..9923581c2ea9db4e7b7bc6624ba1262cdcfedffd 100644
--- a/resources/static/dialog/views/authenticate.ejs
+++ b/resources/static/dialog/views/authenticate.ejs
@@ -13,10 +13,6 @@
               <div id="email_required" class="tooltip" for="email">
                 The email field is required.
               </div>
-
-              <div id="could_not_add" class="tooltip" for="email">
-                We just sent an email to that address! If you really want to send another, wait a minute or two and try again.
-              </div>
           </li>
 
           <li id="hint_section" class="start">
@@ -36,7 +32,6 @@
               </div>
               <input id="password" class="sans" type="password" maxlength="80" tabindex="2" />
 
-
               <div id="password_required" class="tooltip" for="password">
                 The password field is required.
               </div>
@@ -53,8 +48,5 @@
           <button class="newuser" tabindex="3">verify email</button>
 
           <button class="returning" tabindex="3">select email</button>
-
-          <button class="forgot" tabindex="3">Reset Password</button>
-          <button id="cancel_forgot_password" class="forgot" tabindex="4">Cancel</button>
       </div>
   </div>
diff --git a/resources/static/dialog/views/forgotpassword.ejs b/resources/static/dialog/views/forgotpassword.ejs
new file mode 100644
index 0000000000000000000000000000000000000000..00a9fc757f18bfc50bc609e302d5ce6e83648779
--- /dev/null
+++ b/resources/static/dialog/views/forgotpassword.ejs
@@ -0,0 +1,19 @@
+  <strong>Sign in using</strong>
+  <div class="form_section">
+      <ul class="inputs">
+          <li>
+              <label for="email" class="serif">Email</label>
+              <input id="email" class="sans" type="email" value="<%= email %>" disabled />
+
+              <div id="could_not_add" class="tooltip" for="email">
+                We just sent an email to that address! If you really want to send another, wait a minute or two and try again.
+              </div>
+          </li>
+
+      </ul>
+
+      <div class="submit cf">
+          <button tabindex="1">Reset Password</button>
+          <button id="cancel_forgot_password" tabindex="2">Cancel</button>
+      </div>
+  </div>
diff --git a/resources/static/dialog/views/requiredemail.ejs b/resources/static/dialog/views/requiredemail.ejs
index 932a600a33def4056e98456223b69d41e1c5ee03..64627c9a940d284db3ac1acda0192308bf45a61c 100644
--- a/resources/static/dialog/views/requiredemail.ejs
+++ b/resources/static/dialog/views/requiredemail.ejs
@@ -1,9 +1,9 @@
-  <!--strong>Required Email Sign In</strong-->
+  <strong>The site requested you sign in with:</strong>
   <div class="form_section">
       <ul class="inputs">
 
-          The site requested you sign in with
-          <div id="required_email"><%= email %></div>
+          <label for="email" class="serif">Email</label>
+          <input id="required_email" class="sans" type="email" value="<%= email %>" disabled />
           <div id="could_not_add" class="tooltip" for="required_email">
             We just sent an email to that address! If you really want to send another, wait a minute or two and try again.
           </div>
diff --git a/resources/static/test/qunit/controllers/addemail_controller_unit_test.js b/resources/static/test/qunit/controllers/addemail_controller_unit_test.js
index 0d560514ce559aaf63c7770c2737e9ddbcc61b6f..26fb2bc148a4494a0494a43fd27cf69af9953895 100644
--- a/resources/static/test/qunit/controllers/addemail_controller_unit_test.js
+++ b/resources/static/test/qunit/controllers/addemail_controller_unit_test.js
@@ -58,7 +58,6 @@ steal.then(function() {
       hub.unsubscribe(registration);
     }
   }
-  var controller;
 
   module("controllers/addemail_controller", {
     setup: function() {
diff --git a/resources/static/test/qunit/controllers/authenticate_controller_unit_test.js b/resources/static/test/qunit/controllers/authenticate_controller_unit_test.js
index a09787facf69e5dfa1ab91476919533c12e9e94e..9039e019ac95685ae58a344736014f2a4fb2cbf7 100644
--- a/resources/static/test/qunit/controllers/authenticate_controller_unit_test.js
+++ b/resources/static/test/qunit/controllers/authenticate_controller_unit_test.js
@@ -34,7 +34,7 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-steal.then("/dialog/controllers/page_controller", "/dialog/controllers/authenticate_controller", function() {
+steal.then(function() {
   "use strict";
 
   var controller,
@@ -46,7 +46,18 @@ steal.then("/dialog/controllers/page_controller", "/dialog/controllers/authentic
       emailRegistered = false,
       userCreated = true,
       hub = OpenAjax.hub,
-      subscriptions = [];
+      registrations = [];
+
+  function register(message, cb) {
+    registrations.push(hub.subscribe(message, cb));
+  }
+
+  function unregisterAll() {
+    var registration;
+    while(registration = registrations.pop()) {
+      hub.unsubscribe(registration);
+    }
+  }
 
   function reset() {
     el = $("#controller_head");
@@ -56,12 +67,6 @@ steal.then("/dialog/controllers/page_controller", "/dialog/controllers/authentic
 
     emailRegistered = false;
     userCreated = true;
-
-
-    var subscription;
-    while(subscription = subscriptions.pop()) {
-      hub.unsubscribe(subscription);
-    }
   }
 
   module("controllers/authenticate_controller", {
@@ -84,24 +89,23 @@ steal.then("/dialog/controllers/page_controller", "/dialog/controllers/authentic
       reset();
       storage.clear();
       network.setXHR($);
+      unregisterAll();
     }
   });
 
   test("setting email address prefills address field", function() {
       controller.destroy();
       $("#email").val("");
-      controller = el.authenticate({ email: "testuser@testuser.com" }).controller();
-      equal($("#email").val(), "testuser@testuser.com", "email prefilled");
+      controller = el.authenticate({ email: "registered@testuser.com" }).controller();
+      equal($("#email").val(), "registered@testuser.com", "email prefilled");
   });
 
   function testUserUnregistered() {
-    var id = hub.subscribe("create_user", function() {
+    register("create_user", function() {
       ok(true, "email was valid, user not registered");
       start();
     });
 
-    subscriptions.push(id);
-
     controller.checkEmail();
     stop();
   }
@@ -119,40 +123,115 @@ steal.then("/dialog/controllers/page_controller", "/dialog/controllers/authentic
   test("checkEmail with normal email, user registered", function() {
     $("#email").val("registered@testuser.com");
 
-    var id = hub.subscribe("enter_password", function() {
+    register("enter_password", function() {
       ok(true, "email was valid, user registered");
       start();
     });
-    subscriptions.push(id);
 
     controller.checkEmail();
     stop();
   });
 
   function testAuthenticated() {
-    var id = hub.subscribe("authenticated", function() {
+    register("authenticated", function() {
       ok(true, "user authenticated as expected");
       start();
     });
-    subscriptions.push(id);
     controller.authenticate();
 
     stop();
   }
 
   test("normal authentication is kosher", function() {
-      $("#email").val("testuser@testuser.com");
+      $("#email").val("registered@testuser.com");
       $("#password").val("password");
 
       testAuthenticated();
   });
 
   test("leading/trailing whitespace on the username is stripped for authentication", function() {
-      $("#email").val("    testuser@testuser.com    ");
+      $("#email").val("    registered@testuser.com    ");
       $("#password").val("password");
 
       testAuthenticated();
   });
 
+  test("forgotPassword triggers forgot_password message", function() {
+    $("#email").val("registered@testuser.com");
+
+    register("forgot_password", function(msg, info) {
+      equal(info.email, "registered@testuser.com", "forgot_password with correct email triggered");
+      start();  
+    });
+
+    controller.forgotPassword();
+    stop();
+  });
+
+  test("createUser with valid email", function() {
+    $("#email").val("unregistered@testuser.com");
+    register("user_staged", function(msg, info) {
+      equal(info.email, "unregistered@testuser.com", "user_staged with correct email triggered");
+      start();  
+    });
+
+    controller.createUser();
+    stop();
+  });
+
+  test("createUser with invalid email", function() {
+    $("#email").val("unregistered");
+
+    var handlerCalled = false;
+    register("user_staged", function(msg, info) {
+      handlerCalled = true;
+    });
+
+    controller.createUser();
+    setTimeout(function() {
+      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with invalid email");
+      start();  
+    }, 100);
+
+    stop();
+  });
+
+  test("createUser with valid email but throttling", function() {
+    $("#email").val("unregistered@testuser.com");
+
+    var handlerCalled = false;
+    register("user_staged", function(msg, info) {
+      handlerCalled = true;
+    });
+
+    xhr.useResult("throttle");
+    controller.createUser();
+    setTimeout(function() {
+      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with throttling");
+      equal(bid.Tooltip.shown, true, "tooltip is shown");
+      start();  
+    }, 100);
+
+    stop();
+  });
+
+  test("createUser with valid email, XHR error", function() {
+    $("#email").val("unregistered@testuser.com");
+
+    var handlerCalled = false;
+    register("user_staged", function(msg, info) {
+      handlerCalled = true;
+    });
+
+    xhr.useResult("ajaxError");
+    controller.createUser();
+    setTimeout(function() {
+      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with XHR error");
+      start();  
+    }, 100);
+
+    stop();
+  });
+
 });
 
diff --git a/resources/static/test/qunit/controllers/forgotpassword_controller_unit_test.js b/resources/static/test/qunit/controllers/forgotpassword_controller_unit_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d42e9fa9301d6ed7bfadc801fe51ed313b08562e
--- /dev/null
+++ b/resources/static/test/qunit/controllers/forgotpassword_controller_unit_test.js
@@ -0,0 +1,118 @@
+/*jshint browsers:true, forin: true, laxbreak: true */
+/*global steal: true, test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla BrowserID.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+steal.then(function() {
+  "use strict";
+
+  var controller,
+      el = $("body"),
+      bid = BrowserID,
+      storage = bid.Storage,
+      network = bid.Network,
+      xhr = bid.Mocks.xhr,
+      hub = OpenAjax.hub,
+      registrations = [];
+
+  function register(message, cb) {
+    registrations.push(hub.subscribe(message, cb));
+  }
+
+  function unregisterAll() {
+    var registration;
+    while(registration = registrations.pop()) {
+      hub.unsubscribe(registration);
+    }
+  }
+
+  function reset() {
+    el = $("#controller_head");
+    el.find("#formWrap .contents").html("");
+    el.find("#wait .contents").html("");
+    el.find("#error .contents").html("");
+  }
+
+  module("controllers/forgotpassword_controller", {
+    setup: function() {
+      $("#email").val("");
+      reset();
+      storage.clear();
+      network.setXHR(xhr);
+      xhr.useResult("valid");
+      controller = el.forgotpassword({ email: "registered@testuser.com" }).controller();
+    },
+
+    teardown: function() {
+      if (controller) {
+        try {
+          controller.destroy();
+          controller = null;
+        } catch(e) {
+          // may already be destroyed from close inside of the controller.
+        }
+      }
+      reset();
+      storage.clear();
+      network.setXHR($);
+      unregisterAll();
+    }
+  });
+
+  test("email address prefills address field", function() {
+    equal($("#email").val(), "registered@testuser.com", "email prefilled");
+  });
+
+  test("resetPassword raises 'reset_password' with email address", function() {
+    register("reset_password", function(msg, info) {
+      equal(info.email, "registered@testuser.com", "reset_password raised with correct email address");
+      start();
+    });
+
+    controller.resetPassword();
+    stop();
+  });
+
+  test("cancelResetPassword raises 'cancel_forgot_password'", function() {
+    register("cancel_forgot_password", function(msg, info) {
+      ok(true, "cancel_forgot_password triggered");
+      start();
+    });
+
+    controller.cancelResetPassword();
+    stop();
+
+  });
+});
+
diff --git a/resources/static/test/qunit/controllers/required_email_controller_unit_test.js b/resources/static/test/qunit/controllers/required_email_controller_unit_test.js
index cb9463994026fc308b5f2e3a69de921fdbceda8c..5d9d486e95de7ffdd35b7fe8ec45e3b8703d645c 100644
--- a/resources/static/test/qunit/controllers/required_email_controller_unit_test.js
+++ b/resources/static/test/qunit/controllers/required_email_controller_unit_test.js
@@ -316,7 +316,7 @@ steal.then(function() {
   test("verifyAddress of un-authenticated user, forgot password", function() {
     var email = "registered@testuser.com",
         authenticated = false,
-        message = "reset_password";
+        message = "forgot_password";
 
     xhr.setContextInfo({
       authenticated: authenticated 
@@ -337,35 +337,6 @@ steal.then(function() {
     stop();
   });
 
-  test("verifyAddress of un-authenticated user, forgot password, mail throttled", function() {
-    var email = "registered@testuser.com",
-        authenticated = false,
-        message = "reset_password";
-
-    xhr.setContextInfo({
-      authenticated: authenticated 
-    });
-
-    controller = el.requiredemail({
-      email: email, 
-      authenticated: authenticated
-    }).controller();
-
-
-    subscribe(message, function(item, info) {
-      ok(false, "throttling should have prevented close from happening");
-    });
-
-    xhr.useResult("throttle");
-    controller.forgotPassword();
-
-    setTimeout(function() {
-      ok(bid.Tooltip.shown, "tooltip is shown");
-      start();
-    }, 100);
-    stop();
-  });
-
   test("cancel raises the cancel message", function() {
     var email = "registered@testuser.com",
         message = "cancel",
diff --git a/resources/static/test/qunit/qunit.js b/resources/static/test/qunit/qunit.js
index 778176945340e5182c9fbddf47b52c6c892001e4..92c6acc6072d1ea4670d9fe0c5d3b0cf8c56cacb 100644
--- a/resources/static/test/qunit/qunit.js
+++ b/resources/static/test/qunit/qunit.js
@@ -28,6 +28,8 @@ steal.plugins(
       "/dialog/controllers/required_email_controller",
       "/dialog/controllers/pickemail_controller",
       "/dialog/controllers/addemail_controller",
+      "/dialog/controllers/authenticate_controller",
+      "/dialog/controllers/forgotpassword_controller",
 
       "/pages/page_helpers",
 
@@ -61,6 +63,7 @@ steal.plugins(
       "controllers/dialog_controller_unit_test",
       "controllers/checkregistration_controller_unit_test",
       "controllers/authenticate_controller_unit_test",
+      "controllers/forgotpassword_controller_unit_test",
       "controllers/required_email_controller_unit_test"
       
       );