diff --git a/resources/static/pages/js/signin.js b/resources/static/pages/js/signin.js
index 918be1d87402be93a0feac5be9677fdccee85054..a000e9985cf97fe31e10b1d643ac40ed6057efbb 100644
--- a/resources/static/pages/js/signin.js
+++ b/resources/static/pages/js/signin.js
@@ -149,6 +149,10 @@ BrowserID.signIn = (function() {
       self.bind("#email", "change", onEmailChange);
       self.bind("#email", "keyup", onEmailChange);
 
+      // a redirect to the signup page using the link needs to clear the stored
+      // email address or else the user may be redirected here.
+      self.bind(".redirect", "click", pageHelpers.clearStoredEmail);
+
       sc.start.call(self, options);
 
       // If there is an email already set up in pageHelpers.setupEmail, see if
diff --git a/resources/static/pages/js/signup.js b/resources/static/pages/js/signup.js
index 1284ebf88418cac8dff4d94fbeeb705a0830f7c4..f1821cc296fe33334fc7a76ab9d8ef591a300152 100644
--- a/resources/static/pages/js/signup.js
+++ b/resources/static/pages/js/signup.js
@@ -15,10 +15,13 @@ BrowserID.signUp = (function() {
       validation = bid.Validation,
       errors = bid.Errors,
       tooltip = BrowserID.Tooltip,
+      complete = helpers.complete,
       ANIMATION_SPEED = 250,
       storedEmail = pageHelpers,
       winchan = window.WinChan,
+      doc = document,
       primaryUserInfo,
+      lastEmail,
       sc;
 
     function showNotice(selector) {
@@ -28,7 +31,7 @@ BrowserID.signUp = (function() {
     function authWithPrimary(oncomplete) {
       pageHelpers.openPrimaryAuth(winchan, primaryUserInfo.email, primaryUserInfo.auth, primaryAuthComplete);
 
-      oncomplete && oncomplete();
+      complete(oncomplete);
     }
 
     function primaryAuthComplete(error, result, oncomplete) {
@@ -42,19 +45,15 @@ BrowserID.signUp = (function() {
     }
 
     function createPrimaryUser(info, oncomplete) {
-      function complete(status) {
-        oncomplete && oncomplete(status);
-      }
-
       user.createPrimaryUser(info, function onComplete(status, info) {
         switch(status) {
           case "primary.verified":
-            pageHelpers.replaceFormWithNotice("#congrats", complete.bind(null, true));
+            pageHelpers.replaceFormWithNotice("#congrats", complete.curry(oncomplete, true));
             break;
           case "primary.verify":
             primaryUserInfo = info;
             dom.setInner("#primary_email", info.email);
-            pageHelpers.replaceInputsWithNotice("#primary_verify", complete.bind(null, false));
+            pageHelpers.replaceInputsWithNotice("#primary_verify", complete.curry(oncomplete, false));
             break;
           case "primary.could_not_add":
             // XXX Can this happen?
@@ -66,14 +65,17 @@ BrowserID.signUp = (function() {
     }
 
     function enterPasswordState(info) {
+      /*jshint validthis: true*/
       var self=this;
       self.emailToStage = info.email;
       self.submit = passwordSubmit;
 
       dom.addClass("body", "enter_password");
+      dom.focus("#password");
     }
 
     function passwordSubmit(oncomplete) {
+      /*jshint validthis: true*/
       var pass = dom.getInner("#password"),
           vpass = dom.getInner("#vpassword"),
           valid = validation.passwordAndValidationPassword(pass, vpass);
@@ -85,44 +87,42 @@ BrowserID.signUp = (function() {
           }
           else {
             tooltip.showTooltip("#could_not_add");
-            oncomplete && oncomplete(false);
+            complete(oncomplete, false);
           }
         }, pageHelpers.getFailure(errors.createUser, oncomplete));
       }
       else {
-        oncomplete && oncomplete(false);
+        complete(oncomplete, false);
       }
     }
 
     function emailSubmit(oncomplete) {
+      /*jshint validthis: true*/
       var email = helpers.getAndValidateEmail("#email"),
           self = this;
 
       if (email) {
         dom.setAttr('#email', 'disabled', 'disabled');
-        user.isEmailRegistered(email, function(isRegistered) {
-          if(isRegistered) {
-            dom.removeAttr('#email', 'disabled');
-            $('#registeredEmail').html(email);
-            showNotice(".alreadyRegistered");
-            oncomplete && oncomplete(false);
+        user.addressInfo(email, function(info) {
+          dom.removeAttr('#email', 'disabled');
+
+          var known = info.known;
+
+          if(info.type === "secondary" && known) {
+            doc.location = "/signin";
+            complete(oncomplete, false);
           }
-          else {
-            user.addressInfo(email, function(info) {
-              dom.removeAttr('#email', 'disabled');
-              if(info.type === "primary") {
-                createPrimaryUser.call(self, info, oncomplete);
-              }
-              else {
-                enterPasswordState.call(self, info);
-                oncomplete && oncomplete(!isRegistered);
-              }
-            }, pageHelpers.getFailure(errors.addressInfo, oncomplete));
+          else if(info.type === "secondary" && !known) {
+            enterPasswordState.call(self, info);
+            complete(oncomplete, !known);
+          }
+          else if(info.type === "primary") {
+            createPrimaryUser.call(self, info, oncomplete);
           }
-        }, pageHelpers.getFailure(errors.isEmailRegistered, oncomplete));
+        }, pageHelpers.getFailure(errors.addressInfo, oncomplete));
       }
       else {
-        oncomplete && oncomplete(false);
+        complete(oncomplete, false);
       }
     }
 
@@ -130,8 +130,16 @@ BrowserID.signUp = (function() {
       pageHelpers.cancelEmailSent(oncomplete);
     }
 
-    function onEmailKeyUp(event) {
-      if (event.which !== 13) $(".notification").fadeOut(ANIMATION_SPEED);
+    function onEmailChange(event) {
+      /*jshint validthis: true*/
+
+      // this is basically a state reset.
+      var email = dom.getInner("#email");
+      if(email !== lastEmail) {
+        dom.removeClass("body", "enter_password");
+        this.submit = emailSubmit;
+        lastEmail = email;
+      }
     }
 
     var Module = bid.Modules.PageModule.extend({
@@ -139,19 +147,33 @@ BrowserID.signUp = (function() {
         var self=this;
         options = options || {};
 
-        if (options.winchan) {
-          winchan = options.winchan;
-        }
+        if (options.winchan) winchan = options.winchan;
+        if (options.document) doc = options.document;
 
         dom.focus("form input[autofocus]");
 
         pageHelpers.setupEmail();
 
-        self.bind("#email", "keyup", onEmailKeyUp);
+        self.bind("#email", "keyup", onEmailChange);
+        self.bind("#email", "change", onEmailChange);
         self.click("#back", back);
         self.click("#authWithPrimary", authWithPrimary);
 
+        // a redirect to the signin page using the link needs to clear
+        // the stored email address or else the user may be redirected here.
+        self.bind(".redirect", "click", pageHelpers.clearStoredEmail);
+
         sc.start.call(self, options);
+
+        // If there is an email already set up in pageHelpers.setupEmail,
+        // see if the email address is a primary, secondary, known or
+        // unknown.  Redirect if needed.
+        if (dom.getInner("#email")) {
+          self.submit(options.ready);
+        }
+        else {
+          complete(options.ready);
+        }
       },
 
       submit: emailSubmit,
diff --git a/resources/static/test/cases/pages/js/signup.js b/resources/static/test/cases/pages/js/signup.js
index 736e1a3b636b7166812c39f8af524fe3f3164b44..1514a22e68615c2115aa0a4147314cf4260d2e72 100644
--- a/resources/static/test/cases/pages/js/signup.js
+++ b/resources/static/test/cases/pages/js/signup.js
@@ -1,5 +1,5 @@
 /*jshint browser: true, forin: true, laxbreak: true */
-/*global test: true, start: true, module: true, ok: true, equal: true, BrowserID:true */
+/*global test: true, start: true, module: true, ok: true, equal: true, BrowserID:true, strictEqual */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -11,22 +11,38 @@
       network = bid.Network,
       xhr = bid.Mocks.xhr,
       WinChanMock = bid.Mocks.WinChan,
+      WindowMock = bid.Mocks.WindowMock,
       testHelpers = bid.TestHelpers,
+      testDocumentRedirected = testHelpers.testDocumentRedirected,
+      testDocumentNotRedirected = testHelpers.testDocumentNotRedirected,
+      testHasClass = testHelpers.testHasClass,
+      pageHelpers = bid.PageHelpers,
       provisioning = bid.Mocks.Provisioning,
       winchan,
+      docMock,
       controller;
 
+  function createController(options) {
+    winchan = new WinChanMock();
+    docMock = new WindowMock().document;
+
+    options = options || {};
+    _.extend(options, {
+      document: docMock,
+      winchan: winchan
+    });
+
+    controller = bid.signUp.create();
+    controller.start(options);
+  }
+
   module("pages/js/signup", {
     setup: function() {
       testHelpers.setup();
       bid.Renderer.render("#page_head", "site/signup", {});
       $(".emailsent").hide();
-      $(".notification").hide()
-      winchan = new WinChanMock();
-      controller = bid.signUp.create();
-      controller.start({
-        winchan: winchan
-      });
+      $(".notification").hide();
+      createController();
     },
     teardown: function() {
       testHelpers.teardown();
@@ -45,11 +61,59 @@
     });
   }
 
+  asyncTest("start with no email stored - nothing fancy", function() {
+    createController({
+      ready: function() {
+        testDocumentNotRedirected(docMock, "user not signed in");
+        start();
+      }
+    });
+  });
+
+  asyncTest("start with unknown secondary email stored - show password fields", function() {
+    xhr.useResult("unknown_secondary");
+    pageHelpers.setStoredEmail("unregistered@testuser.com");
+    createController({
+      ready: function() {
+        start();
+        testHasClass("body", "enter_password", "enter_password class added to body");
+        testDocumentNotRedirected(docMock);
+      }
+    });
+  });
+
+  asyncTest("start with known secondary email stored - redirect to /signin", function() {
+    xhr.useResult("known_secondary");
+    pageHelpers.setStoredEmail("registered@testuser.com");
+    createController({
+      ready: function() {
+        testDocumentRedirected(docMock, "/signin", "user sent to /signin page");
+        start();
+      }
+    });
+  });
+
+  /*
+  asyncTest("start with known primary email stored - show verify primary", function() {
+    xhr.useResult("primary");
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
+    pageHelpers.setStoredEmail("registered@testuser.com");
+
+    createController({
+      ready: function() {
+        testHasClass("body", "verify_primary", "verify_primary class added to body");
+
+        testDocumentNotRedirected(docMock);
+        start();
+      }
+    });
+  });
+*/
   asyncTest("signup with valid unregistered secondary email - show password", function() {
     $("#email").val("unregistered@testuser.com");
 
     controller.submit(function() {
-      equal($("body").hasClass("enter_password"), true, "new email, password section shown");
+      testHasClass("body", "enter_password", "new email, password section shown");
 
       start();
     });
@@ -60,7 +124,7 @@
     $("#email").val(" unregistered@testuser.com ");
 
     controller.submit(function() {
-      equal($("body").hasClass("enter_password"), true, "new email, password section shown");
+      testHasClass("body", "enter_password", "new email, password section shown");
       start();
     });
   });
@@ -146,6 +210,7 @@
 
   asyncTest("signup with primary email address, user must verify with primary", function() {
     xhr.useResult("primary");
+    provisioning.setStatus(provisioning.NOT_AUTHENTICATED);
     $("#email").val("unregistered@testuser.com");
 
     controller.submit(function(status) {
diff --git a/resources/views/signin.ejs b/resources/views/signin.ejs
index 1db91fa2c5c7024c205c0cd5f7abdd54d20d0ef1..ea4e9f6b889d785e2af193866e9a24a94a5bcbaa 100644
--- a/resources/views/signin.ejs
+++ b/resources/views/signin.ejs
@@ -43,7 +43,7 @@
             <div class="submit cf forminputs">
                 <button tabindex="5"><%- gettext('Sign In') %></button>
                 <div class="remember cf">
-                    <a class="action" href="/signup"><%- gettext('New to Persona? Sign up today.') %></a>
+                    <a class="action redirect" href="/signup"><%- gettext('New to Persona? Sign up today.') %></a>
                 </div>
             </div>
 
diff --git a/resources/views/signup.ejs b/resources/views/signup.ejs
index 7019371f5eca286d60f36768b0cdd090a5091738..b1d5d09db5485ef67e44ad1b1934d67a59810668 100644
--- a/resources/views/signup.ejs
+++ b/resources/views/signup.ejs
@@ -77,7 +77,7 @@
             <div class="submit cf forminputs">
                 <p class="cf">
                   <button><%- gettext('Verify Email') %></button>
-                  <a class="action remember" href="/signin" tabindex="2"><%- gettext('Existing account? Sign in.') %></a>
+                  <a class="action remember redirect" href="/signin" tabindex="2"><%- gettext('Existing account? Sign in.') %></a>
                 </p>
 
                 <p class="tospp">