diff --git a/ChangeLog b/ChangeLog
index 22c4f387b4f17efa2c59fdaf515225af0c1abcfb..4c5f55bd2a68eb6efda0cf930999861c85d78ff7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,8 @@
-train-2012.05.25 (in progress):
+train-2012.06.08 (in progress):
+  * Support non-english passwords: issue #1631
+  * remove obsolete code - 'code_update' handler: issue #1645
+
+train-2012.05.25:
   * many KPI improvements: #1597, #1613
   * code cleanup: #1599, #1602
   * verification links sent before deployment, should still work after - transitional code required by issue #1000: #1592
@@ -8,6 +12,8 @@ train-2012.05.25 (in progress):
   * when user types in wrong password while verifying secondary address (on different browser), show clear tooltip style error: #1557
   * don't make a user type their password when not neccesary (adding secondary address to acct with only primary addresses): #1555
   * perform rigorous checking of inputs to dialog from RP. (PR #1627, bug #747859)
+  * support new parameter names in .get & .request APIs: #1643
+  * perform rigorous checking of arguments returned from primary IdPs: bug #758449
 
 train-2012.05.14:
   * Password is now requested in dialog for new user signup: #1000, #290
diff --git a/bin/browserid b/bin/browserid
index b0109170d498315d4e450bd8661dbb7ee47f90bc..3cb11b874f1a4dc9d8bac954d1627965fba2eff2 100755
--- a/bin/browserid
+++ b/bin/browserid
@@ -126,17 +126,7 @@ wsapi.setup({
 // #9 - handle views for dynamicish content
 views.setup(app);
 
-function doShutdown(readyForShutdownCB) {
-  require('../lib/bcrypt.js').shutdown();
-  db.close(readyForShutdownCB)
-}
-
-// #11 - calls to /code_update from localhost will restart the daemon,
-// this feature is not externally accessible and is only used by
-// the update logic
-shutdown.installUpdateHandler(app, doShutdown);
-
-// #12 if the BROWSERID_FAKE_VERIFICATION env var is defined, we'll include
+// #10 if the BROWSERID_FAKE_VERIFICATION env var is defined, we'll include
 // fake_verification.js.  This is used during testing only and should
 // never be included in a production deployment
 if (process.env['BROWSERID_FAKE_VERIFICATION']) {
@@ -161,7 +151,10 @@ db.open(config.get('database'), function (error) {
   }
 
   // shut down express gracefully on SIGINT
-  shutdown.handleTerminationSignals(app, doShutdown);
+  shutdown.handleTerminationSignals(app, function(readyForShutdownCB) {
+    require('../lib/bcrypt.js').shutdown();
+    db.close(readyForShutdownCB)
+  });
 
   var bindTo = config.get('bind_to');
   app.listen(bindTo.port, bindTo.host, function() {
diff --git a/bin/dbwriter b/bin/dbwriter
index 456a78837d9406c83193fdf54fa2a4b9c8b42e6b..c629863e2241f62b8d94e08342cd66697caffe70 100755
--- a/bin/dbwriter
+++ b/bin/dbwriter
@@ -96,11 +96,6 @@ function doShutdown(readyForShutdownCB) {
   db.close(readyForShutdownCB)
 }
 
-// calls to /code_update from localhost will restart the daemon,
-// this feature is not externally accessible and is only used by
-// the update logic
-shutdown.installUpdateHandler(app, doShutdown);
-
 // open the databse
 db.open(config.get('database'), function (error) {
   if (error) {
diff --git a/bin/keysigner b/bin/keysigner
index 4ed646c9a897b5cf6fb48880dbf5b1617a4271fb..714a4fed322de04c1971f966c1f94755ec1c4784 100755
--- a/bin/keysigner
+++ b/bin/keysigner
@@ -101,9 +101,6 @@ app.post('/wsapi/cert_key', validate(["email", "pubkey", "ephemeral"]), function
   });
 });
 
-// shutdown when code_update is invoked
-shutdown.installUpdateHandler(app);
-
 // shutdown nicely on signals
 shutdown.handleTerminationSignals(app, function() {
   cc.exit();
diff --git a/bin/verifier b/bin/verifier
index 4499256930558eed528919976ddd7a576ada1498..8363e217d27da5a53f41c4a767a6779560d9a8c8 100755
--- a/bin/verifier
+++ b/bin/verifier
@@ -126,9 +126,6 @@ app.post('/verify', function(req, resp, next) {
   });
 });
 
-// shutdown when /code_update is invoked
-shutdown.installUpdateHandler(app);
-
 // shutdown nicely on signals
 shutdown.handleTerminationSignals(app, function() {
   cc.exit();
diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md
index c04de734595374018a42235e3f6eab198c553951..13c3b5fc26a8fa5c93a79d1779ec3854bd95ab32 100644
--- a/docs/DEPLOYMENT.md
+++ b/docs/DEPLOYMENT.md
@@ -2,6 +2,10 @@
    - 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/. -->
 
+**NOTE:** this document is outdated and should be updated, it's left here
+because there is *some* still some potentially useful information.  
+Reader beware.
+
 # How to deploy BrowserID
 
 This describes how to take the code here, put it on a server, and build
@@ -142,9 +146,8 @@ if [ "x$GL_REPO" == 'xbrowserid' ] ; then
     echo "generating production resources"
     cd $NEWCODE/browserid && ./compress.sh && cd -
 
-    # stop the servers
-    curl -o --url http://localhost:62700/code_update > /dev/null 2>&1
-    curl -o --url http://localhost:62800/code_update > /dev/null 2>&1
+    # XXX: stop the servers!  you should deliver SIGINT to each
+    # process
 
     # now move code into place, and keep a backup of the last code
     # that was in production in .old
@@ -275,11 +278,6 @@ server {
     listen       80 default;
     server_name  browserid.org;
 
-    # disallow external server restart.
-    location = /code_update {
-        internal;
-    }
-
     # pass /verify invocations to the verifier
     location /verify {
         proxy_pass        http://127.0.0.1:62800;
diff --git a/lib/http_forward.js b/lib/http_forward.js
index f4b76f5519261cff60d4ad9554fd12d5cffec1cf..f04001e1d6282c7ef88de5030f3ac36824657223 100644
--- a/lib/http_forward.js
+++ b/lib/http_forward.js
@@ -111,7 +111,7 @@ exports.forward = function(dest, req, res, cb) {
     var data;
     if (req.headers['content-type'].indexOf('application/json') === 0) data = JSON.stringify(req.body);
     else data = querystring.stringify(req.body);
-    preq.setHeader('content-length', data.length);
+    preq.setHeader('content-length', Buffer.byteLength(data));
     preq.write(data);
     preq.end();
   } else {
diff --git a/lib/logging.js b/lib/logging.js
index d868df2f772c92da03767466d3abd83d5818029a..058d161869a7e3113ef506304a6f8b81e16e8c0e 100644
--- a/lib/logging.js
+++ b/lib/logging.js
@@ -40,7 +40,7 @@ exports.logger = new (winston.Logger)({
     timestamp: function () { return new Date().toISOString() },
     filename: filename,
     colorize: true,
-    handleExceptions: !!process.env['LOG_TO_CONSOLE']
+    handleExceptions: true
   })]
 });
 
@@ -51,6 +51,6 @@ exports.enableConsoleLogging = function() {
   });
 };
 
-
-
 if (process.env['LOG_TO_CONSOLE']) exports.enableConsoleLogging();
+
+exports.logger.exitOnError = false;
diff --git a/lib/shutdown.js b/lib/shutdown.js
index a4a9a6bc08b5b9bef8b2c695470370b2b355ddca..7fa3c2fdea4a826205b61d3f087e292016627121 100644
--- a/lib/shutdown.js
+++ b/lib/shutdown.js
@@ -2,10 +2,9 @@
  * 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/. */
 
-/* code_update is a tiny abstraction of a handler that can be
- * used to shutdown gracefully upon signals, and can be used
- * to install a 'code_update' hook into a running express
- * server.
+/* shutdown.js is an abstraction for installing graceful shutdown
+ * handlers into processes so that they gracefully shutdown upon
+ * signals.
  */
 
 const logger = require("./logging.js").logger;
@@ -78,17 +77,3 @@ exports.handleTerminationSignals = function(app, callback) {
 
   process.on('SIGINT', endIt('INT')).on('SIGTERM', endIt('TERM')).on('SIGQUIT', endIt('QUIT'));
 };
-
-const CODE_UPDATE_URL = '/code_update';
-
-exports.installUpdateHandler = function(app, callback) {
-  var terminate = connectionListener(app);
-  app.get(CODE_UPDATE_URL, function(req, resp, next) {
-    // don't allow an imprecise match (like one with a trailing slash) to shut the server down.
-    // bug #699171
-    if (req.url !== CODE_UPDATE_URL) return next();
-
-    logger.warn("code updated.  closing " + app.connections + " connections and shutting down.");
-    terminate(callback);
-  });
-};
diff --git a/lib/statsd.js b/lib/statsd.js
index 0e231f3c2383ea92234d4594eee9211548585b86..f7278dca5628b18f7f7329cb04043078822ef653 100644
--- a/lib/statsd.js
+++ b/lib/statsd.js
@@ -29,3 +29,7 @@ if (statsd_config && statsd_config.enabled) {
 
   statsd = new StatsD(options["host"], options["port"]);
 }
+
+process.on('uncaughtException', function(err) {
+  if (statsd) statsd.increment(PREFIX + 'uncaught_exception');
+});
diff --git a/lib/wsapi_client.js b/lib/wsapi_client.js
index 256fcf71c6e395fad3a18dae23fadbb5cef2c0fc..c6ae5bd4208c15fb8a2f94fa219e7c6cb3bd626f 100644
--- a/lib/wsapi_client.js
+++ b/lib/wsapi_client.js
@@ -129,7 +129,7 @@ exports.post = function(cfg, path, context, postArgs, cb) {
     if (typeof postArgs === 'object') {
       postArgs['csrf'] = csrf;
       body = JSON.stringify(postArgs);
-      headers['Content-Length'] = body.length;
+      headers['Content-Length'] = Buffer.byteLength(body);
     }
 
     var req = meth.request({
diff --git a/resources/static/dialog/controllers/dialog.js b/resources/static/dialog/controllers/dialog.js
index 1a3372d72a40f43d41d7b643c642e5a263948856..8e5b8f1cd22e84a05175a9b7b1393c7c69e4a45f 100644
--- a/resources/static/dialog/controllers/dialog.js
+++ b/resources/static/dialog/controllers/dialog.js
@@ -167,6 +167,24 @@ BrowserID.Modules.Dialog = (function() {
           params.tosURL = fixupURL(origin_url, paramsFromRP.termsOfService);
           params.privacyURL = fixupURL(origin_url, paramsFromRP.privacyPolicy);
         }
+
+        if (hash.indexOf("#CREATE_EMAIL=") === 0) {
+          var email = hash.replace(/#CREATE_EMAIL=/, "");
+          if (!bid.verifyEmail(email))
+            throw "invalid #CREATE_EMAIL= (" + email + ")";
+          params.type = "primary";
+          params.email = email;
+          params.add = false;
+        }
+        else if (hash.indexOf("#ADD_EMAIL=") === 0) {
+          var email = hash.replace(/#ADD_EMAIL=/, "");
+          if (!bid.verifyEmail(email))
+            throw "invalid #ADD_EMAIL= (" + email + ")";
+          params.type = "primary";
+          params.email = email;
+          params.add = true;
+        }
+
       } catch(e) {
         // note: renderError accepts HTML and cheerfully injects it into a
         // frame with a powerful origin. So convert 'e' first.
@@ -184,19 +202,6 @@ BrowserID.Modules.Dialog = (function() {
       // XXX Perhaps put this into the state machine.
       self.bind(win, "unload", onWindowUnload);
 
-      if(hash.indexOf("#CREATE_EMAIL=") === 0) {
-        var email = hash.replace(/#CREATE_EMAIL=/, "");
-        params.type = "primary";
-        params.email = email;
-        params.add = false;
-      }
-      else if(hash.indexOf("#ADD_EMAIL=") === 0) {
-        var email = hash.replace(/#ADD_EMAIL=/, "");
-        params.type = "primary";
-        params.email = email;
-        params.add = true;
-      }
-
       self.publish("start", params);
     }
 
diff --git a/resources/static/lib/jschannel.js b/resources/static/lib/jschannel.js
index ad70c3344f106368cf763af3b45f160008ee36ee..c2a5ee41093b37086c9742b8615ff3b8a5756d5c 100644
--- a/resources/static/lib/jschannel.js
+++ b/resources/static/lib/jschannel.js
@@ -1,4 +1,4 @@
-/**
+/*
  * js_channel is a very lightweight abstraction on top of
  * postMessage which defines message formats and semantics
  * to support interactions more rich than just message passing
diff --git a/resources/views/signup.ejs b/resources/views/signup.ejs
index 6e786017f8f383c8af4415c7b49de23fb741a312..e700ed1d8af6ded303ab6c69509ca656863d85c5 100644
--- a/resources/views/signup.ejs
+++ b/resources/views/signup.ejs
@@ -53,7 +53,7 @@
 
                 <li class="password_entry">
                     <label class="serif" for="password">Password</label>
-                    <input class="sans" id="password" placeholder="Password" type="password" tabindex="2" maxlength="80">
+                    <input class="sans" id="password" placeholder="Password" type="password" maxlength="80">
 
                     <div id="password_required" class="tooltip" for="password">
                         Password is required.
@@ -70,7 +70,7 @@
 
                 <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">
+                    <input class="sans" id="vpassword" placeholder="Repeat Password" type="password" maxlength="80">
 
                     <div id="password_required" class="tooltip" for="vpassword">
                       Verification password is required.
@@ -85,7 +85,7 @@
 
             <div class="submit cf forminputs">
                 <div class="remember cf">
-                    <a class="action" href="/signin">Existing account? Sign in.</a>
+                    <a class="action" href="/signin" tabindex="2">Existing account? Sign in.</a>
                 </div>
                 <button>Verify Email</button>
             </div>
@@ -99,7 +99,7 @@
                   </p>
 
                   <p>
-                    <button id="authWithPrimary">Verify</button>
+                    <button id="authWithPrimary" tabindex="1">Verify</button>
                   </p>
                 </li>
             </ul>
diff --git a/scripts/browserid.spec b/scripts/browserid.spec
index 36a711c95e824dfe187a0362939f13123223bbb8..c1b5c7126022afaff6d6aa54d8aab8bcea40fa2f 100644
--- a/scripts/browserid.spec
+++ b/scripts/browserid.spec
@@ -1,7 +1,7 @@
 %define _rootdir /opt/browserid
 
 Name:          browserid-server
-Version:       0.2012.05.25
+Version:       0.2012.06.08
 Release:       1%{?dist}_%{svnrev}
 Summary:       BrowserID server
 Packager:      Pete Fritchman <petef@mozilla.com>
diff --git a/scripts/compress-worker.js b/scripts/compress-worker.js
index 4c9616bffe4a048a05e3cbcd4288ef65f60fb2ad..277a3f7b410d71eaf886c23e0b9967c86d53bae3 100644
--- a/scripts/compress-worker.js
+++ b/scripts/compress-worker.js
@@ -29,15 +29,35 @@ function compressResource(staticPath, name, files, cb) {
     });
   }
 
+  function extract_copyright(code) {
+    var tok = jsp.tokenizer(code), toks, ret = "";
+    toks = tok().comments_before;
+
+    if (toks.length >= 1) {
+      var c = toks[0];
+      // copyrights that we'll include MUST be before code body and have
+      // the form: /** */
+      if (c.value.substr(0, 1) === '*' && c.type === 'comment2') {
+        ret += "/*" + c.value + "*/";
+      }
+    }
+
+    return ret;
+  };
+
   function compress() {
     try {
       var final_code;
       if (/\.js$/.test(name)) {
+        // extract copyright
+        var copyright = extract_copyright(orig_code) || "";
+        if (copyright.length) copyright += "\n\n";
+
         // compress javascript
         var ast = jsp.parse(orig_code); // parse code and get the initial AST
         ast = pro.ast_mangle(ast); // get a new AST with mangled names
         ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
-        final_code = pro.split_lines(pro.gen_code(ast), 32 * 1024); // compressed code here
+        final_code = copyright + pro.split_lines(pro.gen_code(ast), 32 * 1024); // compressed code here
       } else if (/\.css$/.test(name)) {
         // compress css
         var cach_code = cachify_embedded(orig_code);
@@ -89,7 +109,9 @@ function compressResource(staticPath, name, files, cb) {
 }
 
 function cachify_embedded (css_src) {
-  return css_src.replace(/url\s*\(['"](.*)\s*['"]\s*\)/g, function (str, url) {
+  // RegExp is set up to handle multiple url's per declaration, which is
+  // possible for things like background-images.
+  return css_src.replace(/url\s*\(['"]([^\)'"]+)\s*['"]\s*\)/g, function (str, url) {
     // This will throw an error if url doesn't exist. This is good as we will
     // catch typos during build.
     logger.info("For " + str + " making " + url + " into " + cachify.cachify(url));
@@ -107,4 +129,4 @@ process.on('message', function(m) {
       info: info
     });
   });
-});
\ No newline at end of file
+});
diff --git a/tests/simple-stage-user-utf8-password.js b/tests/simple-stage-user-utf8-password.js
new file mode 100644
index 0000000000000000000000000000000000000000..cdd07a8dafbd20b7d17f081a8ecd3211c645892d
--- /dev/null
+++ b/tests/simple-stage-user-utf8-password.js
@@ -0,0 +1,82 @@
+#!/usr/bin/env node
+
+/* 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/. */
+
+require('./lib/test_env.js');
+
+const
+assert = require('assert'),
+vows = require('vows'),
+start_stop = require('./lib/start-stop.js'),
+wsapi = require('./lib/wsapi.js');
+
+var suite = vows.describe('simple-stage-user-utf8-password');
+
+// disable vows (often flakey?) async error behavior
+suite.options.error = false;
+
+start_stop.addStartupBatches(suite);
+
+const
+TEST_DOMAIN = 'example.domain',
+TEST_ORIGIN = 'http://127.0.0.1:10002',
+TEST_SITE = 'http://example.com:652';
+
+// This test simply stages a secondary user. It does so for two users,
+// one with a password that is only ascii, and the other with non-ascii
+// characters in the password (GH-1631).
+
+const test_users =
+  [{
+    email: 'testuser1@' + TEST_DOMAIN,
+    password: 'fakepass',
+  },
+  {
+    email: 'testuser2@' + TEST_DOMAIN,
+    password: 'поддельный пароль', // Russian 'fake password' (34 bytes UTF-8)
+  }];
+
+function makeBatch(site, user) {
+  var batch = {
+    "staging an account": {
+      topic: wsapi.post('/wsapi/stage_user', {
+        site: site,
+        email: user.email,
+        pass: user.password,
+      }),
+      "is 200 OK": function(err, r) {
+        assert.strictEqual(r.code, 200);
+      },
+      "and a token": {
+        topic: function() {
+          start_stop.waitForToken(this.callback);
+        },
+        "is obtained": function (t) {
+          assert.strictEqual(typeof t, 'string');
+        },
+        "and the token can be used": {
+          topic: function(token) {
+            wsapi.post('/wsapi/complete_user_creation', { token: token }).call(this);
+          },
+          "to verify email ownership": function(err, r) {
+            assert.equal(r.code, 200);
+            assert.strictEqual(JSON.parse(r.body).success, true);
+            token = undefined;
+          }
+        }
+      }
+    }
+  };
+  return batch;
+}
+
+suite.addBatch(makeBatch(TEST_SITE, test_users[0]));
+suite.addBatch(makeBatch(TEST_SITE, test_users[1]));
+
+start_stop.addShutdownBatches(suite);
+
+// run or export the suite.
+if (process.argv[1] === __filename) suite.run();
+else suite.export(module);