diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index 00b561a12fae1d6333e302dbd391c089012d09ed..c4cbd340cd562874c109408b844df8547a1dc8bf 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -667,7 +667,7 @@ h1 {
   margin-bottom: 10px;
 }
 
-.siteinfo, #congrats, #signUpForm > .password_entry, .enter_password .hint, #unknown_secondary, #primary_verify, .verify_primary .submit {
+.siteinfo, #congrats, #signUpForm .password_entry, .enter_password .hint, #unknown_secondary, #primary_verify, .verify_primary .submit {
   display: none;
 }
 
@@ -675,7 +675,7 @@ h1 {
   float: left;
 }
 
-.enter_password #signUpForm > .password_entry, .known_secondary #signUpForm > .password_entry,
+.enter_password #signUpForm .password_entry, .known_secondary #signUpForm .password_entry,
 .unknown_secondary #unknown_secondary, .verify_primary #verify_primary {
   display: block;
 }
diff --git a/resources/static/pages/signup.js b/resources/static/pages/signup.js
index 475d53824fef0a7c8366995939d6520720d8468e..3fef51badbfe646ad8f2d9ec523afff178dfd896 100644
--- a/resources/static/pages/signup.js
+++ b/resources/static/pages/signup.js
@@ -12,63 +12,48 @@ BrowserID.signUp = (function() {
       helpers = bid.Helpers,
       pageHelpers = bid.PageHelpers,
       cancelEvent = pageHelpers.cancelEvent,
+      validation = bid.Validation,
       errors = bid.Errors,
       tooltip = BrowserID.Tooltip,
       ANIMATION_SPEED = 250,
       storedEmail = pageHelpers,
       winchan = window.WinChan,
-      verifyEmail,
-      verifyURL;
+      primaryUserInfo,
+      sc;
 
     function showNotice(selector) {
       $(selector).fadeIn(ANIMATION_SPEED);
     }
 
     function authWithPrimary(oncomplete) {
-      pageHelpers.openPrimaryAuth(winchan, verifyEmail, verifyURL, primaryAuthComplete);
+      pageHelpers.openPrimaryAuth(winchan, primaryUserInfo.email, primaryUserInfo.auth, primaryAuthComplete);
 
       oncomplete && oncomplete();
     }
 
     function primaryAuthComplete(error, result, oncomplete) {
-      if(error) {
+      if (error) {
         pageHelpers.showFailure(errors.primaryAuthentication, error, oncomplete);
       }
       else {
         // hey ho, the user is authenticated, re-try the submit.
-        createUser(verifyEmail, oncomplete);
+        createPrimaryUser(primaryUserInfo, oncomplete);
       }
     }
 
-    function createUser(email, oncomplete) {
+    function createPrimaryUser(info, oncomplete) {
       function complete(status) {
         oncomplete && oncomplete(status);
       }
 
-      user.createUser(email, function onComplete(status, info) {
+      user.createPrimaryUser(info, function onComplete(status, info) {
         switch(status) {
-          case "secondary.already_added":
-            $('#registeredEmail').html(email);
-            showNotice(".alreadyRegistered");
-            complete(false);
-            break;
-          case "secondary.verify":
-            pageHelpers.emailSent(complete);
-            break;
-          case "secondary.could_not_add":
-            tooltip.showTooltip("#could_not_add");
-            complete(false);
-            break;
-          case "primary.already_added":
-            // XXX Is this status possible?
-            break;
           case "primary.verified":
             pageHelpers.replaceFormWithNotice("#congrats", complete.bind(null, true));
             break;
           case "primary.verify":
-            verifyEmail = email;
-            verifyURL = info.auth;
-            dom.setInner("#primary_email", email);
+            primaryUserInfo = info;
+            dom.setInner("#primary_email", info.email);
             pageHelpers.replaceInputsWithNotice("#primary_verify", complete.bind(null, false));
             break;
           case "primary.could_not_add":
@@ -80,18 +65,62 @@ BrowserID.signUp = (function() {
       }, pageHelpers.getFailure(errors.createUser, complete));
     }
 
-    function submit(oncomplete) {
-      var email = helpers.getAndValidateEmail("#email");
+    function enterPasswordState(info) {
+      var self=this;
+      self.emailToStage = info.email;
+      self.submit = passwordSubmit;
 
-      function complete(status) {
-        oncomplete && oncomplete(status);
+      dom.addClass("body", "enter_password");
+    }
+
+    function passwordSubmit(oncomplete) {
+      var pass = dom.getInner("#password"),
+          vpass = dom.getInner("#vpassword"),
+          valid = validation.passwordAndValidationPassword(pass, vpass);
+
+      if(valid) {
+        user.createSecondaryUser(this.emailToStage, pass, function(status) {
+          if(status) {
+            pageHelpers.emailSent(oncomplete && oncomplete.curry(true));
+          }
+          else {
+            tooltip.showTooltip("#could_not_add");
+            oncomplete && oncomplete(false);
+          }
+        }, pageHelpers.getFailure(errors.createUser, oncomplete));
+      }
+      else {
+        oncomplete && oncomplete(false);
       }
+    }
+
+    function emailSubmit(oncomplete) {
+      var email = helpers.getAndValidateEmail("#email"),
+          self = this;
 
       if (email) {
-        createUser(email, complete);
+
+        user.isEmailRegistered(email, function(isRegistered) {
+          if(isRegistered) {
+            $('#registeredEmail').html(email);
+            showNotice(".alreadyRegistered");
+            oncomplete && oncomplete(false);
+          }
+          else {
+            user.addressInfo(email, function(info) {
+              if(info.type === "primary") {
+                createPrimaryUser.call(self, info, oncomplete);
+              }
+              else {
+                enterPasswordState.call(self, info);
+                oncomplete && oncomplete(!isRegistered);
+              }
+            }, pageHelpers.getFailure(errors.addressInfo, oncomplete));
+          }
+        }, pageHelpers.getFailure(errors.isEmailRegistered, oncomplete));
       }
       else {
-        complete(false);
+        oncomplete && oncomplete(false);
       }
     }
 
@@ -103,39 +132,45 @@ BrowserID.signUp = (function() {
       if (event.which !== 13) $(".notification").fadeOut(ANIMATION_SPEED);
     }
 
-    function init(config) {
-      config = config || {};
+    var Module = bid.Modules.PageModule.extend({
+      start: function(options) {
+        var self=this;
+        options = options || {};
 
-      if(config.winchan) {
-        winchan = config.winchan;
-      }
+        if (options.winchan) {
+          winchan = options.winchan;
+        }
 
-      $("form input[autofocus]").focus();
+        dom.focus("form input[autofocus]");
 
-      pageHelpers.setupEmail();
+        pageHelpers.setupEmail();
+
+        self.bind("#email", "keyup", onEmailKeyUp);
+        self.click("#back", back);
+        self.click("#authWithPrimary", authWithPrimary);
+
+        sc.start.call(self, options);
+      },
+
+      submit: emailSubmit,
+      // BEGIN TESTING API
+      emailSubmit: emailSubmit,
+      passwordSubmit: passwordSubmit,
+      reset: reset,
+      back: back,
+      authWithPrimary: authWithPrimary,
+      primaryAuthComplete: primaryAuthComplete
+      // END TESTING API
+    });
 
-      dom.bindEvent("#email", "keyup", onEmailKeyUp);
-      dom.bindEvent("form", "submit", cancelEvent(submit));
-      dom.bindEvent("#back", "click", cancelEvent(back));
-      dom.bindEvent("#authWithPrimary", "click", cancelEvent(authWithPrimary));
-    }
 
     // BEGIN TESTING API
     function reset() {
-      dom.unbindEvent("#email", "keyup");
-      dom.unbindEvent("form", "submit");
-      dom.unbindEvent("#back", "click");
-      dom.unbindEvent("#authWithPrimary", "click");
       winchan = window.WinChan;
-      verifyEmail = verifyURL = null;
     }
-
-    init.submit = submit;
-    init.reset = reset;
-    init.back = back;
-    init.authWithPrimary = authWithPrimary;
-    init.primaryAuthComplete = primaryAuthComplete;
     // END TESTING API
 
-    return init;
+    sc = Module.sc;
+
+    return Module;
 }());
diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js
index 61f39797b9e18c1706352e6ba61c6a84c21ea70a..cb9e52e848e9855768f1b519f3620959ba1c5fd2 100644
--- a/resources/static/shared/user.js
+++ b/resources/static/shared/user.js
@@ -298,15 +298,12 @@ BrowserID.User = (function() {
     },
 
     /**
-     * Create a user.  Works for both primaries and secondaries.
+     * Create a primary user.
      * @method createUser
-     * @param {string} email
+     * @param {object} info
      * @param {function} onComplete - function to call on complettion.  Called
      * with two parameters - status and info.
      * Status can be:
-     *  secondary.already_added
-     *  secondary.verify
-     *  secondary.could_not_add
      *  primary.already_added
      *  primary.verified
      *  primary.verify
@@ -315,63 +312,23 @@ BrowserID.User = (function() {
      *  info is passed on primary.verify and contains the info necessary to
      *  verify the user with the IdP
      */
-    // XXX - only used on main site
-    createUser: function(email, onComplete, onFailure) {
-      User.addressInfo(email, function(info) {
-        User.createUserWithInfo(email, info, onComplete, onFailure);
-      }, onFailure);
-    },
-
-    /**
-     * Attempt to create a user with the info returned from
-     * network.addressInfo.  Attempts to create both primary and secondary
-     * based users depending on info.type.
-     * @method createUserWithInfo
-     * @param {string} email
-     * @param {object} info - contains fields returned from network.addressInfo
-     * @param {function} [onComplete]
-     * @param {function} [onFailure]
-     */
-    createUserWithInfo: function(email, info, onComplete, onFailure) {
-      function attemptAddSecondary(email, info) {
-        if (info.known) {
-          onComplete("secondary.already_added");
-        }
-        else {
-          User.createSecondaryUser(email, function(success) {
-            if (success) {
-              onComplete("secondary.verify");
+    createPrimaryUser: function(info, onComplete, onFailure) {
+      var email = info.email;
+      User.provisionPrimaryUser(email, info, function(status, provInfo) {
+        if (status === "primary.verified") {
+          network.authenticateWithAssertion(email, provInfo.assertion, function(status) {
+            if (status) {
+              onComplete("primary.verified");
             }
             else {
-              onComplete("secondary.could_not_add");
+              onComplete("primary.could_not_add");
             }
           }, onFailure);
         }
-      }
-
-      function attemptAddPrimary(email, info) {
-        User.provisionPrimaryUser(email, info, function(status, provInfo) {
-          if (status === "primary.verified") {
-            network.authenticateWithAssertion(email, provInfo.assertion, function(status) {
-              if (status) {
-                onComplete("primary.verified");
-              }
-              else {
-                onComplete("primary.could_not_add");
-              }
-            }, onFailure);
-          }
-          else {
-            onComplete(status, provInfo);
-          }
-        }, onFailure);
-      }
-
-      if (info.type === 'secondary') {
-        attemptAddSecondary(email, info);
-      } else {
-        attemptAddPrimary(email, info);
-      }
+        else {
+          onComplete(status, provInfo);
+        }
+      }, onFailure);
     },
 
     /**
diff --git a/resources/static/test/cases/pages/signup.js b/resources/static/test/cases/pages/signup.js
index 6fe113b2b6ad8e6c5f08a01da9a3d7bc1733a6f7..92c2cd00573462efdfb27549a73f4711ab56fc7f 100644
--- a/resources/static/test/cases/pages/signup.js
+++ b/resources/static/test/cases/pages/signup.js
@@ -13,7 +13,8 @@
       WinChanMock = bid.Mocks.WinChan,
       testHelpers = bid.TestHelpers,
       provisioning = bid.Mocks.Provisioning,
-      winchan;
+      winchan,
+      controller;
 
   module("pages/signup", {
     setup: function() {
@@ -22,18 +23,20 @@
       $(".emailsent").hide();
       $(".notification").hide()
       winchan = new WinChanMock();
-      bid.signUp({
+      controller = bid.signUp.create();
+      controller.start({
         winchan: winchan
       });
     },
     teardown: function() {
       testHelpers.teardown();
-      bid.signUp.reset();
+      controller.reset();
+      controller.destroy();
     }
   });
 
-  function testNotRegistered(extraTests) {
-    bid.signUp.submit(function(status) {
+  function testPasswordNotShown(extraTests) {
+    controller.submit(function(status) {
       strictEqual(status, false, "address was not registered");
       equal($(".emailsent").is(":visible"), false, "email not sent, notice not visible");
 
@@ -42,64 +45,69 @@
     });
   }
 
-  asyncTest("signup with valid unregistered secondary email", function() {
-    xhr.useResult("unknown_secondary");
-
+  asyncTest("signup with valid unregistered secondary email - show password", function() {
     $("#email").val("unregistered@testuser.com");
 
-    bid.signUp.submit(function() {
-      equal($(".emailsent").is(":visible"), true, "email sent, notice visible");
+    controller.submit(function() {
+      equal($("body").hasClass("enter_password"), true, "new email, password section shown");
+
       start();
     });
   });
 
-  asyncTest("signup with valid unregistered email with leading/trailing whitespace", function() {
-    xhr.useResult("unknown_secondary");
 
+  asyncTest("submit with valid unregistered email with leading/trailing whitespace", function() {
     $("#email").val(" unregistered@testuser.com ");
 
-    bid.signUp.submit(function() {
-      equal($(".emailsent").is(":visible"), true, "email sent, notice visible");
+    controller.submit(function() {
+      equal($("body").hasClass("enter_password"), true, "new email, password section shown");
       start();
     });
   });
 
-  asyncTest("signup with valid registered email", function() {
-    xhr.useResult("known_secondary");
+  asyncTest("submit with valid registered email", function() {
     $("#email").val("registered@testuser.com");
 
-    testNotRegistered();
+    testPasswordNotShown();
   });
 
-  asyncTest("signup with invalid email address", function() {
+  asyncTest("submit with invalid email address", function() {
     $("#email").val("invalid");
 
-    testNotRegistered();
+    testPasswordNotShown();
   });
 
-  asyncTest("signup with throttling", function() {
-    xhr.useResult("throttle");
-
+  asyncTest("submit with XHR error", function() {
+    xhr.useResult("ajaxError");
     $("#email").val("unregistered@testuser.com");
 
-    testNotRegistered();
+    testPasswordNotShown(function() {
+      testHelpers.testErrorVisible();
+    });
   });
 
-  asyncTest("signup with XHR error", function() {
-    xhr.useResult("invalid");
+
+  asyncTest("passwordSubmit with throttling", function() {
     $("#email").val("unregistered@testuser.com");
+    $("#password, #vpassword").val("password");
 
-    testNotRegistered(function() {
-      testHelpers.testErrorVisible();
+    xhr.useResult("throttle");
+    controller.passwordSubmit(function(userStaged) {
+      equal(userStaged, false, "email throttling took effect, user not staged");
+      start();
     });
   });
 
-  asyncTest("signup with unregistered secondary email and cancel button pressed", function() {
-    xhr.useResult("unknown_secondary");
+  asyncTest("passwordSubmit happy case, check back button too", function() {
     $("#email").val("unregistered@testuser.com");
+    $("#password, #vpassword").val("password");
 
-    bid.signUp.submit(function() {
-      bid.signUp.back(function() {
+    controller.passwordSubmit(function(userStaged) {
+      equal(userStaged, true, "user has been staged");
+      equal($(".emailsent").is(":visible"), true, "email sent, notice visible");
+
+      // check back button
+      controller.back(function() {
         equal($(".notification:visible").length, 0, "no notifications are visible - visible: " + $(".notification:visible").attr("id"));
         ok($(".forminputs:visible").length, "form inputs are again visible");
         equal($("#email").val(), "unregistered@testuser.com", "email address restored");
@@ -108,6 +116,7 @@
     });
   });
 
+
   asyncTest("signup with primary email address, provisioning failure - expect error screen", function() {
     xhr.useResult("primary");
     $("#email").val("unregistered@testuser.com");
@@ -116,7 +125,7 @@
       msg: "doowap"
     });
 
-    bid.signUp.submit(function(status) {
+    controller.submit(function(status) {
       equal(status, false, "provisioning failure, status false");
       testHelpers.testErrorVisible();
       start();
@@ -128,7 +137,7 @@
     $("#email").val("unregistered@testuser.com");
     provisioning.setStatus(provisioning.AUTHENTICATED);
 
-    bid.signUp.submit(function(status) {
+    controller.submit(function(status) {
       equal(status, true, "primary addition success - true status");
       equal($("#congrats:visible").length, 1, "success notification is visible");
       start();
@@ -139,7 +148,7 @@
     xhr.useResult("primary");
     $("#email").val("unregistered@testuser.com");
 
-    bid.signUp.submit(function(status) {
+    controller.submit(function(status) {
       equal($("#primary_verify:visible").length, 1, "success notification is visible");
       equal($("#primary_email").text(), "unregistered@testuser.com", "correct email shown");
       equal(status, false, "user must authenticate, some action needed.");
@@ -151,8 +160,8 @@
     xhr.useResult("primary");
     $("#email").val("unregistered@testuser.com");
 
-    bid.signUp.submit(function(status) {
-      bid.signUp.authWithPrimary(function() {
+    controller.submit(function(status) {
+      controller.authWithPrimary(function() {
         ok(winchan.oncomplete, "winchan set up");
         start();
       });
@@ -160,7 +169,7 @@
   });
 
   asyncTest("primaryAuthComplete with error, expect incorrect status", function() {
-    bid.signUp.primaryAuthComplete("error", "", function(status) {
+    controller.primaryAuthComplete("error", "", function(status) {
       equal(status, false, "correct status for could not complete");
       testHelpers.testErrorVisible();
       start();
@@ -171,15 +180,15 @@
     xhr.useResult("primary");
     $("#email").val("unregistered@testuser.com");
 
-    bid.signUp.submit(function(status) {
-      bid.signUp.authWithPrimary(function() {
+    controller.submit(function(status) {
+      controller.authWithPrimary(function() {
         // In real life the user would now be authenticated.
         provisioning.setStatus(provisioning.AUTHENTICATED);
 
         // Before primaryAuthComplete is called, we reset the user caches to
         // force re-fetching of what could have been stale user data.
         user.resetCaches();
-        bid.signUp.primaryAuthComplete(null, "success", function(status) {
+        controller.primaryAuthComplete(null, "success", function(status) {
           equal(status, true, "correct status");
           equal($("#congrats:visible").length, 1, "success notification is visible");
           start();
diff --git a/resources/static/test/cases/shared/user.js b/resources/static/test/cases/shared/user.js
index d5593afd7277f2ad019fae2d0339d6fd85ce4771..6a27aa825b24a2ae7e0b7cdabeaf98d633c846f8 100644
--- a/resources/static/test/cases/shared/user.js
+++ b/resources/static/test/cases/shared/user.js
@@ -153,33 +153,11 @@ var vep = require("./vep");
   });
 
 
-  asyncTest("createUser with unknown secondary happy case - expect 'secondary.verify'", function() {
-    xhr.useResult("unknown_secondary");
-
-    lib.createUser("unregistered@testuser.com", function(status) {
-      equal(status, "secondary.verify", "secondary user must be verified");
-      start();
-    }, testHelpers.unexpectedXHRFailure);
-  });
-
-  asyncTest("createUser with unknown secondary, throttled - expect status='secondary.could_not_add'", function() {
-    xhr.useResult("throttle");
-
-    lib.createUser("unregistered@testuser.com", function(status) {
-      equal(status, "secondary.could_not_add", "user creation refused");
-      start();
-    }, testHelpers.unexpectedXHRFailure);
-  });
-
-  asyncTest("createUser with unknown secondary, XHR failure - expect failure call", function() {
-    failureCheck(lib.createUser, "unregistered@testuser.com");
-  });
-
-  asyncTest("createUser with primary, user verified with primary - expect 'primary.verified'", function() {
+  asyncTest("createPrimaryUser with primary, user verified with primary - expect 'primary.verified'", function() {
     xhr.useResult("primary");
     provisioning.setStatus(provisioning.AUTHENTICATED);
 
-    lib.createUser("unregistered@testuser.com", function(status) {
+    lib.createPrimaryUser({email: "unregistered@testuser.com"}, function(status) {
       equal(status, "primary.verified", "primary user is already verified, correct status");
       network.checkAuth(function(authenticated) {
         equal(authenticated, "assertion", "after provisioning user, user should be automatically authenticated to BrowserID");
@@ -188,33 +166,28 @@ var vep = require("./vep");
     }, testHelpers.unexpectedXHRFailure);
   });
 
-  asyncTest("createUser with primary, user must authenticate with primary - expect 'primary.verify'", function() {
+  asyncTest("createPrimaryUser with primary, user must authenticate with primary - expect 'primary.verify'", function() {
     xhr.useResult("primary");
 
-    lib.createUser("unregistered@testuser.com", function(status) {
+    lib.createPrimaryUser({email: "unregistered@testuser.com"}, function(status) {
       equal(status, "primary.verify", "primary must verify with primary, correct status");
       start();
     }, testHelpers.unexpectedXHRFailure);
   });
 
-  asyncTest("createUser with primary, unknown provisioning failure, expect XHR failure callback", function() {
+  asyncTest("createPrimaryUser with primary, unknown provisioning failure, expect XHR failure callback", function() {
     xhr.useResult("primary");
     provisioning.setFailure({
       code: "primaryError",
       msg: "some error"
     });
 
-    lib.createUser("unregistered@testuser.com",
+    lib.createPrimaryUser({email: "unregistered@testuser.com"},
       testHelpers.unexpectedSuccess,
       testHelpers.expectedXHRFailure
     );
   });
 
-  asyncTest("createUserWithInfo", function() {
-    ok(true, "For development speed and reduced duplication of tests, tested via createUser");
-    start();
-  });
-
   asyncTest("provisionPrimaryUser authenticated with IdP, expect primary.verified", function() {
     xhr.useResult("primary");
     provisioning.setStatus(provisioning.AUTHENTICATED);
diff --git a/resources/static/test/mocks/xhr.js b/resources/static/test/mocks/xhr.js
index 17aa6c9851933562e057afbd92c26cb68fa1d4af..d78791805fd24662db2c1e48b7ccdc5a9a4ec96c 100644
--- a/resources/static/test/mocks/xhr.js
+++ b/resources/static/test/mocks/xhr.js
@@ -68,6 +68,7 @@ BrowserID.Mocks.xhr = (function() {
       "get /wsapi/have_email?email=registered%40testuser.com throttle": { email_known: true },
       "get /wsapi/have_email?email=registered%40testuser.com ajaxError": undefined,
       "get /wsapi/have_email?email=unregistered%40testuser.com valid": { email_known: false },
+      "get /wsapi/have_email?email=unregistered%40testuser.com primary": { email_known: false },
       "post /wsapi/remove_email valid": { success: true },
       "post /wsapi/remove_email invalid": { success: false },
       "post /wsapi/remove_email multiple": { success: true },
@@ -104,6 +105,7 @@ BrowserID.Mocks.xhr = (function() {
       "post /wsapi/update_password invalid": undefined,
       "get /wsapi/address_info?email=unregistered%40testuser.com invalid": undefined,
       "get /wsapi/address_info?email=unregistered%40testuser.com throttle": { type: "secondary", known: false },
+      "get /wsapi/address_info?email=unregistered%40testuser.com valid": { type: "secondary", known: false },
       "get /wsapi/address_info?email=unregistered%40testuser.com unknown_secondary": { type: "secondary", known: false },
       "get /wsapi/address_info?email=registered%40testuser.com known_secondary": { type: "secondary", known: true },
       "get /wsapi/address_info?email=registered%40testuser.com primary": { type: "primary", auth: "https://auth_url", prov: "https://prov_url" },
diff --git a/resources/views/signup.ejs b/resources/views/signup.ejs
index 51b280608d0900893cf11ab0a38532e94bd25328..6e786017f8f383c8af4415c7b49de23fb741a312 100644
--- a/resources/views/signup.ejs
+++ b/resources/views/signup.ejs
@@ -50,6 +50,37 @@
                       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 class="password_entry">
+                    <label class="serif" for="password">Password</label>
+                    <input class="sans" id="password" placeholder="Password" type="password" tabindex="2" maxlength="80">
+
+                    <div id="password_required" class="tooltip" for="password">
+                        Password is required.
+                    </div>
+
+                    <div class="tooltip" id="password_length" for="password">
+                        Password must be between 8 and 80 characters long.
+                    </div>
+
+                    <div id="could_not_add" class="tooltip" for="password">
+                        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 class="password_entry">
+                    <label class="serif" for="vpassword">Verify Password</label>
+                    <input class="sans" id="vpassword" placeholder="Repeat Password" type="password" tabindex="2" maxlength="80">
+
+                    <div id="password_required" class="tooltip" for="vpassword">
+                      Verification password is required.
+                    </div>
+
+                    <div class="tooltip" id="passwords_no_match" for="vpassword">
+                      Passwords do not match.
+                    </div>
+
+                </li>
             </ul>
 
             <div class="submit cf forminputs">