diff --git a/browserid/compress.sh b/browserid/compress.sh
index 07a35765a41f12c3635f705ed1de7da0f38a17f3..9f14b328d43b425483b55c9d3f05f997bb99dc9a 100755
--- a/browserid/compress.sh
+++ b/browserid/compress.sh
@@ -33,7 +33,7 @@ echo ''
 
 cd ../js
 # re-minimize everything together
-cat jquery-1.6.2.min.js ../dialog/resources/underscore-min.js browserid.js > lib.js
+cat jquery-1.6.2.min.js ../dialog/resources/underscore-min.js ../dialog/resources/browserid-network.js browserid.js > lib.js
 $UGLIFY < lib.js > lib.min.js
 
 cd ../css
diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js
index 0fc31a0ca95020c6126946f8ee2fa39cf6f171df..ce5ad8bc065ad8608490f6dce5db5c1476792f95 100644
--- a/browserid/static/dialog/controllers/dialog_controller.js
+++ b/browserid/static/dialog/controllers/dialog_controller.js
@@ -174,7 +174,7 @@ PageController.extend("Dialog", {}, {
         var self = this;
         // this is a secondary registration from browserid.org, persist
         // email, keypair, and that fact
-        self.persistAddressAndKeyPair(self.confirmEmail, 
+        BrowserIDIdentities.persistAddressAndKeyPair(self.confirmEmail, 
           self.confirmKeypair, "browserid.org:443");
         self.syncIdentities();
 
@@ -201,49 +201,15 @@ PageController.extend("Dialog", {}, {
       BrowserIDNetwork.logout(this.doAuthenticate.bind(this));
     },
 
-    persistAddressAndKeyPair: function(email, keypair, issuer) {
-      var new_email_obj= {
-        created: new Date(),
-        pub: keypair.pub,
-        priv: keypair.priv
-      };
-      if (issuer) {
-        new_email_obj.issuer = issuer;
-      }
-      
-      addEmail(email, new_email_obj);
-    },
-
     syncIdentities: function() {
-      // send up all email/pubkey pairs to the server, it will response with a
-      // list of emails that need new keys.  This may include emails in the
-      // sent list, and also may include identities registered on other devices.
-      // we'll go through the list and generate new keypairs
-      
-      // identities that don't have an issuer are primary authentications,
-      // and we don't need to worry about rekeying them.
-      var emails = getEmails();
-      var issued_identities = {};
-      _(emails).each(function(email_obj, email_address) {
-          issued_identities[email_address] = email_obj.pub;
-        });
-      
       var self = this;
-      BrowserIDNetwork.syncEmails(issued_identities, 
-        function onKeySyncSuccess(email, keypair) {
-          self.persistAddressAndKeyPair(email, keypair, "browserid.org:443");
-        },
-        function onKeySyncFailure() {
-          self.runErrorDialog(BrowserIDErrors.syncAddress);
-        },
-        function onSuccess() {
-          self.doSignIn();
-        },
-        function onFailure(jqXHR, textStatus, errorThrown) {
-          self.runErrorDialog(BrowserIDErrors.signIn);
-        }
-      );
-
+      BrowserIDIdentities.syncIdentities(function onSuccess() {
+        self.doSignIn();    
+      }, function onFailure(xhr, textStatus, errorThrown) {
+        self.runErrorDialog(BrowserIDErrors.signIn); 
+      }, function onKeySyncFailure() {
+        self.runErrorDialog(BrowserIDErrors.syncAddress);
+      });
     },
 
 
diff --git a/browserid/static/dialog/dialog.js b/browserid/static/dialog/dialog.js
index 238dcc7cb1339b88a8b6da58531a93b319c407ac..c5d82553597d171b7fcd540149012a402acf3e3f 100644
--- a/browserid/static/dialog/dialog.js
+++ b/browserid/static/dialog/dialog.js
@@ -51,6 +51,7 @@ steal.plugins(
                'storage',
                'browserid-extensions',
                'browserid-network',
+               'browserid-identities',
                'browserid-errors',
                'browserid-wait')					// 3rd party script's (like jQueryUI), in resources folder
 
diff --git a/browserid/static/dialog/resources/browserid-identities.js b/browserid/static/dialog/resources/browserid-identities.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2c0c82e9b4ff10175b8fcbbf73a1c8adaab0ea3
--- /dev/null
+++ b/browserid/static/dialog/resources/browserid-identities.js
@@ -0,0 +1,77 @@
+/*jshint browsers:true, forin: true, laxbreak: true */
+/*global _: true, console: true, addEmail: true, removeEmail: true, CryptoStubs: 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 ***** */
+"use strict";
+var BrowserIDIdentities = {
+  
+  syncIdentities: function(onSuccess, onFailure, onKeySyncFailure) {
+    // send up all email/pubkey pairs to the server, it will response with a
+    // list of emails that need new keys.  This may include emails in the
+    // sent list, and also may include identities registered on other devices.
+    // we'll go through the list and generate new keypairs
+    
+    // identities that don't have an issuer are primary authentications,
+    // and we don't need to worry about rekeying them.
+    var emails = getEmails();
+    var issued_identities = {};
+    _(emails).each(function(email_obj, email_address) {
+        issued_identities[email_address] = email_obj.pub;
+      });
+    
+    var self = this;
+    BrowserIDNetwork.syncEmails(issued_identities, 
+      function onKeySyncSuccess(email, keypair) {
+        self.persistAddressAndKeyPair(email, keypair, "browserid.org:443");
+      },
+      onKeySyncFailure, onSuccess, onFailure);
+  },
+
+  persistAddressAndKeyPair: function(email, keypair, issuer) {
+    var new_email_obj= {
+      created: new Date(),
+      pub: keypair.pub,
+      priv: keypair.priv
+    };
+
+    if (issuer) {
+      new_email_obj.issuer = issuer;
+    }
+    
+    addEmail(email, new_email_obj);
+  },
+
+
+};
diff --git a/browserid/static/dialog/resources/browserid-network.js b/browserid/static/dialog/resources/browserid-network.js
index 005392e644f4fd7731f3dd20651a60e7551eb2e4..d2587869c2672d118ff21974e645481d4062fb67 100644
--- a/browserid/static/dialog/resources/browserid-network.js
+++ b/browserid/static/dialog/resources/browserid-network.js
@@ -1,5 +1,5 @@
 /*jshint browsers:true, forin: true, laxbreak: true */
-/*global _: true, console: true, addEmail: true, removeEmail: true, CryptoStubs: true */
+/*global _: true, console: true, addEmail: true, removeEmail: true, clearEmails: true, CryptoStubs: true */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
@@ -108,6 +108,15 @@ var BrowserIDNetwork = (function() {
 
     },
 
+    cancelUser: function(onSuccess) {
+      $.post("/wsapi/account_cancel", {"csrf": BrowserIDNetwork.csrf_token}, function(result) {
+        clearEmails();
+        if(onSuccess) {
+          onSuccess();
+        }
+      });
+    },
+
     addEmail: function(email, keypair, onSuccess, onFailure) {
       $.ajax({
         type: 'POST',
@@ -136,6 +145,24 @@ var BrowserIDNetwork = (function() {
       });
     },
 
+    removeEmail: function(email, onSuccess, onFailure) {
+      $.ajax({
+        type: 'POST',
+        url: '/wsapi/remove_email',
+        data: {
+          email: email,
+          csrf: BrowserIDNetwork.csrf_token
+        },
+        success: function() {
+          removeEmail(email);
+          if(onSuccess) {
+            onSuccess();
+          }
+        },
+        failure: onFailure
+      });
+    },
+
     checkRegistration: function(onSuccess, onFailure) {
       $.ajax({
           url: '/wsapi/registration_status',
@@ -207,6 +234,7 @@ var BrowserIDNetwork = (function() {
 
 
     }
+
   };
 
   $(function() {
diff --git a/browserid/static/js/browserid.js b/browserid/static/js/browserid.js
index a8f11e5bbcf68e9d10ab19c4a5898b517fd5822a..fe3c90043717e260fc6075e01835aa74ab7ed469 100644
--- a/browserid/static/js/browserid.js
+++ b/browserid/static/js/browserid.js
@@ -1,3 +1,4 @@
+/*globals: BrowserIDNetwork: true */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
@@ -39,86 +40,60 @@ $(function() {
   }
 });
 
-var csrf = undefined;
-// execute a function with a csrf token, fetching it if required
-function withCSRF(cb) {
-  if (csrf === undefined) {
-    $.get("/wsapi/csrf", {}, function(result) {
-      csrf = result;
-      cb();
-    }, 'html');
-  } else {
-    setTimeout(cb, 0);
-  }
-}
-
-
 function display_saved_ids()
 {
   var emails = {};
-  if (window.localStorage.emails) {
-    emails = JSON.parse(window.localStorage.emails);
-  }
+  BrowserIDIdentities.syncIdentities(function() {
+    emails = getEmails();
+    displayEmails();
+  });
 
-  $('#cancellink').click(function() {
-    if (confirm('Are you sure you want to cancel your account?')) {
-      withCSRF(function() {
-        $.post("/wsapi/account_cancel", {"csrf": csrf}, function(result) {
-          window.localStorage.emails = null;
+
+  function displayEmails() {
+    $('#cancellink').click(function() {
+      if (confirm('Are you sure you want to cancel your account?')) {
+        BrowserIDNetwork.cancelUser(function() {
           document.location="/";
         });
-      });
-    }
-  });
-
-  $("#emailList").empty();
-  _(emails).each(function(data, e) {
-      var block = $("<div>").addClass("emailblock");
-      var label = $("<div>").addClass("email").text(e);
-      var meta = $("<div>").addClass("meta");
+      }
+    });
 
-      /* 
-        var priv = $("<div class='keyblock'>").text(data.priv);
-        priv.hide();
-       */
+    $("#emailList").empty();
+      _(emails).each(function(data, e) {
+        var block = $("<div>").addClass("emailblock");
+        var label = $("<div>").addClass("email").text(e);
+        var meta = $("<div>").addClass("meta");
 
-      var pub = $("<div class='keyblock'>").text(data.pub);
-      pub.hide();
-      var linkblock = $("<div>");
-      var puba = $("<a>").text("[show public key]");
-      // var priva = $("<a>").text("[show private key]");
-      puba.click(function() {pub.show()});
-      // priva.click(function() {priv.show()});
-      linkblock.append(puba);
-      // linkblock.append(" / ");
-      // linkblock.append(priva);
-      
-      var deauth = $("<button>").text("Forget this Email");
-      meta.append(deauth);
-      deauth.click(function() {
-        var t = JSON.parse(window.localStorage.emails);
-        withCSRF(function() {
+        var pub = $("<div class='keyblock'>").text(data.pub);
+        pub.hide();
+        var linkblock = $("<div>");
+        var puba = $("<a>").text("[show public key]");
+        // var priva = $("<a>").text("[show private key]");
+        puba.click(function() {pub.show()});
+        // priva.click(function() {priv.show()});
+        linkblock.append(puba);
+        // linkblock.append(" / ");
+        // linkblock.append(priva);
+        
+        var deauth = $("<button>").text("Forget this Email");
+        meta.append(deauth);
+        deauth.click(function() {
           // remove email from server
-          $.post("/wsapi/remove_email", {"email" : e, "csrf": csrf}, function(response) {
-            // we delete from store only once we got response
-            delete t[e];
-            window.localStorage.emails = JSON.stringify(t);
-            display_saved_ids();
-          });
+          BrowserIDNetwork.removeEmail(e, display_saved_ids);
         });
-      });
-      
-      var d = new Date(data.created);
-      var datestamp = $("<div class='date'>").text("Signed in at " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ", " + d.getMonth() + "/" + d.getDay() + "/" + d.getUTCFullYear());
+        
+        var d = new Date(data.created);
+        var datestamp = $("<div class='date'>").text("Signed in at " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ", " + d.getMonth() + "/" + d.getDay() + "/" + d.getUTCFullYear());
 
-      meta.append(datestamp);
-      meta.append(linkblock);
-                  
-      block.append(label);
-      block.append(meta);
-      // block.append(priv);
-      block.append(pub);
-      
-      $("#emailList").append(block);
-  });
+        meta.append(datestamp);
+        meta.append(linkblock);
+                    
+        block.append(label);
+        block.append(meta);
+        // block.append(priv);
+        block.append(pub);
+        
+        $("#emailList").append(block);
+    });
+  }
 }
diff --git a/browserid/views/layout.ejs b/browserid/views/layout.ejs
index 1666df98ba5d6b3c46835343e476512cc7629322..969eaad11cb97cc519a42d03813aaa0181a9dc34 100644
--- a/browserid/views/layout.ejs
+++ b/browserid/views/layout.ejs
@@ -10,6 +10,9 @@
       <link rel="stylesheet" type="text/css" href="/css/github.css">
       <link rel="stylesheet" type="text/css" href="/css/style.css">
       <script src="/js/jquery-1.6.2.min.js" type="text/javascript"></script>
+      <script src="/dialog/resources/storage.js" type="text/javascript"></script>
+      <script src="/dialog/resources/browserid-network.js" type="text/javascript"></script>
+      <script src="/dialog/resources/browserid-identities.js" type="text/javascript"></script>
       <script src="/dialog/resources/underscore-min.js" type="text/javascript"></script>
       <script src="/js/browserid.js" type="text/javascript"></script>
   <% } %>