diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index 37e2a3a01a27c09b324110e2671851b781b67bd8..8b23ff1b3a6ffce815152264157a5276596c481c 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -271,38 +271,36 @@ div.steps {
   font-weight: normal;
 }
 
-#manage .buttonrow {
-  margin: 72px 0 14px;
+#manage section {
+  margin-bottom: 20px;
+}
+
+.buttonrow {
+  margin: 0 0 14px;
 }
 
-#manage .buttonrow button {
+.buttonrow > h2 {
+  display: inline-block;
+  font-size: 1em;
+}
+
+#manage button {
   line-height: 20px;
   height: 24px;
-  width: 48px;
   font-size: 12px;
 }
 
-#manageAccounts {
-  background-color: #37A6FF;
-  border: 1px solid #37A6FF;
-  text-shadow: -1px -1px 0 #37A6FF;
-  cursor: pointer;
-
-  -webkit-box-shadow: 0 0 0 1px #76C2FF inset;
-     -moz-box-shadow: 0 0 0 1px #76C2FF inset;
-       -o-box-shadow: 0 0 0 1px #76C2FF inset;
-          box-shadow: 0 0 0 1px #76C2FF inset;
-
-  background-image: -moz-linear-gradient(#76C2FF 0pt, #37A6FF 100%);
-  background-image: -o-linear-gradient(#76C2FF 0pt, #37A6FF 100%);
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #76C2FF), color-stop(100%, #37A6FF));
+.buttonrow > button {
+  width: 48px;
 }
 
-.edit #manageAccounts {
+.buttonrow > .edit { }
+
+.edit .buttonrow > .edit {
   display: none;
 }
 
-#cancelManage {
+.buttonrow > .done {
   display: none;
   background-color: #006EC6;
   border: 1px solid #003E70;
@@ -319,13 +317,12 @@ div.steps {
   background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3AA7FF), color-stop(100%, #006EC6));
 }
 
-.edit #cancelManage {
+.edit .buttonrow > .done {
   display: inline-block;
 }
 
 #manage #emailList {
   list-style-type: none;
-  margin: 0 0 72px 0;
   border-top: 1px solid #eee;
 }
 
@@ -376,10 +373,7 @@ div.steps {
 
 button.delete {
   background-color: #EA7676;
-  height: 24px;
-  vertical-align: middle;
   border: 1px solid #B13D3D;
-  font-size: 12px;
   font-weight: bold;
   font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
   color: #fff;
@@ -417,6 +411,32 @@ button.delete:active {
   background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #C84343), color-stop(100%, #AA3D3D));
 }
 
+#edit_password {
+  margin-bottom: 10px;
+}
+
+#edit_password label {
+  width: 40%;
+  display: inline-block;
+}
+
+#edit_password input[type=password] {
+  width: 40%;
+}
+
+.showedit {
+  opacity: 0;
+  -webkit-transition: all 500ms;
+  -moz-transition: all 500ms;
+  -ms-transition: all 500ms;
+  -o-transition: all 500ms;
+  transition: all 500ms;
+}
+
+.edit .showedit {
+  opacity: 1;
+}
+
 #disclaimer {
   color: #888;
   text-align: right;
@@ -683,7 +703,7 @@ a.forgot {
 }
 
 
-header {
+#wrapper > header {
   position: absolute;
   top: 0;
   font-weight: bold;
@@ -725,7 +745,7 @@ header a.signIn:hover, header a.signOut:hover {
   display: inline;
 }
 
-header,
+#wrapper > header,
 footer {
   display: block;
   width: 100%;
diff --git a/resources/static/pages/manage_account.js b/resources/static/pages/manage_account.js
index c606a69f42ade1ae55adbe5bfadcec9a25140243..0aa3a655f9ec8f5614dbf16a19b0d263cc30347d 100644
--- a/resources/static/pages/manage_account.js
+++ b/resources/static/pages/manage_account.js
@@ -45,7 +45,8 @@ BrowserID.manageAccount = (function() {
       pageHelpers = bid.PageHelpers,
       cancelEvent = pageHelpers.cancelEvent,
       confirmAction = confirm,
-      doc = document;
+      doc = document,
+      tooltip = bid.Tooltip;
 
   function relativeDate(date) {
     var diff = (((new Date()).getTime() - date.getTime()) / 1000),
@@ -211,12 +212,46 @@ BrowserID.manageAccount = (function() {
     }
   }
 
-  function manageAccounts() {
-      $("body").addClass("edit");
+  function startEdit(event) {
+    // XXX add some helpers in the dom library to find section.
+    event.preventDefault();
+    $(event.target).closest("section").addClass("edit");
   }
 
-  function cancelManage() {
-      $("body").removeClass("edit");
+  function cancelEdit(event) {
+    event.preventDefault();
+    $(event.target).closest("section").removeClass("edit");
+  }
+
+  function changePassword(oncomplete) {
+    var oldPassword = dom.getInner("#old_password"),
+        newPassword = dom.getInner("#new_password");
+
+    function complete(status) {
+      typeof oncomplete == "function" && oncomplete(status);
+    }
+
+    if(!oldPassword) {
+      tooltip.showTooltip("#tooltipOldRequired");
+      complete(false);
+    }
+    else if(!newPassword) {
+      tooltip.showTooltip("#tooltipNewRequired");
+      complete(false);
+    }
+    else {
+      user.changePassword(oldPassword, newPassword, function(status) {
+        if(status) {
+          dom.removeClass("#edit_password", "edit");
+        }
+        else {
+          tooltip.showTooltip("#tooltipInvalidPassword");
+        }
+
+        complete(status);
+      }, pageHelpers.getFailure(errors.updatePassword, oncomplete));
+    }
+
   }
 
   function displayHelpTextToNewUser() {
@@ -233,8 +268,10 @@ BrowserID.manageAccount = (function() {
     if (options.confirm) confirmAction = options.confirm;
 
     dom.bindEvent("#cancelAccount", "click", cancelEvent(cancelAccount));
-    dom.bindEvent("#manageAccounts", "click", cancelEvent(manageAccounts));
-    dom.bindEvent("#cancelManage", "click", cancelEvent(cancelManage));
+
+    dom.bindEvent("button.edit", "click", startEdit);
+    dom.bindEvent("button.done", "click", cancelEdit);
+    dom.bindEvent("#edit_password_form", "submit", cancelEvent(changePassword));
 
     syncAndDisplayEmails(oncomplete);
 
@@ -244,13 +281,16 @@ BrowserID.manageAccount = (function() {
   // BEGIN TESTING API
   function reset() {
     dom.unbindEvent("#cancelAccount", "click");
-    dom.unbindEvent("#manageAccounts", "click");
-    dom.unbindEvent("#cancelManage", "click");
+
+    dom.unbindEvent("button.edit", "click");
+    dom.unbindEvent("button.done", "click");
+    dom.unbindEvent("#edit_password_form", "submit");
   }
 
   init.reset = reset;
   init.cancelAccount = cancelAccount;
   init.removeEmail = removeEmail;
+  init.changePassword = changePassword;
   // END TESTING API
 
   return init;
diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js
index c18b2817c54e3c336841f8bde097c31995ea95e2..e024ee1750279d617dedb8d3165a68403cb35f59 100644
--- a/resources/static/pages/page_helpers.js
+++ b/resources/static/pages/page_helpers.js
@@ -94,7 +94,7 @@ BrowserID.PageHelpers = (function() {
       $("#errorBackground").stop().fadeIn();
       $("#error").stop().fadeIn();
 
-      callback && callback();
+      callback && callback(false);
     }
   }
 
diff --git a/resources/static/shared/error-messages.js b/resources/static/shared/error-messages.js
index f1e6cbb681922c7fce6ce5f9978b0a3094b34fa8..340af7f66b437e009941f38af6e3e7ac0c87304f 100644
--- a/resources/static/shared/error-messages.js
+++ b/resources/static/shared/error-messages.js
@@ -119,6 +119,10 @@ BrowserID.Errors = (function(){
       title: "Sync Keys for Address"
     },
 
+    updatePassword: {
+      title: "Updating password"
+    },
+
     xhrError: {
       title: "Communication Error"
     }
diff --git a/resources/static/shared/network.js b/resources/static/shared/network.js
index d15d8d345f41f2834949b6f78bbe1bd859fe35f8..305084129c1311f78e7bedbfddf79af7b2805ba2 100644
--- a/resources/static/shared/network.js
+++ b/resources/static/shared/network.js
@@ -120,7 +120,7 @@ BrowserID.Network = (function() {
     else {
       var url = "/wsapi/session_context";
       xhr.ajax({
-        url: "/wsapi/session_context",
+        url: url,
         success: function(result) {
           csrf_token = result.csrf_token;
           server_time = {
@@ -379,15 +379,22 @@ BrowserID.Network = (function() {
      * @method changePassword
      * @param {string} oldpassword - old password.
      * @param {string} newpassword - new password.
-     * @param {function} [onSuccess] - Callback to call when complete. Will be
+     * @param {function} [onComplete] - Callback to call when complete. Will be
      * called with true if successful, false otw.
      * @param {function} [onFailure] - Called on XHR failure.
      */
-    changePassword: function(oldPassword, newPassword, onSuccess, onFailure) {
-      // XXX fill this in
-      if (onSuccess) {
-        onSuccess(true);
-      }
+    changePassword: function(oldPassword, newPassword, onComplete, onFailure) {
+      post({
+        url: "/wsapi/update_password",
+        data: {
+          oldpass: oldPassword,
+          newpass: newPassword
+        },
+        success: function(response) {
+          if (onComplete) onComplete(response.success);
+        },
+        error: onFailure
+      });
     },
 
 
@@ -420,8 +427,8 @@ BrowserID.Network = (function() {
           email: email,
           site: origin
         },
-        success: function(status) {
-          if (onSuccess) onSuccess(status.success);
+        success: function(response) {
+          if (onSuccess) onSuccess(response.success);
         },
         error: function(info) {
           // 403 is throttling.
diff --git a/resources/static/shared/tooltip.js b/resources/static/shared/tooltip.js
index eb512c0f90e5dbcf75d4a7f9412378640c4ee854..14d21932fee721cc290077c1f3eff982e2b52376 100644
--- a/resources/static/shared/tooltip.js
+++ b/resources/static/shared/tooltip.js
@@ -44,7 +44,7 @@ BrowserID.Tooltip = (function() {
       bid = BrowserID,
       dom = bid.DOM,
       renderer = bid.Renderer,
-      lastTooltip;
+      hideTimer;
 
   function createTooltip(el) {
       var contents = el.html();
@@ -74,7 +74,7 @@ BrowserID.Tooltip = (function() {
 
     bid.Tooltip.shown = true;
     el.fadeIn(ANIMATION_TIME, function() {
-      setTimeout(function() {
+      hideTimer = setTimeout(function() {
         el.fadeOut(ANIMATION_TIME, function() {
           bid.Tooltip.shown = false;
           if(complete) complete();
@@ -118,7 +118,19 @@ BrowserID.Tooltip = (function() {
 
 
  return {
-    showTooltip: showTooltip
+   showTooltip: showTooltip
+   // BEGIN TESTING API
+   ,
+   reset: function() {
+     if(hideTimer) {
+       clearTimeout(hideTimer);
+       hideTimer = null;
+     }
+
+     $(".tooltip").hide();
+     bid.Tooltip.shown = false;
+   }
+   // END TESTING API
  };
 
 }());
diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js
index c093b48de9e41c4f2bc194a0af9b4d21806cdd01..ade50c2718769eca3224a6146c4557069c844255 100644
--- a/resources/static/shared/user.js
+++ b/resources/static/shared/user.js
@@ -322,7 +322,7 @@ BrowserID.User = (function() {
     },
 
     /**
-     * Set the password of the current user.
+     * Set the initial password of the current user.
      * @method setPassword
      * @param {string} password - password to set
      * @param {function} [onComplete] - Called on successful completion.
@@ -332,6 +332,20 @@ BrowserID.User = (function() {
       network.setPassword(password, onComplete, onFailure);
     },
 
+    /**
+     * update the password of the current user.
+     * @method changePassword
+     * @param {string} oldpassword - the old password.
+     * @param {string} newpassword - the new password.
+     * @param {function} [onComplete] - called on completion.  Called with one
+     * parameter, status - set to true if password update is successful, false
+     * otw.
+     * @param {function} [onFailure] - called on XHR failure.
+     */
+    changePassword: function(oldpassword, newpassword, onComplete, onFailure) {
+      network.changePassword(oldpassword, newpassword, onComplete, onFailure);
+    },
+
     /**
      * Request a password reset for the given email address.
      * @method requestPasswordReset
diff --git a/resources/static/test/index.html b/resources/static/test/index.html
index 192c9d03d66c68b00953b0d2d80cdcbf2d3ecbac..6758da3193e71ad8178756de8a1924755330347a 100644
--- a/resources/static/test/index.html
+++ b/resources/static/test/index.html
@@ -40,6 +40,8 @@
         <input id="newEmail" />
         <input id="password" />
         <input id="vpassword" />
+        <input id="old_password" />
+        <input id="new_password" />
         <input type="checkbox" id="remember" />
       </div>
       <div id="congrats">Congrats!</div>
diff --git a/resources/static/test/qunit/mocks/xhr.js b/resources/static/test/qunit/mocks/xhr.js
index a65e6e5bfd0a89c83b719b86e4dc151e70421679..8593376f06d2985ee2954f628d95520cd2b864e2 100644
--- a/resources/static/test/qunit/mocks/xhr.js
+++ b/resources/static/test/qunit/mocks/xhr.js
@@ -56,14 +56,8 @@ BrowserID.Mocks.xhr = (function() {
   var xhr = {
     results: {
       "get /wsapi/session_context valid": contextInfo,
-      "get /wsapi/session_context invalid": contextInfo,
       // We are going to test for XHR failures for session_context using
-      // call to serverTime.  We are going to use the flag contextAjaxError
-      "get /wsapi/session_context ajaxError": contextInfo,
-      "get /wsapi/session_context complete": contextInfo,
-      "get /wsapi/session_context throttle": contextInfo,
-      "get /wsapi/session_context multiple": contextInfo,
-      "get /wsapi/session_context no_identities": contextInfo,
+      // the flag contextAjaxError.
       "get /wsapi/session_context contextAjaxError": undefined,
       "get /wsapi/email_for_token?token=token valid": { email: "testuser@testuser.com" },
       "get /wsapi/email_for_token?token=token invalid": { success: false },
@@ -115,7 +109,10 @@ BrowserID.Mocks.xhr = (function() {
       "get /wsapi/list_emails no_identities": [],
       "get /wsapi/list_emails ajaxError": undefined,
       // Used in conjunction with registration to do a complete userflow
-      "get /wsapi/list_emails complete": {"registered@testuser.com":{}}
+      "get /wsapi/list_emails complete": {"registered@testuser.com":{}},
+      "post /wsapi/update_password valid": { success: true },
+      "post /wsapi/update_password incorrectPassword": { success: false },
+      "post /wsapi/update_password invalid": undefined
     },
 
     setContextInfo: function(field, value) {
@@ -145,7 +142,18 @@ BrowserID.Mocks.xhr = (function() {
         ok(false, "missing csrf token on POST request");
       }
 
-      var resName = req.type + " " + req.url + " " + xhr.resultType;
+
+      var resultType = xhr.resultType;
+
+      // Unless the contextAjaxError is specified, use the "valid" context info.
+      // This makes it so we do not have to keep adding new items for
+      // context_info for every possible result type.
+      if(req.url === "/wsapi/session_context" && resultType !== "contextAjaxError") {
+        resultType = "valid";
+      }
+
+      var resName = req.type + " " + req.url + " " + resultType;
+
       var result = xhr.results[resName];
 
       var type = typeof result;
diff --git a/resources/static/test/qunit/pages/manage_account_unit_test.js b/resources/static/test/qunit/pages/manage_account_unit_test.js
index 1906a5919202ad69d3eefc8934f9b5e8dfa1edd5..0c18b7e66161c0e440133638c21566a354908d13 100644
--- a/resources/static/test/qunit/pages/manage_account_unit_test.js
+++ b/resources/static/test/qunit/pages/manage_account_unit_test.js
@@ -44,6 +44,7 @@
       testHelpers = bid.TestHelpers,
       validToken = true,
       TEST_ORIGIN = "http://browserid.org",
+      tooltip = bid.Tooltip,
       mocks = {
         confirm: function() { return true; },
         document: { location: "" }
@@ -165,4 +166,73 @@
       });
     });
   });
+
+  asyncTest("changePassword with missing old password, expect tooltip", function() {
+    bid.manageAccount(mocks, function() {
+      $("#old_password").val("");
+      $("#new_password").val("newpassword");
+
+      bid.manageAccount.changePassword(function(status) {
+        equal(status, false, "on missing old password, status is false");
+        equal(tooltip.shown, true, "tooltip is visible");
+        start();
+      });
+    });
+  });
+
+  asyncTest("changePassword with missing new password, expect tooltip", function() {
+    bid.manageAccount(mocks, function() {
+      $("#old_password").val("oldpassword");
+      $("#new_password").val("");
+
+      bid.manageAccount.changePassword(function(status) {
+        equal(status, false, "on missing new password, status is false");
+        equal(tooltip.shown, true, "tooltip is visible");
+        start();
+      });
+    });
+  });
+
+  asyncTest("changePassword with incorrect old password, expect tooltip", function() {
+    bid.manageAccount(mocks, function() {
+      xhr.useResult("incorrectPassword");
+
+      $("#old_password").val("incorrectpassword");
+      $("#new_password").val("newpassword");
+
+      bid.manageAccount.changePassword(function(status) {
+        equal(status, false, "on incorrect old password, status is false");
+        equal(tooltip.shown, true, "tooltip is visible");
+        start();
+      });
+    });
+  });
+
+  asyncTest("changePassword with XHR error, expect error message", function() {
+    bid.manageAccount(mocks, function() {
+      xhr.useResult("invalid");
+
+      $("#old_password").val("oldpassword");
+      $("#new_password").val("newpassword");
+
+      bid.manageAccount.changePassword(function(status) {
+        equal(status, false, "on xhr error, status is false");
+        start();
+      });
+    });
+  });
+
+  asyncTest("changePassword happy case", function() {
+    bid.manageAccount(mocks, function() {
+      $("#old_password").val("oldpassword");
+      $("#new_password").val("newpassword");
+
+      bid.manageAccount.changePassword(function(status) {
+        equal(status, true, "on proper completion, status is true");
+        equal(tooltip.shown, false, "on proper completion, tooltip is not shown");
+        start();
+      });
+    });
+  });
+
 }());
diff --git a/resources/static/test/qunit/shared/network_unit_test.js b/resources/static/test/qunit/shared/network_unit_test.js
index d8d3fa46745c3111a52e938a9058458ebe17e288..00c342dc2d26a973c74ae732e0040216b5c8a847 100644
--- a/resources/static/test/qunit/shared/network_unit_test.js
+++ b/resources/static/test/qunit/shared/network_unit_test.js
@@ -546,63 +546,6 @@
     failureCheck(network.requestPasswordReset, "address", "origin");
   });
 
-  wrappedAsyncTest("resetPassword", function() {
-    network.resetPassword("password", function onSuccess() {
-      // XXX need a test here;
-      ok(true);
-      wrappedStart();
-    }, function onFailure() {
-      ok(false);
-      wrappedStart();
-    });
-
-  });
-
-  wrappedAsyncTest("resetPassword with XHR failure", function() {
-    xhr.useResult("ajaxError");
-/*
-    the body of this function is not yet written
-
-    network.resetPassword("password", function onSuccess() {
-      ok(false, "XHR failure should never call success");
-      wrappedStart();
-    }, function onFailure() {
-      ok(true, "XHR failure should always call failure");
-      wrappedStart();
-    });
-*/
-    start();
-  });
-
-  wrappedAsyncTest("changePassword", function() {
-    network.changePassword("oldpassword", "newpassword", function onSuccess() {
-      // XXX need a real wrappedAsyncTest here.
-      ok(true);
-      wrappedStart();
-    }, function onFailure() {
-      ok(false);
-      wrappedStart();
-    });
-
-  });
-
-  wrappedAsyncTest("changePassword with XHR failure", function() {
-    xhr.useResult("ajaxError");
-
-    /*
-    the body of this function is not yet written.
-    network.changePassword("oldpassword", "newpassword", function onSuccess() {
-      ok(false, "XHR failure should never call success");
-      wrappedStart();
-    }, function onFailure() {
-      ok(true, "XHR failure should always call failure");
-      wrappedStart();
-    });
-
-    */
-    start();
-  });
-
   wrappedAsyncTest("serverTime", function() {
     // I am forcing the server time to be 1.25 seconds off.
     xhr.setContextInfo("server_time", new Date().getTime() - 1250);
@@ -662,4 +605,38 @@
     });
 
   });
+
+  asyncTest("changePassword happy case, expect complete callback with true status", function() {
+    network.changePassword("oldpassword", "newpassword", function onComplete(status) {
+      equal(status, true, "calls onComplete with true status");
+      start();
+    }, function onFailure() {
+      ok(false, "unexpected failure");
+      start();
+    });
+  });
+
+  asyncTest("changePassword with incorrect old password, expect complete callback with false status", function() {
+    xhr.useResult("incorrectPassword");
+
+    network.changePassword("oldpassword", "newpassword", function onComplete(status) {
+      equal(status, false, "calls onComplete with false status");
+      start();
+    }, function onFailure() {
+      ok(false, "unexpected failure");
+      start();
+    });
+  });
+
+  asyncTest("changePassword with XHR error, expect error callback", function() {
+    xhr.useResult("ajaxError");
+
+    network.changePassword("oldpassword", "newpassword", function onComplete() {
+      ok(false, "XHR failure should never call complete");
+      start();
+    }, function onFailure() {
+      ok(true, "XHR failure should always call failure");
+      start();
+    });
+  });
 }());
diff --git a/resources/static/test/qunit/shared/tooltip_unit_test.js b/resources/static/test/qunit/shared/tooltip_unit_test.js
index 6c5d7e359aa030f9675044e89f58296794d22bb5..1c3bb4065c284e2c291e615155157e235cfdea0e 100644
--- a/resources/static/test/qunit/shared/tooltip_unit_test.js
+++ b/resources/static/test/qunit/shared/tooltip_unit_test.js
@@ -76,4 +76,15 @@
     });
   });
 
+  asyncTest("show tooltip, then reset - hides tooltip, resets shown status", function() {
+    tooltip.showTooltip("#shortTooltip");
+    setTimeout(function() {
+      tooltip.reset();
+
+      equal($(".tooltip:visible").length, 0, "after reset, all tooltips are hidden");
+      equal(tooltip.shown, false, "after reset, tooltip status is reset");
+      start();
+    }, 100);
+  });
+
 }());
diff --git a/resources/static/test/qunit/testHelpers/helpers.js b/resources/static/test/qunit/testHelpers/helpers.js
index d7ca0c676660680ba8737649b1fa02ba827b4cfc..aa0601edd49076bb6cc5aef74c52949f440cb6a2 100644
--- a/resources/static/test/qunit/testHelpers/helpers.js
+++ b/resources/static/test/qunit/testHelpers/helpers.js
@@ -5,6 +5,7 @@
       storage = bid.Storage,
       xhr = bid.Mocks.xhr,
       screens = bid.Screens,
+      tooltip = bid.Tooltip,
       registrations = [];
       calls = {};
 
@@ -49,6 +50,7 @@
       mediator.reset();
       screens.wait.hide();
       screens.error.hide();
+      tooltip.reset();
     },
 
     teardown: function() {
@@ -59,6 +61,7 @@
       $("#error").html("<div class='contents'></div>").hide();
       screens.wait.hide();
       screens.error.hide();
+      tooltip.reset();
     },
 
     register: register,
diff --git a/resources/views/index.ejs b/resources/views/index.ejs
index 46cae5c26fa0a3bfe6856940f8437bff1614f065..9d9aea739112578bb45d68478ad9551920e336e3 100644
--- a/resources/views/index.ejs
+++ b/resources/views/index.ejs
@@ -5,15 +5,45 @@
 
       <div id="manage">
           <h1 class="serif">Account Manager</h1>
-          <div class="buttonrow cf">
-              <strong>Your Email Addresses</strong>
-
-              <button id="manageAccounts" href="#">edit</button>
-              <button id="cancelManage" href="#">done</button>
-          </div>
-          <ul id="emailList">
-          </ul>
-          <div id="disclaimer">You may, at any time, <a href="#" id="cancelAccount">cancel your account</a></div>
+
+          <section>
+            <header class="buttonrow cf">
+                <h2>Your Email Addresses</h2>
+
+                <button class="edit">edit</button>
+                <button class="done">done</button>
+            </header>
+
+            <ul id="emailList">
+            </ul>
+          </section>
+
+          <section id="edit_password">
+            <header class="buttonrow cf">
+              <h2>Password</h2>
+
+              <button class="edit">edit</button>
+              <button class="done">cancel</button>
+            </header>
+
+            <div class="showedit">
+              <label for="old_password">Old Password</label>
+              <label for="new_password">New Password</label>
+            </div>
+
+            <form id="edit_password_form" class="showedit">
+              <input type="password" id="old_password" name="old_password" placeholder="old password"/>
+              <input type="password" id="new_password" name="new_password" placeholder="new password"/>
+              <button id="changePassword">done</button>
+
+              <div class="tooltip" for="old_password" id="tooltipOldRequired">Old password is required</div>
+              <div class="tooltip" for="old_password" id="tooltipInvalidPassword">Incorrect old password, password not updated</div>
+              <div class="tooltip" for="new_password" id="tooltipNewRequired">New password is required</div>
+            </form>
+          </section>
+
+
+          <p id="disclaimer">You may, at any time, <a href="#" id="cancelAccount">cancel your account</a></p>
       </div>
   </div>