Bug 753099 Update peptest to work with global compartments change r=ctalbert
authorMark Cote <mcote@mozilla.com>
Wed, 09 May 2012 13:59:31 -0700
changeset 93626 65b5a34ffb7f432eb546e281de0c459dab4435d9
parent 93625 6d551fea3297099963df21c3c816371e89a22c61
child 93627 8a8cadee668f0e801e4489be832ffdb3dc4c30ca
push id9237
push userctalbert@mozilla.com
push dateWed, 09 May 2012 21:02:30 +0000
treeherdermozilla-inbound@65b5a34ffb7f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersctalbert
bugs753099
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 753099 Update peptest to work with global compartments change r=ctalbert
testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
testing/peptest/peptest/extension/resource/mozmill/driver/elementslib.js
testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
testing/peptest/peptest/extension/resource/mozmill/driver/mozmill.js
testing/peptest/peptest/extension/resource/mozmill/driver/msgbroker.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/arrays.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/dom.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/objects.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/os.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/strings.js
testing/peptest/peptest/extension/resource/mozmill/stdlib/utils.js
testing/peptest/setup.py
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/controller.js
@@ -1,100 +1,138 @@
-// ***** 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 Corporation Code.
-//
-// The Initial Developer of the Original Code is
-// Adam Christian.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-//
-// Contributor(s):
-//  Adam Christian <adam.christian@gmail.com>
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-//  Henrik Skupin <hskupin@mozilla.com>
-//  Aaron Train <atrain@mozilla.com>
-//
-// 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 *****
+/* 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/. */
+
+var EXPORTED_SYMBOLS = ["MozMillController", "globalEventRegistry",
+                        "sleep", "windowMap"];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
 
-var EXPORTED_SYMBOLS = ["MozMillController", "globalEventRegistry", "sleep"];
-
-var EventUtils = {}; Components.utils.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
+var EventUtils = {}; Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
 
-var utils = {}; Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
-var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
-var mozelement = {}; Components.utils.import('resource://mozmill/driver/mozelement.js', mozelement);
-var broker = {}; Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
+var broker = {}; Cu.import('resource://mozmill/driver/msgbroker.js', broker);
+var elementslib = {}; Cu.import('resource://mozmill/driver/elementslib.js', elementslib);
+var mozelement = {}; Cu.import('resource://mozmill/driver/mozelement.js', mozelement);
+var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
 
-var hwindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
-                .getService(Components.interfaces.nsIAppShellService)
-                .hiddenDOMWindow;
-var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].
-     getService(Components.interfaces.nsIConsoleService);
+var hwindow = Cc["@mozilla.org/appshell/appShellService;1"]
+              .getService(Ci.nsIAppShellService).hiddenDOMWindow;
+var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
+                      .getService(Ci.nsIConsoleService);
 
 // Declare most used utils functions in the controller namespace
 var sleep = utils.sleep;
 var assert = utils.assert;
 var waitFor = utils.waitFor;
 
-waitForEvents = function() {}
+
+// The window map which is used to store information e.g. loaded state of each
+// open chrome and content window.
+var windowMap = {
+  _windows : { },
+
+  /**
+   * Check if a given window id is contained in the map of windows
+   *
+   * @param {Number} aWindowId
+   *        Outer ID of the window to check.
+   * @returns {Boolean} True if the window is part of the map, otherwise false.
+   */
+  contains : function (aWindowId) {
+    return (aWindowId in this._windows);
+  },
+
+  /**
+   * Retrieve the value of the specified window's property.
+   *
+   * @param {Number} aWindowId
+   *        Outer ID of the window to check.
+   * @param {String} aProperty
+   *        Property to retrieve the value from
+   * @return {Object} Value of the window's property
+   */
+  getValue : function (aWindowId, aProperty) {
+    if (!this.contains(aWindowId)) {
+      return undefined;
+    } else {
+      var win = this._windows[aWindowId];
+
+      return (aProperty in win) ? win[aProperty]
+                                : undefined;
+    }
+  },
+
+  /**
+   * Remove the entry for a given window
+   *
+   * @param {Number} aWindowId
+   *        Outer ID of the window to check.
+   */
+  remove : function (aWindowId) {
+    if (this.contains(aWindowId))
+      delete this._windows[aWindowId];
+    //dump("* current map: " + JSON.stringify(this._windows) + "\n");
+  },
+
+  /**
+   * Update the property value of a given window
+   *
+   * @param {Number} aWindowId
+   *        Outer ID of the window to check.
+   * @param {String} aProperty
+   *        Property to update the value for
+   * @param {Object} 
+   *        Value to set
+   */
+  update : function (aWindowId, aProperty, aValue) {
+    if (!this.contains(aWindowId))
+      this._windows[aWindowId] = { };
+
+    this._windows[aWindowId][aProperty] = aValue;
+    //dump("* current map: " + JSON.stringify(this._windows) + "\n");
+  }
+}
+
+
+waitForEvents = function () {
+}
 
 waitForEvents.prototype = {
   /**
    * Initialize list of events for given node
    */
-  init : function waitForEvents_init(node, events) {
+  init: function waitForEvents_init(node, events) {
     if (node.getNode != undefined)
       node = node.getNode();
 
     this.events = events;
     this.node = node;
     node.firedEvents = {};
     this.registry = {};
 
-    for each(e in events) {
-      var listener = function(event) {
+    for each (var e in events) {
+      var listener = function (event) {
         this.firedEvents[event.type] = true;
       }
+
       this.registry[e] = listener;
       this.registry[e].result = false;
       this.node.addEventListener(e, this.registry[e], true);
     }
   },
 
   /**
    * Wait until all assigned events have been fired
    */
-  wait : function waitForEvents_wait(timeout, interval)
-  {
+  wait: function waitForEvents_wait(timeout, interval) {
     for (var e in this.registry) {
-      utils.waitFor(function() {
+      utils.waitFor(function () {
         return this.node.firedEvents[e] == true;
       }, "Timeout happened before event '" + ex +"' was fired.", timeout, interval);
 
       this.node.removeEventListener(e, this.registry[e], true);
     }
   }
 }
 
@@ -105,83 +143,82 @@ waitForEvents.prototype = {
  * @param {MozMillController} controller
  *        Mozmill controller of the window under test
  * @param {string} menuSelector
  *        jQuery like selector string of the element
  * @param {object} document
  *        Document to use for finding the menu
  *        [optional - default: aController.window.document]
  */
-var Menu = function(controller, menuSelector, document) {
+var Menu = function (controller, menuSelector, document) {
   this._controller = controller;
   this._menu = null;
 
   document = document || controller.window.document;
   var node = document.querySelector(menuSelector);
   if (node) {
     // We don't unwrap nodes automatically yet (Bug 573185)
     node = node.wrappedJSObject || node;
     this._menu = new mozelement.Elem(node);
-  }
-  else {
+  } else {
     throw new Error("Menu element '" + menuSelector + "' not found.");
   }
 }
 
 Menu.prototype = {
 
   /**
    * Open and populate the menu
    *
    * @param {ElemBase} contextElement
    *        Element whose context menu has to be opened
    * @returns {Menu} The Menu instance
    */
-  open : function(contextElement) {
+  open: function Menu_open(contextElement) {
     // We have to open the context menu
     var menu = this._menu.getNode();
     if ((menu.localName == "popup" || menu.localName == "menupopup") &&
         contextElement && contextElement.exists()) {
       this._controller.rightClick(contextElement);
-      this._controller.waitFor(function() {
+      this._controller.waitFor(function () {
         return menu.state == "open";
       }, "Context menu has been opened.");
     }
 
     // Run through the entire menu and populate with dynamic entries
     this._buildMenu(menu);
 
     return this;
   },
 
   /**
    * Close the menu
    *
    * @returns {Menu} The Menu instance
    */
-  close : function() {
+  close: function Menu_close() {
     var menu = this._menu.getNode();
 
     this._controller.keypress(this._menu, "VK_ESCAPE", {});
-    this._controller.waitFor(function() {
+    this._controller.waitFor(function () {
       return menu.state == "closed";
     }, "Context menu has been closed.");
 
     return this;
   },
 
   /**
    * Retrieve the specified menu entry
    *
    * @param {string} itemSelector
    *        jQuery like selector string of the menu item
    * @returns {ElemBase} Menu element
    * @throws Error If menu element has not been found
    */
-  getItem : function(itemSelector) {
+  getItem: function Menu_getItem(itemSelector) {
     var node = this._menu.getNode().querySelector(itemSelector);
 
     if (!node) {
       throw new Error("Menu entry '" + itemSelector + "' not found.");
     }
 
     return new mozelement.Elem(node);
   },
@@ -189,147 +226,154 @@ Menu.prototype = {
   /**
    * Click the specified menu entry
    *
    * @param {string} itemSelector
    *        jQuery like selector string of the menu item
    *
    * @returns {Menu} The Menu instance
    */
-  click : function(itemSelector) {
+  click: function Menu_click(itemSelector) {
     this._controller.click(this.getItem(itemSelector));
 
     return this;
   },
 
   /**
    * Synthesize a keypress against the menu
    *
    * @param {string} key
    *        Key to press
    * @param {object} modifier
    *        Key modifiers
    * @see MozMillController#keypress
    *
    * @returns {Menu} The Menu instance
    */
-  keypress : function(key, modifier) {
+  keypress: function Menu_keypress(key, modifier) {
     this._controller.keypress(this._menu, key, modifier);
 
     return this;
   },
 
   /**
    * Opens the context menu, click the specified entry and
    * make sure that the menu has been closed.
    *
    * @param {string} itemSelector
    *        jQuery like selector string of the element
    * @param {ElemBase} contextElement
    *        Element whose context menu has to be opened
    *
    * @returns {Menu} The Menu instance
    */
-  select : function(itemSelector, contextElement) {
+  select: function Menu_select(itemSelector, contextElement) {
     this.open(contextElement);
     this.click(itemSelector);
     this.close();
   },
 
   /**
    * Recursive function which iterates through all menu elements and
    * populates the menus with dynamic menu entries.
    *
    * @param {node} menu
    *        Top menu node whose elements have to be populated
    */
-  _buildMenu : function(menu) {
+  _buildMenu: function Menu__buildMenu(menu) {
     var items = menu ? menu.childNodes : null;
 
-    Array.forEach(items, function(item) {
+    Array.forEach(items, function (item) {
       // When we have a menu node, fake a click onto it to populate
       // the sub menu with dynamic entries
       if (item.tagName == "menu") {
         var popup = item.querySelector("menupopup");
+
         if (popup) {
           if (popup.allowevents) {
             var popupEvent = this._controller.window.document.createEvent("MouseEvent");
-            popupEvent.initMouseEvent("popupshowing", true, true, this._controller.window, 0,
-                                             0, 0, 0, 0, false, false, false, false, 0, null);
+            popupEvent.initMouseEvent("popupshowing", true, true,
+                                      this._controller.window, 0, 0, 0, 0, 0,
+                                      false, false, false, false, 0, null);
             popup.dispatchEvent(popupEvent);
           }
+
           this._buildMenu(popup);
         }
       }
     }, this);
   }
 };
 
 var MozMillController = function (window) {
   this.window = window;
 
   this.mozmillModule = {};
-  Components.utils.import('resource://mozmill/driver/mozmill.js', this.mozmillModule);
+  Cu.import('resource://mozmill/driver/mozmill.js', this.mozmillModule);
 
-  utils.waitFor(function() {
+  utils.waitFor(function () {
     return window != null && this.isLoaded();
   }, "controller(): Window could not be initialized.", undefined, undefined, this);
 
-  if ( controllerAdditions[window.document.documentElement.getAttribute('windowtype')] != undefined ) {
+  var windowType = window.document.documentElement.getAttribute('windowtype');
+  if (controllerAdditions[windowType] != undefined ) {
     this.prototype = new utils.Copy(this.prototype);
-    controllerAdditions[window.document.documentElement.getAttribute('windowtype')](this);
-    this.windowtype = window.document.documentElement.getAttribute('windowtype');
+    controllerAdditions[windowType](this);
+    this.windowtype = windowType;
   }
 }
 
 // constructs a MozMillElement from the controller's window
-MozMillController.prototype.__defineGetter__("rootElement", function() {
-  if (this._rootElement == undefined)
-    this._rootElement = new mozelement.MozMillElement(undefined, undefined, {'element': this.window.document.documentElement});
+MozMillController.prototype.__defineGetter__("rootElement", function () {
+  if (this._rootElement == undefined) {
+    this._rootElement = new mozelement.MozMillElement(undefined, undefined,
+                                                      {'element': this.window.document.documentElement});
+  }
+
   return this._rootElement;
 });
 
 MozMillController.prototype.sleep = utils.sleep;
 
 // Open the specified url in the current tab
-MozMillController.prototype.open = function(url)
-{
-  switch(this.mozmillModule.Application) {
+MozMillController.prototype.open = function (url) {
+  switch (this.mozmillModule.Application) {
     case "Firefox":
-      this.window.gBrowser.loadURI(url);
-      break;
     case "SeaMonkey":
       this.window.getBrowser().loadURI(url);
       break;
     default:
       throw new Error("MozMillController.open not supported.");
   }
 
   broker.pass({'function':'Controller.open()'});
 }
 
 /**
  * Take a screenshot of specified node
- *
+ * 
  * @param {element} node
  *   the window or DOM element to capture
  * @param {string} name
  *   the name of the screenshot used in reporting and as filename
  * @param {boolean} save
  *   if true saves the screenshot as 'name.png' in tempdir, otherwise returns a dataURL
  * @param {element list} highlights
  *   a list of DOM elements to highlight by drawing a red rectangle around them
  */
 MozMillController.prototype.screenShot = function _screenShot(node, name, save, highlights) {
   if (!node) {
     throw new Error("node is undefined");
   }
 
   // Unwrap the node and highlights
-  if ("getNode" in node) node = node.getNode();
+  if ("getNode" in node) {
+    node = node.getNode();
+  }
+
   if (highlights) {
     for (var i = 0; i < highlights.length; ++i) {
       if ("getNode" in highlights[i]) {
         highlights[i] = highlights[i].getNode();
       }
     }
   }
 
@@ -341,698 +385,798 @@ MozMillController.prototype.screenShot =
       filepath = utils.takeScreenshot(node, name, highlights);
     } else {
       dataURL = utils.takeScreenshot(node, undefined, highlights);
     }
   } catch (e) {
     throw new Error("controller.screenShot() failed: " + e);
   }
 
-  // Create a timestamp
-  var d = new Date();
   // Report object
-  var obj = { "filepath": filepath,
-              "dataURL": dataURL,
-              "name": name,
-              "timestamp": d.toLocaleString(),
-            }
+  var obj = {"filepath": filepath,
+             "dataURL": dataURL,
+             "name": name,
+             "timestamp": new Date().toLocaleString()};
+
   // Send the screenshot object to python over jsbridge
   broker.sendMessage("screenShot", obj);
-  broker.pass({'function':'controller.screenShot()'});
+  broker.pass({'function': 'controller.screenShot()'});
 }
 
 /**
  * Checks if the specified window has been loaded
  *
- * @param {DOMWindow} [window=this.window] Window object to check for loaded state
+ * @param {DOMWindow} [aWindow=this.window] Window object to check for loaded state
  */
-MozMillController.prototype.isLoaded = function(window) {
-  var win = window || this.window;
+MozMillController.prototype.isLoaded = function (aWindow) {
+  var win = aWindow || this.window;
 
-  return ("mozmillDocumentLoaded" in win) && win.mozmillDocumentLoaded;
+  var id = utils.getWindowId(win);
+  return windowMap.contains(id) && windowMap.getValue(id, "loaded");
 };
 
-MozMillController.prototype.waitFor = function(callback, message, timeout,
-                                               interval, thisObject) {
+MozMillController.prototype.waitFor = function (callback, message, timeout,
+                                                interval, thisObject) {
   utils.waitFor(callback, message, timeout, interval, thisObject);
-
   broker.pass({'function':'controller.waitFor()'});
 }
 
-MozMillController.prototype.__defineGetter__("waitForEvents", function() {
-  if (this._waitForEvents == undefined)
+MozMillController.prototype.__defineGetter__("waitForEvents", function () {
+  if (this._waitForEvents == undefined) {
     this._waitForEvents = new waitForEvents();
+  }
+
   return this._waitForEvents;
 });
 
 /**
  * Wrapper function to create a new instance of a menu
  * @see Menu
  */
 MozMillController.prototype.getMenu = function (menuSelector, document) {
   return new Menu(this, menuSelector, document);
 };
 
-MozMillController.prototype.__defineGetter__("mainMenu", function() {
+MozMillController.prototype.__defineGetter__("mainMenu", function () {
   return this.getMenu("menubar");
 });
 
-MozMillController.prototype.__defineGetter__("menus", function() {
-        throw('controller.menus - DEPRECATED Use controller.mainMenu instead.');
-
+MozMillController.prototype.__defineGetter__("menus", function () {
+  logDeprecated('controller.menus', 'Use controller.mainMenu instead');
 });
 
 MozMillController.prototype.waitForImage = function (elem, timeout, interval) {
-  this.waitFor(function() {
+  this.waitFor(function () {
     return elem.getNode().complete == true;
   }, "timeout exceeded for waitForImage " + elem.getInfo(), timeout, interval);
 
   broker.pass({'function':'Controller.waitForImage()'});
 }
 
 MozMillController.prototype.startUserShutdown = function (timeout, restart, next, resetProfile) {
   if (restart && resetProfile) {
-      throw new Error("You can't have a user-restart and reset the profile; there is a race condition");
+    throw new Error("You can't have a user-restart and reset the profile; there is a race condition");
   }
+
   broker.sendMessage('userShutdown', {'user': true,
-                                  'restart': Boolean(restart),
-                                  'next': next,
-                                  'resetProfile': Boolean(resetProfile)});
+                                      'restart': Boolean(restart),
+                                      'next': next,
+                                      'resetProfile': Boolean(resetProfile)});
   this.window.setTimeout(broker.sendMessage, timeout, 'userShutdown', 0);
 }
 
-MozMillController.prototype.restartApplication = function (next, resetProfile)
-{
+MozMillController.prototype.restartApplication = function (next, resetProfile) {
   // restart the application via the python runner
   // - next : name of the next test function to run after restart
   // - resetProfile : whether to reset the profile after restart
   broker.sendMessage('userShutdown', {'user': false,
-                                  'restart': true,
-                                  'next': next,
-                                  'resetProfile': Boolean(resetProfile)});
+                                      'restart': true,
+                                      'next': next,
+                                      'resetProfile': Boolean(resetProfile)});
   broker.sendMessage('endTest');
   broker.sendMessage('persist');
   utils.getMethodInWindows('goQuitApplication')();
 }
 
-MozMillController.prototype.stopApplication = function (resetProfile)
-{
+MozMillController.prototype.stopApplication = function (resetProfile) {
   // stop the application via the python runner
   // - resetProfile : whether to reset the profile after shutdown
   broker.sendMessage('userShutdown', {'user': false,
-                                  'restart': false,
-                                  'resetProfile': Boolean(resetProfile)});
+                                      'restart': false,
+                                      'resetProfile': Boolean(resetProfile)});
   broker.sendMessage('endTest');
   broker.sendMessage('persist');
   utils.getMethodInWindows('goQuitApplication')();
 }
 
 //Browser navigation functions
-MozMillController.prototype.goBack = function(){
+MozMillController.prototype.goBack = function () {
   this.window.content.history.back();
   broker.pass({'function':'Controller.goBack()'});
+
   return true;
 }
-MozMillController.prototype.goForward = function(){
+
+MozMillController.prototype.goForward = function () {
   this.window.content.history.forward();
   broker.pass({'function':'Controller.goForward()'});
+
   return true;
 }
-MozMillController.prototype.refresh = function(){
+
+MozMillController.prototype.refresh = function () {
   this.window.content.location.reload(true);
   broker.pass({'function':'Controller.refresh()'});
+
   return true;
 }
 
 function logDeprecated(funcName, message) {
-   broker.log({'function': funcName + '() - DEPRECATED', 'message': funcName + '() is deprecated' + message});
+  broker.log({'function': funcName + '() - DEPRECATED',
+              'message': funcName + '() is deprecated. ' + message});
 }
 
 function logDeprecatedAssert(funcName) {
-   logDeprecated('controller.' + funcName, '. use the generic `assert` module instead');
+   logDeprecated('controller.' + funcName,
+                 '. Use the generic `assertion` module instead.');
 }
 
 MozMillController.prototype.assertText = function (el, text) {
   logDeprecatedAssert("assertText");
-  //this.window.focus();
+
   var n = el.getNode();
 
-  if (n && n.innerHTML == text){
-    broker.pass({'function':'Controller.assertText()'});
-    return true;
-   }
+  if (n && n.innerHTML == text) {
+    broker.pass({'function': 'Controller.assertText()'});
+  } else {
+    throw new Error("could not validate element " + el.getInfo() +
+                    " with text "+ text);
+  }
 
-  throw new Error("could not validate element " + el.getInfo()+" with text "+ text);
-  return false;
-
+  return true;
 };
 
-//Assert that a specified node exists
+/**
+ * Assert that a specified node exists
+ */
 MozMillController.prototype.assertNode = function (el) {
   logDeprecatedAssert("assertNode");
 
   //this.window.focus();
   var element = el.getNode();
-  if (!element){
+  if (!element) {
     throw new Error("could not find element " + el.getInfo());
-    return false;
   }
-  broker.pass({'function':'Controller.assertNode()'});
+
+  broker.pass({'function': 'Controller.assertNode()'});
   return true;
 };
 
-// Assert that a specified node doesn't exist
+/**
+ * Assert that a specified node doesn't exist
+ */
 MozMillController.prototype.assertNodeNotExist = function (el) {
   logDeprecatedAssert("assertNodeNotExist");
 
-  //this.window.focus();
   try {
     var element = el.getNode();
-  } catch(err){
-    broker.pass({'function':'Controller.assertNodeNotExist()'});
-    return true;
+  } catch (e) {
+    broker.pass({'function': 'Controller.assertNodeNotExist()'});
   }
 
   if (element) {
     throw new Error("Unexpectedly found element " + el.getInfo());
-    return false;
   } else {
     broker.pass({'function':'Controller.assertNodeNotExist()'});
-    return true;
   }
+
+  return true;
 };
 
-//Assert that a form element contains the expected value
+/**
+ * Assert that a form element contains the expected value
+ */
 MozMillController.prototype.assertValue = function (el, value) {
   logDeprecatedAssert("assertValue");
 
-  //this.window.focus();
   var n = el.getNode();
 
-  if (n && n.value == value){
-    broker.pass({'function':'Controller.assertValue()'});
-    return true;
+  if (n && n.value == value) {
+    broker.pass({'function': 'Controller.assertValue()'});
+  } else {
+    throw new Error("could not validate element " + el.getInfo() +
+                    " with value " + value);
   }
-  throw new Error("could not validate element " + el.getInfo()+" with value "+ value);
+
   return false;
 };
 
 /**
  * Check if the callback function evaluates to true
  */
-MozMillController.prototype.assert = function(callback, message, thisObject)
-{
+MozMillController.prototype.assert = function (callback, message, thisObject) {
   logDeprecatedAssert("assert");
-  utils.assert(callback, message, thisObject);
 
+  utils.assert(callback, message, thisObject);
   broker.pass({'function': ": controller.assert('" + callback + "')"});
+
   return true;
 }
 
-//Assert that a provided value is selected in a select element
+/**
+ * Assert that a provided value is selected in a select element
+ */
 MozMillController.prototype.assertSelected = function (el, value) {
   logDeprecatedAssert("assertSelected");
 
-  //this.window.focus();
   var n = el.getNode();
   var validator = value;
 
-  if (n && n.options[n.selectedIndex].value == validator){
+  if (n && n.options[n.selectedIndex].value == validator) {
     broker.pass({'function':'Controller.assertSelected()'});
-    return true;
-    }
-  throw new Error("could not assert value for element " + el.getInfo()+" with value "+ value);
-  return false;
+  } else {
+    throw new Error("could not assert value for element " + el.getInfo() +
+                    " with value " + value);
+  }
+
+  return true;
 };
 
-//Assert that a provided checkbox is checked
+/**
+ * Assert that a provided checkbox is checked
+ */
 MozMillController.prototype.assertChecked = function (el) {
   logDeprecatedAssert("assertChecked");
 
-  //this.window.focus();
   var element = el.getNode();
 
-  if (element && element.checked == true){
+  if (element && element.checked == true) {
     broker.pass({'function':'Controller.assertChecked()'});
-    return true;
-    }
-  throw new Error("assert failed for checked element " + el.getInfo());
-  return false;
+  } else {
+    throw new Error("assert failed for checked element " + el.getInfo());
+  }
+
+  return true;
 };
 
-// Assert that a provided checkbox is not checked
+/**
+ * Assert that a provided checkbox is not checked
+ */
 MozMillController.prototype.assertNotChecked = function (el) {
   logDeprecatedAssert("assertNotChecked");
 
   var element = el.getNode();
 
   if (!element) {
     throw new Error("Could not find element" + el.getInfo());
   }
 
-  if (!element.hasAttribute("checked") || element.checked != true){
-    broker.pass({'function':'Controller.assertNotChecked()'});
-    return true;
-    }
-  throw new Error("assert failed for not checked element " + el.getInfo());
-  return false;
+  if (!element.hasAttribute("checked") || element.checked != true) {
+    broker.pass({'function': 'Controller.assertNotChecked()'});
+  } else {
+    throw new Error("assert failed for not checked element " + el.getInfo());
+  }
+
+  return true;
 };
 
 /**
  * Assert that an element's javascript property exists or has a particular value
  *
  * if val is undefined, will return true if the property exists.
  * if val is specified, will return true if the property exists and has the correct value
  */
-MozMillController.prototype.assertJSProperty = function(el, attrib, val) {
+MozMillController.prototype.assertJSProperty = function (el, attrib, val) {
   logDeprecatedAssert("assertJSProperty");
 
   var element = el.getNode();
+
   if (!element){
     throw new Error("could not find element " + el.getInfo());
-    return false;
   }
+
   var value = element[attrib];
-  var res = (value !== undefined && (val === undefined ? true : String(value) == String(val)));
+  var res = (value !== undefined && (val === undefined ? true :
+                                                         String(value) == String(val)));
   if (res) {
     broker.pass({'function':'Controller.assertJSProperty("' + el.getInfo() + '") : ' + val});
   } else {
-    throw new Error("Controller.assertJSProperty(" + el.getInfo() + ") : " +
-                     (val === undefined ? "property '" + attrib + "' doesn't exist" : val + " == " + value));
+    throw new Error("Controller.assertJSProperty(" + el.getInfo() + ") : " + 
+                    (val === undefined ? "property '" + attrib +
+                    "' doesn't exist" : val + " == " + value));
   }
-  return res;
+
+  return true;
 };
 
-/**
+/** 
  * Assert that an element's javascript property doesn't exist or doesn't have a particular value
  *
  * if val is undefined, will return true if the property doesn't exist.
  * if val is specified, will return true if the property doesn't exist or doesn't have the specified value
  */
-MozMillController.prototype.assertNotJSProperty = function(el, attrib, val) {
+MozMillController.prototype.assertNotJSProperty = function (el, attrib, val) {
   logDeprecatedAssert("assertNotJSProperty");
 
   var element = el.getNode();
+
   if (!element){
     throw new Error("could not find element " + el.getInfo());
-    return false;
   }
+
   var value = element[attrib];
   var res = (val === undefined ? value === undefined : String(value) != String(val));
   if (res) {
     broker.pass({'function':'Controller.assertNotProperty("' + el.getInfo() + '") : ' + val});
   } else {
     throw new Error("Controller.assertNotJSProperty(" + el.getInfo() + ") : " +
-                     (val === undefined ? "property '" + attrib + "' exists" : val + " != " + value));
+                    (val === undefined ? "property '" + attrib +
+                    "' exists" : val + " != " + value));
   }
-  return res;
+
+  return true;
 };
 
-/**
+/** 
  * Assert that an element's dom property exists or has a particular value
  *
  * if val is undefined, will return true if the property exists.
  * if val is specified, will return true if the property exists and has the correct value
  */
-MozMillController.prototype.assertDOMProperty = function(el, attrib, val) {
+MozMillController.prototype.assertDOMProperty = function (el, attrib, val) {
   logDeprecatedAssert("assertDOMProperty");
 
   var element = el.getNode();
+
   if (!element){
     throw new Error("could not find element " + el.getInfo());
-    return false;
   }
+
   var value, res = element.hasAttribute(attrib);
   if (res && val !== undefined) {
     value = element.getAttribute(attrib);
     res = (String(value) == String(val));
   }
 
   if (res) {
     broker.pass({'function':'Controller.assertDOMProperty("' + el.getInfo() + '") : ' + val});
   } else {
     throw new Error("Controller.assertDOMProperty(" + el.getInfo() + ") : " +
-                     (val === undefined ? "property '" + attrib + "' doesn't exist" : val + " == " + value));
+                    (val === undefined ? "property '" + attrib +
+                    "' doesn't exist" : val + " == " + value));
   }
-  return res;
+
+  return true;
 };
 
 /**
  * Assert that an element's dom property doesn't exist or doesn't have a particular value
  *
  * if val is undefined, will return true if the property doesn't exist.
  * if val is specified, will return true if the property doesn't exist or doesn't have the specified value
  */
-MozMillController.prototype.assertNotDOMProperty = function(el, attrib, val) {
+MozMillController.prototype.assertNotDOMProperty = function (el, attrib, val) {
   logDeprecatedAssert("assertNotDOMProperty");
 
   var element = el.getNode();
-  if (!element){
+
+  if (!element) {
     throw new Error("could not find element " + el.getInfo());
-    return false;
   }
+
   var value, res = element.hasAttribute(attrib);
   if (res && val !== undefined) {
     value = element.getAttribute(attrib);
     res = (String(value) == String(val));
   }
+
   if (!res) {
     broker.pass({'function':'Controller.assertNotDOMProperty("' + el.getInfo() + '") : ' + val});
   } else {
-    throw new Error("Controller.assertNotDOMProperty(" + el.getInfo() + ") : " +
-                     (val == undefined ? "property '" + attrib + "' exists" : val + " == " + value));
+    throw new Error("Controller.assertNotDOMProperty(" + el.getInfo() + ") : " + 
+                    (val == undefined ? "property '" + attrib +
+                    "' exists" : val + " == " + value));
   }
-  return !res;
+
+  return true;
 };
 
-// deprecated - Use assertNotJSProperty or assertNotDOMProperty instead
-MozMillController.prototype.assertProperty = function(el, attrib, val) {
-  logDeprecatedAssert("assertProperty");
-  return this.assertJSProperty(el, attrib, val);
-};
-
-// deprecated - Use assertNotJSProperty or assertNotDOMProperty instead
-MozMillController.prototype.assertPropertyNotExist = function(el, attrib) {
-  logDeprecatedAssert("assertPropertyNotExist");
-  return this.assertNotJSProperty(el, attrib);
-};
-
-// Assert that a specified image has actually loaded
-// The Safari workaround results in additional requests
-// for broken images (in Safari only) but works reliably
+/**
+ * Assert that a specified image has actually loaded. The Safari workaround results
+ * in additional requests for broken images (in Safari only) but works reliably
+ */
 MozMillController.prototype.assertImageLoaded = function (el) {
   logDeprecatedAssert("assertImageLoaded");
 
-  //this.window.focus();
   var img = el.getNode();
+
   if (!img || img.tagName != 'IMG') {
     throw new Error('Controller.assertImageLoaded() failed.')
     return false;
   }
+
   var comp = img.complete;
   var ret = null; // Return value
 
   // Workaround for Safari -- it only supports the
   // complete attrib on script-created images
   if (typeof comp == 'undefined') {
     test = new Image();
     // If the original image was successfully loaded,
     // src for new one should be pulled from cache
     test.src = img.src;
     comp = test.complete;
   }
 
   // Check the complete attrib. Note the strict
   // equality check -- we don't want undefined, null, etc.
   // --------------------------
-  // False -- Img failed to load in IE/Safari, or is
-  // still trying to load in FF
   if (comp === false) {
+    // False -- Img failed to load in IE/Safari, or is
+    // still trying to load in FF
     ret = false;
+  } else if (comp === true && img.naturalWidth == 0) {
+    // True, but image has no size -- image failed to
+    // load in FF
+    ret = false;
+  } else {
+    // Otherwise all we can do is assume everything's
+    // hunky-dory
+   ret = true;
   }
-  // True, but image has no size -- image failed to
-  // load in FF
-  else if (comp === true && img.naturalWidth == 0) {
-    ret = false;
-  }
-  // Otherwise all we can do is assume everything's
-  // hunky-dory
-  else {
-    ret = true;
-  }
+
   if (ret) {
     broker.pass({'function':'Controller.assertImageLoaded'});
   } else {
     throw new Error('Controller.assertImageLoaded() failed.')
   }
 
-  return ret;
+  return true;
 };
 
-// Drag one element to the top x,y coords of another specified element
+/**
+ * Drag one element to the top x,y coords of another specified element
+ */
 MozMillController.prototype.mouseMove = function (doc, start, dest) {
   // if one of these elements couldn't be looked up
   if (typeof start != 'object'){
     throw new Error("received bad coordinates");
-    return false;
   }
+
   if (typeof dest != 'object'){
     throw new Error("received bad coordinates");
-    return false;
   }
 
-  var triggerMouseEvent = function(element, clientX, clientY) {
+  var triggerMouseEvent = function (element, clientX, clientY) {
     clientX = clientX ? clientX: 0;
     clientY = clientY ? clientY: 0;
 
     // make the mouse understand where it is on the screen
     var screenX = element.boxObject.screenX ? element.boxObject.screenX : 0;
     var screenY = element.boxObject.screenY ? element.boxObject.screenY : 0;
 
     var evt = element.ownerDocument.createEvent('MouseEvents');
     if (evt.initMouseEvent) {
-      evt.initMouseEvent('mousemove', true, true, element.ownerDocument.defaultView, 1, screenX, screenY, clientX, clientY)
-    }
-    else {
-      //LOG.warn("element doesn't have initMouseEvent; firing an event which should -- but doesn't -- have other mouse-event related attributes here, as well as controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown");
+      evt.initMouseEvent('mousemove', true, true, element.ownerDocument.defaultView,
+                         1, screenX, screenY, clientX, clientY);
+    } else {
       evt.initEvent('mousemove', true, true);
     }
+
     element.dispatchEvent(evt);
   };
 
   // Do the initial move to the drag element position
   triggerMouseEvent(doc.body, start[0], start[1]);
   triggerMouseEvent(doc.body, dest[0], dest[1]);
+
   broker.pass({'function':'Controller.mouseMove()'});
   return true;
 }
 
-// Drag an element to the specified offset on another element, firing mouse and drag events.
-// Returns the captured dropEffect. Adapted from EventUtils' synthesizeDrop()
-MozMillController.prototype.dragToElement = function(src, dest, offsetX,
-    offsetY, aWindow, dropEffect, dragData) {
+/**
+ * Drag an element to the specified offset on another element, firing mouse and
+ * drag events. Returns the captured dropEffect.
+ * Adapted from EventUtils' synthesizeDrop()
+ */
+MozMillController.prototype.dragToElement = function (src, dest, offsetX,
+                                                      offsetY, aWindow,
+                                                      dropEffect, dragData) {
   srcElement = src.getNode();
   destElement = dest.getNode();
   aWindow = aWindow || srcElement.ownerDocument.defaultView;
   offsetX = offsetX || 20;
   offsetY = offsetY || 20;
 
   var dataTransfer;
 
-  var trapDrag = function(event) {
+  var trapDrag = function (event) {
     dataTransfer = event.dataTransfer;
-    if(!dragData)
+    if (!dragData)
       return;
 
     for (var i = 0; i < dragData.length; i++) {
       var item = dragData[i];
       for (var j = 0; j < item.length; j++) {
         dataTransfer.mozSetDataAt(item[j].type, item[j].data, i);
       }
     }
+
     dataTransfer.dropEffect = dropEffect || "move";
     event.preventDefault();
     event.stopPropagation();
   }
 
   aWindow.addEventListener("dragstart", trapDrag, true);
-  EventUtils.synthesizeMouse(srcElement, 2, 2, { type: "mousedown" }, aWindow); // fire mousedown 2 pixels from corner of element
+  // Fire mousedown 2 pixels from corner of element
+  EventUtils.synthesizeMouse(srcElement, 2, 2, { type: "mousedown" }, aWindow);
   EventUtils.synthesizeMouse(srcElement, 11, 11, { type: "mousemove" }, aWindow);
   EventUtils.synthesizeMouse(srcElement, offsetX, offsetY, { type: "mousemove" }, aWindow);
   aWindow.removeEventListener("dragstart", trapDrag, true);
 
   var event = aWindow.document.createEvent("DragEvents");
-  event.initDragEvent("dragenter", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
+  event.initDragEvent("dragenter", true, true, aWindow, 0, 0, 0, 0, 0,
+                      false, false, false, false, 0, null, dataTransfer);
   destElement.dispatchEvent(event);
 
   var event = aWindow.document.createEvent("DragEvents");
-  event.initDragEvent("dragover", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
+  event.initDragEvent("dragover", true, true, aWindow, 0, 0, 0, 0, 0,
+                      false, false, false, false, 0, null, dataTransfer);
   if (destElement.dispatchEvent(event)) {
     EventUtils.synthesizeMouse(destElement, offsetX, offsetY, { type: "mouseup" }, aWindow);
     return "none";
   }
 
   event = aWindow.document.createEvent("DragEvents");
-  event.initDragEvent("drop", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
+  event.initDragEvent("drop", true, true, aWindow, 0, 0, 0, 0, 0,
+                      false, false, false, false, 0, null, dataTransfer);
   destElement.dispatchEvent(event);
   EventUtils.synthesizeMouse(destElement, offsetX, offsetY, { type: "mouseup" }, aWindow);
 
   return dataTransfer.dropEffect;
 }
 
 function preferencesAdditions(controller) {
   var mainTabs = controller.window.document.getAnonymousElementByAttribute(controller.window.document.documentElement, 'anonid', 'selector');
   controller.tabs = {};
+
   for (var i = 0; i < mainTabs.childNodes.length; i++) {
     var node  = mainTabs.childNodes[i];
     var obj = {'button':node}
     controller.tabs[i] = obj;
     var label = node.attributes.item('label').value.replace('pane', '');
     controller.tabs[label] = obj;
   }
-  controller.prototype.__defineGetter__("activeTabButton",
-    function () {return mainTabs.getElementsByAttribute('selected', true)[0];
+
+  controller.prototype.__defineGetter__("activeTabButton", function () {
+    return mainTabs.getElementsByAttribute('selected', true)[0];
   })
 }
 
-function Tabs (controller) {
+function Tabs(controller) {
   this.controller = controller;
 }
-Tabs.prototype.getTab = function(index) {
-  return this.controller.window.gBrowser.browsers[index].contentDocument;
+
+Tabs.prototype.getTab = function (index) {
+  return this.controller.window.getBrowser().browsers[index].contentDocument;
 }
-Tabs.prototype.__defineGetter__("activeTab", function() {
-  return this.controller.window.gBrowser.selectedBrowser.contentDocument;
-})
-Tabs.prototype.selectTab = function(index) {
+
+Tabs.prototype.__defineGetter__("activeTab", function () {
+  return this.controller.window.getBrowser().contentDocument;
+});
+
+Tabs.prototype.selectTab = function (index) {
   // GO in to tab manager and grab the tab by index and call focus.
 }
+
 Tabs.prototype.findWindow = function (doc) {
   for (var i = 0; i <= (this.controller.window.frames.length - 1); i++) {
     if (this.controller.window.frames[i].document == doc) {
       return this.controller.window.frames[i];
     }
   }
+
   throw new Error("Cannot find window for document. Doc title == " + doc.title);
 }
-Tabs.prototype.getTabWindow = function(index) {
+
+Tabs.prototype.getTabWindow = function (index) {
   return this.findWindow(this.getTab(index));
 }
+
 Tabs.prototype.__defineGetter__("activeTabWindow", function () {
   return this.findWindow(this.activeTab);
-})
+});
+
 Tabs.prototype.__defineGetter__("length", function () {
-  return this.controller.window.gBrowser.browsers.length;
-})
-Tabs.prototype.__defineGetter__("activeTabIndex", function() {
-  return this.controller.window.gBrowser.tabContainer.selectedIndex;
-})
-Tabs.prototype.selectTabIndex = function(i) {
-  this.controller.window.gBrowser.selectTabAtIndex(i);
+  return this.controller.window.getBrowser().browsers.length;
+});
+
+Tabs.prototype.__defineGetter__("activeTabIndex", function () {
+  return this.controller.window.getBrowser().tabContainer.selectedIndex;
+});
+
+Tabs.prototype.selectTabIndex = function (i) {
+  this.controller.window.getBrowser().selectTabAtIndex(i);
 }
 
 function browserAdditions (controller) {
   controller.tabs = new Tabs(controller);
 
-  controller.waitForPageLoad = function(aDocument, aTimeout, aInterval) {
+  controller.waitForPageLoad = function (aDocument, aTimeout, aInterval) {
     var timeout = aTimeout || 30000;
     var win = null;
 
     // If a user tries to do waitForPageLoad(2000), this will assign the
     // interval the first arg which is most likely what they were expecting
     if (typeof(aDocument) == "number"){
       timeout = aDocument;
     }
 
     // If we have a real document use its default view
     if (aDocument && (typeof(aDocument) === "object") &&
         "defaultView" in aDocument)
       win = aDocument.defaultView;
 
     // If no document has been specified, fallback to the default view of the
     // currently selected tab browser
-    win = win || this.window.gBrowser.selectedBrowser.contentWindow;
+    win = win || this.window.getBrowser().contentWindow;
 
     // Wait until the content in the tab has been loaded
     this.waitFor(function () {
-        var loaded = this.isLoaded(win);
-        var firstRun = !('mozmillWaitForPageLoad' in win);
-        var ret = firstRun && loaded;
-        if (ret) {
-          win.mozmillWaitForPageLoad = true;
-        }
-        return ret;
+      var loaded = this.isLoaded(win);
+      var firstRun = !('mozmillWaitForPageLoad' in win);
+      var ret = firstRun && loaded;
+
+      if (ret) {
+        win.mozmillWaitForPageLoad = true;
+      }
+
+      return ret;
     }, "controller.waitForPageLoad(): Timeout waiting for page loaded.",
         timeout, aInterval, this);
 
     broker.pass({'function':'controller.waitForPageLoad()'});
   }
 }
 
-controllerAdditions = {
+var controllerAdditions = {
   'Browser:Preferences':preferencesAdditions,
-  'navigator:browser'  :browserAdditions,
-}
+  'navigator:browser'  :browserAdditions
+};
+
+/**
+ *  DEPRECATION WARNING
+ *
+ * The following methods have all been DEPRECATED as of Mozmill 2.0
+ */
+MozMillController.prototype.assertProperty = function (el, attrib, val) {
+  logDeprecatedAssert("assertProperty");
+
+  return this.assertJSProperty(el, attrib, val);
+};
+
+MozMillController.prototype.assertPropertyNotExist = function (el, attrib) {
+  logDeprecatedAssert("assertPropertyNotExist");
+  return this.assertNotJSProperty(el, attrib);
+};
 
 /**
  *  DEPRECATION WARNING
  *
  * The following methods have all been DEPRECATED as of Mozmill 2.0
  * Use the MozMillElement object instead (https://developer.mozilla.org/en/Mozmill/Mozmill_Element_Object)
  */
 MozMillController.prototype.select = function (elem, index, option, value) {
-  return elem.select(index, option, value);
+  logDeprecated("controller.select", "Use the MozMillElement object.");
+
+  return elem.select(index, option, value); 
 };
 
-MozMillController.prototype.keypress = function(aTarget, aKey, aModifiers, aExpectedEvent) {
-  if (aTarget == null) { aTarget = this.rootElement; }
+MozMillController.prototype.keypress = function (aTarget, aKey, aModifiers, aExpectedEvent) {
+  logDeprecated("controller.keypress", "Use the MozMillElement object.");
+
+  if (aTarget == null) {
+    aTarget = this.rootElement;
+  }
+
   return aTarget.keypress(aKey, aModifiers, aExpectedEvent);
 }
 
 MozMillController.prototype.type = function (aTarget, aText, aExpectedEvent) {
-  if (aTarget == null) { aTarget = this.rootElement; }
+  logDeprecated("controller.type", "Use the MozMillElement object.");
+
+  if (aTarget == null) {
+    aTarget = this.rootElement;
+  }
 
   var that = this;
   var retval = true;
-  Array.forEach(aText, function(letter) {
+  Array.forEach(aText, function (letter) {
     if (!that.keypress(aTarget, letter, {}, aExpectedEvent)) {
       retval = false; }
   });
 
   return retval;
 }
 
-MozMillController.prototype.mouseEvent = function(aTarget, aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
+MozMillController.prototype.mouseEvent = function (aTarget, aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
+  logDeprecated("controller.mouseEvent", "Use the MozMillElement object.");
+
   return aTarget.mouseEvent(aOffsetX, aOffsetY, aEvent, aExpectedEvent);
 }
 
-MozMillController.prototype.click = function(elem, left, top, expectedEvent) {
+MozMillController.prototype.click = function (elem, left, top, expectedEvent) {
+  logDeprecated("controller.click", "Use the MozMillElement object.");
+
   return elem.click(left, top, expectedEvent);
 }
 
-MozMillController.prototype.doubleClick = function(elem, left, top, expectedEvent) {
+MozMillController.prototype.doubleClick = function (elem, left, top, expectedEvent) {
+  logDeprecated("controller.doubleClick", "Use the MozMillElement object.");
+
   return elem.doubleClick(left, top, expectedEvent);
 }
 
 MozMillController.prototype.mouseDown = function (elem, button, left, top, expectedEvent) {
+  logDeprecated("controller.mouseDown", "Use the MozMillElement object.");
+
   return elem.mouseDown(button, left, top, expectedEvent);
 };
 
 MozMillController.prototype.mouseOut = function (elem, button, left, top, expectedEvent) {
+  logDeprecated("controller.mouseOut", "Use the MozMillElement object.");
+
   return elem.mouseOut(button, left, top, expectedEvent);
 };
 
 MozMillController.prototype.mouseOver = function (elem, button, left, top, expectedEvent) {
+  logDeprecated("controller.mouseOver", "Use the MozMillElement object.");
+
   return elem.mouseOver(button, left, top, expectedEvent);
 };
 
 MozMillController.prototype.mouseUp = function (elem, button, left, top, expectedEvent) {
+  logDeprecated("controller.mouseUp", "Use the MozMillElement object.");
+
   return elem.mouseUp(button, left, top, expectedEvent);
 };
 
-MozMillController.prototype.middleClick = function(elem, left, top, expectedEvent) {
+MozMillController.prototype.middleClick = function (elem, left, top, expectedEvent) {
+  logDeprecated("controller.middleClick", "Use the MozMillElement object.");
+
   return elem.middleClick(elem, left, top, expectedEvent);
 }
 
-MozMillController.prototype.rightClick = function(elem, left, top, expectedEvent) {
+MozMillController.prototype.rightClick = function (elem, left, top, expectedEvent) {
+  logDeprecated("controller.rightClick", "Use the MozMillElement object.");
+
   return elem.rightClick(left, top, expectedEvent);
 }
 
-MozMillController.prototype.check = function(elem, state) {
+MozMillController.prototype.check = function (elem, state) {
+  logDeprecated("controller.check", "Use the MozMillElement object.");
+
   return elem.check(state);
 }
 
-MozMillController.prototype.radio = function(elem) {
+MozMillController.prototype.radio = function (elem) {
+  logDeprecated("controller.radio", "Use the MozMillElement object.");
+
   return elem.select();
 }
 
 MozMillController.prototype.waitThenClick = function (elem, timeout, interval) {
+  logDeprecated("controller.waitThenClick", "Use the MozMillElement object.");
+
   return elem.waitThenClick(timeout, interval);
 }
 
-MozMillController.prototype.waitForElement = function(elem, timeout, interval) {
+MozMillController.prototype.waitForElement = function (elem, timeout, interval) {
+  logDeprecated("controller.waitForElement", "Use the MozMillElement object.");
+
   return elem.waitForElement(timeout, interval);
 }
 
-MozMillController.prototype.waitForElementNotPresent = function(elem, timeout, interval) {
+MozMillController.prototype.waitForElementNotPresent = function (elem, timeout, interval) {
+  logDeprecated("controller.waitForElementNotPresent", "Use the MozMillElement object.");
+
   return elem.waitForElementNotPresent(timeout, interval);
 }
-
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/elementslib.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/elementslib.js
@@ -1,478 +1,525 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Adam Christian.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Adam Christian <adam.christian@gmail.com>
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ["Elem", "ID", "Link", "XPath", "Selector", "Name", "Anon", "AnonXPath",
                         "Lookup", "_byID", "_byName", "_byAttrib", "_byAnonAttrib",
                        ];
 
-var utils = {}; Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
-var strings = {}; Components.utils.import('resource://mozmill/stdlib/strings.js', strings);
-var arrays = {}; Components.utils.import('resource://mozmill/stdlib/arrays.js', arrays);
-var json2 = {}; Components.utils.import('resource://mozmill/stdlib/json2.js', json2);
-var withs = {}; Components.utils.import('resource://mozmill/stdlib/withs.js', withs);
-var dom = {}; Components.utils.import('resource://mozmill/stdlib/dom.js', dom);
-var objects = {}; Components.utils.import('resource://mozmill/stdlib/objects.js', objects);
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
 
-var countQuotes = function(str){
+var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
+var strings = {}; Cu.import('resource://mozmill/stdlib/strings.js', strings);
+var arrays = {}; Cu.import('resource://mozmill/stdlib/arrays.js', arrays);
+var json2 = {}; Cu.import('resource://mozmill/stdlib/json2.js', json2);
+var withs = {}; Cu.import('resource://mozmill/stdlib/withs.js', withs);
+var dom = {}; Cu.import('resource://mozmill/stdlib/dom.js', dom);
+var objects = {}; Cu.import('resource://mozmill/stdlib/objects.js', objects);
+
+var countQuotes = function (str) {
   var count = 0;
   var i = 0;
-  while(i < str.length) {
+
+  while (i < str.length) {
     i = str.indexOf('"', i);
     if (i != -1) {
       count++;
       i++;
     } else {
       break;
     }
   }
+
   return count;
 };
 
 /**
  * smartSplit()
  *
  * Takes a lookup string as input and returns
  * a list of each node in the string
  */
 var smartSplit = function (str) {
   // Ensure we have an even number of quotes
   if (countQuotes(str) % 2 != 0) {
     throw new Error ("Invalid Lookup Expression");
   }
-  
+
   /**
    * This regex matches a single "node" in a lookup string.
    * In otherwords, it matches the part between the two '/'s
    *
    * Regex Explanation:
    * \/ - start matching at the first forward slash
    * ([^\/"]*"[^"]*")* - match as many pairs of quotes as possible until we hit a slash (ignore slashes inside quotes)
    * [^\/]* - match the remainder of text outside of last quote but before next slash
    */
   var re = /\/([^\/"]*"[^"]*")*[^\/]*/g
   var ret = []
   var match = re.exec(str);
+
   while (match != null) {
     ret.push(match[0].replace(/^\//, ""));
     match = re.exec(str);
   }
+
   return ret;
 };
 
 /**
  * defaultDocuments()
  *
  * Returns a list of default documents in which to search for elements
  * if no document is provided
  */
 function defaultDocuments() {
-  var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
-  win = windowManager.getMostRecentWindow("navigator:browser");
-  return [win.gBrowser.selectedBrowser.contentDocument, win.document];
+  var win = Cc['@mozilla.org/appshell/window-mediator;1']
+            .getService(Ci.nsIWindowMediator)
+            .getMostRecentWindow("navigator:browser");
+
+  return [win.getBrowser().contentDocument, win.document];
 };
 
 /**
  * nodeSearch()
  *
  * Takes an optional document, callback and locator string
  * Returns a handle to the located element or null
  */
 function nodeSearch(doc, func, string) {
   if (doc != undefined) {
     var documents = [doc];
   } else {
     var documents = defaultDocuments();
   }
+
   var e = null;
   var element = null;
+
   //inline function to recursively find the element in the DOM, cross frame.
-  var search = function(win, func, string) {
-    if (win == null)
+  var search = function (win, func, string) {
+    if (win == null) {
       return;
+    }
 
     //do the lookup in the current window
     element = func.call(win, string);
-    
+
     if (!element || (element.length == 0)) {
       var frames = win.frames;
-      for (var i=0; i < frames.length; i++) {
+      for (var i = 0; i < frames.length; i++) {
         search(frames[i], func, string);
       }
+    } else {
+      e = element;
     }
-    else { e = element; }
   };
-  
+
   for (var i = 0; i < documents.length; ++i) {
     var win = documents[i].defaultView;
     search(win, func, string);
-    if (e) break;
+    if (e) {
+      break;
+    }
   }
+
   return e;
 };
 
 /**
  * Selector()
  *
  * Finds an element by selector string
  */
 function Selector(_document, selector, index) {
   if (selector == undefined) {
     throw new Error('Selector constructor did not recieve enough arguments.');
   }
+
   this.selector = selector;
+
   this.getNodeForDocument = function (s) {
     return this.document.querySelectorAll(s);
   };
+
   var nodes = nodeSearch(_document, this.getNodeForDocument, this.selector);
+
   return nodes ? nodes[index || 0] : null;
 };
 
 /**
  * ID()
  *
  * Finds an element by ID
  */
 function ID(_document, nodeID) {
   if (nodeID == undefined) {
     throw new Error('ID constructor did not recieve enough arguments.');
   }
+
   this.getNodeForDocument = function (nodeID) {
     return this.document.getElementById(nodeID);
   };
+
   return nodeSearch(_document, this.getNodeForDocument, nodeID);
 };
 
 /**
  * Link()
  *
  * Finds a link by innerHTML
  */
 function Link(_document, linkName) {
   if (linkName == undefined) {
     throw new Error('Link constructor did not recieve enough arguments.');
   }
-  
+
   this.getNodeForDocument = function (linkName) {
-    var getText = function(el){
+    var getText = function (el) {
       var text = "";
-      if (el.nodeType == 3){ //textNode
-        if (el.data != undefined){
+
+      if (el.nodeType == 3) { //textNode
+        if (el.data != undefined) {
           text = el.data;
         } else {
           text = el.innerHTML;
         }
-      text = text.replace(/n|r|t/g, " ");
+
+        text = text.replace(/n|r|t/g, " ");
       }
-      if (el.nodeType == 1){ //elementNode
+      else if (el.nodeType == 1) { //elementNode
         for (var i = 0; i < el.childNodes.length; i++) {
           var child = el.childNodes.item(i);
           text += getText(child);
         }
-        if (el.tagName == "P" || el.tagName == "BR" || el.tagName == "HR" || el.tagName == "DIV") {
-          text += "n";
+
+        if (el.tagName == "P" || el.tagName == "BR" ||
+            el.tagName == "HR" || el.tagName == "DIV") {
+          text += "\n";
         }
       }
+
       return text;
     };
-  
+
     //sometimes the windows won't have this function
-    try { 
-      var links = this.document.getElementsByTagName('a'); }
-    catch(err){ // ADD LOG LINE mresults.write('Error: '+ err, 'lightred'); 
+    try {
+      var links = this.document.getElementsByTagName('a');
+    } catch (e) {
+      // ADD LOG LINE mresults.write('Error: '+ e, 'lightred');
     }
+
     for (var i = 0; i < links.length; i++) {
       var el = links[i];
       //if (getText(el).indexOf(this.linkName) != -1) {
-      if (el.innerHTML.indexOf(linkName) != -1){
+      if (el.innerHTML.indexOf(linkName) != -1) {
         return el;
       }
     }
+
     return null;
   };
-  
+
   return nodeSearch(_document, this.getNodeForDocument, linkName);
 };
 
 /**
  * XPath()
  *
  * Finds an element by XPath
  */
 function XPath(_document, expr) {
   if (expr == undefined) {
     throw new Error('XPath constructor did not recieve enough arguments.');
   }
-  
+
   this.getNodeForDocument = function (s) {
     var aNode = this.document;
     var aExpr = s;
     var xpe = null;
 
     if (this.document.defaultView == null) {
       xpe = new getMethodInWindows('XPathEvaluator')();
     } else {
       xpe = new this.document.defaultView.XPathEvaluator();
     }
-    var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement : aNode.ownerDocument.documentElement);
+
+    var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement
+                                                                      : aNode.ownerDocument.documentElement);
     var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
     var found = [];
     var res;
-    while (res = result.iterateNext())
+
+    while (res = result.iterateNext()) {
       found.push(res);
+    }
+
     return found[0];
   };
+
   return nodeSearch(_document, this.getNodeForDocument, expr);
 };
 
 /**
  * Name()
  *
  * Finds an element by Name
  */
 function Name(_document, nName) {
   if (nName == undefined) {
     throw new Error('Name constructor did not recieve enough arguments.');
   }
+
   this.getNodeForDocument = function (s) {
     try{
       var els = this.document.getElementsByName(s);
-      if (els.length > 0) { return els[0]; }
+      if (els.length > 0) {
+        return els[0];
+      }
+    } catch (e) {
     }
-    catch(err){};
+
     return null;
   };
+
   return nodeSearch(_document, this.getNodeForDocument, nName);
 };
 
 
 var _returnResult = function (results) {
   if (results.length == 0) {
     return null
-  } else if (results.length == 1) {
+  }
+  else if (results.length == 1) {
     return results[0];
   } else {
     return results;
   }
 }
+
 var _forChildren = function (element, name, value) {
   var results = [];
   var nodes = [e for each (e in element.childNodes) if (e)]
+
   for (var i in nodes) {
     var n = nodes[i];
     if (n[name] == value) {
       results.push(n);
     }
   }
+
   return results;
 }
+
 var _forAnonChildren = function (_document, element, name, value) {
   var results = [];
   var nodes = [e for each (e in _document.getAnoymousNodes(element)) if (e)];
+
   for (var i in nodes ) {
     var n = nodes[i];
     if (n[name] == value) {
       results.push(n);
     }
   }
+
   return results;
 }
+
 var _byID = function (_document, parent, value) {
   return _returnResult(_forChildren(parent, 'id', value));
 }
+
 var _byName = function (_document, parent, value) {
   return _returnResult(_forChildren(parent, 'tagName', value));
 }
+
 var _byAttrib = function (parent, attributes) {
   var results = [];
+  var nodes = parent.childNodes;
 
-  var nodes = parent.childNodes;
   for (var i in nodes) {
     var n = nodes[i];
     requirementPass = 0;
     requirementLength = 0;
+
     for (var a in attributes) {
       requirementLength++;
       try {
         if (n.getAttribute(a) == attributes[a]) {
           requirementPass++;
         }
-      } catch (err) {
+      } catch (e) {
         // Workaround any bugs in custom attribute crap in XUL elements
       }
     }
+
     if (requirementPass == requirementLength) {
       results.push(n);
     }
   }
+
   return _returnResult(results)
 }
+
 var _byAnonAttrib = function (_document, parent, attributes) {
   var results = [];
-  
+
   if (objects.getLength(attributes) == 1) {
-    for (var i in attributes) {var k = i; var v = attributes[i]; }
-    var result = _document.getAnonymousElementByAttribute(parent, k, v)
+    for (var i in attributes) {
+      var k = i;
+      var v = attributes[i];
+    }
+
+    var result = _document.getAnonymousElementByAttribute(parent, k, v);
     if (result) {
       return result;
-      
-    } 
+    }
   }
+
   var nodes = [n for each (n in _document.getAnonymousNodes(parent)) if (n.getAttribute)];
+
   function resultsForNodes (nodes) {
     for (var i in nodes) {
       var n = nodes[i];
       requirementPass = 0;
       requirementLength = 0;
+
       for (var a in attributes) {
         requirementLength++;
         if (n.getAttribute(a) == attributes[a]) {
           requirementPass++;
         }
       }
+
       if (requirementPass == requirementLength) {
         results.push(n);
       }
     }
-  }  
-  resultsForNodes(nodes)  
+  }
+
+  resultsForNodes(nodes);
   if (results.length == 0) {
     resultsForNodes([n for each (n in parent.childNodes) if (n != undefined && n.getAttribute)])
   }
+
   return _returnResult(results)
 }
+
 var _byIndex = function (_document, parent, i) {
   if (parent instanceof Array) {
     return parent[i];
   }
+
   return parent.childNodes[i];
 }
+
 var _anonByName = function (_document, parent, value) {
   return _returnResult(_forAnonChildren(_document, parent, 'tagName', value));
 }
+
 var _anonByAttrib = function (_document, parent, value) {
   return _byAnonAttrib(_document, parent, value);
 }
+
 var _anonByIndex = function (_document, parent, i) {
   return _document.getAnonymousNodes(parent)[i];
 }
 
 /**
  * Lookup()
  *
  * Finds an element by Lookup expression
  */
-function Lookup (_document, expression) {
+function Lookup(_document, expression) {
   if (expression == undefined) {
     throw new Error('Lookup constructor did not recieve enough arguments.');
   }
 
   var expSplit = [e for each (e in smartSplit(expression) ) if (e != '')];
-  expSplit.unshift(_document)
+  expSplit.unshift(_document);
+
   var nCases = {'id':_byID, 'name':_byName, 'attrib':_byAttrib, 'index':_byIndex};
   var aCases = {'name':_anonByName, 'attrib':_anonByAttrib, 'index':_anonByIndex};
-  
- 
+
   var reduceLookup = function (parent, exp) {
     // Handle case where only index is provided
     var cases = nCases;
-    
+
     // Handle ending index before any of the expression gets mangled
     if (withs.endsWith(exp, ']')) {
       var expIndex = json2.JSON.parse(strings.vslice(exp, '[', ']'));
     }
+
     // Handle anon
     if (withs.startsWith(exp, 'anon')) {
-      var exp = strings.vslice(exp, '(', ')');
-      var cases = aCases;
+      exp = strings.vslice(exp, '(', ')');
+      cases = aCases;
     }
+
     if (withs.startsWith(exp, '[')) {
       try {
         var obj = json2.JSON.parse(strings.vslice(exp, '[', ']'));
-      } catch (err) {
-        throw new Error(err+'. String to be parsed was || '+strings.vslice(exp, '[', ']')+' ||');
+      } catch (e) {
+        throw new Error(e + '. String to be parsed was || ' +
+                        strings.vslice(exp, '[', ']') + ' ||');
       }
+
       var r = cases['index'](_document, parent, obj);
       if (r == null) {
-        throw new Error('Expression "'+exp+'" returned null. Anonymous == '+(cases == aCases));
+        throw new Error('Expression "' + exp +
+                        '" returned null. Anonymous == ' + (cases == aCases));
       }
+
       return r;
     }
-    
+
     for (var c in cases) {
       if (withs.startsWith(exp, c)) {
         try {
           var obj = json2.JSON.parse(strings.vslice(exp, '(', ')'))
-        } catch(err) {
-           throw new Error(err+'. String to be parsed was || '+strings.vslice(exp, '(', ')')+'  ||');
+        } catch (e) {
+           throw new Error(e + '. String to be parsed was || ' +
+                           strings.vslice(exp, '(', ')') + '  ||');
         }
         var result = cases[c](_document, parent, obj);
       }
     }
-    
+
     if (!result) {
       if ( withs.startsWith(exp, '{') ) {
         try {
-          var obj = json2.JSON.parse(exp)
-        } catch(err) {
-          throw new Error(err+'. String to be parsed was || '+exp+' ||');
+          var obj = json2.JSON.parse(exp);
+        } catch (e) {
+          throw new Error(e + '. String to be parsed was || ' + exp + ' ||');
         }
-        
+
         if (cases == aCases) {
-          var result = _anonByAttrib(_document, parent, obj)
+          var result = _anonByAttrib(_document, parent, obj);
         } else {
-          var result = _byAttrib(parent, obj)
+          var result = _byAttrib(parent, obj);
         }
       }
+
       if (!result) {
-        throw new Error('Expression "'+exp+'" returned null. Anonymous == '+(cases == aCases));
+        throw new Error('Expression "' + exp +
+                        '" returned null. Anonymous == ' + (cases == aCases));
       }
     }
-    
+
     // Final return
     if (expIndex) {
       // TODO: Check length and raise error
       return result[expIndex];
     } else {
       // TODO: Check length and raise error
       return result;
     }
+
     // Maybe we should cause an exception here
     return false;
   };
+
   return expSplit.reduce(reduceLookup);
 };
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/mozelement.js
@@ -1,55 +1,27 @@
-/* ***** 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 Mozmill Elements.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation
- *
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Andrew Halberstadt <halbersa@gmail.com>
- *
- * 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 ***** */
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ["Elem", "Selector", "ID", "Link", "XPath", "Name", "Lookup",
                         "MozMillElement", "MozMillCheckBox", "MozMillRadio", "MozMillDropList",
                         "MozMillTextBox", "subclasses",
                        ];
 
-var EventUtils = {};  Components.utils.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
-var utils = {};       Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
-var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
-var broker = {};      Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
+const NAMESPACE_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+var EventUtils = {};  Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
+
+var broker = {};      Cu.import('resource://mozmill/driver/msgbroker.js', broker);
+var elementslib = {}; Cu.import('resource://mozmill/driver/elementslib.js', elementslib);
+var utils = {};       Cu.import('resource://mozmill/stdlib/utils.js', utils);
 
 // A list of all the subclasses available.  Shared modules can push their own subclasses onto this list
 var subclasses = [MozMillCheckBox, MozMillRadio, MozMillDropList, MozMillTextBox];
 
 /**
  * createInstance()
  *
  * Returns an new instance of a MozMillElement
@@ -59,100 +31,108 @@ function createInstance(locatorType, loc
   if (elem) {
     var args = { "element": elem,
                  "document": document };
     for (var i = 0; i < subclasses.length; ++i) {
       if (subclasses[i].isType(elem)) {
         return new subclasses[i](locatorType, locator, args);
       }
     }
-    if (MozMillElement.isType(elem)) return new MozMillElement(locatorType, locator, args);
+
+    if (MozMillElement.isType(elem)) {
+      return new MozMillElement(locatorType, locator, args);
+    }
   }
+
   throw new Error("could not find element " + locatorType + ": " + locator);
 };
 
-var Elem = function(node) {
+var Elem = function (node) {
   return createInstance("Elem", node, node);
 };
 
-var Selector = function(document, selector, index) {
+var Selector = function (document, selector, index) {
   return createInstance("Selector", selector, elementslib.Selector(document, selector, index), document);
 };
 
-var ID = function(document, nodeID) {
+var ID = function (document, nodeID) {
   return createInstance("ID", nodeID, elementslib.ID(document, nodeID), document);
 };
 
-var Link = function(document, linkName) {
+var Link = function (document, linkName) {
   return createInstance("Link", linkName, elementslib.Link(document, linkName), document);
 };
 
-var XPath = function(document, expr) {
+var XPath = function (document, expr) {
   return createInstance("XPath", expr, elementslib.XPath(document, expr), document);
 };
 
-var Name = function(document, nName) {
+var Name = function (document, nName) {
   return createInstance("Name", nName, elementslib.Name(document, nName), document);
 };
 
-var Lookup = function(document, expression) {
+var Lookup = function (document, expression) {
   return createInstance("Lookup", expression, elementslib.Lookup(document, expression), document);
 };
 
-
 /**
  * MozMillElement
  * The base class for all mozmill elements
  */
 function MozMillElement(locatorType, locator, args) {
   args = args || {};
   this._locatorType = locatorType;
   this._locator = locator;
   this._element = args["element"];
   this._document = args["document"];
   this._owner = args["owner"];
   // Used to maintain backwards compatibility with controller.js
   this.isElement = true;
 }
 
 // Static method that returns true if node is of this element type
-MozMillElement.isType = function(node) {
+MozMillElement.isType = function (node) {
   return true;
 };
 
 // This getter is the magic behind lazy loading (note distinction between _element and element)
-MozMillElement.prototype.__defineGetter__("element", function() {
+MozMillElement.prototype.__defineGetter__("element", function () {
   if (this._element == undefined) {
     if (elementslib[this._locatorType]) {
       this._element = elementslib[this._locatorType](this._document, this._locator);
-    } else if (this._locatorType == "Elem") {
+    }
+    else if (this._locatorType == "Elem") {
       this._element = this._locator;
     } else {
       throw new Error("Unknown locator type: " + this._locatorType);
     }
   }
+
   return this._element;
 });
 
 // Returns the actual wrapped DOM node
-MozMillElement.prototype.getNode = function() {
+MozMillElement.prototype.getNode = function () {
   return this.element;
 };
 
-MozMillElement.prototype.getInfo = function() {
+MozMillElement.prototype.getInfo = function () {
   return this._locatorType + ": " + this._locator;
 };
 
 /**
  * Sometimes an element which once existed will no longer exist in the DOM
  * This function re-searches for the element
  */
-MozMillElement.prototype.exists = function() {
+MozMillElement.prototype.exists = function () {
   this._element = undefined;
-  if (this.element) return true;
+  if (this.element) {
+    return true;
+  }
+
   return false;
 };
 
 /**
  * Synthesize a keypress event on the given element
  *
  * @param {string} aKey
  *        Key to use for synthesizing the keypress event. It can be a simple
@@ -170,33 +150,36 @@ MozMillElement.prototype.exists = functi
  *                  shiftKey   - Hold down the shift key
  *                               [optional - default: false]
  * @param {object} aExpectedEvent
  *        Information about the expected event to occur
  *        Elements: target     - Element which should receive the event
  *                               [optional - default: current element]
  *                  type       - Type of the expected key event
  */
-MozMillElement.prototype.keypress = function(aKey, aModifiers, aExpectedEvent) {
+MozMillElement.prototype.keypress = function (aKey, aModifiers, aExpectedEvent) {
   if (!this.element) {
     throw new Error("Could not find element " + this.getInfo());
   }
 
-  var win = this.element.ownerDocument? this.element.ownerDocument.defaultView : this.element;
+  var win = this.element.ownerDocument ? this.element.ownerDocument.defaultView
+                                       : this.element;
   this.element.focus();
 
   if (aExpectedEvent) {
-    var target = aExpectedEvent.target? aExpectedEvent.target.getNode() : this.element;
+    var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
+                                       : this.element;
     EventUtils.synthesizeKeyExpectEvent(aKey, aModifiers || {}, target, aExpectedEvent.type,
-                                                            "MozMillElement.keypress()", win);
+                                        "MozMillElement.keypress()", win);
   } else {
     EventUtils.synthesizeKey(aKey, aModifiers || {}, win);
   }
 
   broker.pass({'function':'MozMillElement.keypress()'});
+
   return true;
 };
 
 
 /**
  * Synthesize a general mouse event on the given element
  *
  * @param {ElemBase} aTarget
@@ -225,172 +208,191 @@ MozMillElement.prototype.keypress = func
  *                               'mouseup', 'mouseover', 'mouseout')
  *                               [optional - default: 'mousedown' + 'mouseup']
  * @param {object} aExpectedEvent
  *        Information about the expected event to occur
  *        Elements: target     - Element which should receive the event
  *                               [optional - default: current element]
  *                  type       - Type of the expected mouse event
  */
-MozMillElement.prototype.mouseEvent = function(aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
+MozMillElement.prototype.mouseEvent = function (aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
   if (!this.element) {
     throw new Error(arguments.callee.name + ": could not find element " + this.getInfo());
   }
 
   // If no offset is given we will use the center of the element to click on.
   var rect = this.element.getBoundingClientRect();
   if (isNaN(aOffsetX)) {
     aOffsetX = rect.width / 2;
   }
+
   if (isNaN(aOffsetY)) {
     aOffsetY = rect.height / 2;
   }
 
   // Scroll element into view otherwise the click will fail
   if (this.element.scrollIntoView) {
     this.element.scrollIntoView();
   }
 
   if (aExpectedEvent) {
     // The expected event type has to be set
-    if (!aExpectedEvent.type)
+    if (!aExpectedEvent.type) {
       throw new Error(arguments.callee.name + ": Expected event type not specified");
+    }
 
     // If no target has been specified use the specified element
-    var target = aExpectedEvent.target ? aExpectedEvent.target.getNode() : this.element;
+    var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
+                                       : this.element;
     if (!target) {
-      throw new Error(arguments.callee.name + ": could not find element " + aExpectedEvent.target.getInfo());
+      throw new Error(arguments.callee.name + ": could not find element " +
+                      aExpectedEvent.target.getInfo());
     }
 
     EventUtils.synthesizeMouseExpectEvent(this.element, aOffsetX, aOffsetY, aEvent,
                                           target, aExpectedEvent.event,
                                           "MozMillElement.mouseEvent()",
                                           this.element.ownerDocument.defaultView);
   } else {
     EventUtils.synthesizeMouse(this.element, aOffsetX, aOffsetY, aEvent,
                                this.element.ownerDocument.defaultView);
   }
+
+  return true;
 };
 
 /**
  * Synthesize a mouse click event on the given element
  */
-MozMillElement.prototype.click = function(left, top, expectedEvent) {
+MozMillElement.prototype.click = function (left, top, expectedEvent) {
   // Handle menu items differently
   if (this.element && this.element.tagName == "menuitem") {
     this.element.click();
   } else {
     this.mouseEvent(left, top, {}, expectedEvent);
   }
 
   broker.pass({'function':'MozMillElement.click()'});
+
+  return true;
 };
 
 /**
  * Synthesize a double click on the given element
  */
-MozMillElement.prototype.doubleClick = function(left, top, expectedEvent) {
+MozMillElement.prototype.doubleClick = function (left, top, expectedEvent) {
   this.mouseEvent(left, top, {clickCount: 2}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.doubleClick()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse down event on the given element
  */
 MozMillElement.prototype.mouseDown = function (button, left, top, expectedEvent) {
   this.mouseEvent(left, top, {button: button, type: "mousedown"}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.mouseDown()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse out event on the given element
  */
 MozMillElement.prototype.mouseOut = function (button, left, top, expectedEvent) {
   this.mouseEvent(left, top, {button: button, type: "mouseout"}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.mouseOut()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse over event on the given element
  */
 MozMillElement.prototype.mouseOver = function (button, left, top, expectedEvent) {
   this.mouseEvent(left, top, {button: button, type: "mouseover"}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.mouseOver()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse up event on the given element
  */
 MozMillElement.prototype.mouseUp = function (button, left, top, expectedEvent) {
   this.mouseEvent(left, top, {button: button, type: "mouseup"}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.mouseUp()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse middle click event on the given element
  */
-MozMillElement.prototype.middleClick = function(left, top, expectedEvent) {
+MozMillElement.prototype.middleClick = function (left, top, expectedEvent) {
   this.mouseEvent(left, top, {button: 1}, expectedEvent);
 
   broker.pass({'function':'MozMillElement.middleClick()'});
+
   return true;
 };
 
 /**
  * Synthesize a mouse right click event on the given element
  */
-MozMillElement.prototype.rightClick = function(left, top, expectedEvent) {
+MozMillElement.prototype.rightClick = function (left, top, expectedEvent) {
   this.mouseEvent(left, top, {type : "contextmenu", button: 2 }, expectedEvent);
 
   broker.pass({'function':'MozMillElement.rightClick()'});
+
   return true;
 };
 
-MozMillElement.prototype.waitForElement = function(timeout, interval) {
+MozMillElement.prototype.waitForElement = function (timeout, interval) {
   var elem = this;
-  utils.waitFor(function() {
+
+  utils.waitFor(function () {
     return elem.exists();
   }, "Timeout exceeded for waitForElement " + this.getInfo(), timeout, interval);
 
   broker.pass({'function':'MozMillElement.waitForElement()'});
 };
 
-MozMillElement.prototype.waitForElementNotPresent = function(timeout, interval) {
+MozMillElement.prototype.waitForElementNotPresent = function (timeout, interval) {
   var elem = this;
-  utils.waitFor(function() {
+
+  utils.waitFor(function () {
     return !elem.exists();
   }, "Timeout exceeded for waitForElementNotPresent " + this.getInfo(), timeout, interval);
 
   broker.pass({'function':'MozMillElement.waitForElementNotPresent()'});
 };
 
-MozMillElement.prototype.waitThenClick = function (timeout, interval, left, top, expectedEvent) {
+MozMillElement.prototype.waitThenClick = function (timeout, interval,
+                                                   left, top, expectedEvent) {
   this.waitForElement(timeout, interval);
   this.click(left, top, expectedEvent);
 };
 
 // Dispatches an HTMLEvent
 MozMillElement.prototype.dispatchEvent = function (eventType, canBubble, modifiers) {
   canBubble = canBubble || true;
   var evt = this.element.ownerDocument.createEvent('HTMLEvents');
   evt.shiftKey = modifiers["shift"];
   evt.metaKey = modifiers["meta"];
   evt.altKey = modifiers["alt"];
   evt.ctrlKey = modifiers["ctrl"];
   evt.initEvent(eventType, canBubble, true);
+
   this.element.dispatchEvent(evt);
 };
 
 
 //---------------------------------------------------------------------------------------------------------------------------------------
 
 
 /**
@@ -400,53 +402,55 @@ MozMillElement.prototype.dispatchEvent =
 MozMillCheckBox.prototype = new MozMillElement();
 MozMillCheckBox.prototype.parent = MozMillElement.prototype;
 MozMillCheckBox.prototype.constructor = MozMillCheckBox;
 function MozMillCheckBox(locatorType, locator, args) {
   this.parent.constructor.call(this, locatorType, locator, args);
 }
 
 // Static method returns true if node is this type of element
-MozMillCheckBox.isType = function(node) {
+MozMillCheckBox.isType = function (node) {
   if ((node.localName.toLowerCase() == "input" && node.getAttribute("type") == "checkbox") ||
       (node.localName.toLowerCase() == 'toolbarbutton' && node.getAttribute('type') == 'checkbox') ||
       (node.localName.toLowerCase() == 'checkbox')) {
     return true;
   }
+
   return false;
 };
 
 /**
  * Enable/Disable a checkbox depending on the target state
  */
-MozMillCheckBox.prototype.check = function(state) {
+MozMillCheckBox.prototype.check = function (state) {
   var result = false;
 
   if (!this.element) {
     throw new Error("could not find element " + this.getInfo());
-    return false;
   }
 
   // If we have a XUL element, unwrap its XPCNativeWrapper
-  if (this.element.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
+  if (this.element.namespaceURI == NAMESPACE_XUL) {
     this.element = utils.unwrapNode(this.element);
   }
 
   state = (typeof(state) == "boolean") ? state : false;
   if (state != this.element.checked) {
     this.click();
     var element = this.element;
-    utils.waitFor(function() {
+
+    utils.waitFor(function () {
       return element.checked == state;
     }, "Checkbox " + this.getInfo() + " could not be checked/unchecked", 500);
 
     result = true;
   }
 
-  broker.pass({'function':'MozMillCheckBox.check(' + this.getInfo() + ', state: ' + state + ')'});
+  broker.pass({'function':'MozMillCheckBox.check(' + this.getInfo() +
+               ', state: ' + state + ')'});
   return result;
 };
 
 //----------------------------------------------------------------------------------------------------------------------------------------
 
 
 /**
  * MozMillRadio
@@ -455,55 +459,58 @@ MozMillCheckBox.prototype.check = functi
 MozMillRadio.prototype = new MozMillElement();
 MozMillRadio.prototype.parent = MozMillElement.prototype;
 MozMillRadio.prototype.constructor = MozMillRadio;
 function MozMillRadio(locatorType, locator, args) {
   this.parent.constructor.call(this, locatorType, locator, args);
 }
 
 // Static method returns true if node is this type of element
-MozMillRadio.isType = function(node) {
+MozMillRadio.isType = function (node) {
   if ((node.localName.toLowerCase() == 'input' && node.getAttribute('type') == 'radio') ||
       (node.localName.toLowerCase() == 'toolbarbutton' && node.getAttribute('type') == 'radio') ||
       (node.localName.toLowerCase() == 'radio') ||
       (node.localName.toLowerCase() == 'radiogroup')) {
     return true;
   }
+
   return false;
 };
 
 /**
  * Select the given radio button
  *
  * index - Specifies which radio button in the group to select (only applicable to radiogroup elements)
  *         Defaults to the first radio button in the group
  */
-MozMillRadio.prototype.select = function(index) {
+MozMillRadio.prototype.select = function (index) {
   if (!this.element) {
     throw new Error("could not find element " + this.getInfo());
   }
 
   if (this.element.localName.toLowerCase() == "radiogroup") {
     var element = this.element.getElementsByTagName("radio")[index || 0];
     new MozMillRadio("Elem", element).click();
   } else {
     var element = this.element;
     this.click();
   }
 
-  utils.waitFor(function() {
+  utils.waitFor(function () {
     // If we have a XUL element, unwrap its XPCNativeWrapper
-    if (element.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
+    if (element.namespaceURI == NAMESPACE_XUL) {
       element = utils.unwrapNode(element);
       return element.selected == true;
     }
+
     return element.checked == true;
   }, "Radio button " + this.getInfo() + " could not be selected", 500);
 
   broker.pass({'function':'MozMillRadio.select(' + this.getInfo() + ')'});
+
   return true;
 };
 
 //----------------------------------------------------------------------------------------------------------------------------------------
 
 
 /**
  * MozMillDropList
@@ -512,23 +519,24 @@ MozMillRadio.prototype.select = function
 MozMillDropList.prototype = new MozMillElement();
 MozMillDropList.prototype.parent = MozMillElement.prototype;
 MozMillDropList.prototype.constructor = MozMillDropList;
 function MozMillDropList(locatorType, locator, args) {
   this.parent.constructor.call(this, locatorType, locator, args);
 };
 
 // Static method returns true if node is this type of element
-MozMillDropList.isType = function(node) {
+MozMillDropList.isType = function (node) {
   if ((node.localName.toLowerCase() == 'toolbarbutton' && (node.getAttribute('type') == 'menu' || node.getAttribute('type') == 'menu-button')) ||
       (node.localName.toLowerCase() == 'menu') ||
       (node.localName.toLowerCase() == 'menulist') ||
       (node.localName.toLowerCase() == 'select' )) {
     return true;
   }
+
   return false;
 };
 
 /* Select the specified option and trigger the relevant events of the element */
 MozMillDropList.prototype.select = function (indx, option, value) {
   if (!this.element){
     throw new Error("Could not find element " + this.getInfo());
   }
@@ -541,16 +549,17 @@ MozMillDropList.prototype.select = funct
     if (indx != undefined) {
       // Resetting a menulist has to be handled separately
       if (indx == -1) {
         this.dispatchEvent('focus', false);
         this.element.selectedIndex = indx;
         this.dispatchEvent('change', true);
 
         broker.pass({'function':'MozMillDropList.select()'});
+
         return true;
       } else {
         item = this.element.options.item(indx);
       }
     } else {
       for (var i = 0; i < this.element.options.length; i++) {
         var entry = this.element.options.item(i);
         if (option != undefined && entry.innerHTML == option ||
@@ -564,39 +573,40 @@ MozMillDropList.prototype.select = funct
     // Click the item
     try {
       // EventUtils.synthesizeMouse doesn't work.
       this.dispatchEvent('focus', false);
       item.selected = true;
       this.dispatchEvent('change', true);
 
       broker.pass({'function':'MozMillDropList.select()'});
+
       return true;
-    } catch (ex) {
+    } catch (e) {
       throw new Error("No item selected for element " + this.getInfo());
-      return false;
     }
   }
   //if we have a xul menupopup select accordingly
-  else if (this.element.namespaceURI.toLowerCase() == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
+  else if (this.element.namespaceURI.toLowerCase() == NAMESPACE_XUL) {
     var ownerDoc = this.element.ownerDocument;
     // Unwrap the XUL element's XPCNativeWrapper
     this.element = utils.unwrapNode(this.element);
     // Get the list of menuitems
     menuitems = this.element.getElementsByTagName("menupopup")[0].getElementsByTagName("menuitem");
 
     var item = null;
 
     if (indx != undefined) {
       if (indx == -1) {
         this.dispatchEvent('focus', false);
-        this.element.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild = null;
+        this.element.boxObject.QueryInterface(Ci.nsIMenuBoxObject).activeChild = null;
         this.dispatchEvent('change', true);
 
         broker.pass({'function':'MozMillDropList.select()'});
+
         return true;
       } else {
         item = menuitems[indx];
       }
     } else {
       for (var i = 0; i < menuitems.length; i++) {
         var entry = menuitems[i];
         if (option != undefined && entry.label == option ||
@@ -608,30 +618,30 @@ MozMillDropList.prototype.select = funct
     }
 
     // Click the item
     try {
       EventUtils.synthesizeMouse(this.element, 1, 1, {}, ownerDoc.defaultView);
 
       // Scroll down until item is visible
       for (var i = 0; i <= menuitems.length; ++i) {
-        var selected = this.element.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild;
+        var selected = this.element.boxObject.QueryInterface(Ci.nsIMenuBoxObject).activeChild;
         if (item == selected) {
           break;
         }
         EventUtils.synthesizeKey("VK_DOWN", {}, ownerDoc.defaultView);
       }
 
       EventUtils.synthesizeMouse(item, 1, 1, {}, ownerDoc.defaultView);
 
       broker.pass({'function':'MozMillDropList.select()'});
+
       return true;
-    } catch (ex) {
+    } catch (e) {
       throw new Error('No item selected for element ' + this.getInfo());
-      return false;
     }
   }
 };
 
 
 //----------------------------------------------------------------------------------------------------------------------------------------
 
 
@@ -642,22 +652,23 @@ MozMillDropList.prototype.select = funct
 MozMillTextBox.prototype = new MozMillElement();
 MozMillTextBox.prototype.parent = MozMillElement.prototype;
 MozMillTextBox.prototype.constructor = MozMillTextBox;
 function MozMillTextBox(locatorType, locator, args) {
   this.parent.constructor.call(this, locatorType, locator, args);
 };
 
 // Static method returns true if node is this type of element
-MozMillTextBox.isType = function(node) {
+MozMillTextBox.isType = function (node) {
   if ((node.localName.toLowerCase() == 'input' && (node.getAttribute('type') == 'text' || node.getAttribute('type') == 'search')) ||
       (node.localName.toLowerCase() == 'textarea') ||
       (node.localName.toLowerCase() == 'textbox')) {
     return true;
   }
+
   return false;
 };
 
 /**
  * Synthesize keypress events for each character on the given element
  *
  * @param {string} aText
  *        The text to send as single keypress events
@@ -680,24 +691,28 @@ MozMillTextBox.isType = function(node) {
  *                  type       - Type of the expected key event
  */
 MozMillTextBox.prototype.sendKeys = function (aText, aModifiers, aExpectedEvent) {
   if (!this.element) {
     throw new Error("could not find element " + this.getInfo());
   }
 
   var element = this.element;
-  Array.forEach(aText, function(letter) {
-    var win = element.ownerDocument? element.ownerDocument.defaultView : element;
+  Array.forEach(aText, function (letter) {
+    var win = element.ownerDocument ? element.ownerDocument.defaultView
+                                    : element;
     element.focus();
 
     if (aExpectedEvent) {
-      var target = aExpectedEvent.target ? aExpectedEvent.target.getNode() : element;
-      EventUtils.synthesizeKeyExpectEvent(letter, aModifiers || {}, target, aExpectedEvent.type,
-                                                              "MozMillTextBox.sendKeys()", win);
+      var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
+                                         : element;
+      EventUtils.synthesizeKeyExpectEvent(letter, aModifiers || {}, target,
+                                          aExpectedEvent.type,
+                                          "MozMillTextBox.sendKeys()", win);
     } else {
       EventUtils.synthesizeKey(letter, aModifiers || {}, win);
     }
   });
 
   broker.pass({'function':'MozMillTextBox.type()'});
+
   return true;
 };
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/mozmill.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/mozmill.js
@@ -1,153 +1,123 @@
-// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-//  Gary Kwong <nth10sd@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ["controller", "utils", "elementslib", "os",
                         "getBrowserController", "newBrowserController", 
                         "getAddonsController", "getPreferencesController", 
                         "newMail3PaneController", "getMail3PaneController", 
                         "wm", "platform", "getAddrbkController", 
                         "getMsgComposeController", "getDownloadsController",
                         "Application", "cleanQuit", "findElement",
                         "getPlacesController", 'isMac', 'isLinux', 'isWindows',
                         "firePythonCallback"
                        ];
-                        
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
 // imports
-var controller = {};  Components.utils.import('resource://mozmill/driver/controller.js', controller);
-var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
-var broker = {};      Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
-var findElement = {}; Components.utils.import('resource://mozmill/driver/mozelement.js', findElement);
-var utils = {};       Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
-var os = {}; Components.utils.import('resource://mozmill/stdlib/os.js', os);
+var controller = {};  Cu.import('resource://mozmill/driver/controller.js', controller);
+var elementslib = {}; Cu.import('resource://mozmill/driver/elementslib.js', elementslib);
+var broker = {};      Cu.import('resource://mozmill/driver/msgbroker.js', broker);
+var findElement = {}; Cu.import('resource://mozmill/driver/mozelement.js', findElement);
+var utils = {};       Cu.import('resource://mozmill/stdlib/utils.js', utils);
+var os = {}; Cu.import('resource://mozmill/stdlib/os.js', os);
 
 try {
-  Components.utils.import("resource://gre/modules/AddonManager.jsm");
-} catch(e) { /* Firefox 4 only */ }
+  Cu.import("resource://gre/modules/AddonManager.jsm");
+} catch (e) {
+  /* Firefox 4 only */
+}
 
 // platform information
 var platform = os.getPlatform();
 var isMac = false;
 var isWindows = false;
 var isLinux = false;
+
 if (platform == "darwin"){
   isMac = true;
 }
+
 if (platform == "winnt"){
   isWindows = true;
 }
+
 if (platform == "linux"){
   isLinux = true;
 }
 
-var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-           .getService(Components.interfaces.nsIWindowMediator);
-           
-var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
-               .getService(Components.interfaces.nsIXULAppInfo);
+var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
+                      .getService(Ci.nsIConsoleService);
+var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+var locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
+             .getService(Ci.nsIXULChromeRegistry)
+             .getSelectedLocale("global");
+var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
 
-var locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-               .getService(Components.interfaces.nsIXULChromeRegistry)
-               .getSelectedLocale("global");
-
-var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].
-    getService(Components.interfaces.nsIConsoleService);
-
-                       
-applicationDictionary = {
-  "{718e30fb-e89b-41dd-9da7-e25a45638b28}": "Sunbird",    
+const applicationDictionary = {
+  "{718e30fb-e89b-41dd-9da7-e25a45638b28}": "Sunbird",
   "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}": "SeaMonkey",
   "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": "Firefox",
-  "{3550f703-e582-4d05-9a08-453d09bdfdc6}": 'Thunderbird',
-}                 
-                       
+  "{3550f703-e582-4d05-9a08-453d09bdfdc6}": 'Thunderbird'
+};
+
 var Application = applicationDictionary[appInfo.ID];
 
 if (Application == undefined) {
   // Default to Firefox
   var Application = 'Firefox';
 }
 
 // get startup time if available
 // see http://blog.mozilla.com/tglek/2011/04/26/measuring-startup-speed-correctly/
 var startupInfo = {};
 try {
-    var _startupInfo = Components.classes["@mozilla.org/toolkit/app-startup;1"]
-        .getService(Components.interfaces.nsIAppStartup).getStartupInfo();
-    for (var i in _startupInfo) {
-        startupInfo[i] = _startupInfo[i].getTime(); // convert from Date object to ms since epoch
-    }
-} catch(e) {
-    startupInfo = null; 
+  var _startupInfo = Cc["@mozilla.org/toolkit/app-startup;1"]
+                     .getService(Ci.nsIAppStartup).getStartupInfo();
+  for (var i in _startupInfo) {
+    // convert from Date object to ms since epoch
+    startupInfo[i] = _startupInfo[i].getTime();
+  }
+} catch (e) {
+  startupInfo = null;
 }
 
 
 // keep list of installed addons to send to jsbridge for test run report
 var addons = "null"; // this will be JSON parsed
-if(typeof AddonManager != "undefined") {
-  AddonManager.getAllAddons(function(addonList) {
-      var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
-          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+if (typeof AddonManager != "undefined") {
+  AddonManager.getAllAddons(function (addonList) {
+      var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+                      .createInstance(Ci.nsIScriptableUnicodeConverter);
       converter.charset = 'utf-8';
 
       function replacer(key, value) {
-          if (typeof(value) == "string") {
-              try {
-                  return converter.ConvertToUnicode(value);
-              } catch(e) {
-                  var newstring = '';
-                  for (var i=0; i < value.length; i++) {
-                      replacement = '';
-                      if ((32 <= value.charCodeAt(i)) && (value.charCodeAt(i) < 127)) {
-                          // eliminate non-convertable characters;
-                          newstring += value.charAt(i);
-                      } else {
-                          newstring += replacement;
-                      }
-                  }
-                  return newstring;
+        if (typeof(value) == "string") {
+          try {
+            return converter.ConvertToUnicode(value);
+          } catch (e) {
+            var newstring = '';
+            for (var i=0; i < value.length; i++) {
+              replacement = '';
+              if ((32 <= value.charCodeAt(i)) && (value.charCodeAt(i) < 127)) {
+                // eliminate non-convertable characters;
+                newstring += value.charAt(i);
+              } else {
+                newstring += replacement;
               }
+            }
+            return newstring;
           }
-          return value;
+        }
+        return value;
       }
 
       addons = converter.ConvertToUnicode(JSON.stringify(addonList, replacer))
   });
 }
 
 function cleanQuit () {
   utils.getMethodInWindows('goQuitApplication')();
@@ -158,269 +128,307 @@ function addHttpResource (directory, nam
 }
 
 function newBrowserController () {
   return new controller.MozMillController(utils.getMethodInWindows('OpenBrowserWindow')());
 }
 
 function getBrowserController () {
   var browserWindow = wm.getMostRecentWindow("navigator:browser");
+
   if (browserWindow == null) {
     return newBrowserController();
-  }
-  else {
+  } else {
     return new controller.MozMillController(browserWindow);
   }
 }
 
 function getPlacesController () {
   utils.getMethodInWindows('PlacesCommandHook').showPlacesOrganizer('AllBookmarks');
+
   return new controller.MozMillController(wm.getMostRecentWindow(''));
 }
 
 function getAddonsController () {
   if (Application == 'SeaMonkey') {
     utils.getMethodInWindows('toEM')();
-  } else if (Application == 'Thunderbird') {
+  }
+  else if (Application == 'Thunderbird') {
     utils.getMethodInWindows('openAddonsMgr')();
-  } else if (Application == 'Sunbird') {
+  }
+  else if (Application == 'Sunbird') {
     utils.getMethodInWindows('goOpenAddons')();
   } else {
     utils.getMethodInWindows('BrowserOpenAddonsMgr')();
   }
+
   return new controller.MozMillController(wm.getMostRecentWindow(''));
 }
 
 function getDownloadsController() {
   utils.getMethodInWindows('BrowserDownloadsUI')();
+
   return new controller.MozMillController(wm.getMostRecentWindow(''));
 }
 
 function getPreferencesController() {
   if (Application == 'Thunderbird') {
     utils.getMethodInWindows('openOptionsDialog')();
   } else {
     utils.getMethodInWindows('openPreferences')();
   }
+
   return new controller.MozMillController(wm.getMostRecentWindow(''));
 }
 
 // Thunderbird functions
 function newMail3PaneController () {
   return new controller.MozMillController(utils.getMethodInWindows('toMessengerWindow')());
 }
  
 function getMail3PaneController () {
   var mail3PaneWindow = wm.getMostRecentWindow("mail:3pane");
+
   if (mail3PaneWindow == null) {
     return newMail3PaneController();
-  }
-  else {
+  } else {
     return new controller.MozMillController(mail3PaneWindow);
   }
 }
 
 // Thunderbird - Address book window
 function newAddrbkController () {
   utils.getMethodInWindows("toAddressBook")();
   utils.sleep(2000);
   var addyWin = wm.getMostRecentWindow("mail:addressbook");
+
   return new controller.MozMillController(addyWin);
 }
 
 function getAddrbkController () {
   var addrbkWindow = wm.getMostRecentWindow("mail:addressbook");
   if (addrbkWindow == null) {
     return newAddrbkController();
-  }
-  else {
+  } else {
     return new controller.MozMillController(addrbkWindow);
   }
 }
 
 function firePythonCallback (filename, method, args, kwargs) {
   obj = {'filename': filename, 'method': method};
   obj['args'] = args || [];
   obj['kwargs'] = kwargs || {};
+
   broker.sendMessage("firePythonCallback", obj);
 }
 
 function timer (name) {
   this.name = name;
   this.timers = {};
+  this.actions = [];
+
   frame.timers.push(this);
-  this.actions = [];
 }
+
 timer.prototype.start = function (name) {
   this.timers[name].startTime = (new Date).getTime();
-} 
+}
+
 timer.prototype.stop = function (name) {
   var t = this.timers[name];
+
   t.endTime = (new Date).getTime();
   t.totalTime = (t.endTime - t.startTime);
 }
+
 timer.prototype.end = function () {
   frame.events.fireEvent("timer", this);
   frame.timers.remove(this);
 }
 
 // Initialization
 
 /**
  * Console listener which listens for error messages in the console and forwards
  * them to the Mozmill reporting system for output.
  */
 function ConsoleListener() {
  this.register();
 }
+
 ConsoleListener.prototype = {
- observe: function(aMessage) {
-   var msg = aMessage.message;
-   var re = /^\[.*Error:.*(chrome|resource):\/\/.*/i;
-   if (msg.match(re)) {
-     broker.fail(aMessage);
-   }
- },
- QueryInterface: function (iid) {
-	if (!iid.equals(Components.interfaces.nsIConsoleListener) && !iid.equals(Components.interfaces.nsISupports)) {
-		throw Components.results.NS_ERROR_NO_INTERFACE;
-   }
-   return this;
- },
- register: function() {
-   var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                              .getService(Components.interfaces.nsIConsoleService);
-   aConsoleService.registerListener(this);
- },
- unregister: function() {
-   var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
-                              .getService(Components.interfaces.nsIConsoleService);
-   aConsoleService.unregisterListener(this);
+  observe: function (aMessage) {
+    var msg = aMessage.message;
+    var re = /^\[.*Error:.*(chrome|resource):\/\/.*/i;
+    if (msg.match(re)) {
+      broker.fail(aMessage);
+    }
+  },
+
+  QueryInterface: function (iid) {
+    if (!iid.equals(Ci.nsIConsoleListener) && !iid.equals(Ci.nsISupports)) {
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    }
+
+    return this;
+  },
+
+  register: function () {
+    var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
+                          .getService(Ci.nsIConsoleService);
+    aConsoleService.registerListener(this);
+  },
+
+  unregister: function () {
+    var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
+                          .getService(Ci.nsIConsoleService);
+    aConsoleService.unregisterListener(this);
  }
 }
 
 // start listening
 var consoleListener = new ConsoleListener();
-  
-// Observer for new top level windows
-var windowObserver = {
-  observe: function(subject, topic, data) {
-    attachEventListeners(subject);
+
+
+// Observer when a new top-level window is ready
+var windowReadyObserver = {
+  observe: function (aSubject, aTopic, aData) {
+    attachEventListeners(aSubject);
   }
 };
-  
+
+
+// Observer when a top-level window is closed
+var windowCloseObserver = {
+  observe: function (aSubject, aTopic, aData) {
+    controller.windowMap.remove(utils.getWindowId(aSubject));
+  }
+};
+
+
 /**
  * Attach event listeners
+ *
+ * @param {ChromeWindow} aWindow
+ *        Window to attach listeners on.
  */
 function attachEventListeners(aWindow) {
   // These are the event handlers
-  function pageShowHandler(event) {
-    var doc = event.originalTarget;
+  var pageShowHandler = function (aEvent) {
+    var doc = aEvent.originalTarget;
 
     // Only update the flag if we have a document as target
     // see https://bugzilla.mozilla.org/show_bug.cgi?id=690829
     if ("defaultView" in doc) {
-      doc.defaultView.mozmillDocumentLoaded = true;
+      var id = utils.getWindowId(doc.defaultView);
+      controller.windowMap.update(id, "loaded", true);
+      //dump("*** pageshow event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
     }
 
     // We need to add/remove the unload/pagehide event listeners to preserve caching.
-    aWindow.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
-    aWindow.gBrowser.addEventListener("pagehide", pageHideHandler, true);
+    aWindow.getBrowser().addEventListener("beforeunload", beforeUnloadHandler, true);
+    aWindow.getBrowser().addEventListener("pagehide", pageHideHandler, true);
   };
 
-  function DOMContentLoadedHandler(event) {
-    var doc = event.originalTarget;
+  var DOMContentLoadedHandler = function (aEvent) {
+    var doc = aEvent.originalTarget;
 
     var errorRegex = /about:.+(error)|(blocked)\?/;
     if (errorRegex.exec(doc.baseURI)) {
       // Wait about 1s to be sure the DOM is ready
       utils.sleep(1000);
 
       // Only update the flag if we have a document as target
       if ("defaultView" in doc) {
-        doc.defaultView.mozmillDocumentLoaded = true;
+        var id = utils.getWindowId(doc.defaultView);
+        controller.windowMap.update(id, "loaded", true);
+        //dump("*** DOMContentLoaded event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
       }
 
       // We need to add/remove the unload event listener to preserve caching.
-      aWindow.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
+      aWindow.getBrowser().addEventListener("beforeunload", beforeUnloadHandler, true);
     }
   };
-  
+
   // beforeunload is still needed because pagehide doesn't fire before the page is unloaded.
   // still use pagehide for cases when beforeunload doesn't get fired
-  function beforeUnloadHandler(event) {
-    var doc = event.originalTarget;
+  var beforeUnloadHandler = function (aEvent) {
+    var doc = aEvent.originalTarget;
 
     // Only update the flag if we have a document as target
     if ("defaultView" in doc) {
-      doc.defaultView.mozmillDocumentLoaded = false;
+      var id = utils.getWindowId(doc.defaultView);
+      controller.windowMap.update(id, "loaded", false);
+      //dump("*** beforeunload event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
     }
 
-    aWindow.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
+    aWindow.getBrowser().removeEventListener("beforeunload", beforeUnloadHandler, true);
   };
 
-  function pageHideHandler(event) {
+  var pageHideHandler = function (aEvent) {
     // If event.persisted is false, the beforeUnloadHandler should fire
     // and there is no need for this event handler.
-    if (event.persisted) {
-      var doc = event.originalTarget;
+    if (aEvent.persisted) {
+      var doc = aEvent.originalTarget;
 
       // Only update the flag if we have a document as target
       if ("defaultView" in doc) {
-        doc.defaultView.mozmillDocumentLoaded = false;
+        var id = utils.getWindowId(doc.defaultView);
+        controller.windowMap.update(id, "loaded", false);
+        //dump("*** pagehide event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
       }
 
-      aWindow.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
+      aWindow.getBrowser().removeEventListener("beforeunload", beforeUnloadHandler, true);
     }
-
   };
 
-  function onWindowLoaded(event) {
-    aWindow.mozmillDocumentLoaded = true;
+  var onWindowLoaded = function (aEvent) {
+    controller.windowMap.update(utils.getWindowId(aWindow), "loaded", true);
 
-    if ("gBrowser" in aWindow) {
+    let browser = aWindow.getBrowser();
+    if (browser) {
       // Page is ready
-      aWindow.gBrowser.addEventListener("pageshow", pageShowHandler, true);
+      browser.addEventListener("pageshow", pageShowHandler, true);
 
-      // Note: Error pages will never fire a "load" event. For those we
+      // Note: Error pages will never fire a "pageshow" event. For those we
       // have to wait for the "DOMContentLoaded" event. That's the final state.
       // Error pages will always have a baseURI starting with
       // "about:" followed by "error" or "blocked".
-      aWindow.gBrowser.addEventListener("DOMContentLoaded", DOMContentLoadedHandler, true);
-    
+      browser.addEventListener("DOMContentLoaded", DOMContentLoadedHandler, true);
+
       // Leave page (use caching)
-      aWindow.gBrowser.addEventListener("pagehide", pageHideHandler, true);
+      browser.addEventListener("pagehide", pageHideHandler, true);
     }
-
   }
 
   // Add the event handlers to the tabbedbrowser once its window has loaded
   if (aWindow.content) {
     onWindowLoaded();
   } else {
     aWindow.addEventListener("load", onWindowLoaded, false);
   }
 }
-  
+
 /**
  * Initialize Mozmill
  */
 function initialize() {
   // Activate observer for new top level windows
-  var observerService = Components.classes["@mozilla.org/observer-service;1"].
-                        getService(Components.interfaces.nsIObserverService);
-  observerService.addObserver(windowObserver, "toplevel-window-ready", false);
+  var observerService = Cc["@mozilla.org/observer-service;1"].
+                        getService(Ci.nsIObserverService);
+  observerService.addObserver(windowReadyObserver, "toplevel-window-ready", false);
+  observerService.addObserver(windowCloseObserver, "outer-window-destroyed", false);
 
   // Attach event listeners to all open windows
-  var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"].
-                   getService(Components.interfaces.nsIWindowMediator).getEnumerator("");
+  var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"].
+                   getService(Ci.nsIWindowMediator).getEnumerator("");
   while (enumerator.hasMoreElements()) {
     var win = enumerator.getNext();
     attachEventListeners(win);
 
     // For windows or dialogs already open we have to explicitly set the property
-    // otherwise windows which load really quick never gets the property set and
-    // we fail to create the controller
-    win.mozmillDocumentLoaded = true;
-  };
+    // otherwise windows which load really quick on startup never gets the
+    // property set and we fail to create the controller
+    controller.windowMap.update(utils.getWindowId(win), "loaded", true);
+  }
 }
 
 initialize();
--- a/testing/peptest/peptest/extension/resource/mozmill/driver/msgbroker.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/driver/msgbroker.js
@@ -1,58 +1,24 @@
-/* ***** 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 Mozmill.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation
- *
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Andrew Halberstadt <halbersa@gmail.com>
- *
- * 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 ***** */
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['addListener', 'addObject',
                         'removeListener',
                         'sendMessage', 'log', 'pass', 'fail'];
 
 var listeners = {};
 
 // add a listener for a specific message type
 function addListener(msgType, listener) {
-
   if (listeners[msgType] === undefined) {
     listeners[msgType] = [];
   }
+
   listeners[msgType].push(listener);
 }
 
 // add each method in an object as a message listener
 function addObject(object) {
   for (var msgType in object) {
     addListener(msgType, object[msgType]);
   }
@@ -68,16 +34,17 @@ function removeListener(listener) {
     }
   }
 }
 
 function sendMessage(msgType, obj) {
   if (listeners[msgType] === undefined) {
     return;
   }
+
   for (let i = 0; i < listeners[msgType].length; ++i) {
     listeners[msgType][i](obj);
   }
 }
 
 function log(obj) {
   sendMessage('log', obj);
 }
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/EventUtils.js
@@ -1,14 +1,14 @@
 // Export all available functions for Mozmill
 var EXPORTED_SYMBOLS = ["sendMouseEvent", "sendChar", "sendString", "sendKey",
                         "synthesizeMouse", "synthesizeMouseScroll", "synthesizeKey",
                         "synthesizeMouseExpectEvent", "synthesizeKeyExpectEvent",
                         "synthesizeDragStart", "synthesizeDrop", "synthesizeText",
-                        "disableNonTestMouseEvents", "synthesizeComposition", 
+                        "disableNonTestMouseEvents", "synthesizeComposition",
                         "synthesizeQuerySelectedText", "synthesizeQueryTextContent",
                         "synthesizeQueryCaretRect", "synthesizeQueryTextRect",
                         "synthesizeQueryEditorRect", "synthesizeCharAtPoint",
                         "synthesizeSelectionSet"];
 
 /**
  * Get the array with available key events
  */
@@ -32,17 +32,17 @@ function getKeyEvent(aWindow) {
  * object with the properties set that the real mouse event object should
  * have. This includes the type of the mouse event.
  * E.g. to send an click event to the node with id 'node' you might do this:
  *
  * sendMouseEvent({type:'click'}, 'node');
  */
 function sendMouseEvent(aEvent, aTarget, aWindow) {
   if (['click', 'mousedown', 'mouseup', 'mouseover', 'mouseout'].indexOf(aEvent.type) == -1) {
-    throw new Error("sendMouseEvent doesn't know about event type '"+aEvent.type+"'");
+    throw new Error("sendMouseEvent doesn't know about event type '" + aEvent.type + "'");
   }
 
   if (!aWindow) {
     aWindow = window;
   }
 
   if (!(aTarget instanceof Element)) {
     aTarget = aWindow.document.getElementById(aTarget);
@@ -111,28 +111,29 @@ function sendChar(aChar, aTarget) {
 function sendString(aStr, aTarget) {
   for (var i = 0; i < aStr.length; ++i) {
     sendChar(aStr.charAt(i), aTarget);
   }
 }
 
 /**
  * Send the non-character key aKey to the node with id aTarget. If aTarget is
- * not provided, use "target".  The name of the key should be a lowercase
- * version of the part that comes after "DOM_VK_" in the KeyEvent constant
- * name for this key.  No modifiers are handled at this point.
+ * not provided, use "target".
+ * The name of the key should be the part that comes after "DOM_VK_" in the
+ *   KeyEvent constant name for this key.
+ * No modifiers are handled at this point.
  *
  * Returns true if the keypress event was accepted (no calls to preventDefault
  * or anything like that), false otherwise.
  */
 function sendKey(aKey, aTarget, aWindow) {
   if (!aWindow)
     aWindow = window;
 
-  keyName = "DOM_VK_" + aKey.toUpperCase();
+  var keyName = "DOM_VK_" + aKey.toUpperCase();
 
   if (!getKeyEvent(aWindow)[keyName]) {
     throw "Unknown key: " + keyName;
   }
 
   return __doEventDispatch(aTarget, 0, getKeyEvent(aWindow)[keyName], false);
 }
 
@@ -233,17 +234,17 @@ function synthesizeMouse(aTarget, aOffse
     var clickCount = aEvent.clickCount || 1;
     var modifiers = _parseModifiers(aEvent);
 
     var rect = aTarget.getBoundingClientRect();
 
     var left = rect.left + aOffsetX;
     var top = rect.top + aOffsetY;
 
-    if (aEvent.type) {
+    if (("type" in aEvent) && aEvent.type) {
       utils.sendMouseEvent(aEvent.type, left, top, button, clickCount, modifiers);
     }
     else {
       utils.sendMouseEvent("mousedown", left, top, button, clickCount, modifiers);
       utils.sendMouseEvent("mouseup", left, top, button, clickCount, modifiers);
     }
   }
 }
@@ -285,17 +286,17 @@ function synthesizeMouseScroll(aTarget, 
     var button = aEvent.button || 0;
     var modifiers = _parseModifiers(aEvent);
 
     var rect = aTarget.getBoundingClientRect();
 
     var left = rect.left;
     var top = rect.top;
 
-    var type = aEvent.type || "DOMMouseScroll";
+    var type = (("type" in aEvent) && aEvent.type) || "DOMMouseScroll";
     var axis = aEvent.axis || "vertical";
     var scrollFlags = (axis == "horizontal") ? kIsHorizontal : kIsVertical;
     if (aEvent.hasPixels) {
       scrollFlags |= kHasPixels;
     }
     utils.sendMouseScrollEvent(type, left + aOffsetX, top + aOffsetY, button,
                                scrollFlags, aEvent.delta, modifiers);
   }
@@ -327,25 +328,26 @@ function synthesizeKey(aKey, aEvent, aWi
     var keyCode = 0, charCode = 0;
     if (aKey.indexOf("VK_") == 0)
       keyCode = getKeyEvent(aWindow)["DOM_" + aKey];
     else
       charCode = aKey.charCodeAt(0);
 
     var modifiers = _parseModifiers(aEvent);
 
-    if (aEvent.type) {
-      utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
-    }
-    else {
+    if (!("type" in aEvent) || !aEvent.type) {
+      // Send keydown + keypress + keyup events.
       var keyDownDefaultHappened =
           utils.sendKeyEvent("keydown", keyCode, charCode, modifiers);
       utils.sendKeyEvent("keypress", keyCode, charCode, modifiers,
                          !keyDownDefaultHappened);
       utils.sendKeyEvent("keyup", keyCode, charCode, modifiers);
+    } else {
+      // Send standalone event.
+      utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
     }
   }
 }
 
 var _gSeenEvent = false;
 
 /**
  * Indicate that an event with an original target of aExpectedTarget and
@@ -695,16 +697,17 @@ function synthesizeText(aEvent, aWindow)
  *                 the result might be null.
  */
 function synthesizeQuerySelectedText(aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_SELECTED_TEXT, 0, 0, 0, 0);
 }
 
 /**
  * Synthesize a query text content event.
  *
  * @param aOffset  The character offset.  0 means the first character in the
  *                 selection root.
@@ -715,16 +718,17 @@ function synthesizeQuerySelectedText(aWi
  *                 the result might be null.
  */
 function synthesizeQueryTextContent(aOffset, aLength, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_TEXT_CONTENT,
                                      aOffset, aLength, 0, 0);
 }
 
 /**
  * Synthesize a query caret rect event.
  *
  * @param aOffset  The caret offset.  0 means left side of the first character
@@ -734,16 +738,17 @@ function synthesizeQueryTextContent(aOff
  *                 the result might be null.
  */
 function synthesizeQueryCaretRect(aOffset, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_CARET_RECT,
                                      aOffset, 0, 0, 0);
 }
 
 /**
  * Synthesize a query text rect event.
  *
  * @param aOffset  The character offset.  0 means the first character in the
@@ -755,16 +760,17 @@ function synthesizeQueryCaretRect(aOffse
  *                 the result might be null.
  */
 function synthesizeQueryTextRect(aOffset, aLength, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_TEXT_RECT,
                                      aOffset, aLength, 0, 0);
 }
 
 /**
  * Synthesize a query editor rect event.
  *
  * @param aWindow  Optional (If null, current |window| will be used)
@@ -772,16 +778,17 @@ function synthesizeQueryTextRect(aOffset
  *                 the result might be null.
  */
 function synthesizeQueryEditorRect(aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_EDITOR_RECT, 0, 0, 0, 0);
 }
 
 /**
  * Synthesize a character at point event.
  *
  * @param aX, aY   The offset in the client area of the DOM window.
  * @param aWindow  Optional (If null, current |window| will be used)
@@ -789,16 +796,17 @@ function synthesizeQueryEditorRect(aWind
  *                 the result might be null.
  */
 function synthesizeCharAtPoint(aX, aY, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return null;
   }
+
   return utils.sendQueryContentEvent(utils.QUERY_CHARACTER_AT_POINT,
                                      0, 0, aX, aY);
 }
 
 /**
  * Synthesize a selection set event.
  *
  * @param aOffset  The character offset.  0 means the first character in the
@@ -811,10 +819,11 @@ function synthesizeCharAtPoint(aX, aY, a
  * @return         True, if succeeded.  Otherwise false.
  */
 function synthesizeSelectionSet(aOffset, aLength, aReverse, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (!utils) {
     return false;
   }
+
   return utils.sendSelectionSetEvent(aOffset, aLength, aReverse);
 }
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/arrays.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/arrays.js
@@ -1,93 +1,69 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['inArray', 'getSet', 'indexOf', 'rindexOf', 'compare'];
 
-function inArray (array, value) {
-  for (i in array) {
+function inArray(array, value) {
+  for (var i in array) {
     if (value == array[i]) {
       return true;
     }
   }
+
   return false;
 }
 
-function getSet (array) {
+function getSet(array) {
   var narray = [];
-  for (i in array) {
-    if ( !inArray(narray, array[i]) ) {
+
+  for (var i in array) {
+    if (!inArray(narray, array[i])) {
       narray.push(array[i]);
-    } 
+    }
   }
+
   return narray;
 }
 
-function indexOf (array, v, offset) {
-  for (i in array) {
+function indexOf(array, v, offset) {
+  for (var i in array) {
     if (offset == undefined || i >= offset) {
-      if ( !isNaN(i) && array[i] == v) {
+      if (!isNaN(i) && array[i] == v) {
         return new Number(i);
       }
     }
   }
+
   return -1;
 }
 
 function rindexOf (array, v) {
   var l = array.length;
-  for (i in array) {
+
+  for (var i in array) {
     if (!isNaN(i)) {
-      var i = new Number(i)
+      var i = new Number(i);
     }
+
     if (!isNaN(i) && array[l - i] == v) {
       return l - i;
     }
   }
+
   return -1;
 }
 
 function compare (array, carray) {
   if (array.length != carray.length) {
     return false;
   }
-  for (i in array) {
+
+  for (var i in array) {
     if (array[i] != carray[i]) {
       return false;
     }
   }
+
   return true;
-}
\ No newline at end of file
+}
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/dom.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/dom.js
@@ -1,54 +1,24 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['getAttributes'];
 
 
 var getAttributes = function (node) {
   var attributes = {};
-  for (i in node.attributes) {
-    if ( !isNaN(i) ) {
+
+  for (var i in node.attributes) {
+    if (!isNaN(i)) {
       try {
         var attr = node.attributes[i];
         attributes[attr.name] = attr.value;
-      } catch (err) {
+      }
+      catch (e) {
       }
     }
   }
+
   return attributes;
 }
 
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/objects.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/objects.js
@@ -1,52 +1,20 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['getLength', ];//'compare'];
 
 var getLength = function (obj) {
   var len = 0;
   for (i in obj) {
     len++;
   }
+
   return len;
 }
 
 // var logging = {}; Components.utils.import('resource://mozmill/stdlib/logging.js', logging);
 
 // var objectsLogger = logging.getLogger('objectsLogger');
 
 // var compare = function (obj1, obj2, depth, recursion) {
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/os.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/os.js
@@ -1,86 +1,57 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['listDirectory', 'getFileForPath', 'abspath', 'getPlatform'];
 
-function listDirectory (file) {
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+function listDirectory(file) {
   // file is the given directory (nsIFile)
   var entries = file.directoryEntries;
   var array = [];
-  while (entries.hasMoreElements())
-  {
+
+  while (entries.hasMoreElements()) {
     var entry = entries.getNext();
-    entry.QueryInterface(Components.interfaces.nsIFile);
+    entry.QueryInterface(Ci.nsIFile);
     array.push(entry);
   }
+
   return array;
 }
 
-function getFileForPath (path) {
-  var file = Components.classes["@mozilla.org/file/local;1"]
-                       .createInstance(Components.interfaces.nsILocalFile);
+function getFileForPath(path) {
+  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
   file.initWithPath(path);
   return file;
 }
 
-function abspath (rel, file) {  
+function abspath(rel, file) {
   var relSplit = rel.split('/');
+
   if (relSplit[0] == '..' && !file.isDirectory()) {
     file = file.parent;
   }
-  for each(p in relSplit) {
+
+  for each(var p in relSplit) {
     if (p == '..') {
       file = file.parent;
-    } else if (p == '.'){
+    } else if (p == '.') {
       if (!file.isDirectory()) {
         file = file.parent;
       }
     } else {
       file.append(p);
     }
   }
+
   return file.path;
 }
 
-function getPlatform () {
-  var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
-                   .getService(Components.interfaces.nsIXULRuntime);
+function getPlatform() {
+  var xulRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
   mPlatform = xulRuntime.OS.toLowerCase();
+
   return mPlatform;
 }
-
-
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/strings.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/strings.js
@@ -1,50 +1,17 @@
-// ***** BEGIN LICENSE BLOCK *****// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Mikeal Rogers.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ['trim', 'vslice'];
 
 var arrays = {}; Components.utils.import('resource://mozmill/stdlib/arrays.js', arrays);
 
 var trim = function (str) {
   return (str.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
 }
 
 var vslice = function (str, svalue, evalue) {
   var sindex = arrays.indexOf(str, svalue);
   var eindex = arrays.rindexOf(str, evalue);
   return str.slice(sindex + 1, eindex);
-}
\ No newline at end of file
+}
--- a/testing/peptest/peptest/extension/resource/mozmill/stdlib/utils.js
+++ b/testing/peptest/peptest/extension/resource/mozmill/stdlib/utils.js
@@ -1,296 +1,285 @@
-// ***** 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 Corporation Code.
-// 
-// The Initial Developer of the Original Code is
-// Adam Christian.
-// Portions created by the Initial Developer are Copyright (C) 2008
-// the Initial Developer. All Rights Reserved.
-// 
-// Contributor(s):
-//  Adam Christian <adam.christian@gmail.com>
-//  Mikeal Rogers <mikeal.rogers@gmail.com>
-//  Henrik Skupin <hskupin@mozilla.com>
-// 
-// 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 *****
+/* 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/. */
 
 var EXPORTED_SYMBOLS = ["openFile", "saveFile", "saveAsFile", "genBoiler", 
                         "getFile", "Copy", "getChromeWindow", "getWindows", "runEditor",
-                        "runFile", "getWindowByTitle", "getWindowByType", "tempfile", 
-                        "getMethodInWindows", "getPreference", "setPreference",
+                        "runFile", "getWindowByTitle", "getWindowByType", "getWindowId",
+                        "tempfile", "getMethodInWindows", "getPreference", "setPreference",
                         "sleep", "assert", "unwrapNode", "TimeoutError", "waitFor",
                         "takeScreenshot",
                        ];
 
-var hwindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
-              .getService(Components.interfaces.nsIAppShellService)
-              .hiddenDOMWindow;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
 
-var uuidgen = Components.classes["@mozilla.org/uuid-generator;1"]
-    .getService(Components.interfaces.nsIUUIDGenerator);
+var hwindow = Cc["@mozilla.org/appshell/appShellService;1"]
+              .getService(Ci.nsIAppShellService).hiddenDOMWindow;
+
+var uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
 
 function Copy (obj) {
   for (var n in obj) {
     this[n] = obj[n];
   }
 }
 
 function getChromeWindow(aWindow) {
-  var chromeWin = aWindow
-           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-           .getInterface(Components.interfaces.nsIWebNavigation)
-           .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
-           .rootTreeItem
-           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-           .getInterface(Components.interfaces.nsIDOMWindow)
-           .QueryInterface(Components.interfaces.nsIDOMChromeWindow);
+  var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIWebNavigation)
+                  .QueryInterface(Ci.nsIDocShellTreeItem)
+                  .rootTreeItem
+                  .QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIDOMWindow)
+                  .QueryInterface(Ci.nsIDOMChromeWindow);
+
   return chromeWin;
 }
 
 function getWindows(type) {
   if (type == undefined) {
-      type = "";
+    type = "";
   }
-  var windows = []
-  var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                     .getService(Components.interfaces.nsIWindowMediator)
-                     .getEnumerator(type);
-  while(enumerator.hasMoreElements()) {
+
+  var windows = [];
+  var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"]
+                   .getService(Ci.nsIWindowMediator).getEnumerator(type);
+
+  while (enumerator.hasMoreElements()) {
     windows.push(enumerator.getNext());
   }
+
   if (type == "") {
     windows.push(hwindow);
   }
+
   return windows;
 }
 
-function getMethodInWindows (methodName) {
-  for each(w in getWindows()) {
+function getMethodInWindows(methodName) {
+  for each (var w in getWindows()) {
     if (w[methodName] != undefined) {
       return w[methodName];
     }
   }
+
   throw new Error("Method with name: '" + methodName + "' is not in any open window.");
 }
 
 function getWindowByTitle(title) {
-  for each(w in getWindows()) {
+  for each (var w in getWindows()) {
     if (w.document.title && w.document.title == title) {
       return w;
     }
   }
+
+  throw new Error("Window with title: '" + title + "' not found.");
 }
 
 function getWindowByType(type) {
-  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-           .getService(Components.interfaces.nsIWindowMediator);
+  var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
+           .getService(Ci.nsIWindowMediator);
+
   return wm.getMostRecentWindow(type);
 }
 
+/**
+ * Retrieve the outer window id for the given window.
+ * 
+ * @param {Number} aWindow
+ *        Window to retrieve the id from.
+ * @returns {Boolean} The outer window id
+ **/
+function getWindowId(aWindow) {
+  try {
+    // Normally we can retrieve the id via window utils
+    return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
+                   getInterface(Ci.nsIDOMWindowUtils).
+                   outerWindowID;
+  } catch (e) {
+    // ... but for observer notifications we need another interface
+    return aWindow.QueryInterface(Ci.nsISupportsPRUint64).data;
+  }
+}
+
 function tempfile(appention) {
   if (appention == undefined) {
-    var appention = "mozmill.utils.tempfile"
+    appention = "mozmill.utils.tempfile";
   }
-	var tempfile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
-	tempfile.append(uuidgen.generateUUID().toString().replace('-', '').replace('{', '').replace('}',''))
-	tempfile.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
-	tempfile.append(appention);
-	tempfile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
-	// do whatever you need to the created file
-	return tempfile.clone()
+
+  var tempfile = Cc["@mozilla.org/file/directory_service;1"]
+                 .getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
+  tempfile.append(uuidgen.generateUUID().toString().replace('-', '')
+                                                   .replace('{', '')
+                                                   .replace('}',''));
+  tempfile.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
+  tempfile.append(appention);
+  tempfile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
+  // do whatever you need to the created file
+
+  return tempfile.clone();
 }
 
-var checkChrome = function() {
-   var loc = window.document.location.href;
-   try {
-       loc = window.top.document.location.href;
-   } catch (e) {}
+var checkChrome = function () {
+  var loc = window.document.location.href;
+  try {
+    loc = window.top.document.location.href;
+  } catch (e) {
+  }
+
+  return /^chrome:\/\//.test(loc);
+}
+
+var runFile = function (w) {
+  var nsIFilePicker = Ci.nsIFilePicker;
 
-   if (/^chrome:\/\//.test(loc)) { return true; } 
-   else { return false; }
+  //define the file picker window
+  var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+  fp.init(w, "Select a File", nsIFilePicker.modeOpen);
+  fp.appendFilter("JavaScript Files","*.js");
+
+  // if we get a file
+  var res = fp.show();
+  if (res == nsIFilePicker.returnOK) {
+    var thefile = fp.file;
+
+    //create the paramObj with a files array attrib
+    var paramObj = {};
+    paramObj.files = [];
+    paramObj.files.push(thefile.path);
+  }
 }
 
- 
- var runFile = function(w){
-   //define the interface
-   var nsIFilePicker = Components.interfaces.nsIFilePicker;
-   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
-   //define the file picker window
-   fp.init(w, "Select a File", nsIFilePicker.modeOpen);
-   fp.appendFilter("JavaScript Files","*.js");
-   //show the window
-   var res = fp.show();
-   //if we got a file
-   if (res == nsIFilePicker.returnOK){
-     var thefile = fp.file;
-     //create the paramObj with a files array attrib
-     var paramObj = {};
-     paramObj.files = [];
-     paramObj.files.push(thefile.path);
-   }
- };
- 
- var saveFile = function(w, content, filename){
-   //define the file interface
-   var file = Components.classes["@mozilla.org/file/local;1"]
-                        .createInstance(Components.interfaces.nsILocalFile);
-   //point it at the file we want to get at
-   file.initWithPath(filename);
-   
-   // file is nsIFile, data is a string
-   var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
-                            .createInstance(Components.interfaces.nsIFileOutputStream);
+var saveFile = function (w, content, filename) {
+  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+  file.initWithPath(filename);
+
+  var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
+                 .createInstance(Ci.nsIFileOutputStream);
+
+  // use 0x02 | 0x10 to open file for appending.
+  foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0); 
+  // write, create, truncate
+  // In a c file operation, we have no need to set file mode with or operation,
+  // directly using "r" or "w" usually.
+
+  foStream.write(content, content.length);
+  foStream.close();
+};
+
+var saveAsFile = function (w, content) {
+  var nsIFilePicker = Ci.nsIFilePicker;
+
+  // define the file picker window
+  var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+  fp.init(w, "Select a File", nsIFilePicker.modeSave);
+  fp.appendFilter("JavaScript Files","*.js");
+
+  //if we get a file
+  var res = fp.show();
+  if ((res == nsIFilePicker.returnOK) || (res == nsIFilePicker.returnReplace)) {
+    var thefile = fp.file;
+
+    // forcing the user to save as a .js file
+    if (thefile.path.indexOf(".js") == -1){
+      var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+      file.initWithPath(thefile.path + ".js");
+      var thefile = file;
+    }
+
+    // file is nsIFile, data is a string
+    var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
+                   .createInstance(Ci.nsIFileOutputStream);
 
-   // use 0x02 | 0x10 to open file for appending.
-   foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0); 
-   // write, create, truncate
-   // In a c file operation, we have no need to set file mode with or operation,
-   // directly using "r" or "w" usually.
-   
-   foStream.write(content, content.length);
-   foStream.close();
- };
- 
-  var saveAsFile = function(w, content){
-     //define the interface
-     var nsIFilePicker = Components.interfaces.nsIFilePicker;
-     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
-     //define the file picker window
-     fp.init(w, "Select a File", nsIFilePicker.modeSave);
-     fp.appendFilter("JavaScript Files","*.js");
-     //show the window
-     var res = fp.show();
-     //if we got a file
-     if ((res == nsIFilePicker.returnOK) || (res == nsIFilePicker.returnReplace)){
-       var thefile = fp.file;
-              
-       //forcing the user to save as a .js file
-       if (thefile.path.indexOf(".js") == -1){
-         //define the file interface
-         var file = Components.classes["@mozilla.org/file/local;1"]
-                              .createInstance(Components.interfaces.nsILocalFile);
-         //point it at the file we want to get at
-         file.initWithPath(thefile.path+".js");
-         var thefile = file;
-       }
-       
-       // file is nsIFile, data is a string
-       var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
-                               .createInstance(Components.interfaces.nsIFileOutputStream);
+    // use 0x02 | 0x10 to open file for appending.
+    foStream.init(thefile, 0x02 | 0x08 | 0x20, 0666, 0); 
+    // write, create, truncate
+    // In a c file operation, we have no need to set file mode with or operation,
+    // directly using "r" or "w" usually.
+    foStream.write(content, content.length);
+    foStream.close();
+
+    return thefile.path;
+  }
+}
+
+var openFile = function (w) {
+  var nsIFilePicker = Ci.nsIFilePicker;
+
+  // define the file picker window
+  var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+  fp.init(w, "Select a File", nsIFilePicker.modeOpen);
+  fp.appendFilter("JavaScript Files", "*.js");
+
+  // if we get a file
+  var res = fp.show();
+  if (res == nsIFilePicker.returnOK) {
+    var thefile = fp.file;
+    var data = getFile(thefile.path);
 
-       // use 0x02 | 0x10 to open file for appending.
-       foStream.init(thefile, 0x02 | 0x08 | 0x20, 0666, 0); 
-       // write, create, truncate
-       // In a c file operation, we have no need to set file mode with or operation,
-       // directly using "r" or "w" usually.
-       foStream.write(content, content.length);
-       foStream.close();
-       return thefile.path;
-     }
-  };
-  
- var openFile = function(w){
-    //define the interface
-    var nsIFilePicker = Components.interfaces.nsIFilePicker;
-    var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
-    //define the file picker window
-    fp.init(w, "Select a File", nsIFilePicker.modeOpen);
-    fp.appendFilter("JavaScript Files","*.js");
-    //show the window
-    var res = fp.show();
-    //if we got a file
-    if (res == nsIFilePicker.returnOK){
-      var thefile = fp.file;
-      //create the paramObj with a files array attrib
-      var data = getFile(thefile.path);
+    return {path: thefile.path, data: data};
+  }
+}
+
+var getFile = function (path) {
+  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+  file.initWithPath(path);
 
-      return {path:thefile.path, data:data};
-    }
-  };
-  
- var getFile = function(path){
-   //define the file interface
-   var file = Components.classes["@mozilla.org/file/local;1"]
-                        .createInstance(Components.interfaces.nsILocalFile);
-   //point it at the file we want to get at
-   file.initWithPath(path);
-   // define file stream interfaces
-   var data = "";
-   var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
-                           .createInstance(Components.interfaces.nsIFileInputStream);
-   var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
-                           .createInstance(Components.interfaces.nsIScriptableInputStream);
-   fstream.init(file, -1, 0, 0);
-   sstream.init(fstream); 
+  var data = "";
+  var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
+                .createInstance(Ci.nsIFileInputStream);
+  var sstream = Cc["@mozilla.org/scriptableinputstream;1"]
+                .createInstance(Ci.nsIScriptableInputStream);
+  fstream.init(file, -1, 0, 0);
+  sstream.init(fstream); 
 
-   //pull the contents of the file out
-   var str = sstream.read(4096);
-   while (str.length > 0) {
-     data += str;
-     str = sstream.read(4096);
-   }
+  //pull the contents of the file out
+  var str = sstream.read(4096);
+  while (str.length > 0) {
+    data += str;
+    str = sstream.read(4096);
+  }
 
-   sstream.close();
-   fstream.close();
+  sstream.close();
+  fstream.close();
 
-   //data = data.replace(/\r|\n|\r\n/g, "");
-   return data;
- };
+  //data = data.replace(/\r|\n|\r\n/g, "");
+  return data;
+};
  
 /**
  * Called to get the state of an individual preference.
  *
  * @param aPrefName     string The preference to get the state of.
  * @param aDefaultValue any    The default value if preference was not found.
  *
  * @returns any The value of the requested preference
  *
  * @see setPref
  * Code by Henrik Skupin: <hskupin@gmail.com>
  */
 function getPreference(aPrefName, aDefaultValue) {
   try {
-    var branch = Components.classes["@mozilla.org/preferences-service;1"].
-                 getService(Components.interfaces.nsIPrefBranch);
+    var branch = Cc["@mozilla.org/preferences-service;1"]
+                 .getService(Ci.nsIPrefBranch);
+
     switch (typeof aDefaultValue) {
       case ('boolean'):
         return branch.getBoolPref(aPrefName);
       case ('string'):
         return branch.getCharPref(aPrefName);
       case ('number'):
         return branch.getIntPref(aPrefName);
       default:
         return branch.getComplexValue(aPrefName);
     }
-  } catch(e) {
+  } catch (e) {
     return aDefaultValue;
   }
 }
 
 /**
  * Called to set the state of an individual preference.
  *
  * @param aPrefName string The preference to set the state of.
@@ -298,70 +287,69 @@ function getPreference(aPrefName, aDefau
  *
  * @returns boolean Returns true if value was successfully set.
  *
  * @see getPref
  * Code by Henrik Skupin: <hskupin@gmail.com>
  */
 function setPreference(aName, aValue) {
   try {
-    var branch = Components.classes["@mozilla.org/preferences-service;1"].
-                 getService(Components.interfaces.nsIPrefBranch);
+    var branch = Cc["@mozilla.org/preferences-service;1"]
+                 .getService(Ci.nsIPrefBranch);
+
     switch (typeof aValue) {
       case ('boolean'):
         branch.setBoolPref(aName, aValue);
         break;
       case ('string'):
         branch.setCharPref(aName, aValue);
         break;
       case ('number'):
         branch.setIntPref(aName, aValue);
         break;
       default:
         branch.setComplexValue(aName, aValue);
     }
-  } catch(e) {
+  } catch (e) {
     return false;
   }
 
   return true;
 }
 
 /**
  * Sleep for the given amount of milliseconds
  *
  * @param {number} milliseconds
  *        Sleeps the given number of milliseconds
  */
 function sleep(milliseconds) {
-  // We basically just call this once after the specified number of milliseconds
   var timeup = false;
-  function wait() { timeup = true; }
-  hwindow.setTimeout(wait, milliseconds);
 
-  var thread = Components.classes["@mozilla.org/thread-manager;1"].
-               getService().currentThread;
-  while(!timeup) {
+  hwindow.setTimeout(function () { timeup = true; }, milliseconds);
+  var thread = Cc["@mozilla.org/thread-manager;1"]
+               .getService().currentThread;
+  while (!timeup) {
     thread.processNextEvent(true);
   }
 }
 
 /**
  * Check if the callback function evaluates to true
  */
 function assert(callback, message, thisObject) {
   var result = callback.call(thisObject);
 
   if (!result) {
     throw new Error(message || arguments.callee.name + ": Failed for '" + callback + "'");
   }
 
   return true;
 }
-	   
+
 /**
  * Unwraps a node which is wrapped into a XPCNativeWrapper or XrayWrapper
  *
  * @param {DOMnode} Wrapped DOM node
  * @returns {DOMNode} Unwrapped DOM node
  */
 function unwrapNode(aNode) {
   var node = aNode;
@@ -369,56 +357,59 @@ function unwrapNode(aNode) {
     // unwrap is not available on older branches (3.5 and 3.6) - Bug 533596
     if ("unwrap" in XPCNativeWrapper) {	   
       node = XPCNativeWrapper.unwrap(node);
     }
     else if (node.wrappedJSObject != null) {
       node = node.wrappedJSObject;
     }
   }
+
   return node;
 }
 
 /**
  * TimeoutError
  *
  * Error object used for timeouts
  */
 function TimeoutError(message, fileName, lineNumber) {
   var err = new Error();
+  this.message = (message === undefined ? err.message : message);
+  this.fileName = (fileName === undefined ? err.fileName : fileName);
+  this.lineNumber = (lineNumber === undefined ? err.lineNumber : lineNumber);
+
   if (err.stack) {
     this.stack = err.stack;
   }
-  this.message = message === undefined ? err.message : message;
-  this.fileName = fileName === undefined ? err.fileName : fileName;
-  this.lineNumber = lineNumber === undefined ? err.lineNumber : lineNumber;
-};
+}
 TimeoutError.prototype = new Error();
 TimeoutError.prototype.constructor = TimeoutError;
 TimeoutError.prototype.name = 'TimeoutError';
 
 /**
  * Waits for the callback evaluates to true
  */
 function waitFor(callback, message, timeout, interval, thisObject) {
   timeout = timeout || 5000;
   interval = interval || 100;
 
-  var self = {counter: 0, result: callback.call(thisObject)};
+  var self = {counter: 0,
+              result: callback.call(thisObject)};
 
   function wait() {
     self.counter += interval;
     self.result = callback.call(thisObject);
   }
 
   var timeoutInterval = hwindow.setInterval(wait, interval);
-  var thread = Components.classes["@mozilla.org/thread-manager;1"].
-               getService().currentThread;
+  var thread = Cc["@mozilla.org/thread-manager;1"]
+               .getService().currentThread;
 
-  while((self.result != true) && (self.counter < timeout))  {
+  while ((self.result != true) && (self.counter < timeout))  {
     thread.processNextEvent(true);
   }
 
   hwindow.clearInterval(timeoutInterval);
 
   if (self.counter >= timeout) {
     message = message || arguments.callee.name + ": Timeout exceeded for '" + callback + "'";
     throw new TimeoutError(message);
@@ -432,71 +423,75 @@ function waitFor(callback, message, time
  * See https://developer.mozilla.org/en/DOM/window.innerHeight
  * 
  * Note this function will not work if the user has custom toolbars (via extension) at the bottom or left/right of the screen
  */
 function getChromeOffset(elem) {
   var win = elem.ownerDocument.defaultView;
   // Calculate x offset
   var chromeWidth = 0;
+
   if (win["name"] != "sidebar") { 
     chromeWidth = win.outerWidth - win.innerWidth;
   }
 
   // Calculate y offset
   var chromeHeight = win.outerHeight - win.innerHeight;
   // chromeHeight == 0 means elem is already in the chrome and doesn't need the addonbar offset
   if (chromeHeight > 0) {
     // window.innerHeight doesn't include the addon or find bar, so account for these if present
     var addonbar = win.document.getElementById("addon-bar");
-    if (addonbar) { 
+    if (addonbar) {
       chromeHeight -= addonbar.scrollHeight;
     }
+
     var findbar = win.document.getElementById("FindToolbar");
     if (findbar) {
       chromeHeight -= findbar.scrollHeight;
     }
   }
 
   return {'x':chromeWidth, 'y':chromeHeight}; 
 }
 
 /**
  * Takes a screenshot of the specified DOM node 
  */
 function takeScreenshot(node, name, highlights) {
   var rect, win, width, height, left, top, needsOffset;
   // node can be either a window or an arbitrary DOM node
   try {
-    win = node.ownerDocument.defaultView;   // node is an arbitrary DOM node
+    // node is an arbitrary DOM node
+    win = node.ownerDocument.defaultView;
     rect = node.getBoundingClientRect();
     width = rect.width;
     height = rect.height;
     top = rect.top;
     left = rect.left;
     // offset for highlights not needed as they will be relative to this node
     needsOffset = false;
   } catch (e) {
-    win = node;                             // node is a window
+    // node is a window
+    win = node;
     width = win.innerWidth;
     height = win.innerHeight;
     top = 0;
     left = 0;
     // offset needed for highlights to take 'outerHeight' of window into account
     needsOffset = true;
   }
 
   var canvas = win.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
   canvas.width = width;
   canvas.height = height;
 
   var ctx = canvas.getContext("2d");
   // Draws the DOM contents of the window to the canvas
   ctx.drawWindow(win, left, top, width, height, "rgb(255,255,255)");
-  
+
   // This section is for drawing a red rectangle around each element passed in via the highlights array
   if (highlights) {
     ctx.lineWidth = "2";
     ctx.strokeStyle = "red";
     ctx.save();
 
     for (var i = 0; i < highlights.length; ++i) {
       var elem = highlights[i];
@@ -511,47 +506,43 @@ function takeScreenshot(node, name, high
         // Don't need to offset the window chrome, just make relative to containing node
         offsetY = -top;
         offsetX = -left;
       }
 
       // Draw the rectangle
       ctx.strokeRect(rect.left + offsetX, rect.top + offsetY, rect.width, rect.height);
     }
-  } // end highlights
+  }
 
   // if there is a name save the file, else return dataURL
-  if (name) {
-    return saveCanvas(canvas, name);
-  } 
-  return canvas.toDataURL("image/png","");
+  return (name ? saveCanvas(canvas, name)
+               : canvas.toDataURL("image/png",""));
 }
 
 /**
  * Takes a canvas as input and saves it to the file tempdir/name.png
  * Returns the filepath of the saved file
  */
 function saveCanvas(canvas, name) {
-  var file = Components.classes["@mozilla.org/file/directory_service;1"]
-                                .getService(Components.interfaces.nsIProperties)
-                                .get("TmpD", Components.interfaces.nsIFile);
+  var file = Cc["@mozilla.org/file/directory_service;1"]
+             .getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
   file.append("mozmill_screens");
   file.append(name + ".png");
-  file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
+  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
 
-  // create a data url from the canvas and then create URIs of the source and targets  
-  var io = Components.classes["@mozilla.org/network/io-service;1"]
-                              .getService(Components.interfaces.nsIIOService);
+  // create a data url from the canvas and then create URIs of the source and targets
+  var io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
   var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
-  var target = io.newFileURI(file)
- 
+  var target = io.newFileURI(file);
+
   // prepare to save the canvas data
-  var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
-                                   .createInstance(Components.interfaces.nsIWebBrowserPersist);
+  var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+                .createInstance(Ci.nsIWebBrowserPersist);
 
-  persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
-  persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
- 
+  persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+  persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+
   // save the canvas data to the file
   persist.saveURI(source, null, null, null, null, file);
 
   return file.path;
 }
--- a/testing/peptest/setup.py
+++ b/testing/peptest/setup.py
@@ -6,17 +6,17 @@ import os
 from setuptools import setup, find_packages
 
 try:
     here = os.path.dirname(os.path.abspath(__file__))
     description = file(os.path.join(here, 'README.md')).read()
 except IOError:
     description = ''
 
-version = "0.1"
+version = "1.0"
 
 dependencies = ['ManifestDestiny',
                 'mozhttpd',
                 'mozlog',
                 'mozprofile >= 0.1',
                 'mozprocess',
                 'mozrunner >= 3.0b3',
                ]