diff --git a/example/rp/index.html b/example/rp/index.html
index 4cff0e90686b3ce95b7667ed7f7f88e4ca0988f6..9eb54b10869eceb66b082c507ed73ac345c6b516 100644
--- a/example/rp/index.html
+++ b/example/rp/index.html
@@ -126,7 +126,6 @@ navigator.id.addEventListener('logout', function(event) {
 });
 
 navigator.id.addEventListener('loginCanceled', function(event) {
-alert("");
   var txt = 'got event at ' + (new Date).toString();
   $(".loginCanceledEvents > pre").text(txt);
 });
@@ -145,7 +144,7 @@ $(document).ready(function() {
     });
   });
 
-  // explicitly trigger events at document ready
+  // explicitly trigger events at document load
   navigator.id.setLoggedInUser(null);
 });
 
diff --git a/lib/db/mysql.js b/lib/db/mysql.js
index 2931097bcde0d45dd58fdeef5265e1c1524a2a6f..19a6aa4ff01375917223f96af897e89d60817de5 100644
--- a/lib/db/mysql.js
+++ b/lib/db/mysql.js
@@ -118,7 +118,6 @@ exports.open = function(cfg, cb) {
     logger.debug("connecting to database: " + database);
     options.database = database;
     client = mysql.createClient(options);
-
     client.ping(function(err) {
       logger.debug("connection to database " + (err ? ("fails: " + err) : "established"));
       cb(err);
diff --git a/resources/static/communication_iframe/start.js b/resources/static/communication_iframe/start.js
index 386ca965ebb036038498164264af023583456e91..1737dff674794a001ea1698c17f90c1d7f8127a4 100644
--- a/resources/static/communication_iframe/start.js
+++ b/resources/static/communication_iframe/start.js
@@ -6,7 +6,8 @@
 (function() {
   var bid = BrowserID,
       network = bid.Network,
-      user = bid.User;
+      user = bid.User,
+      storage = bid.Storage;
 
   network.init();
 
@@ -25,28 +26,31 @@
     }
   }
 
-  chan.bind("getPersistentAssertion", function(trans, params) {
-    setRemoteOrigin(trans.origin);
+  var loggedInUser = undefined;
 
-    trans.delayReturn(true);
+  // one of two events will cause us to begin checking to
+  // see if an event shall be emitted - either an explicit
+  // loggedInUser event or page load.
+  chan.bind("loggedInUser", function(trans, email) {
+    loggedInUser = email;
+  });
 
-    user.getPersistentSigninAssertion(function(rv) {
-      trans.complete(rv);
-    }, function() {
-      trans.error();
+  chan.bind("loaded", function(trans, params) {
+    setRemoteOrigin(trans.origin);
+
+    user.getSilentAssertion(loggedInUser, function(email, assertion) {
+      if (email && assertion) chan.notify({ method: 'login', params: assertion });
+      else chan.notify({ method: 'logout' });
+    }, function(err) {
+      chan.notify({ method: 'logout' });
     });
+
+    trans.complete();
   });
 
   chan.bind("logout", function(trans, params) {
     setRemoteOrigin(trans.origin);
-
-    trans.delayReturn(true);
-
-    user.clearPersistentSignin(function(rv) {
-      trans.complete(rv);
-    }, function() {
-      trans.error();
-    });
+    storage.setLoggedIn(remoteOrigin, false);
+    trans.complete();
   });
 }());
-
diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index e2c74432efbaf327f993f5b19397d1f99fa7a50a..cab5f6f6f370ed8554dd055e3509186c942069f5 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -655,20 +655,6 @@ h1 {
   height: 28px;
 }
 
-#signUpForm .remember {
-  display: inline-block;
-  line-height: 28px;
-}
-
-#signUpForm .remember .checkAlign {
-  float: left;
-}
-
-#signUpForm .remember label {
-  margin-left: 5px;
-  float: left;
-}
-
 #signUpForm .error {
   margin-top: 20px;
   color: red;
diff --git a/resources/static/dialog/controllers/pick_email.js b/resources/static/dialog/controllers/pick_email.js
index 87a311462475ff78ceae1e4d588dc969a60d5825..3a352f19d60e757caf362bacb00539a9b96568a5 100644
--- a/resources/static/dialog/controllers/pick_email.js
+++ b/resources/static/dialog/controllers/pick_email.js
@@ -51,10 +51,6 @@ BrowserID.Modules.PickEmail = (function() {
       var origin = user.getOrigin();
       storage.site.set(origin, "email", email);
 
-      if (self.allowPersistent) {
-        storage.site.set(origin, "remember", $("#remember").is(":checked"));
-      }
-
       self.close("email_chosen", { email: email });
     }
   }
@@ -90,14 +86,11 @@ BrowserID.Modules.PickEmail = (function() {
 
       options = options || {};
 
-      self.allowPersistent = options.allow_persistent;
       dom.addClass("body", "pickemail");
 
       self.renderDialog("pick_email", {
         identities: getSortedIdentities(),
         siteemail: storage.site.get(origin, "email"),
-        allow_persistent: options.allow_persistent || false,
-        remember: storage.site.get(origin, "remember") || false,
         privacy_url: options.privacyURL,
         tos_url: options.tosURL
       });
diff --git a/resources/static/dialog/css/m.css b/resources/static/dialog/css/m.css
index 08b24fe3105acd15ac6dc8915ee5e52af9e22fd4..f3e6dc32525b26460c9cf42e990e374fc336b81d 100644
--- a/resources/static/dialog/css/m.css
+++ b/resources/static/dialog/css/m.css
@@ -139,10 +139,8 @@
     margin-bottom: 20px;
   }
 
-  label[for=remember] {
-    display: block;
-    font-size: 15px;
-    margin-bottom: 25px;
+  .form_section {
+    margin-top: 20px;
   }
 
   #content, .form_section, .inputs, .vertical {
diff --git a/resources/static/dialog/css/popup.css b/resources/static/dialog/css/popup.css
index d3765789e63f85d99d05c94960e50bbb8b3a7c33..1c198c0824b04f7d5dbffe78b6ee663e17aa38d8 100644
--- a/resources/static/dialog/css/popup.css
+++ b/resources/static/dialog/css/popup.css
@@ -372,11 +372,6 @@ footer {
     display: none;
 }
 
-label[for=remember] {
-  display: inline-block;
-  margin-bottom: 10px;
-}
-
 a.emphasize {
   background-color: #F0EFED;
   color: #4E4E4E;
diff --git a/resources/static/dialog/resources/internal_api.js b/resources/static/dialog/resources/internal_api.js
index 70d81219a29c5a626d17fa7f18bbfde5dea62678..6285f8cb788357cf7ac11f80b46b76d82f309840 100644
--- a/resources/static/dialog/resources/internal_api.js
+++ b/resources/static/dialog/resources/internal_api.js
@@ -27,7 +27,7 @@
     }
 
     user.checkAuthentication(function onComplete(authenticated) {
-      if(authenticated) {
+      if (authenticated) {
         storage.site.set(origin, "remember", true);
       }
 
diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js
index a955170a02bc17f24994a7dc9b72602efaecdc95..8ccc31247d5f596ba37d337c9f2e369c4ecb1b2b 100644
--- a/resources/static/dialog/resources/state.js
+++ b/resources/static/dialog/resources/state.js
@@ -37,7 +37,6 @@ BrowserID.State = (function() {
       info = info || {};
 
       self.hostname = info.hostname;
-      self.allowPersistent = !!info.allowPersistent;
       self.privacyURL = info.privacyURL;
       self.tosURL = info.tosURL;
       requiredEmail = info.requiredEmail;
@@ -70,6 +69,7 @@ BrowserID.State = (function() {
       var authenticated = info.authenticated;
 
       if (requiredEmail) {
+        self.email = requiredEmail;
         startState("doAuthenticateWithRequiredEmail", {
           email: requiredEmail,
           privacyURL: self.privacyURL,
@@ -97,6 +97,7 @@ BrowserID.State = (function() {
     });
 
     subscribe("user_confirmed", function() {
+      self.email = self.stagedEmail;
       startState("doEmailConfirmed", { email: self.stagedEmail} );
     });
 
@@ -165,7 +166,6 @@ BrowserID.State = (function() {
     subscribe("pick_email", function() {
       startState("doPickEmail", {
         origin: self.hostname,
-        allow_persistent: self.allowPersistent,
         privacyURL: self.privacyURL,
         tosURL: self.tosURL
       });
@@ -177,6 +177,8 @@ BrowserID.State = (function() {
       var email = info.email,
           idInfo = storage.getEmail(email);
 
+      self.email = email;
+
       function oncomplete() {
         complete(info.complete);
       }
@@ -245,6 +247,7 @@ BrowserID.State = (function() {
     subscribe("assertion_generated", function(msg, info) {
       self.success = true;
       if (info.assertion !== null) {
+        bid.Storage.setLoggedIn(user.getOrigin(), self.email);
         startState("doAssertionGenerated", info.assertion);
       }
       else {
diff --git a/resources/static/dialog/views/pick_email.ejs b/resources/static/dialog/views/pick_email.ejs
index be2fdd3fae2d01aadfb975af222eeedfaa79154d..a9dbdae0af95ae247065e29a8b318bfa83185357 100644
--- a/resources/static/dialog/views/pick_email.ejs
+++ b/resources/static/dialog/views/pick_email.ejs
@@ -23,28 +23,18 @@
 
 
       <div class="submit add cf">
-      <% if (allow_persistent) { %>
-          <label for="remember" class="selectable">
-            <input type="checkbox" id="remember" name="remember" <% if (remember) { %> checked="checked" <% } %> />
-            <%= gettext('Always sign in using this email') %>
-          </label>
-      <% } %>
-
-      <% if (privacy_url && tos_url) { %>
-        <p>
-<%= format(
-          gettext('By clicking %s, you confirm that you accept this site\'s <a %s>Terms of Use</a> and <a %s>Privacy Policy</a>.'),
-                   [ gettext('sign in'),
-                     format(' href="%s" target="_new"', [tos_url]),
-                     format(' href="%s" target="_new"', [privacy_url])
-                   ]) %>
-        </p>
-        <p>
-      <% } %>
-          <button id="signInButton"><%= gettext('sign in') %></button>
       <% if (privacy_url && tos_url) { %>
+        <p class="tospp">
+          <%= format(
+            gettext('By clicking %s, you confirm that you accept this site\'s <a %s>Terms of Use</a> and <a %s>Privacy Policy</a>.'),
+                    [ gettext('sign in'),
+                      format(' href="%s" target="_new"', [tos_url]),
+                      format(' href="%s" target="_new"', [privacy_url])
+                    ]) %>
         </p>
       <% } %>
+
+        <button id="signInButton"><%= gettext('sign in') %></button>
+        <br style="clear: both" />
       </div>
   </div>
-
diff --git a/resources/static/include_js/include.js b/resources/static/include_js/include.js
index 0aa5b545828d04e2466f073e873f31d9ec6706fb..d1b12fd75ba82a5cb16f651b88c966574e63cd26 100644
--- a/resources/static/include_js/include.js
+++ b/resources/static/include_js/include.js
@@ -979,7 +979,17 @@
         iframe.style.display = "none";
         doc.body.appendChild(iframe);
         iframe.src = ipServer + "/communication_iframe";
-        commChan = Channel.build({window: iframe.contentWindow, origin: ipServer, scope: "mozid_ni"});
+        commChan = Channel.build({
+          window: iframe.contentWindow,
+          origin: ipServer,
+          scope: "mozid_ni",
+          onReady: function() {
+            // once the channel is set up, we'll fire a loaded message.  this is the
+            // cutoff point where we'll say if 'setLoggedInUser' was not called before
+            // this point, then it wont be called (XXX: optimize and improve me)
+            commChan.call({ method: 'loaded', success: function(){}, error: function() {} });
+          }
+        });
 
         commChan.bind('logout', function(trans, params) {
           emitEvent('logout');
@@ -992,11 +1002,10 @@
     }
 
     navigator.id.addEventListener = function(type, listener/*, useCapture */) {
-      // 1. allocate iframe if it is not allocated
+      // allocate iframe if it is not allocated
       _open_hidden_iframe();
 
-      // 2. add event to listeners table if it's not there already
-      // XXX: should we throw or silently ignore?
+      // add event to listeners table if it's not there already
       if (!listeners[type]) throw "unsupported event type: '" + type + "'";
 
       // is the function already registered?
@@ -1009,14 +1018,21 @@
     navigator.id.removeEventListener = function(type, listener/*, useCapture */) {
       if (!useCapture) useCapture = false;
 
-      // 1. remove event from listeners table
+      // remove event from listeners table
+      var i;
+      for (i = 0; i < listeners[type].length; i++) {
+        if (listeners[type][i] === listener) break;
+      }
+      if (i < listeners[type][i] === listener) {
+        listeners[type].splice(i, 1);
+      }
     };
 
     navigator.id.logout = function() {
-      // 1. allocate iframe if it is not allocated
+      // allocate iframe if it is not allocated
       _open_hidden_iframe();
 
-      // 2. send logout message
+      // send logout message
       commChan.notify({ method: 'logout', params: email });
     };
 
diff --git a/resources/static/shared/storage.js b/resources/static/shared/storage.js
index 40288033af84e75d874a8fc4f677bd31b1649d8a..0e7cfa0deb376f79c80130579555d354528f7d75 100644
--- a/resources/static/shared/storage.js
+++ b/resources/static/shared/storage.js
@@ -159,7 +159,6 @@ BrowserID.Storage = (function() {
     }
   }
 
-
   function managePageGet(key) {
     var allInfo = JSON.parse(storage.managePage || "{}");
     return allInfo[key];
@@ -176,6 +175,22 @@ BrowserID.Storage = (function() {
     delete allInfo[key];
     storage.managePage = JSON.stringify(allInfo);
   }
+
+  function setLoggedIn(origin, email) {
+    var allInfo = JSON.parse(storage.loggedIn || "{}");
+    if (email) allInfo[origin] = email;
+    else delete allInfo[origin];
+    storage.loggedIn = JSON.stringify(allInfo);
+  }
+  function getLoggedIn(origin) {
+    var allInfo = JSON.parse(storage.loggedIn || "{}");
+    return allInfo[origin];
+  }
+  function watchLoggedIn(origin, callback) {
+    throw "not yet implemented";
+  }
+
+
   return {
     /**
      * Add an email address and optional key pair.
@@ -242,6 +257,24 @@ BrowserID.Storage = (function() {
       remove: managePageRemove
     },
 
+    /** set logged in state for a site
+     * @param {string} origin - the site to set logged in state for
+     * @param {string} email - the email that the user is logged in with or falsey if login state should be cleared
+     */
+    setLoggedIn: setLoggedIn,
+
+    /** check if the user is logged into a site
+     * @param {string} origin - the site to set check the logged in state of
+     * @returns the email with which the user is logged in
+     */
+    getLoggedIn: getLoggedIn,
+
+    /** watch for changes in the logged in state of a page
+     * @param {string} origin - the site to watch the status of
+     * @param {function} callback - a callback to invoke when state changes
+     */
+    watchLoggedIn: watchLoggedIn,
+
     /**
      * Clear all stored data - email addresses, key pairs, temporary key pairs,
      * site/email associations.
diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js
index d4a23aec70aacea814a0e07caa9c6b341bc52c08..2c2102cb0b57072177f66d245fb6a7b9f3698835 100644
--- a/resources/static/shared/user.js
+++ b/resources/static/shared/user.js
@@ -1046,27 +1046,27 @@ BrowserID.User = (function() {
     },
 
     /**
-     * Get an assertion for the current domain, as long as the user has
-     * selected that they want the email/site remembered
+     * Get an assertion for the current domain if the user is signed into it
      * @method getPersistentSigninAssertion
      * @param {function} onComplete - called on completion.  Called with an
      * assertion if successful, null otw.
      * @param {function} onFailure - called on XHR failure.
      */
-    getPersistentSigninAssertion: function(onComplete, onFailure) {
+    getSilentAssertion: function(siteSpecifiedEmail, onComplete, onFailure) {
       User.checkAuthentication(function(authenticated) {
         if (authenticated) {
-          var remembered = storage.site.get(origin, "remember");
-          var email = storage.site.get(origin, "email");
-          if (remembered && email) {
-            User.getAssertion(email, origin, onComplete, onFailure);
+          var loggedInEmail = storage.getLoggedIn(origin);
+          if (loggedInEmail && siteSpecifiedEmail != loggedInEmail) {
+            User.getAssertion(loggedInEmail, origin, function(assertion) {
+              onComplete(loggedInEmail, assertion);
+            }, onFailure);
           }
           else if (onComplete) {
-            onComplete(null);
+            onComplete(loggedInEmail, null);
           }
         }
         else if (onComplete) {
-          onComplete(null);
+          onComplete(null, null);
         }
       }, onFailure);
     },
@@ -1078,10 +1078,10 @@ BrowserID.User = (function() {
      * a boolean, true if successful, false otw.
      * @param {function} onFailure - called on XHR failure.
      */
-    clearPersistentSignin: function(onComplete, onFailure) {
+    logout: function(onComplete, onFailure) {
       User.checkAuthentication(function(authenticated) {
         if (authenticated) {
-          storage.site.set(origin, "remember", false);
+          storage.setLoggedIn(origin, false);
           if (onComplete) {
             onComplete(true);
           }
@@ -1111,8 +1111,6 @@ BrowserID.User = (function() {
 
       onComplete(hasSecondary);
     }
-
-
   };
 
   User.setOrigin(document.location.host);