Bug 1515877 - Turn on ESLint in mailnews/test/fakeserver draft
authorGeoff Lankow <geoff@darktrojan.net>
Fri, 08 Mar 2019 22:09:33 +1300
changeset 71667 923ad88dede21c876411708561972a882eac469f
parent 71664 b740b113b39428a6c1ed0ecbc0a6ca8919fe4047
child 71668 fa8a8de2e0e32968ee670741a4c31c50f755887f
push id7932
push usergeoff@darktrojan.net
push dateFri, 08 Mar 2019 09:10:02 +0000
treeherdertry-comm-central@82dd40d6af59 [default view] [failures only]
bugs1515877
Bug 1515877 - Turn on ESLint in mailnews/test/fakeserver
.eslintignore
mailnews/test/fakeserver/auth.js
mailnews/test/fakeserver/imapd.js
mailnews/test/fakeserver/maild.js
mailnews/test/fakeserver/nntpd.js
mailnews/test/fakeserver/pop3d.js
mailnews/test/fakeserver/smtpd.js
--- a/.eslintignore
+++ b/.eslintignore
@@ -39,17 +39,16 @@ mailnews/base/*
 mailnews/build/*
 mailnews/compose/*
 mailnews/db/*
 mailnews/imap/*
 mailnews/import/*
 mailnews/intl/*
 mailnews/jsaccount/*
 mailnews/mime/*
-mailnews/test/fakeserver/*
 
 # mailnews/extensions exclusions
 mailnews/extensions/*
 !mailnews/extensions/newsblog
 
 # mail exclusions
 mail/app/profile/all-thunderbird.js
 mail/app/profile/channel-prefs.js
--- a/mailnews/test/fakeserver/auth.js
+++ b/mailnews/test/fakeserver/auth.js
@@ -11,32 +11,32 @@
  * In fact, you could use this to implement a real server in JS :-) .
  *
  * @author Ben Bucksch <ben.bucksch beonex.com>
  */
 
 var EXPORTED_SYMBOLS = [
   "AuthPLAIN",
   "AuthLOGIN",
-  "AuthCRAM"
+  "AuthCRAM",
 ];
 
 /**
  * Implements AUTH PLAIN
  * @see RFC 4616
  */
 var AuthPLAIN = {
   /**
    * Takes full PLAIN auth line, and decodes it.
    *
    * @param line {String}
    * @returns {Object { username : value, password : value } }
    * @throws {String}   error to return to client
    */
-  decodeLine: function(line) {
+  decodeLine(line) {
     dump("AUTH PLAIN line -" + line + "-\n");
     line = atob(line); // base64 decode
     let aap = line.split("\u0000"); // 0-charater is delimiter
     if (aap.length != 3)
       throw "Expected three parts";
     /* aap is: authorize-id, authenticate-id, password.
        Generally, authorize-id = authenticate-id = username.
        authorize-id may thus be empty and then defaults to authenticate-id. */
@@ -49,35 +49,34 @@ var AuthPLAIN = {
       throw "Expecting a authorize-id that's either the same as authenticate-id or empty";
     return result;
   },
 
   /**
    * Create an AUTH PLAIN line, to allow a client to authenticate to a server.
    * Useful for tests.
    */
-  encodeLine : function(username, password)
-  {
+  encodeLine(username, password) {
     username = username.substring(0, 255);
     password = password.substring(0, 255);
     return btoa("\u0000" + username + "\u0000" + password); // base64 encode
   },
 };
 
 var AuthLOGIN = {
   /**
    * Takes full LOGIN auth line, and decodes it.
    * It may contain either username or password,
    * depending on state/step (first username, then pw).
    *
    * @param line {String}
    * @returns {String}   username or password
    * @throws {String}   error to return to client
    */
-  decodeLine: function (line) {
+  decodeLine(line) {
     dump("AUTH LOGIN -" + atob(line) + "-\n");
     return atob(line); // base64 decode
   },
 };
 
 /**
   * Implements AUTH CRAM-MD5
   * @see RFC 2195, RFC 2104
@@ -91,58 +90,55 @@ var AuthCRAM = {
    *
    * You need to store it, you'll need it to check the client response.
    *
    * @param domain {String}   Your hostname or domain,
    *    e.g. "example.com", "mx.example.com" or just "localhost".
    * @returns {String}   The challenge.
    *   It's already base64-encoded. Send it as-is to the client.
    */
-  createChallenge : function(domain)
-  {
+  createChallenge(domain) {
     var timestamp = new Date().getTime(); // unixtime
     var challenge = "<" + timestamp + "@" + domain + ">";
     dump("CRAM challenge unencoded: " + challenge + "\n");
     return btoa(challenge);
   },
   /**
    * Takes full CRAM-MD5 auth line, and decodes it.
    *
    * Compare the returned |digest| to the result of
    * encodeCRAMMD5(). If they match, the |username|
    * returned here is authenticated.
    *
    * @param line {String}
    * @returns {Object { username : value, digest : value } }
    * @throws {String}   error to return to client
    */
-  decodeLine : function(line)
-  {
+  decodeLine(line) {
     dump("AUTH CRAM-MD5 line -" + line + "-\n");
     line = atob(line);
     dump("base64 decoded -" + line + "-\n");
     var sp = line.split(" ");
     if (sp.length != 2)
       throw "Expected one space";
     var result = {};
     result.username = sp[0];
     result.digest = sp[1];
     return result;
   },
   /**
    * @param text {String}   server challenge (base64-encoded)
    * @param key {String}   user's password
    * @return {String}   digest as hex string
    */
-  encodeCRAMMD5 : function(text, key)
-  {
+  encodeCRAMMD5(text, key) {
     text = atob(text); // createChallenge() returns it already encoded
     dump("encodeCRAMMD5(text: -" + text + "-, key: -" + key + "-)\n");
     const kInputLen = 64;
-    //const kHashLen = 16;
+    // const kHashLen = 16;
     const kInnerPad = 0x36; // per spec
     const kOuterPad = 0x5C;
 
     key = this.textToNumberArray(key);
     text = this.textToNumberArray(text);
     // Make sure key is exactly kDigestLen bytes long. Algo per spec.
     if (key.length > kInputLen)
       key = this.md5(key); // (results in kHashLen)
@@ -151,43 +147,38 @@ var AuthCRAM = {
 
     // MD5((key XOR outerpad) + MD5((key XOR innerpad) + text)) , per spec
     var digest = this.md5(this.xor(key, kOuterPad)
          .concat(this.md5(this.xor(key, kInnerPad)
          .concat(text))));
     return this.arrayToHexString(digest);
   },
   // Utils
-  xor : function(binary, value)
-  {
+  xor(binary, value) {
     var result = [];
     for (var i = 0; i < binary.length; i++)
       result.push(binary[i] ^ value);
     return result;
   },
-  md5 : function(binary)
-  {
+  md5(binary) {
     var md5 = Cc["@mozilla.org/security/hash;1"]
         .createInstance(Ci.nsICryptoHash);
     md5.init(Ci.nsICryptoHash.MD5);
     md5.update(binary, binary.length);
     return this.textToNumberArray(md5.finish(false));
   },
-  textToNumberArray : function(text)
-  {
+  textToNumberArray(text) {
     var array = [];
     for (var i = 0; i < text.length; i++)
       array.push(text.charCodeAt(i) & 0xFF); // convert string (only lower byte) to array
     return array;
   },
-  arrayToHexString : function(binary)
-  {
+  arrayToHexString(binary) {
     var result = "";
-    for (var i = 0; i < binary.length; i++)
-    {
+    for (var i = 0; i < binary.length; i++) {
       if (binary[i] > 255)
         throw "unexpected that value > 255";
       let hex = binary[i].toString(16);
       if (hex.length < 2)
         hex = "0" + hex;
       result += hex;
     }
     return result;
--- a/mailnews/test/fakeserver/imapd.js
+++ b/mailnews/test/fakeserver/imapd.js
@@ -1,176 +1,173 @@
 /* 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/. */
 // This file implements test IMAP servers
 
 var EXPORTED_SYMBOLS = [
-  'imapDaemon',
-  'imapMailbox',
-  'imapMessage',
-  'IMAP_RFC3501_handler',
-  'configurations',
-  'mixinExtension',
-  'IMAP_GMAIL_extension',
-  'IMAP_MOVE_extension',
-  'IMAP_CUSTOM_extension',
-  'IMAP_RFC2197_extension',
-  'IMAP_RFC2342_extension',
-  'IMAP_RFC3348_extension',
-  'IMAP_RFC4315_extension',
-  'IMAP_RFC5258_extension',
-  'IMAP_RFC2195_extension'
+  "imapDaemon",
+  "imapMailbox",
+  "imapMessage",
+  "IMAP_RFC3501_handler",
+  "configurations",
+  "mixinExtension",
+  "IMAP_GMAIL_extension",
+  "IMAP_MOVE_extension",
+  "IMAP_CUSTOM_extension",
+  "IMAP_RFC2197_extension",
+  "IMAP_RFC2342_extension",
+  "IMAP_RFC3348_extension",
+  "IMAP_RFC4315_extension",
+  "IMAP_RFC5258_extension",
+  "IMAP_RFC2195_extension",
 ];
 
-////////////////////////////////////////////////////////////////////////////////
-//                          IMAP DAEMON ORGANIZATION                          //
-////////////////////////////////////////////////////////////////////////////////
-// The large numbers of RFCs all induce some implicit assumptions as to the   //
-// organization of an IMAP server. Ideally, we'd like to be as inclusive as   //
-// possible so that we can guarantee that it works for every type of server.  //
-// Unfortunately, such all-accepting setups make generic algorithms hard to   //
-// use; given their difficulty in a generic framework, it seems unlikely that //
-// a server would implement such characteristics. It also seems likely that   //
-// if mailnews had a problem with the implementation, then most clients would //
-// see similar problems, so as to make the server widely unusable. In any     //
-// case, if someone complains about not working on bugzilla, it can be added  //
-// to the test suite.                                                         //
-// So, with that in mind, this is the basic layout of the daemon:             //
-// DAEMON                                                                     //
-// + Namespaces: parentless mailboxes whose names are the namespace name. The //
-//     type of the namespace is specified by the type attribute.              //
-// + Mailboxes: imapMailbox objects with several properties. If a mailbox     //
-// | |   property begins with a '_', then it should not be serialized because //
-// | |   it can be discovered from other means; in particular, a '_' does not //
-// | |   necessarily mean that it is a private property that should not be    //
-// | |   accessed. The parent of a top-level mailbox is null, not "".         //
-// | + I18N names: RFC 3501 specifies a modified UTF-7 form for names.        //
-// | |     However, a draft RFC makes the names UTF-8; it is expected to be   //
-// | |     completed and implemented "soon". Therefore, the correct usage is  //
-// | |     to specify the mailbox names as one normally does in JS and the    //
-// | |     protocol will take care of conversion itself.                      //
-// | + Case-sensitivity: RFC 3501 takes no position on this issue, only that  //
-// | |     a case-insensitive server must treat the base-64 parts of mailbox  //
-// | |     names as case-sensitive. The draft UTF8 RFC says nothing on this   //
-// | |     topic, but Crispin recommends using Unicode case-insensitivity. We //
-// | |     therefore treat names in such manner (if the case-insensitive flag //
-// | |     is set), in technical violation of RFC 3501.                       //
-// | + Flags: Flags are (as confirmed by Crispin) case-insensitive. Internal  //
-// |       flag equality, though, uses case-sensitive checks. Therefore they  //
-// |       should be normalized to a title-case form (e.g., \Noselect).       //
-// + Synchronization: On certain synchronizing commands, the daemon will call //
-// |   a synchronizing function to allow manipulating code the chance to      //
-// |   perform various (potentially expensive) actions.                       //
-// + Messages: A message is represented internally as an annotated URI.       //
-////////////////////////////////////////////////////////////////////////////////
+// IMAP DAEMON ORGANIZATION
+// ------------------------
+// The large numbers of RFCs all induce some implicit assumptions as to the
+// organization of an IMAP server. Ideally, we'd like to be as inclusive as
+// possible so that we can guarantee that it works for every type of server.
+// Unfortunately, such all-accepting setups make generic algorithms hard to
+// use; given their difficulty in a generic framework, it seems unlikely that
+// a server would implement such characteristics. It also seems likely that
+// if mailnews had a problem with the implementation, then most clients would
+// see similar problems, so as to make the server widely unusable. In any
+// case, if someone complains about not working on bugzilla, it can be added
+// to the test suite.
+// So, with that in mind, this is the basic layout of the daemon:
+// DAEMON
+// + Namespaces: parentless mailboxes whose names are the namespace name. The
+//     type of the namespace is specified by the type attribute.
+// + Mailboxes: imapMailbox objects with several properties. If a mailbox
+// | |   property begins with a '_', then it should not be serialized because
+// | |   it can be discovered from other means; in particular, a '_' does not
+// | |   necessarily mean that it is a private property that should not be
+// | |   accessed. The parent of a top-level mailbox is null, not "".
+// | + I18N names: RFC 3501 specifies a modified UTF-7 form for names.
+// | |     However, a draft RFC makes the names UTF-8; it is expected to be
+// | |     completed and implemented "soon". Therefore, the correct usage is
+// | |     to specify the mailbox names as one normally does in JS and the
+// | |     protocol will take care of conversion itself.
+// | + Case-sensitivity: RFC 3501 takes no position on this issue, only that
+// | |     a case-insensitive server must treat the base-64 parts of mailbox
+// | |     names as case-sensitive. The draft UTF8 RFC says nothing on this
+// | |     topic, but Crispin recommends using Unicode case-insensitivity. We
+// | |     therefore treat names in such manner (if the case-insensitive flag
+// | |     is set), in technical violation of RFC 3501.
+// | + Flags: Flags are (as confirmed by Crispin) case-insensitive. Internal
+// |       flag equality, though, uses case-sensitive checks. Therefore they
+// |       should be normalized to a title-case form (e.g., \Noselect).
+// + Synchronization: On certain synchronizing commands, the daemon will call
+// |   a synchronizing function to allow manipulating code the chance to
+// |   perform various (potentially expensive) actions.
+// + Messages: A message is represented internally as an annotated URI.
 
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const {MimeParser} = ChromeUtils.import("resource:///modules/mimeParser.jsm");
 var {
   AuthPLAIN,
   AuthLOGIN,
   AuthCRAM,
 } = ChromeUtils.import("resource://testing-common/mailnews/auth.js");
 
 function imapDaemon(flags, syncFunc) {
   this._flags = flags;
 
   this.namespaces = [];
   this.idResponse = "NIL";
-  this.root = new imapMailbox("", null, {type : IMAP_NAMESPACE_PERSONAL});
-  this.uidvalidity = Math.round(Date.now()/1000);
+  this.root = new imapMailbox("", null, {type: IMAP_NAMESPACE_PERSONAL});
+  this.uidvalidity = Math.round(Date.now() / 1000);
   this.inbox = new imapMailbox("INBOX", null, this.uidvalidity++);
   this.root.addMailbox(this.inbox);
   this.namespaces.push(this.root);
   this.syncFunc = syncFunc;
   // This can be used to cause the artificial failure of any given command.
   this.commandToFail = "";
   // This can be used to simulate timeouts on large copies
   this.copySleep = 0;
 }
 imapDaemon.prototype = {
-  synchronize : function (mailbox, update) {
+  synchronize(mailbox, update) {
     if (this.syncFunc)
       this.syncFunc.call(null, this);
     if (update) {
       for (var message of mailbox._messages) {
         message.recent = false;
       }
     }
   },
-  getNamespace : function (name) {
+  getNamespace(name) {
     for (var namespace of this.namespaces) {
       if (name.indexOf(namespace.name) == 0 &&
           name[namespace.name.length] == namespace.delimiter)
         return namespace;
     }
     return this.root;
   },
-  createNamespace : function (name, type) {
-    var newbox = this.createMailbox(name, {type : type});
+  createNamespace(name, type) {
+    var newbox = this.createMailbox(name, {type});
     this.namespaces.push(newbox);
   },
-  getMailbox : function (name) {
+  getMailbox(name) {
     if (name == "")
       return this.root;
     // INBOX is case-insensitive, no matter what
     if (name.toUpperCase().startsWith("INBOX"))
       name = "INBOX" + name.substr(5);
     // We want to find a child who has the same name, but we don't quite know
     // what the delimiter is. The convention is that different namespaces use a
     // name starting with '#', so that's how we'll work it out.
-    if (name.startsWith('#')) {
-      var root = null;
-      for (var mailbox of this.root._children) {
+    let mailbox;
+    if (name.startsWith("#")) {
+      for (mailbox of this.root._children) {
         if (mailbox.name.indexOf(name) == 0 &&
             name[mailbox.name.length] == mailbox.delimiter) {
-          root = mailbox;
           break;
         }
       }
       if (!mailbox)
         return null;
 
       // Now we continue like normal
-      var names = name.split(mailbox.delimiter);
+      let names = name.split(mailbox.delimiter);
       names.splice(0, 1);
-      for (var part of names) {
+      for (let part of names) {
         mailbox = mailbox.getChild(part);
         if (!mailbox || mailbox.nonExistent)
           return null;
       }
-      return mailbox;
     } else {
       // This is easy, just split it up using the inbox's delimiter
-      var names = name.split(this.inbox.delimiter);
-      var mailbox = this.root;
+      let names = name.split(this.inbox.delimiter);
+      mailbox = this.root;
 
-      for (var part of names) {
+      for (let part of names) {
         mailbox = mailbox.getChild(part);
         if (!mailbox || mailbox.nonExistent)
           return null;
       }
-      return mailbox;
     }
+    return mailbox;
   },
-  createMailbox : function (name, oldBox) {
+  createMailbox(name, oldBox) {
     var namespace = this.getNamespace(name);
     if (namespace.name != "")
-      name = name.substring(namespace.name.length+1);
+      name = name.substring(namespace.name.length + 1);
     var prefixes = name.split(namespace.delimiter);
-    if (prefixes[prefixes.length-1] == '')
-      var subName = prefixes.splice(prefixes.length - 2, 2)[0];
+    var subName;
+    if (prefixes[prefixes.length - 1] == "")
+      subName = prefixes.splice(prefixes.length - 2, 2)[0];
     else
-      var subName = prefixes.splice(prefixes.length - 1, 1)[0];
+      subName = prefixes.splice(prefixes.length - 1, 1)[0];
     var box = namespace;
     for (var component of prefixes) {
       box = box.getChild(component);
       // Yes, we won't autocreate intermediary boxes
-      if (box == null || box.flags.indexOf('\\NoInferiors') != -1)
+      if (box == null || box.flags.includes("\\NoInferiors"))
         return false;
     }
     // If this is an imapMailbox...
     if (oldBox && oldBox._children) {
       // Only delete now so we don't screw ourselves up if creation fails
       this.deleteMailbox(oldBox);
       oldBox._parent = box == this.root ? null : box;
       let newBox = new imapMailbox(subName, box, this.uidvalidity++);
@@ -182,45 +179,45 @@ imapDaemon.prototype = {
         this.inbox = new imapMailbox("INBOX", null, this.uidvalidity++);
         this.root.addMailbox(this.inbox);
       }
       oldBox.name = subName;
     } else if (oldBox) {
       // oldBox is a regular {} object, so it contains mailbox data but is not
       // a mailbox itself. Pass it into the constructor and let that deal with
       // it...
-      var childBox = new imapMailbox(subName, box == this.root ? null : box,
-                                     oldBox);
+      let childBox = new imapMailbox(subName, box == this.root ? null : box, oldBox);
       box.addMailbox(childBox);
       // And return the new mailbox, since this is being used by people setting
       // up the daemon.
       return childBox;
     } else {
       var creatable = hasFlag(this._flags, IMAP_FLAG_NEEDS_DELIMITER) ?
                       name[name.length - 1] == namespace.delimiter :
                       true;
-      var childBox = new imapMailbox(subName, box == this.root ? null : box,
-        { flags : creatable ? [] : ['\\NoInferiors'],
-          uidvalidity : this.uidvalidity++ });
+      let childBox = new imapMailbox(subName, box == this.root ? null : box, {
+        flags: creatable ? [] : ["\\NoInferiors"],
+        uidvalidity: this.uidvalidity++,
+      });
       box.addMailbox(childBox);
     }
     return true;
   },
-  deleteMailbox : function (mailbox) {
+  deleteMailbox(mailbox) {
     if (mailbox._children.length == 0) {
       // We don't preserve the subscribed state for deleted mailboxes
       var parentBox = mailbox._parent == null ? this.root : mailbox._parent;
       parentBox._children.splice(parentBox._children.indexOf(mailbox), 1);
     } else {
       // clear mailbox
       mailbox._messages = [];
       mailbox.flags.push("\\Noselect");
     }
-  }
-}
+  },
+};
 
 function imapMailbox(name, parent, state) {
   this.name = name;
   this._parent = parent;
   this._children = [];
   this._messages = [];
   this._updates = [];
 
@@ -243,203 +240,206 @@ function imapMailbox(name, parent, state
   this.setDefault("specialUseFlag", "");
   this.setDefault("uidnext", 1);
   this.setDefault("msgflags", ["\\Seen", "\\Answered", "\\Flagged",
                                "\\Deleted", "\\Draft"]);
   this.setDefault("permflags", ["\\Seen", "\\Answered", "\\Flagged",
                                 "\\Deleted", "\\Draft", "\\*"]);
 }
 imapMailbox.prototype = {
-  setDefault : function(prop, def) {
+  setDefault(prop, def) {
     this[prop] = prop in this ? this[prop] : def;
   },
-  addMailbox : function (mailbox) {
+  addMailbox(mailbox) {
     this._children.push(mailbox);
   },
-  getChild : function (name) {
-    var equal;
+  getChild(name) {
     for (var mailbox of this._children) {
       if (name == mailbox.name)
         return mailbox;
     }
     return null;
   },
-  matchKids : function (pattern) {
+  matchKids(pattern) {
     if (pattern == "")
       return this._parent ? this._parent.matchKids("") : [this];
 
     var portions = pattern.split(this.delimiter);
     var matching = [this];
     for (var folder of portions) {
       if (folder.length == 0)
         continue;
 
-      let generator = folder.indexOf("*") >= 0 ? "allChildren" : "_children";
-      let possible = matching.reduce(function (arr, elem) {
+      let generator = folder.includes("*") ? "allChildren" : "_children";
+      let possible = matching.reduce(function(arr, elem) {
         return arr.concat(elem[generator]);
       }, []);
 
-      if (folder == '*' || folder == '%') {
+      if (folder == "*" || folder == "%") {
         matching = possible;
         continue;
       }
 
-      let parts = folder.split(/[*%]/).filter(function (str) {
+      let parts = folder.split(/[*%]/).filter(function(str) {
           return str.length > 0;
       });
-      matching = possible.filter(function (mailbox) {
+      matching = possible.filter(function(mailbox) {
         let index = 0, name = mailbox.fullName;
         for (var part of parts) {
           index = name.indexOf(part, index);
           if (index == -1)
             return false;
         }
         return true;
       });
     }
     return matching;
   },
-  get fullName () {
+  get fullName() {
     return (this._parent ? this._parent.fullName + this.delimiter : "") +
            this.name;
   },
   get displayName() {
-    let manager = Cc['@mozilla.org/charset-converter-manager;1']
+    let manager = Cc["@mozilla.org/charset-converter-manager;1"]
                     .getService(Ci.nsICharsetConverterManager);
     // Escape backslash and double-quote with another backslash before encoding.
-    return manager.unicodeToMutf7(this.fullName.replace(/([\\"])/g, '\\$1'));
+    return manager.unicodeToMutf7(this.fullName.replace(/([\\"])/g, "\\$1"));
   },
   get allChildren() {
-    return this._children.reduce(function (arr, elem) {
+    return this._children.reduce(function(arr, elem) {
       return arr.concat(elem._allChildrenInternal);
     }, []);
   },
   get _allChildrenInternal() {
-    return this._children.reduce(function (arr, elem) {
+    return this._children.reduce(function(arr, elem) {
       return arr.concat(elem._allChildrenInternal);
     }, [this]);
   },
-  addMessage : function (message) {
+  addMessage(message) {
     this._messages.push(message);
     if (message.uid >= this.uidnext)
       this.uidnext = message.uid + 1;
-    if (this._updates.indexOf("EXISTS") == -1)
+    if (!this._updates.includes("EXISTS"))
       this._updates.push("EXISTS");
     if ("__highestuid" in this && message.uid > this.__highestuid)
       this.__highestuid = message.uid;
   },
-  get _highestuid () {
+  get _highestuid() {
     if ("__highestuid" in this)
       return this.__highestuid;
     var highest = 0;
     for (var message of this._messages)
       if (message.uid > highest)
         highest = message.uid;
     this.__highestuid = highest;
     return highest;
   },
-  expunge : function () {
+  expunge() {
     var response = "";
     for (var i = 0; i < this._messages.length; i++) {
-      if (this._messages[i].flags.indexOf("\\Deleted") >= 0) {
+      if (this._messages[i].flags.includes("\\Deleted")) {
         response += "* " + (i + 1) + " EXPUNGE\0";
         this._messages.splice(i--, 1);
       }
     }
     if (response.length > 0)
       delete this.__highestuid;
     return response;
-  }
-}
+  },
+};
 
 function imapMessage(URI, uid, flags) {
   this._URI = URI;
   this.uid = uid;
   this.size = 0;
-  this.flags = new Array;
+  this.flags = [];
   for (let flag in flags)
     this.flags.push(flag);
   this.recent = false;
 }
 imapMessage.prototype = {
   get channel() {
     return Services.io.newChannel(this._URI,
                                   null,
                                   null,
                                   null,
                                   Services.scriptSecurityManager.getSystemPrincipal(),
                                   null,
                                   Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
                                   Ci.nsIContentPolicy.TYPE_OTHER);
   },
-  setFlag : function (flag) {
-   if (this.flags.indexOf(flag) == -1)
+  setFlag(flag) {
+   if (!this.flags.includes(flag))
      this.flags.push(flag);
   },
   // This allows us to simulate servers that approximate the rfc822 size.
-  setSize: function(size) {
+  setSize(size) {
     this.size = size;
   },
-  clearFlag : function (flag) {
+  clearFlag(flag) {
     let index = this.flags.indexOf(flag);
     if (index != -1)
       this.flags.splice(index, 1);
   },
-  getText : function (start, length) {
+  getText(start, length) {
     if (!start)
       start = 0;
     if (!length)
       length = -1;
     var channel = this.channel;
     var istream = channel.open();
     var bstream = Cc["@mozilla.org/binaryinputstream;1"]
                     .createInstance(Ci.nsIBinaryInputStream);
     bstream.setInputStream(istream);
     var str = bstream.readBytes(start);
     if (str.length != start)
-      throw "Erm, we didn't just pass through 8-bit";
+      throw new Error("Erm, we didn't just pass through 8-bit");
     length = length == -1 ? istream.available() : length;
     if (length > istream.available())
       length = istream.available();
     str = bstream.readBytes(length);
     return str;
   },
 
   get _partMap() {
     if (this.__partMap)
       return this.__partMap;
     var partMap = {};
     var emitter = {
-      startPart: function imap_buildMap_startPart(partNum, headers) {
-        var imapPartNum = partNum.replace('$','');
+      startPart(partNum, headers) {
+        var imapPartNum = partNum.replace("$", "");
         // If there are multiple imap parts that this represents, we'll
         // overwrite with the latest. This is what we want (most deeply nested).
         partMap[imapPartNum] = [partNum, headers];
-      }
+      },
     };
-    MimeParser.parseSync(this.getText(), emitter,
-      {bodyformat: 'none', stripcontinuations: false});
+    MimeParser.parseSync(this.getText(), emitter, {
+      bodyformat: "none",
+      stripcontinuations: false,
+    });
     return this.__partMap = partMap;
   },
-  getPartHeaders: function (partNum) {
+  getPartHeaders(partNum) {
     return this._partMap[partNum][1];
   },
-  getPartBody: function (partNum) {
-    var body = '';
+  getPartBody(partNum) {
+    var body = "";
     var emitter = {
-      deliverPartData: function (partNum, data) {
+      deliverPartData(partNum, data) {
         body += data;
-      }
+      },
     };
     var mimePartNum = this._partMap[partNum][0];
-    MimeParser.parseSync(this.getText(), emitter,
-      { pruneat: mimePartNum, bodyformat: 'raw'});
+    MimeParser.parseSync(this.getText(), emitter, {
+      pruneat: mimePartNum,
+      bodyformat: "raw",
+    });
     return body;
-  }
-}
+  },
+};
 // IMAP FLAGS
 // If you don't specify any flag, no flags are set.
 /**
  * This flag represents whether or not the daemon is case-insensitive.
  */
 var IMAP_FLAG_CASE_INSENSITIVE = 1;
 /**
  * This flag represents whether or not CREATE hierarchies need a delimiter.
@@ -460,290 +460,282 @@ var IMAP_NAMESPACE_OTHER_USERS = 1;
 var IMAP_NAMESPACE_SHARED = 2;
 
 // IMAP server helpers
 var IMAP_STATE_NOT_AUTHED = 0;
 var IMAP_STATE_AUTHED = 1;
 var IMAP_STATE_SELECTED = 2;
 
 function parseCommand(text, partial) {
+  var args = [];
+  var current = args;
+  var stack = [];
   if (partial) {
-    var args = partial.args;
-    var current = partial.current;
-    var stack = partial.stack;
+    args = partial.args;
+    current = partial.current;
+    stack = partial.stack;
     current.push(partial.text);
-  } else {
-    var args = [];
-    var current = args;
-    var stack = [];
   }
-  var atom = '';
+  var atom = "";
   while (text.length > 0) {
     let c = text[0];
 
     if (c == '"') {
       let index = 1;
-      let s = '';
+      let s = "";
       while (index < text.length && text[index] != '"') {
-        if (text[index] == '\\') {
+        if (text[index] == "\\") {
           index++;
-          if (text[index] != '"' && text[index] != '\\')
-            throw "Expected quoted character";
+          if (text[index] != '"' && text[index] != "\\")
+            throw new Error("Expected quoted character");
         }
         s += text[index++];
       }
       if (index == text.length)
-        throw "Expected DQUOTE";
+        throw new Error("Expected DQUOTE");
       current.push(s);
-      text = text.substring(index+1);
+      text = text.substring(index + 1);
       continue;
-    } else if (c == '{') {
-      let end = text.indexOf('}');
+    } else if (c == "{") {
+      let end = text.indexOf("}");
       if (end == -1)
-        throw "Expected CLOSE_BRACKET";
-      if (end+1 != text.length)
-        throw "Expected CRLF";
+        throw new Error("Expected CLOSE_BRACKET");
+      if (end + 1 != text.length)
+        throw new Error("Expected CRLF");
       let length = parseInt(text.substring(1, end));
-      let state = {};
       // Usable state
-      throw { length : length, current : current, args : args, stack : stack,
-              text : '' };
-    } else if (c == '(') {
+      throw { length, current, args, stack, text: "" };
+    } else if (c == "(") {
       stack.push(current);
       current = [];
-    } else if (c == ')') {
+    } else if (c == ")") {
       if (atom.length > 0) {
         current.push(atom);
-        atom = '';
+        atom = "";
       }
       let hold = current;
       current = stack.pop();
       if (current == undefined)
-        throw "Unexpected CLOSE_PAREN";
+        throw new Error("Unexpected CLOSE_PAREN");
       current.push(hold);
-    } else if (c == ' ') {
+    } else if (c == " ") {
       if (atom.length > 0) {
         current.push(atom);
-        atom = '';
+        atom = "";
       }
     } else if (text.toUpperCase().startsWith("NIL") &&
-               (text.length == 3 || text[3] == ' ')) {
+               (text.length == 3 || text[3] == " ")) {
       current.push(null);
       text = text.substring(4);
       continue;
     } else {
       atom += c;
     }
     text = text.substring(1);
   }
   if (stack.length != 0)
-    throw "Expected CLOSE_PAREN!";
+    throw new Error("Expected CLOSE_PAREN!");
   if (atom.length > 0)
     args.push(atom);
   return args;
 }
 
 function formatArg(argument, spec) {
   // Get NILs out of the way quickly
   var nilAccepted = false;
-  if (spec.startsWith('n') && spec[1] != 'u') {
+  if (spec.startsWith("n") && spec[1] != "u") {
     spec = spec.substring(1);
     nilAccepted = true;
   }
   if (argument == null) {
     if (!nilAccepted)
-      throw "Unexpected NIL!";
+      throw new Error("Unexpected NIL!");
 
     return null;
   }
 
   // array!
-  if (spec.startsWith('(')) {
+  if (spec.startsWith("(")) {
     // typeof array is object. Don't ask me why.
     if (!Array.isArray(argument))
-      throw "Expected list!";
+      throw new Error("Expected list!");
     // Strip the '(' and ')'...
     spec = spec.substring(1, spec.length - 1);
     // ... and apply to the rest
-    return argument.map(function (item) { return formatArg(item, spec); });
+    return argument.map(function(item) { return formatArg(item, spec); });
   }
 
   // or!
-  var pipe = spec.indexOf('|');
+  var pipe = spec.indexOf("|");
   if (pipe > 0) {
     var first = spec.substring(0, pipe);
     try {
       return formatArg(argument, first);
     } catch (e) {
       return formatArg(argument, spec.substring(pipe + 1));
     }
   }
 
   // By now, we know that the input should be generated from an atom or string.
   if (typeof argument != "string")
-    throw "Expected argument of type " + spec + "!";
+    throw new Error("Expected argument of type " + spec + "!");
 
   if (spec == "atom") {
     argument = argument.toUpperCase();
   } else if (spec == "mailbox") {
-    let manager = Cc['@mozilla.org/charset-converter-manager;1']
+    let manager = Cc["@mozilla.org/charset-converter-manager;1"]
                     .getService(Ci.nsICharsetConverterManager);
     argument = manager.mutf7ToUnicode(argument);
   } else if (spec == "string") {
     // Do nothing
   } else if (spec == "flag") {
     argument = argument.toLowerCase();
-    if (!('a' <= argument[0] && argument[0] <= 'z') &&
-        !('A' <= argument[0] && argument[0] <= 'Z')) {
+    if (!("a" <= argument[0] && argument[0] <= "z") &&
+        !("A" <= argument[0] && argument[0] <= "Z")) {
       argument = argument[0] + argument[1].toUpperCase() + argument.substr(2);
     } else {
       argument = argument[0].toUpperCase() + argument.substr(1);
     }
   } else if (spec == "number") {
     if (argument == parseInt(argument))
       argument = parseInt(argument);
   } else if (spec == "date") {
     if (!(/^\d{1,2}-[A-Z][a-z]{2}-\d{4}( \d{2}(:\d{2}){2} [+-]\d{4})?$/.test(
           argument)))
-     throw "Expected date!";
-    argument = new Date(Date.parse(argument.replace(/-(?!\d{4}$)/g, ' ')));
+     throw new Error("Expected date!");
+    argument = new Date(Date.parse(argument.replace(/-(?!\d{4}$)/g, " ")));
   } else {
-    throw "Unknown spec " + spec;
+    throw new Error("Unknown spec " + spec);
   }
 
   return argument;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//                              IMAP TEST SERVERS                             //
-////////////////////////////////////////////////////////////////////////////////
-// Because of IMAP and the LEMONADE RFCs, we have a myriad of different       //
-// server configurations that we should ideally be supporting. We handle them //
-// by defining a core RFC 3501 implementation and then have different server  //
-// extensions subclass the server through functions below. However, we also   //
-// provide standard configurations for best handling.                         //
-// Configurations:                                                            //
-// * Barebones RFC 3501                                                       //
-// * Cyrus                                                                    //
-// * UW IMAP                                                                  //
-// * Courier                                                                  //
-// * Exchange                                                                 //
-// * Dovecot                                                                  //
-// * Zimbra                                                                   //
-// * GMail                                                                    //
-// KNOWN DEVIATIONS FROM RFC 3501:                                            //
-// + The autologout timer is 3 minutes, not 30 minutes. A test with a logout  //
-//   of 30 minutes would take a very long time if it failed.                  //
-// + SEARCH (except for UNDELETED) and STARTTLS are not supported,            //
-//   nor is all of FETCH.                                                     //
-// + Concurrent mailbox access is probably compliant with a rather liberal    //
-//   implementation of RFC 3501, although probably not what one would expect, //
-//   and certainly not what the Dovecot IMAP server tests expect.             //
-////////////////////////////////////////////////////////////////////////////////
+// IMAP TEST SERVERS
+// -----------------
+// Because of IMAP and the LEMONADE RFCs, we have a myriad of different
+// server configurations that we should ideally be supporting. We handle them
+// by defining a core RFC 3501 implementation and then have different server
+// extensions subclass the server through functions below. However, we also
+// provide standard configurations for best handling.
+// Configurations:
+// * Barebones RFC 3501
+// * Cyrus
+// * UW IMAP
+// * Courier
+// * Exchange
+// * Dovecot
+// * Zimbra
+// * GMail
+// KNOWN DEVIATIONS FROM RFC 3501:
+// + The autologout timer is 3 minutes, not 30 minutes. A test with a logout
+//   of 30 minutes would take a very long time if it failed.
+// + SEARCH (except for UNDELETED) and STARTTLS are not supported,
+//   nor is all of FETCH.
+// + Concurrent mailbox access is probably compliant with a rather liberal
+//   implementation of RFC 3501, although probably not what one would expect,
+//   and certainly not what the Dovecot IMAP server tests expect.
 
 /* IMAP Fakeserver operates in a different manner than the rest of fakeserver
  * because of some differences in the protocol. Commands are dispatched through
  * onError, which parses the message into components. Like other fakeserver
  * implementations, the command property will be called, but this time with an
  * argument that is an array of data items instead of a string representing the
  * rest of the line.
  */
 function IMAP_RFC3501_handler(daemon) {
-
   this.kUsername = "user";
   this.kPassword = "password";
   this.kAuthSchemes = []; // Added by RFC2195 extension. Test may modify as needed.
-  this.kCapabilities = [/*"LOGINDISABLED", "STARTTLS",*/]; // Test may modify as needed.
+  this.kCapabilities = [/* "LOGINDISABLED", "STARTTLS",*/]; // Test may modify as needed.
   this.kUidCommands = ["FETCH", "STORE", "SEARCH", "COPY"];
 
   this._daemon = daemon;
   this.closing = false;
   this.dropOnStartTLS = false;
   // map: property = auth scheme {String}, value = start function on this obj
   this._kAuthSchemeStartFunction = {};
 
   this._enabledCommands = {
     // IMAP_STATE_NOT_AUTHED
-    0: ['CAPABILITY', 'NOOP', 'LOGOUT', 'STARTTLS', 'AUTHENTICATE', 'LOGIN'],
+    0: ["CAPABILITY", "NOOP", "LOGOUT", "STARTTLS", "AUTHENTICATE", "LOGIN"],
     // IMAP_STATE_AUTHED
-    1: ['CAPABILITY', 'NOOP', 'LOGOUT', 'SELECT', 'EXAMINE', 'CREATE', 'DELETE',
-        'RENAME', 'SUBSCRIBE', 'UNSUBSCRIBE', 'LIST', 'LSUB', 'STATUS',
-        'APPEND'],
+    1: ["CAPABILITY", "NOOP", "LOGOUT", "SELECT", "EXAMINE", "CREATE", "DELETE",
+        "RENAME", "SUBSCRIBE", "UNSUBSCRIBE", "LIST", "LSUB", "STATUS",
+        "APPEND"],
     // IMAP_STATE_SELECTED
-    2: ['CAPABILITY', 'NOOP', 'LOGOUT', 'SELECT', 'EXAMINE', 'CREATE', 'DELETE',
-        'RENAME', 'SUBSCRIBE', 'UNSUBSCRIBE', 'LIST', 'LSUB', 'STATUS',
-        'APPEND', 'CHECK', 'CLOSE', 'EXPUNGE', 'SEARCH', 'FETCH', 'STORE',
-        'COPY', 'UID']
+    2: ["CAPABILITY", "NOOP", "LOGOUT", "SELECT", "EXAMINE", "CREATE", "DELETE",
+        "RENAME", "SUBSCRIBE", "UNSUBSCRIBE", "LIST", "LSUB", "STATUS",
+        "APPEND", "CHECK", "CLOSE", "EXPUNGE", "SEARCH", "FETCH", "STORE",
+        "COPY", "UID"],
   };
   // Format explanation:
   // atom -> UPPERCASE
   // string -> don't touch!
   // mailbox -> Apply ->UTF16 transformation with case-insensitivity stuff
   // flag -> Titlecase (or \Titlecase, $Titlecase, etc.)
   // date -> Make it a JSDate object
   // number -> Make it a number, if possible
   // ( ) -> list, apply flags as specified
   // [ ] -> optional argument.
   // x|y -> either x or y format.
   // ... -> variable args, don't parse
   this._argFormat = {
-    CAPABILITY : [],
-    NOOP : [],
-    LOGOUT : [],
-    STARTTLS : [],
-    AUTHENTICATE : ["atom", "..."],
-    LOGIN : ["string", "string"],
-    SELECT : ["mailbox"],
-    EXAMINE : ["mailbox"],
-    CREATE : ["mailbox"],
-    DELETE : ["mailbox"],
-    RENAME : ["mailbox", "mailbox"],
-    SUBSCRIBE : ["mailbox"],
-    UNSUBSCRIBE : ["mailbox"],
-    LIST : ["mailbox", "mailbox"],
-    LSUB : ["mailbox", "mailbox"],
-    STATUS : ["mailbox", "(atom)"],
-    APPEND : ["mailbox", "[(flag)]", "[date]", "string"],
-    CHECK : [],
-    CLOSE : [],
-    EXPUNGE : [],
-    SEARCH : ["atom", "..."],
-    FETCH : ["number", "atom|(atom|(atom))"],
-    STORE : ["number", "atom", "flag|(flag)"],
-    COPY : ["number", "mailbox"],
-    UID : ["atom", "..."]
+    CAPABILITY: [],
+    NOOP: [],
+    LOGOUT: [],
+    STARTTLS: [],
+    AUTHENTICATE: ["atom", "..."],
+    LOGIN: ["string", "string"],
+    SELECT: ["mailbox"],
+    EXAMINE: ["mailbox"],
+    CREATE: ["mailbox"],
+    DELETE: ["mailbox"],
+    RENAME: ["mailbox", "mailbox"],
+    SUBSCRIBE: ["mailbox"],
+    UNSUBSCRIBE: ["mailbox"],
+    LIST: ["mailbox", "mailbox"],
+    LSUB: ["mailbox", "mailbox"],
+    STATUS: ["mailbox", "(atom)"],
+    APPEND: ["mailbox", "[(flag)]", "[date]", "string"],
+    CHECK: [],
+    CLOSE: [],
+    EXPUNGE: [],
+    SEARCH: ["atom", "..."],
+    FETCH: ["number", "atom|(atom|(atom))"],
+    STORE: ["number", "atom", "flag|(flag)"],
+    COPY: ["number", "mailbox"],
+    UID: ["atom", "..."],
   };
 
   this.resetTest();
 }
 IMAP_RFC3501_handler.prototype = {
 
-  resetTest : function() {
+  resetTest() {
     this._state = IMAP_STATE_NOT_AUTHED;
     this._multiline = false;
     this._nextAuthFunction = undefined; // should be in RFC2195_ext, but too lazy
   },
-  onStartup : function () {
+  onStartup() {
     this._state = IMAP_STATE_NOT_AUTHED;
     return "* OK IMAP4rev1 Fakeserver started up";
   },
 
-  ////////////////////////////////////
-  // CENTRALIZED DISPATCH FUNCTIONS //
-  ////////////////////////////////////
+  // CENTRALIZED DISPATCH FUNCTIONS
 
   // IMAP sends commands in the form of "tag command args", but fakeserver
   // parsing tries to call the tag, which doesn't exist. Instead, we use this
   // error method to do the actual command dispatch. Mailnews uses numbers for
   // tags, which won't impede on actual commands.
-  onError : function (tag, realLine) {
+  onError(tag, realLine) {
     this._tag = tag;
     var space = realLine.indexOf(" ");
     var command = space == -1 ? realLine : realLine.substring(0, space);
-    realLine = space == -1 ? "" : realLine.substring(space+1);
+    realLine = space == -1 ? "" : realLine.substring(space + 1);
 
     // Now parse realLine into an array of atoms, etc.
     try {
       var args = parseCommand(realLine);
     } catch (state) {
       if (typeof state == "object") {
         this._partial = state;
         this._partial.command = command;
@@ -752,25 +744,25 @@ IMAP_RFC3501_handler.prototype = {
       }
 
       return this._tag + " BAD " + state;
     }
 
     // If we're here, we have a command with arguments. Dispatch!
     return this._dispatchCommand(command, args);
   },
-  onMultiline : function (line) {
+  onMultiline(line) {
     // A multiline arising form a literal being passed
     if (this._partial) {
       // There are two cases to be concerned with:
       // 1. The CRLF is internal or end (we want more)
       // 1a. The next line is the actual command stuff!
       // 2. The CRLF is in the middle (rest of the line is args)
       if (this._partial.length >= line.length + 2) { // Case 1
-        this._partial.text += line + '\r\n';
+        this._partial.text += line + "\r\n";
         this._partial.length -= line.length + 2;
         return undefined;
       } else if (this._partial.length != 0) {
         this._partial.text += line.substring(0, this._partial.length);
         line = line.substring(this._partial.length);
       }
       var command = this._partial.command;
       var args;
@@ -804,89 +796,90 @@ IMAP_RFC3501_handler.prototype = {
         return this._tag + " BAD I'm lost. Internal server error during auth";
       }
       try {
         return this._tag + " " + func.call(this, line);
       } catch (e) { return this._tag + " BAD " + e; }
     }
     return undefined;
   },
-  _dispatchCommand : function (command, args) {
+  _dispatchCommand(command, args) {
     this.sendingLiteral = false;
     command = command.toUpperCase();
     if (command == this._daemon.commandToFail.toUpperCase())
       return this._tag + " NO " + command + " failed";
+    var response;
     if (command in this) {
       this._lastCommand = command;
       // Are we allowed to execute this command?
-      if (this._enabledCommands[this._state].indexOf(command) == -1)
+      if (!this._enabledCommands[this._state].includes(command))
         return this._tag + " BAD illegal command for current state " + this._state;
 
       try {
         // Format the arguments nicely
         args = this._treatArgs(args, command);
 
       // UID command by itself is not useful for PerformTest
       if (command == "UID")
         this._lastCommand += " " + args[0];
 
         // Finally, run the thing
-        var response = this[command](args);
+        response = this[command](args);
       } catch (e) {
         if (typeof e == "string") {
-          var response = e;
+          response = e;
         } else {
           throw e;
         }
       }
     } else {
-      var response = "BAD " + command  + " not implemented";
+      response = "BAD " + command + " not implemented";
     }
 
     // Add status updates
     if (this._selectedMailbox) {
       for (var update of this._selectedMailbox._updates) {
-        var line;
+        let line;
         switch (update) {
         case "EXISTS":
           line = "* " + this._selectedMailbox._messages.length + " EXISTS";
           break;
         }
-        response = line + '\0' + response;
+        response = line + "\0" + response;
       }
     }
 
-    var lines = response.split(/\u0000/);
+    var lines = response.split("\0");
     response = "";
-    for (var line of lines) {
-      if (!line.startsWith('+') && !line.startsWith('*'))
+    for (let line of lines) {
+      if (!line.startsWith("+") && !line.startsWith("*"))
         response += this._tag + " ";
       response += line + "\r\n";
     }
     return response;
   },
-  _treatArgs : function (args, command) {
+  _treatArgs(args, command) {
     var format = this._argFormat[command];
     var treatedArgs = [];
     for (var i = 0; i < format.length; i++) {
       var spec = format[i];
 
       if (spec == "...") {
         treatedArgs = treatedArgs.concat(args);
         args = [];
         break;
       }
 
       if (args.length == 0)
-        if (spec.startsWith('[')) // == optional arg
+        if (spec.startsWith("[")) // == optional arg
           continue;
         else
-          throw "BAD not enough arguments";
+          throw new Error("BAD not enough arguments");
 
-      if (spec.startsWith('[')) {
+      if (spec.startsWith("[")) {
         // We have an optional argument. See if the format matches and move on
         // if it doesn't. Ideally, we'd rethink our decision if a later
         // application turns out to be wrong, but that's ugly to do
         // iteratively. Should any IMAP extension require it, we'll have to
         // come back and change this assumption, though.
         spec = spec.substr(1, spec.length - 2);
         try {
           var out = formatArg(args[0], spec);
@@ -895,209 +888,203 @@ IMAP_RFC3501_handler.prototype = {
         }
         treatedArgs.push(out);
         args.shift();
         continue;
       }
       try {
         treatedArgs.push(formatArg(args.shift(), spec));
       } catch (e) {
-        throw "BAD " + e;
+        throw new Error("BAD " + e);
       }
     }
     if (args.length != 0)
-      throw "BAD Too many arguments";
+      throw new Error("BAD Too many arguments");
     return treatedArgs;
   },
 
-  //////////////////////////
-  //  PROTOCOL COMMANDS   //
-  // (ordered as in spec) //
-  //////////////////////////
-  CAPABILITY : function (args) {
+  // PROTOCOL COMMANDS (ordered as in spec)
+
+  CAPABILITY(args) {
     var capa = "* CAPABILITY IMAP4rev1 " + this.kCapabilities.join(" ");
     if (this.kAuthSchemes.length > 0)
       capa += " AUTH=" + this.kAuthSchemes.join(" AUTH=");
-    capa += "\0" + "OK CAPABILITY completed";
+    capa += "\0OK CAPABILITY completed";
     return capa;
   },
-  LOGOUT : function (args) {
+  LOGOUT(args) {
     this.closing = true;
     if (this._selectedMailbox)
       this._daemon.synchronize(this._selectedMailbox, !this._readOnly);
     this._state = IMAP_STATE_NOT_AUTHED;
     return "* BYE IMAP4rev1 Logging out\0OK LOGOUT completed";
   },
-  NOOP : function (args) {
+  NOOP(args) {
     return "OK NOOP completed";
   },
-  STARTTLS : function (args) {
+  STARTTLS(args) {
     // simulate annoying server that drops connection on STARTTLS
     if (this.dropOnStartTLS) {
       this.closing = true;
       return "";
-    }
-    else
-      return "BAD maild doesn't support TLS ATM";
+    } return "BAD maild doesn't support TLS ATM";
   },
-  _nextAuthFunction : undefined,
-  AUTHENTICATE : function (args) {
+  _nextAuthFunction: undefined,
+  AUTHENTICATE(args) {
     var scheme = args[0]; // already uppercased by type "atom"
     // |scheme| contained in |kAuthSchemes|?
-    if (!this.kAuthSchemes.some(function (s) { return s == scheme; }))
+    if (!this.kAuthSchemes.some(function(s) { return s == scheme; }))
       return "-ERR AUTH " + scheme + " not supported";
 
     var func = this._kAuthSchemeStartFunction[scheme];
     if (!func || typeof(func) != "function")
       return "BAD I just pretended to implement AUTH " + scheme + ", but I don't";
     return func.apply(this, args.slice(1));
   },
-  LOGIN : function (args) {
-    if (this.kCapabilities.some(function(c) { return c == "LOGINDISABLED"; } ))
+  LOGIN(args) {
+    if (this.kCapabilities.some(function(c) { return c == "LOGINDISABLED"; }))
       return "BAD old-style LOGIN is disabled, use AUTHENTICATE";
-    if (args[0] == this.kUsername &&
-        args[1] == this.kPassword) {
+    if (args[0] == this.kUsername && args[1] == this.kPassword) {
       this._state = IMAP_STATE_AUTHED;
       return "OK authenticated";
     }
-    else
-      return "BAD invalid password, I won't authenticate you";
+    return "BAD invalid password, I won't authenticate you";
   },
-  SELECT : function (args) {
+  SELECT(args) {
     var box = this._daemon.getMailbox(args[0]);
     if (!box)
       return "NO no such mailbox";
 
     if (this._selectedMailbox)
       this._daemon.synchronize(this._selectedMailbox, !this._readOnly);
     this._state = IMAP_STATE_SELECTED;
     this._selectedMailbox = box;
     this._readOnly = false;
 
     var response = "* FLAGS (" + box.msgflags.join(" ") + ")\0";
     response += "* " + box._messages.length + " EXISTS\0* ";
-    response += box._messages.reduce(function (count, message) {
+    response += box._messages.reduce(function(count, message) {
       return count + (message.recent ? 1 : 0);
     }, 0);
     response += " RECENT\0";
     for (var i = 0; i < box._messages.length; i++) {
-      if (box._messages[i].flags.indexOf("\\Seen") == -1) {
+      if (!box._messages[i].flags.includes("\\Seen")) {
         response += "* OK [UNSEEN " + (i + 1) + "]\0";
         break;
       }
     }
     response += "* OK [PERMANENTFLAGS (" + box.permflags.join(" ") + ")]\0";
     response += "* OK [UIDNEXT " + box.uidnext + "]\0";
     if ("uidvalidity" in box)
       response += "* OK [UIDVALIDITY " + box.uidvalidity + "]\0";
     return response + "OK [READ-WRITE] SELECT completed";
   },
-  EXAMINE : function (args) {
+  EXAMINE(args) {
     var box = this._daemon.getMailbox(args[0]);
     if (!box)
       return "NO no such mailbox";
 
     if (this._selectedMailbox)
       this._daemon.synchronize(this._selectedMailbox, !this._readOnly);
     this._state = IMAP_STATE_SELECTED;
     this._selectedMailbox = box;
     this._readOnly = true;
 
     var response = "* FLAGS (" + box.msgflags.join(" ") + ")\0";
     response += "* " + box._messages.length + " EXISTS\0* ";
-    response += box._messages.reduce(function (count, message) {
+    response += box._messages.reduce(function(count, message) {
       return count + (message.recent ? 1 : 0);
     }, 0);
     response += " RECENT\0";
     for (var i = 0; i < box._messages.length; i++) {
-      if (box._messages[i].flags.indexOf("\\Seen") == -1) {
+      if (!box._messages[i].flags.includes("\\Seen")) {
         response += "* OK [UNSEEN " + (i + 1) + "]\0";
         break;
       }
     }
     response += "* OK [PERMANENTFLAGS (" + box.permflags.join(" ") + ")]\0";
     response += "* OK [UIDNEXT " + box.uidnext + "]\0";
     response += "* OK [UIDVALIDITY " + box.uidvalidity + "]\0";
     return response + "OK [READ-ONLY] EXAMINE completed";
   },
-  CREATE : function (args) {
+  CREATE(args) {
     if (this._daemon.getMailbox(args[0]))
       return "NO mailbox already exists";
     if (!this._daemon.createMailbox(args[0]))
       return "NO cannot create mailbox";
     return "OK CREATE completed";
   },
-  DELETE : function (args) {
+  DELETE(args) {
     var mbox = this._daemon.getMailbox(args[0]);
     if (!mbox || mbox.name == "")
       return "NO no such mailbox";
     if (mbox._children.length > 0) {
       for (let i = 0; i < mbox.flags.length; i++)
         if (mbox.flags[i] == "\\Noselect")
           return "NO cannot delete mailbox";
     }
     this._daemon.deleteMailbox(mbox);
     return "OK DELETE completed";
   },
-  RENAME : function (args) {
+  RENAME(args) {
     var mbox = this._daemon.getMailbox(args[0]);
     if (!mbox || mbox.name == "")
       return "NO no such mailbox";
     if (!this._daemon.createMailbox(args[1], mbox))
       return "NO cannot rename mailbox";
     return "OK RENAME completed";
   },
-  SUBSCRIBE : function (args) {
+  SUBSCRIBE(args) {
     var mailbox = this._daemon.getMailbox(args[0]);
     if (!mailbox)
       return "NO error in subscribing";
     mailbox.subscribed = true;
     return "OK SUBSCRIBE completed";
   },
-  UNSUBSCRIBE : function (args) {
+  UNSUBSCRIBE(args) {
     var mailbox = this._daemon.getMailbox(args[0]);
     if (mailbox)
       mailbox.subscribed = false;
     return "OK UNSUBSCRIBE completed";
   },
-  LIST : function (args) {
+  LIST(args) {
     // even though this is the LIST function for RFC 3501, code for
     // LIST-EXTENDED (RFC 5258) is included here to keep things simple and
     // avoid duplication. We can get away with this because the _treatArgs
     // function filters out invalid args for servers that don't support
     // LIST-EXTENDED before they even get here.
 
     let listFunctionName = "_LIST";
     // check for optional list selection options argument used by LIST-EXTENDED
     // and other related RFCs
     if (args.length == 3 || (args.length > 3 && args[3] == "RETURN")) {
       let selectionOptions = args.shift();
-      selectionOptions = selectionOptions.toString().split(' ');
+      selectionOptions = selectionOptions.toString().split(" ");
       selectionOptions.sort();
       for (let option of selectionOptions) {
         listFunctionName += "_" + option.replace(/-/g, "_");
       }
     }
     // check for optional list return options argument used by LIST-EXTENDED
     // and other related RFCs
     if ((args.length > 2 && args[2] == "RETURN") ||
-        this.kCapabilities.indexOf("CHILDREN") >= 0) {
+        this.kCapabilities.includes("CHILDREN")) {
       listFunctionName += "_RETURN";
-      let returnOptions = args[3] ? args[3].toString().split(' ') : [];
-      if ((this.kCapabilities.indexOf("CHILDREN") >= 0) &&
-          (returnOptions.indexOf("CHILDREN") == -1)) {
+      let returnOptions = args[3] ? args[3].toString().split(" ") : [];
+      if ((this.kCapabilities.includes("CHILDREN")) &&
+          (!returnOptions.includes("CHILDREN"))) {
         returnOptions.push("CHILDREN");
       }
       returnOptions.sort();
       for (let option of returnOptions) {
         listFunctionName += "_" + option.replace(/-/g, "_");
       }
     }
     if (!this[listFunctionName])
-      return 'BAD unknown LIST request options';
+      return "BAD unknown LIST request options";
 
     let base = this._daemon.getMailbox(args[0]);
     if (!base)
       return "NO no such mailbox";
     let requestedBoxes;
     // check for multiple mailbox patterns used by LIST-EXTENDED
     // and other related RFCs
     if (args[1].startsWith("(")) {
@@ -1110,241 +1097,238 @@ IMAP_RFC3501_handler.prototype = {
       let people = base.matchKids(requestedBox);
       for (let box of people) {
         response += this[listFunctionName](box);
       }
     }
     return response + "OK LIST completed";
   },
   // _LIST is the standard LIST command response
-  _LIST : function (aBox) {
+  _LIST(aBox) {
     if (aBox.nonExistent) {
       return "";
     }
-    return '* LIST (' + aBox.flags.join(" ") + ') "' + aBox.delimiter +
+    return "* LIST (" + aBox.flags.join(" ") + ') "' + aBox.delimiter +
            '" "' + aBox.displayName + '"\0';
   },
-  LSUB : function (args) {
+  LSUB(args) {
     var base = this._daemon.getMailbox(args[0]);
     if (!base)
       return "NO no such mailbox";
     var people = base.matchKids(args[1]);
     var response = "";
     for (var box of people) {
       if (box.subscribed)
         response += '* LSUB () "' + box.delimiter +
                     '" "' + box.displayName + '"\0';
     }
     return response + "OK LSUB completed";
   },
-  STATUS : function (args) {
+  STATUS(args) {
     var box = this._daemon.getMailbox(args[0]);
     if (!box)
       return "NO no such mailbox exists";
     for (let i = 0; i < box.flags.length; i++)
       if (box.flags[i] == "\\Noselect")
         return "NO STATUS not allowed on Noselect folder";
     var parts = [];
     for (var status of args[1]) {
       var line = status + " ";
       switch (status) {
       case "MESSAGES":
         line += box._messages.length;
         break;
       case "RECENT":
-        line += box._messages.reduce(function (count, message) {
+        line += box._messages.reduce(function(count, message) {
           return count + (message.recent ? 1 : 0);
         }, 0);
         break;
       case "UIDNEXT":
         line += box.uidnext;
         break;
       case "UIDVALIDITY":
         line += box.uidvalidity;
         break;
       case "UNSEEN":
-        line += box._messages.reduce(function (count, message) {
-          return count + (message.flags.indexOf('\\Seen') == -1 ? 1 : 0);
+        line += box._messages.reduce(function(count, message) {
+          return count + (message.flags.includes("\\Seen") ? 0 : 1);
         }, 0);
         break;
       default:
         return "BAD unknown status flag: " + status;
       }
       parts.push(line);
     }
-    return "* STATUS \"" + args[0] + "\" (" + parts.join(' ') +
+    return "* STATUS \"" + args[0] + "\" (" + parts.join(" ") +
            ")\0OK STATUS completed";
   },
-  APPEND : function (args) {
+  APPEND(args) {
     var mailbox = this._daemon.getMailbox(args[0]);
     if (!mailbox)
       return "NO [TRYCREATE] no such mailbox";
+    var flags, date, text;
     if (args.length == 3) {
       if (args[1] instanceof Date) {
-        var flags = [];
-        var date = args[1];
+        flags = [];
+        date = args[1];
       } else {
-        var flags = args[1];
-        var date = Date.now();
+        flags = args[1];
+        date = Date.now();
       }
-      var text = args[2];
+      text = args[2];
     } else if (args.length == 4) {
-      var flags = args[1];
-      var date = args[2];
-      var text = args[3];
+      flags = args[1];
+      date = args[2];
+      text = args[3];
     } else {
-      var flags = [];
-      var date = Date.now();
-      var text = args[1];
+      flags = [];
+      date = Date.now();
+      text = args[1];
     }
     var msg = new imapMessage("data:text/plain," + encodeURI(text),
                               mailbox.uidnext++, flags);
     msg.recent = true;
     msg.date = date;
     mailbox.addMessage(msg);
     return "OK APPEND complete";
   },
-  CHECK : function (args) {
+  CHECK(args) {
     this._daemon.synchronize(this._selectedMailbox, false);
     return "OK CHECK completed";
   },
-  CLOSE : function (args) {
+  CLOSE(args) {
     this._selectedMailbox.expunge();
     this._daemon.synchronize(this._selectedMailbox, !this._readOnly);
     this._selectedMailbox = null;
     this._state = IMAP_STATE_AUTHED;
     return "OK CLOSE completed";
   },
-  EXPUNGE : function (args) {
+  EXPUNGE(args) {
     // Will be either empty or LF-terminated already
     var response = this._selectedMailbox.expunge();
     this._daemon.synchronize(this._selectedMailbox);
     return response + "OK EXPUNGE completed";
   },
-  SEARCH : function (args, uid) {
+  SEARCH(args, uid) {
     if (args[0] == "UNDELETED") {
       let response = "* SEARCH";
       let messages = this._selectedMailbox._messages;
       for (let i = 0; i < messages.length; i++) {
-        if (messages[i].flags.indexOf("\\Deleted") == -1)
+        if (!messages[i].flags.includes("\\Deleted"))
           response += " " + messages[i].uid;
       }
-      response += '\0';
+      response += "\0";
       return response + "OK SEARCH COMPLETED\0";
     }
-    else
-      return "BAD not here yet";
+    return "BAD not here yet";
   },
-  FETCH : function (args, uid) {
+  FETCH(args, uid) {
     // Step 1: Get the messages to fetch
     var ids = [];
     var messages = this._parseSequenceSet(args[0], uid, ids);
 
     // Step 2: Ensure that the fetching items are in a neat format
     if (typeof args[1] == "string") {
       if (args[1] in this.fetchMacroExpansions)
         args[1] = this.fetchMacroExpansions[args[1]];
       else
         args[1] = [args[1]];
     }
-    if (uid && args[1].indexOf("UID") == -1)
+    if (uid && !args[1].includes("UID"))
       args[1].push("UID");
 
     // Step 2.1: Preprocess the item fetch stack
     var items = [], prefix = undefined;
-    for (var item of args[1]) {
-      if (item.indexOf('[') > 0 && item.indexOf(']') == -1) {
+    for (let item of args[1]) {
+      if (item.indexOf("[") > 0 && !item.includes("]")) {
         // We want to append everything into an item until we find a ']'
-        prefix = item + ' ';
+        prefix = item + " ";
         continue;
       }
       if (prefix !== undefined) {
-        if (typeof item != "string" || item.indexOf(']') == -1) {
-          prefix += (typeof item == "string" ? item : '(' + item.join(' ') + ')')
-                  + ' ';
+        if (typeof item != "string" || !item.includes("]")) {
+          prefix += (typeof item == "string" ? item : "(" + item.join(" ") + ")") + " ";
           continue;
         }
         // Replace superfluous space with a ']'.
-        prefix = prefix.substr(0, prefix.length - 1) + ']';
+        prefix = prefix.substr(0, prefix.length - 1) + "]";
         item = prefix;
         prefix = undefined;
       }
       item = item.toUpperCase();
-      if (items.indexOf(item) == -1)
+      if (!items.includes(item))
         items.push(item);
     }
 
     // Step 3: Fetch time!
     var response = "";
     for (var i = 0; i < messages.length; i++) {
       response += "* " + ids[i] + " FETCH (";
       var parts = [];
-      for (var item of items) {
-
+      for (let item of items) {
         // Brief explanation: an item like BODY[]<> can't be hardcoded easily,
         // so we go for the initial alphanumeric substring, passing in the
         // actual string as an optional second part.
         var front = item.split(/[^A-Z0-9-]/, 1)[0];
         var functionName = "_FETCH_" + front.replace(/-/g, "_");
 
         if (!(functionName in this))
           return "BAD can't fetch " + front;
         try {
           parts.push(this[functionName](messages[i], item));
         } catch (ex) {
-
-          return "BAD error in fetching: "+ex;
+          return "BAD error in fetching: " + ex;
         }
       }
-      response += parts.join(" ") + ')\0';
+      response += parts.join(" ") + ")\0";
     }
     return response + "OK FETCH completed";
   },
-  STORE : function (args, uid) {
+  STORE(args, uid) {
     var ids = [];
     var messages = this._parseSequenceSet(args[0], uid, ids);
 
     args[1] = args[1].toUpperCase();
-    var silent = args[1].includes('.SILENT', 1);
+    var silent = args[1].includes(".SILENT", 1);
     if (silent)
-      args[1] = args[1].substring(0, args[1].indexOf('.'));
+      args[1] = args[1].substring(0, args[1].indexOf("."));
 
     if (typeof args[2] != "object")
       args[2] = [args[2]];
 
     var response = "";
     for (var i = 0; i < messages.length; i++) {
       var message = messages[i];
       switch (args[1]) {
       case "FLAGS":
         message.flags = args[2];
         break;
       case "+FLAGS":
-        for (var flag of args[2])
+        for (let flag of args[2])
           message.setFlag(flag);
         break;
       case "-FLAGS":
-        for (var flag of args[2]) {
+        for (let flag of args[2]) {
           var index;
           if ((index = message.flags.indexOf(flag)) != -1)
             message.flags.splice(index, 1);
         }
         break;
       default:
         return "BAD change what now?";
       }
       response += "* " + ids[i] + " FETCH (FLAGS (";
-      response += message.flags.join(' ');
-      response += '))\0';
+      response += message.flags.join(" ");
+      response += "))\0";
     }
     if (silent)
       response = "";
-    return response + 'OK STORE completed';
+    return response + "OK STORE completed";
   },
-  COPY : function (args, uid) {
+  COPY(args, uid) {
     var messages = this._parseSequenceSet(args[0], uid);
 
     var dest = this._daemon.getMailbox(args[1]);
     if (!dest)
       return "NO [TRYCREATE] what mailbox?";
 
     for (var message of messages) {
       let newMessage = new imapMessage(message._URI, dest.uidnext++,
@@ -1360,239 +1344,242 @@ IMAP_RFC3501_handler.prototype = {
       while (true) {
         alarm = new Date();
         if (alarm.getTime() - startingMSeconds > this._daemon.copySleep)
           break;
       }
     }
     return "OK COPY completed";
   },
-  UID : function (args) {
+  UID(args) {
     var name = args.shift();
-    if (this.kUidCommands.indexOf(name) == -1)
+    if (!this.kUidCommands.includes(name))
       return "BAD illegal command " + name;
 
     args = this._treatArgs(args, name);
     return this[name](args, true);
   },
 
-  postCommand : function (reader) {
+  postCommand(reader) {
     if (this.closing) {
       this.closing = false;
       reader.closeSocket();
     }
     if (this.sendingLiteral)
       reader.preventLFMunge();
     reader.setMultiline(this._multiline);
     if (this._lastCommand == reader.watchWord)
       reader.stopTest();
   },
-  onServerFault : function (e) {
-    return ("_tag" in this ? this._tag : '*') + ' BAD Internal server error: ' + e;
+  onServerFault(e) {
+    return ("_tag" in this ? this._tag : "*") + " BAD Internal server error: " + e;
   },
 
-  ////////////////////////////////////
-  // FETCH sub commands and helpers //
-  ////////////////////////////////////
-  fetchMacroExpansions : {
-    ALL: ["FLAGS", "INTERNALDATE", "RFC822.SIZE", /*"ENVELOPE"*/],
+  // FETCH sub commands and helpers
+
+  fetchMacroExpansions: {
+    ALL: ["FLAGS", "INTERNALDATE", "RFC822.SIZE"/* , "ENVELOPE"*/],
     FAST: ["FLAGS", "INTERNALDATE", "RFC822.SIZE"],
-    FULL: ["FLAGS", "INTERNALDATE", "RFC822.SIZE", /*"ENVELOPE", "BODY"*/]
+    FULL: ["FLAGS", "INTERNALDATE", "RFC822.SIZE"/* , "ENVELOPE", "BODY"*/],
   },
-  _parseSequenceSet : function (set, uid, ids /*optional*/) {
+  _parseSequenceSet(set, uid, ids /* optional*/) {
     if (typeof set == "number") {
       if (uid) {
-        for (var i = 0; i < this._selectedMailbox._messages.length; i++) {
+        for (let i = 0; i < this._selectedMailbox._messages.length; i++) {
           var message = this._selectedMailbox._messages[i];
           if (message.uid == set) {
             if (ids)
               ids.push(i + 1);
             return [message];
           }
         }
         return [];
-      } else {
-        if (!(set - 1 in this._selectedMailbox._messages))
-          return [];
-        if (ids)
-          ids.push(set);
-        return [this._selectedMailbox._messages[set - 1]];
       }
+      if (!(set - 1 in this._selectedMailbox._messages))
+        return [];
+      if (ids)
+        ids.push(set);
+      return [this._selectedMailbox._messages[set - 1]];
     }
 
     var daemon = this;
     function part2num(part) {
-      if (part == '*') {
+      if (part == "*") {
         if (uid)
           return daemon._selectedMailbox._highestuid;
-        else
-          return daemon._selectedMailbox._messages.length;
+        return daemon._selectedMailbox._messages.length;
       }
       let re = /[0-9]/g;
       let num = part.match(re);
-      if(!num || (num.length != part.length))
-        throw "BAD invalid UID " + part;
+      if (!num || (num.length != part.length))
+        throw new Error("BAD invalid UID " + part);
       return parseInt(part);
     }
 
     var elements = set.split(/,/);
     set = [];
     for (var part of elements) {
-      if (!part.includes(':')) {
+      if (!part.includes(":")) {
         set.push(part2num(part));
       } else {
         var range = part.split(/:/);
         range[0] = part2num(range[0]);
         range[1] = part2num(range[1]);
         if (range[0] > range[1]) {
           let temp = range[1];
           range[1] = range[0];
           range[0] = temp;
         }
         for (let i = range[0]; i <= range[1]; i++)
           set.push(i);
       }
     }
     set.sort();
-    for (var i = set.length - 1; i > 0; i--) {
+    for (let i = set.length - 1; i > 0; i--) {
       if (set[i] == set[i - 1])
         set.splice(i, 0);
     }
 
     if (!ids)
       ids = [];
+    var messages;
     if (uid) {
-      var messages = this._selectedMailbox._messages.filter(function (msg, i) {
-        if (set.indexOf(msg.uid) == -1)
+      messages = this._selectedMailbox._messages.filter(function(msg, i) {
+        if (!set.includes(msg.uid))
           return false;
         ids.push(i + 1);
         return true;
       });
     } else {
-      var messages = [];
+      messages = [];
       for (var id of set) {
         if (id - 1 in this._selectedMailbox._messages) {
           ids.push(id);
           messages.push(this._selectedMailbox._messages[id - 1]);
         }
       }
     }
     return messages;
   },
-  _FETCH_BODY : function (message, query) {
+  _FETCH_BODY(message, query) {
     if (query == "BODY")
       return "BODYSTRUCTURE " + bodystructure(message.getText(), false);
     // parts = [ name, section, empty, {, partial, empty } ]
     var parts = query.split(/[[\]<>]/);
 
     if (parts[0] != "BODY.PEEK" && !this._readOnly)
       message.setFlag("\\Seen");
 
     if (parts[3])
-      parts[3] = parts[3].split(/\./).map(function (e) { return parseInt(e); });
+      parts[3] = parts[3].split(/\./).map(function(e) { return parseInt(e); });
 
     if (parts[1].length == 0) {
       // Easy case: we have BODY[], just send the message...
-      var response = "BODY[]";
+      let response = "BODY[]";
+      var text;
       if (parts[3]) {
         response += "<" + parts[3][0] + ">";
-        var text = message.getText(parts[3][0], parts[3][1]);
+        text = message.getText(parts[3][0], parts[3][1]);
       } else {
-        var text = message.getText();
+        text = message.getText();
       }
       response += " {" + text.length + "}\r\n";
       response += text;
       return response;
     }
 
     // What's inside the command?
     var data = /((?:\d+\.)*\d+)(?:\.([^ ]+))?/.exec(parts[1]);
+    var partNum;
     if (data) {
-      var partNum = data[1];
+      partNum = data[1];
       query = data[2];
     } else {
-      var partNum = "";
+      partNum = "";
       if (parts[1].includes(" ", 1))
         query = parts[1].substring(0, parts[1].indexOf(" "));
       else
         query = parts[1];
     }
+    var queryArgs;
     if (parts[1].includes(" ", 1))
-      var queryArgs = parseCommand(parts[1].substr(parts[1].indexOf(" ")))[0];
+      queryArgs = parseCommand(parts[1].substr(parts[1].indexOf(" ")))[0];
     else
-      var queryArgs = [];
+      queryArgs = [];
 
     // Now we have three parameters representing the part number (empty for top-
     // level), the subportion representing what we want to find (empty for the
     // body), and an array of arguments if we have a subquery. If we made an
     // error here, it will pop until it gets to FETCH, which will just pop at a
     // BAD response, which is what should happen if the query is malformed.
     // Now we dump it all off onto imapMessage to mess with.
 
     // Start off the response
-    var response = "BODY[" + parts[1] + "]";
+    let response = "BODY[" + parts[1] + "]";
     if (parts[3])
       response += "<" + parts[3][0] + ">";
     response += " ";
 
-    var data = "";
+    data = "";
     switch (query) {
     case "":
     case "TEXT":
       data += message.getPartBody(partNum);
       break;
     case "HEADER": // I believe this specifies mime for an RFC822 message only
       data += message.getPartHeaders(partNum).rawHeaderText + "\r\n";
       break;
     case "MIME":
       data += message.getPartHeaders(partNum).rawHeaderText + "\r\n\r\n";
       break;
-    case "HEADER.FIELDS":
-      var joinList = [];
-      var headers = message.getPartHeaders(partNum);
+    case "HEADER.FIELDS": {
+      let joinList = [];
+      let headers = message.getPartHeaders(partNum);
       for (let header of queryArgs) {
         header = header.toLowerCase();
         if (headers.has(header))
           joinList.push(headers.getRawHeader(header).map(value =>
-                         `${header}: ${value}`).join('\r\n'));
+                         `${header}: ${value}`).join("\r\n"));
       }
-      data += joinList.join('\r\n') + "\r\n";
+      data += joinList.join("\r\n") + "\r\n";
       break;
-    case "HEADER.FIELDS.NOT":
-      var joinList = [];
-      var headers = message.getPartHeaders(partNum);
+    }
+    case "HEADER.FIELDS.NOT": {
+      let joinList = [];
+      let headers = message.getPartHeaders(partNum);
       for (let header of headers) {
         if (!(header in queryArgs))
           joinList.push(headers.getRawHeader(header).map(value =>
-                         `${header}: ${value}`).join('\r\n'));
+                         `${header}: ${value}`).join("\r\n"));
       }
-      data += joinList.join('\r\n') + "\r\n";
+      data += joinList.join("\r\n") + "\r\n";
       break;
+    }
     default:
       data += message.getPartBody(partNum);
     }
 
     this.sendingLiteral = true;
-    response += '{' + data.length + '}\r\n';
+    response += "{" + data.length + "}\r\n";
     response += data;
     return response;
   },
-  _FETCH_BODYSTRUCTURE : function (message, query) {
+  _FETCH_BODYSTRUCTURE(message, query) {
     return "BODYSTRUCTURE " + bodystructure(message.getText(), true);
   },
-  //_FETCH_ENVELOPE,
-  _FETCH_FLAGS : function (message) {
+  // _FETCH_ENVELOPE,
+  _FETCH_FLAGS(message) {
     var response = "FLAGS (";
     response += message.flags.join(" ");
     if (message.recent)
       response += " \\Recent";
     response += ")";
     return response;
   },
-  _FETCH_INTERNALDATE : function (message) {
+  _FETCH_INTERNALDATE(message) {
     let date = message.date;
     // Format timestamp as: "%d-%b-%Y %H:%M:%S %z" (%b in English).
     let year = date.getFullYear().toString();
     let month = date.toLocaleDateString("en-US", {month: "short"});
     let day = date.getDate().toString();
     let hours = date.getHours().toString().padStart(2, "0");
     let minutes = date.getMinutes().toString().padStart(2, "0");
     let seconds = date.getSeconds().toString().padStart(2, "0");
@@ -1600,17 +1587,17 @@ IMAP_RFC3501_handler.prototype = {
     let tzoff = Math.floor(Math.abs(offset) / 60) * 100 + Math.abs(offset) % 60;
     let timeZone = (offset < 0 ? "+" : "-") + tzoff.toString().padStart(4, "0");
 
     let response = "INTERNALDATE \"";
     response += `${day}-${month}-${year} ${hours}:${minutes}:${seconds} ${timeZone}`;
     response += "\"";
     return response;
   },
-  _FETCH_RFC822 : function (message, query) {
+  _FETCH_RFC822(message, query) {
     if (query == "RFC822")
       return this._FETCH_BODY(message, "BODY[]").replace("BODY[]", "RFC822");
     if (query == "RFC822.HEADER")
       return this._FETCH_BODY(message, "BODY.PEEK[HEADER]")
                  .replace("BODY[HEADER]", "RFC822.HEADER");
     if (query == "RFC822.TEXT")
       return this._FETCH_BODY(message, "BODY[TEXT]")
                  .replace("BODY[TEXT]", "RFC822.TEXT");
@@ -1619,124 +1606,128 @@ IMAP_RFC3501_handler.prototype = {
       var channel = message.channel;
       var length = message.size ? message.size : channel.contentLength;
       if (length == -1) {
         var inputStream = channel.open();
         length = inputStream.available();
         inputStream.close();
       }
       return "RFC822.SIZE " + length;
-    } else {
-      throw "Unknown item "+query;
     }
+    throw new Error("Unknown item " + query);
   },
-  _FETCH_UID : function (message) {
+  _FETCH_UID(message) {
     return "UID " + message.uid;
-  }
-}
+  },
+};
 
-////////////////////////////////////////////////////////////////////////////////
-//                            IMAP4 RFC extensions                            //
-////////////////////////////////////////////////////////////////////////////////
-// Since there are so many extensions to IMAP, and since these extensions are //
-// not strictly hierarchical (e.g., an RFC 2342-compliant server can also be  //
-// RFC 3516-compliant, but a server might only implement one of them), they   //
-// must be handled differently from other fakeserver implementations.         //
-// An extension is defined as follows: it is an object (not a function and    //
-// prototype pair!). This object is "mixed" into the handler via the helper   //
-// function mixinExtension, which applies appropriate magic to make the       //
-// handler compliant to the extension. Functions are added untransformed, but //
-// both arrays and objects are handled by appending the values onto the       //
-// original state of the handler. Semantics apply as for the base itself.     //
-////////////////////////////////////////////////////////////////////////////////
+// IMAP4 RFC extensions
+// --------------------
+// Since there are so many extensions to IMAP, and since these extensions are
+// not strictly hierarchical (e.g., an RFC 2342-compliant server can also be
+// RFC 3516-compliant, but a server might only implement one of them), they
+// must be handled differently from other fakeserver implementations.
+// An extension is defined as follows: it is an object (not a function and
+// prototype pair!). This object is "mixed" into the handler via the helper
+// function mixinExtension, which applies appropriate magic to make the
+// handler compliant to the extension. Functions are added untransformed, but
+// both arrays and objects are handled by appending the values onto the
+// original state of the handler. Semantics apply as for the base itself.
 
 // Note that UIDPLUS (RFC4315) should be mixed in last (or at least after the
 // MOVE extension) because it changes behavior of that extension.
 var configurations = {
   Cyrus: ["RFC2342", "RFC2195", "RFC5258"],
   UW: ["RFC2342", "RFC2195"],
   Dovecot: ["RFC2195", "RFC5258"],
   Zimbra: ["RFC2197", "RFC2342", "RFC2195", "RFC5258"],
   Exchange: ["RFC2342", "RFC2195"],
   LEMONADE: ["RFC2342", "RFC2195"],
   CUSTOM1: ["MOVE", "RFC4315", "CUSTOM"],
-  GMail: ["GMAIL", "RFC2197", "RFC2342", "RFC3348", "RFC4315"]
+  GMail: ["GMAIL", "RFC2197", "RFC2342", "RFC3348", "RFC4315"],
 };
 
 function mixinExtension(handler, extension) {
   if (extension.preload)
     extension.preload(handler);
 
   for (var property in extension) {
-    if (property == 'preload')
+    if (property == "preload")
       continue;
     if (typeof extension[property] == "function") {
       // This is a function, so we add it to the handler
       handler[property] = extension[property];
     } else if (extension[property] instanceof Array) {
       // This is an array, so we append the values
       if (!(property in handler))
         handler[property] = [];
       handler[property] = handler[property].concat(extension[property]);
+    } else if (property in handler) { // This is an object, so we add in the values
+      // Hack to make arrays et al. work recursively
+      mixinExtension(handler[property], extension[property]);
     } else {
-      // This is an object, so we add in the values
-      if (property in handler)
-        // Hack to make arrays et al. work recursively
-        mixinExtension(handler[property], extension[property]);
-      else
-        handler[property] = extension[property];
+      handler[property] = extension[property];
     }
   }
 }
 
 // Support for Gmail extensions: XLIST and X-GM-EXT-1
 var IMAP_GMAIL_extension = {
-  preload: function (toBeThis) {
+  preload(toBeThis) {
     toBeThis._preGMAIL_STORE = toBeThis.STORE;
     toBeThis._preGMAIL_STORE_argFormat = toBeThis._argFormat.STORE;
     toBeThis._argFormat.STORE = ["number", "atom", "..."];
   },
-  XLIST : function (args) {
+  XLIST(args) {
     // XLIST is really just SPECIAL-USE that does not conform to RFC 6154
     args.push("RETURN");
     args.push("SPECIAL-USE");
     return this.LIST(args);
   },
-  _LIST_RETURN_CHILDREN : function (aBox) {
+  _LIST_RETURN_CHILDREN(aBox) {
     return IMAP_RFC5258_extension._LIST_RETURN_CHILDREN(aBox);
   },
-  _LIST_RETURN_CHILDREN_SPECIAL_USE : function (aBox) {
+  _LIST_RETURN_CHILDREN_SPECIAL_USE(aBox) {
     if (aBox.nonExistent) {
       return "";
     }
-    return '* LIST (' + aBox.flags.join(" ") +
-           ((aBox._children.length > 0) ?
-            (((aBox.flags.length > 0) ? ' ' : '') + '\\HasChildren') :
-            ((aBox.flags.indexOf('\\NoInferiors') == -1) ?
-             (((aBox.flags.length > 0) ? ' ' : '') + '\\HasNoChildren') :
-             '')) +
-           ((aBox.specialUseFlag && aBox.specialUseFlag.length > 0) ?
-            (' ' + aBox.specialUseFlag) : '') +
-           ') "' + aBox.delimiter +
-           '" "' + aBox.displayName + '"\0';
+
+    let result = "* LIST (" + aBox.flags.join(" ");
+    if (aBox._children.length > 0) {
+      if (aBox.flags.length > 0) {
+        result += " ";
+      }
+      result += "\\HasChildren";
+    } else if (!aBox.flags.includes("\\NoInferiors")) {
+      if (aBox.flags.length > 0) {
+        result += " ";
+      }
+      result += "\\HasNoChildren";
+    }
+    if (aBox.specialUseFlag && aBox.specialUseFlag.length > 0) {
+      result += " " + aBox.specialUseFlag;
+    }
+    result += ') "' + aBox.delimiter;
+    result += '" "' + aBox.displayName + '"\0';
+    return result;
   },
-  STORE : function (args, uid) {
+  STORE(args, uid) {
     let regex = /[+-]?FLAGS.*/;
     if (regex.test(args[1])) {
       // if we are storing flags, use the method that was overridden
       this._argFormat = this._preGMAIL_STORE_argFormat;
       args = this._treatArgs(args, "STORE");
       return this._preGMAIL_STORE(args, uid);
     }
     // otherwise, handle gmail specific cases
     let ids = [];
     let messages = this._parseSequenceSet(args[0], uid, ids);
     args[2] = formatArg(args[2], "string|(string)");
     for (let i = 0; i < args[2].length; i++) {
-      if (args[2][i].indexOf(' ') > -1) {
+      if (args[2][i].includes(" ")) {
         args[2][i] = '"' + args[2][i] + '"';
       }
     }
     let response = "";
     for (let i = 0; i < messages.length; i++) {
       let message = messages[i];
       switch (args[1]) {
       case "X-GM-LABELS":
@@ -1753,61 +1744,58 @@ var IMAP_GMAIL_extension = {
           return "BAD can't store X-GM-LABELS";
         }
         break;
       case "-X-GM-LABELS":
         if (message.xGmLabels) {
           for (let i = 0; i < args[2].length; i++) {
             let idx = message.xGmLabels.indexOf(args[2][i]);
             if (idx != -1) {
-              message.xGmLabels.splice(idx,1);
+              message.xGmLabels.splice(idx, 1);
             }
           }
         } else {
           return "BAD can't store X-GM-LABELS";
         }
         break;
       default:
         return "BAD change what now?";
       }
       response += "* " + ids[i] + " FETCH (X-GM-LABELS (";
-      response += message.xGmLabels.join(' ');
-      response += '))\0';
+      response += message.xGmLabels.join(" ");
+      response += "))\0";
     }
-    return response + 'OK STORE completed';
+    return response + "OK STORE completed";
   },
-  _FETCH_X_GM_MSGID : function (message) {
+  _FETCH_X_GM_MSGID(message) {
     if (message.xGmMsgid) {
-        return "X-GM-MSGID " + message.xGmMsgid;
-    } else {
-        return "BAD can't fetch X-GM-MSGID";
+      return "X-GM-MSGID " + message.xGmMsgid;
     }
+    return "BAD can't fetch X-GM-MSGID";
   },
-  _FETCH_X_GM_THRID : function (message) {
+  _FETCH_X_GM_THRID(message) {
     if (message.xGmThrid) {
-        return "X-GM-THRID " + message.xGmThrid;
-    } else {
-        return "BAD can't fetch X-GM-THRID";
+      return "X-GM-THRID " + message.xGmThrid;
     }
+    return "BAD can't fetch X-GM-THRID";
   },
-  _FETCH_X_GM_LABELS : function (message) {
+  _FETCH_X_GM_LABELS(message) {
     if (message.xGmLabels) {
-        return "X-GM-LABELS " + message.xGmLabels;
-    } else {
-        return "BAD can't fetch X-GM-LABELS";
+      return "X-GM-LABELS " + message.xGmLabels;
     }
+    return "BAD can't fetch X-GM-LABELS";
   },
   kCapabilities: ["XLIST", "X-GM-EXT-1"],
-  _argFormat : { XLIST : ["mailbox", "mailbox"] },
+  _argFormat: { XLIST: ["mailbox", "mailbox"] },
   // Enabled in AUTHED and SELECTED states
-  _enabledCommands : { 1 : ["XLIST"], 2 : ["XLIST"] }
+  _enabledCommands: { 1: ["XLIST"], 2: ["XLIST"] },
 };
 
 var IMAP_MOVE_extension = {
-  MOVE: function (args, uid) {
+  MOVE(args, uid) {
     let messages = this._parseSequenceSet(args[0], uid);
 
     let dest = this._daemon.getMailbox(args[1]);
     if (!dest)
       return "NO [TRYCREATE] what mailbox?";
 
     for (var message of messages) {
       let newMessage = new imapMessage(message._URI, dest.uidnext++,
@@ -1828,40 +1816,40 @@ var IMAP_MOVE_extension = {
       delete mailbox.__highestuid;
 
     return response + "OK MOVE completed";
   },
   kCapabilities: ["MOVE"],
   kUidCommands: ["MOVE"],
   _argFormat: { MOVE: ["number", "mailbox"] },
   // Enabled in SELECTED state
-  _enabledCommands: { 2: ["MOVE"] }
+  _enabledCommands: { 2: ["MOVE"] },
 };
 
 // Provides methods for testing fetchCustomAttribute and issueCustomCommand
 var IMAP_CUSTOM_extension = {
-  preload: function (toBeThis) {
+  preload(toBeThis) {
     toBeThis._preCUSTOM_STORE = toBeThis.STORE;
     toBeThis._preCUSTOM_STORE_argFormat = toBeThis._argFormat.STORE;
     toBeThis._argFormat.STORE = ["number", "atom", "..."];
   },
-  STORE : function (args, uid) {
+  STORE(args, uid) {
     let regex = /[+-]?FLAGS.*/;
     if (regex.test(args[1])) {
       // if we are storing flags, use the method that was overridden
       this._argFormat = this._preCUSTOM_STORE_argFormat;
       args = this._treatArgs(args, "STORE");
       return this._preCUSTOM_STORE(args, uid);
     }
     // otherwise, handle custom attribute
     let ids = [];
     let messages = this._parseSequenceSet(args[0], uid, ids);
     args[2] = formatArg(args[2], "string|(string)");
     for (let i = 0; i < args[2].length; i++) {
-      if (args[2][i].indexOf(' ') > -1) {
+      if (args[2][i].includes(" ")) {
         args[2][i] = '"' + args[2][i] + '"';
       }
     }
     let response = "";
     for (let i = 0; i < messages.length; i++) {
       let message = messages[i];
       switch (args[1]) {
       case "X-CUSTOM-VALUE":
@@ -1885,349 +1873,355 @@ var IMAP_CUSTOM_extension = {
           return "BAD can't store X-CUSTOM-LIST";
         }
         break;
       case "-X-CUSTOM-LIST":
         if (message.xCustomList) {
           for (let i = 0; i < args[2].length; i++) {
             let idx = message.xCustomList.indexOf(args[2][i]);
             if (idx != -1) {
-              message.xCustomList.splice(idx,1);
+              message.xCustomList.splice(idx, 1);
             }
           }
         } else {
           return "BAD can't store X-CUSTOM-LIST";
         }
         break;
       default:
         return "BAD change what now?";
       }
       response += "* " + ids[i] + " FETCH (X-CUSTOM-LIST (";
-      response += message.xCustomList.join(' ');
-      response += '))\0';
+      response += message.xCustomList.join(" ");
+      response += "))\0";
     }
-    return response + 'OK STORE completed';
+    return response + "OK STORE completed";
   },
-  _FETCH_X_CUSTOM_VALUE : function (message) {
+  _FETCH_X_CUSTOM_VALUE(message) {
     if (message.xCustomValue) {
         return "X-CUSTOM-VALUE " + message.xCustomValue;
-    } else {
+    }
         return "BAD can't fetch X-CUSTOM-VALUE";
-    }
   },
-  _FETCH_X_CUSTOM_LIST : function (message) {
+  _FETCH_X_CUSTOM_LIST(message) {
     if (message.xCustomList) {
-        return "X-CUSTOM-LIST (" + message.xCustomList.join(' ') + ")";
-    } else {
+        return "X-CUSTOM-LIST (" + message.xCustomList.join(" ") + ")";
+    }
         return "BAD can't fetch X-CUSTOM-LIST";
-    }
   },
-  kCapabilities: ["X-CUSTOM1"]
+  kCapabilities: ["X-CUSTOM1"],
 };
 
 // RFC 2197: ID
 var IMAP_RFC2197_extension = {
-  ID : function (args) {
+  ID(args) {
     let clientID = "(";
     for (let i of args)
       clientID += "\"" + i + "\"";
 
     clientID += ")";
     let clientStrings = clientID.split(",");
     clientID = "";
     for (let i of clientStrings)
-      clientID += "\"" + i + "\" "
+      clientID += "\"" + i + "\" ";
     clientID = clientID.slice(1, clientID.length - 3);
     clientID += ")";
     this._daemon.clientID = clientID;
     return "* ID " + this._daemon.idResponse + "\0OK Success";
   },
   kCapabilities: ["ID"],
   _argFormat: { ID: ["(string)"] },
-  _enabledCommands : { 1 : ["ID"], 2 : ["ID"] }
+  _enabledCommands: { 1: ["ID"], 2: ["ID"] },
 };
 
 // RFC 2342: IMAP4 Namespace (NAMESPACE)
 var IMAP_RFC2342_extension = {
-  NAMESPACE : function (args) {
+  NAMESPACE(args) {
     var namespaces = [[], [], []];
-    for (var namespace of this._daemon.namespaces)
+    for (let namespace of this._daemon.namespaces)
       namespaces[namespace.type].push(namespace);
 
     var response = "* NAMESPACE";
     for (var type of namespaces) {
       if (type.length == 0) {
         response += " NIL";
         continue;
       }
       response += " (";
-      for (var namespace of type) {
+      for (let namespace of type) {
         response += "(\"";
         response += namespace.displayName;
         response += "\" \"";
         response += namespace.delimiter;
         response += "\")";
       }
       response += ")";
     }
     response += "\0OK NAMESPACE command completed";
     return response;
   },
-  kCapabilities : ["NAMESPACE"],
-  _argFormat : { NAMESPACE : [] },
+  kCapabilities: ["NAMESPACE"],
+  _argFormat: { NAMESPACE: [] },
   // Enabled in AUTHED and SELECTED states
-  _enabledCommands : { 1 : ["NAMESPACE"], 2 : ["NAMESPACE"] }
+  _enabledCommands: { 1: ["NAMESPACE"], 2: ["NAMESPACE"] },
 };
 
 // RFC 3348 Child Mailbox (CHILDREN)
 var IMAP_RFC3348_extension = {
-  kCapabilities: ["CHILDREN"]
-}
+  kCapabilities: ["CHILDREN"],
+};
 
 // RFC 4315: UIDPLUS
 var IMAP_RFC4315_extension = {
-  preload: function (toBeThis) {
+  preload(toBeThis) {
     toBeThis._preRFC4315UID = toBeThis.UID;
     toBeThis._preRFC4315APPEND = toBeThis.APPEND;
     toBeThis._preRFC4315COPY = toBeThis.COPY;
     toBeThis._preRFC4315MOVE = toBeThis.MOVE;
   },
-  UID: function (args) {
+  UID(args) {
     // XXX: UID EXPUNGE is not supported.
     return this._preRFC4315UID(args);
   },
-  APPEND: function (args) {
+  APPEND(args) {
     let response = this._preRFC4315APPEND(args);
     if (response.indexOf("OK") == 0) {
       let mailbox = this._daemon.getMailbox(args[0]);
       let uid = mailbox.uidnext - 1;
       response = "OK [APPENDUID " + mailbox.uidvalidity + " " + uid + "]" +
                    response.substring(2);
     }
     return response;
   },
-  COPY: function (args) {
+  COPY(args) {
     let mailbox = this._daemon.getMailbox(args[0]);
     if (mailbox)
       var first = mailbox.uidnext;
     let response = this._preRFC4315COPY(args);
     if (response.indexOf("OK") == 0) {
       let last = mailbox.uidnext - 1;
       response = "OK [COPYUID " + this._selectedMailbox.uidvalidity +
                    " " + args[0] + " " + first + ":" + last + "]" +
                    response.substring(2);
     }
     return response;
   },
-  MOVE: function (args) {
+  MOVE(args) {
     let mailbox = this._daemon.getMailbox(args[1]);
     if (mailbox)
       var first = mailbox.uidnext;
     let response = this._preRFC4315MOVE(args);
-    if (response.indexOf("OK MOVE") != -1) {
+    if (response.includes("OK MOVE")) {
       let last = mailbox.uidnext - 1;
       response =
         response.replace("OK MOVE",
                          "OK [COPYUID " + this._selectedMailbox.uidvalidity +
                             " " + args[0] + " " + first + ":" + last + "]");
     }
     return response;
   },
-  kCapabilities: ["UIDPLUS"]
+  kCapabilities: ["UIDPLUS"],
 };
 
 // RFC 5258: LIST-EXTENDED
 var IMAP_RFC5258_extension = {
-  preload: function (toBeThis) {
+  preload(toBeThis) {
     toBeThis._argFormat.LIST = ["[(atom)]", "mailbox", "mailbox|(mailbox)",
                                 "[atom]", "[(atom)]"];
   },
-  _LIST_SUBSCRIBED : function (aBox) {
+  _LIST_SUBSCRIBED(aBox) {
     if (!aBox.subscribed) {
       return "";
     }
-    return '* LIST (' + aBox.flags.join(" ") +
-           ((aBox.flags.length > 0) ? ' ' : '') + '\\Subscribed' +
-           (aBox.nonExistent ? ' \\NonExistent' : '') + ') "' +
-           aBox.delimiter + '" "' + aBox.displayName + '"\0';
+
+    let result = "* LIST (" + aBox.flags.join(" ");
+    if (aBox.flags.length > 0) {
+      result += " ";
+    }
+    result += "\\Subscribed";
+    if (aBox.nonExistent) {
+      result += " \\NonExistent";
+    }
+    result += ') "' + aBox.delimiter + '" "' + aBox.displayName + '"\0';
+    return result;
   },
-  _LIST_RETURN_CHILDREN : function (aBox) {
+  _LIST_RETURN_CHILDREN(aBox) {
     if (aBox.nonExistent) {
       return "";
     }
-    return '* LIST (' + aBox.flags.join(" ") +
-           ((aBox._children.length > 0) ?
-            (((aBox.flags.length > 0) ? ' ' : '') + '\\HasChildren') :
-            ((aBox.flags.indexOf('\\NoInferiors') == -1) ?
-             (((aBox.flags.length > 0) ? ' ' : '') + '\\HasNoChildren') :
-             '')) + ') "' + aBox.delimiter + '" "' + aBox.displayName + '"\0';
+
+    let result = "* LIST (" + aBox.flags.join(" ");
+    if (aBox._children.length > 0) {
+      if (aBox.flags.length > 0) {
+        result += " ";
+      }
+      result += "\\HasChildren";
+    } else if (!aBox.flags.includes("\\NoInferiors")) {
+      if (aBox.flags.length > 0) {
+        result += " ";
+      }
+      result += "\\HasNoChildren";
+    }
+    result += ') "' + aBox.delimiter + '" "' + aBox.displayName + '"\0';
+    return result;
   },
-  _LIST_RETURN_SUBSCRIBED : function (aBox) {
+  _LIST_RETURN_SUBSCRIBED(aBox) {
     if (aBox.nonExistent) {
       return "";
     }
-    return '* LIST (' + aBox.flags.join(" ") +
-           (aBox.subscribed ? (((aBox.flags.length > 0) ? ' ' : '') +
-                               '\\Subscribed') : '') +
-           ') "' + aBox.delimiter + '" "' + aBox.displayName + '"\0';
+
+    let result = "* LIST (" + aBox.flags.join(" ");
+    if (aBox.subscribed) {
+      if (aBox.flags.length > 0) {
+        result += " ";
+      }
+      result += "\\Subscribed";
+    }
+    result += ') "' + aBox.delimiter + '" "' + aBox.displayName + '"\0';
+    return result;
   },
   // TODO implement _LIST_REMOTE, _LIST_RECURSIVEMATCH, _LIST_RETURN_SUBSCRIBED
   // and all valid combinations thereof. Currently, nsImapServerResponseParser
   // does not support any of these responses anyway.
 
-  kCapabilities: ["LIST-EXTENDED"]
+  kCapabilities: ["LIST-EXTENDED"],
 };
 
 /**
  * This implements AUTH schemes. Could be moved into RFC3501 actually.
  * The test can en-/disable auth schemes by modifying kAuthSchemes.
  */
 var IMAP_RFC2195_extension = {
-  kAuthSchemes : [ "CRAM-MD5" , "PLAIN", "LOGIN" ],
+  kAuthSchemes: ["CRAM-MD5", "PLAIN", "LOGIN"],
 
-  preload: function (handler) {
+  preload(handler) {
     handler._kAuthSchemeStartFunction["CRAM-MD5"] = this.authCRAMStart;
-    handler._kAuthSchemeStartFunction["PLAIN"] = this.authPLAINStart;
-    handler._kAuthSchemeStartFunction["LOGIN"] = this.authLOGINStart;
+    handler._kAuthSchemeStartFunction.PLAIN = this.authPLAINStart;
+    handler._kAuthSchemeStartFunction.LOGIN = this.authLOGINStart;
   },
 
-  authPLAINStart : function (lineRest)
-  {
+  authPLAINStart(lineRest) {
     this._nextAuthFunction = this.authPLAINCred;
     this._multiline = true;
 
     return "+";
   },
-  authPLAINCred : function (line)
-  {
+  authPLAINCred(line) {
     var req = AuthPLAIN.decodeLine(line);
     if (req.username == this.kUsername &&
         req.password == this.kPassword) {
       this._state = IMAP_STATE_AUTHED;
       return "OK Hello friend! Friends give friends good advice: Next time, use CRAM-MD5";
     }
-    else {
-      return "BAD Wrong username or password, crook!";
-    }
+    return "BAD Wrong username or password, crook!";
   },
 
-  authCRAMStart : function (lineRest)
-  {
+  authCRAMStart(lineRest) {
     this._nextAuthFunction = this.authCRAMDigest;
     this._multiline = true;
 
     this._usedCRAMMD5Challenge = AuthCRAM.createChallenge("localhost");
     return "+ " + this._usedCRAMMD5Challenge;
   },
-  authCRAMDigest : function (line)
-  {
+  authCRAMDigest(line) {
     var req = AuthCRAM.decodeLine(line);
     var expectedDigest = AuthCRAM.encodeCRAMMD5(
         this._usedCRAMMD5Challenge, this.kPassword);
     if (req.username == this.kUsername &&
         req.digest == expectedDigest) {
       this._state = IMAP_STATE_AUTHED;
       return "OK Hello friend!";
     }
-    else {
-      return "BAD Wrong username or password, crook!";
-    }
+    return "BAD Wrong username or password, crook!";
   },
 
-  authLOGINStart : function (lineRest)
-  {
+  authLOGINStart(lineRest) {
     this._nextAuthFunction = this.authLOGINUsername;
     this._multiline = true;
 
     return "+ " + btoa("Username:");
   },
-  authLOGINUsername : function (line)
-  {
+  authLOGINUsername(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kUsername)
       this._nextAuthFunction = this.authLOGINPassword;
     else // Don't return error yet, to not reveal valid usernames
       this._nextAuthFunction = this.authLOGINBadUsername;
     this._multiline = true;
     return "+ " + btoa("Password:");
   },
-  authLOGINBadUsername : function (line)
-  {
+  authLOGINBadUsername(line) {
     return "BAD Wrong username or password, crook!";
   },
-  authLOGINPassword : function (line)
-  {
+  authLOGINPassword(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kPassword) {
       this._state = IMAP_STATE_AUTHED;
       return "OK Hello friend! Where did you pull out this old auth scheme?";
     }
-    else {
-      return "BAD Wrong username or password, crook!";
-    }
+    return "BAD Wrong username or password, crook!";
   },
 };
 
 // FETCH BODYSTRUCTURE
 function bodystructure(msg, extension) {
   if (!msg || msg == "")
     return "";
 
   // Use the mime parser emitter to generate body structure data. Most of the
   // string will be built as we exit a part. Currently not working:
   // 1. Some of the fields return NIL instead of trying to calculate them.
   // 2. MESSAGE is missing the ENVELOPE and the lines at the end.
-  var bodystruct = '';
+  var bodystruct = "";
   function paramToString(params) {
     let paramList = [];
     for (let [param, value] of params)
       paramList.push('"' + param.toUpperCase() + '" "' + value + '"');
-    return paramList.length == 0 ? 'NIL' : '(' + paramList.join(' ') + ')';
+    return paramList.length == 0 ? "NIL" : "(" + paramList.join(" ") + ")";
   }
   var headerStack = [];
   var BodyStructureEmitter = {
-    startPart: function bodystructure_startPart(partNum, headers) {
-      bodystruct += '(';
+    startPart(partNum, headers) {
+      bodystruct += "(";
       headerStack.push(headers);
       this.numLines = 0;
       this.length = 0;
     },
-    deliverPartData: function bodystructure_deliverPartData(partNum, data) {
+    deliverPartData(partNum, data) {
       this.length += data.length;
-      this.numLines += Array.from(data).filter(x => x == '\n').length;
+      this.numLines += Array.from(data).filter(x => x == "\n").length;
     },
-    endPart: function bodystructure_endPart(partNum) {
+    endPart(partNum) {
       // Grab the headers from before
       let headers = headerStack.pop();
       let contentType = headers.contentType;
       if (contentType.mediatype == "multipart") {
         bodystruct += ' "' + contentType.subtype.toUpperCase() + '"';
         if (extension) {
-          bodystruct += ' ' + paramToString(contentType);
+          bodystruct += " " + paramToString(contentType);
           // XXX: implement the rest
-          bodystruct += ' NIL NIL NIL';
+          bodystruct += " NIL NIL NIL";
         }
       } else {
         bodystruct += '"' + contentType.mediatype.toUpperCase() + '" "' +
           contentType.subtype.toUpperCase() + '"';
-        bodystruct += ' ' + paramToString(contentType);
+        bodystruct += " " + paramToString(contentType);
 
         // XXX: Content ID, Content description
-        bodystruct += ' NIL NIL';
+        bodystruct += " NIL NIL";
 
-        let cte = headers.has('content-transfer-encoding') ?
-          headers.get('content-transfer-encoding') : '7BIT';
+        let cte = headers.has("content-transfer-encoding") ?
+          headers.get("content-transfer-encoding") : "7BIT";
         bodystruct += ' "' + cte + '"';
 
-        bodystruct += ' ' + this.length;
+        bodystruct += " " + this.length;
         if (contentType.mediatype == "text")
-          bodystruct += ' ' + this.numLines;
+          bodystruct += " " + this.numLines;
 
         // XXX: I don't want to implement these yet
         if (extension)
-          bodystruct += ' NIL NIL NIL NIL';
+          bodystruct += " NIL NIL NIL NIL";
       }
-      bodystruct += ')';
-    }
+      bodystruct += ")";
+    },
   };
   MimeParser.parseSync(msg, BodyStructureEmitter, {});
   return bodystruct;
 }
--- a/mailnews/test/fakeserver/maild.js
+++ b/mailnews/test/fakeserver/maild.js
@@ -4,19 +4,19 @@
  * 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/. */
 
 // Much of the original code is taken from netwerk's httpserver implementation
 
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var EXPORTED_SYMBOLS = [
-  'nsMailServer',
-  'gThreadManager', // TODO: kill this export
-  'fsDebugNone', 'fsDebugAll', 'fsDebugRecv', 'fsDebugRecvSend'
+  "nsMailServer",
+  "gThreadManager", // TODO: kill this export
+  "fsDebugNone", "fsDebugAll", "fsDebugRecv", "fsDebugRecvSend",
 ];
 
 var CC = Components.Constructor;
 
 /**
  * The XPCOM thread manager. This declaration is obsolete and exists only
  * because deleting it breaks several dozen tests at the moment.
  */
@@ -35,34 +35,34 @@ var fsDebugAll = 3;
 var ServerSocket = CC("@mozilla.org/network/server-socket;1",
                         "nsIServerSocket",
                         "init");
 var BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
                              "nsIBinaryInputStream",
                              "setInputStream");
 
 // Time out after 3 minutes
-var TIMEOUT = 3*60*1000;
+var TIMEOUT = 3 * 60 * 1000;
 
-/******************************************************************************
+/**
  * The main server handling class. A fake server consists of three parts, this
  * server implementation (which handles the network communication), the handler
  * (which handles the state for a connection), and the daemon (which handles
  * the state for the logical server). To make a new server, one needs to pass
  * in a function to create handlers--not the handlers themselves--and the
  * backend daemon. Since each handler presumably needs access to the logical
  * server daemon, that is passed into the handler creation function. A new
  * handler will be constructed for every connection made.
  *
  * As the core code is inherently single-threaded, it is guaranteed that all of
  * the calls to the daemon will be made on the same thread, so you do not have
  * to worry about reentrancy in daemon calls.
  *
- ******************************************************************************
  * Typical usage:
+ *
  * function createHandler(daemon) {
  *   return new handler(daemon);
  * }
  * do_test_pending();
  * var server = new nsMailServer(createHandler, serverDaemon);
  * // Port to use. I tend to like using 1024 + default port number myself.
  * server.start(port);
  *
@@ -79,17 +79,17 @@ var TIMEOUT = 3*60*1000;
  * // Finished with tests
  * server.stop();
  *
  * var thread = Services.tm.currentThread;
  * while (thread.hasPendingEvents())
  *   thread.processNextEvent(true);
  *
  * do_test_finished();
- *****************************************************************************/
+ */
 function nsMailServer(handlerCreator, daemon) {
   this._debug = fsDebugNone;
 
   /** The port on which this server listens. */
   this._port = -1;
 
   /** The socket associated with this. */
   this._socket = null;
@@ -115,19 +115,19 @@ function nsMailServer(handlerCreator, da
 
   /**
    * An array to hold refs to all the input streams below, so that they don't
    * get GCed
    */
   this._inputStreams = [];
 }
 nsMailServer.prototype = {
-  onSocketAccepted : function (socket, trans) {
+  onSocketAccepted(socket, trans) {
     if (this._debug != fsDebugNone)
-      dump("Received Connection from " + trans.host + ":" + trans.port + '\n');
+      dump("Received Connection from " + trans.host + ":" + trans.port + "\n");
 
     const SEGMENT_SIZE = 1024;
     const SEGMENT_COUNT = 1024;
     var input = trans.openInputStream(0, SEGMENT_SIZE, SEGMENT_COUNT)
                      .QueryInterface(Ci.nsIAsyncInputStream);
     this._inputStreams.push(input);
 
     var handler = this._handlerCreator(this._daemon);
@@ -137,71 +137,71 @@ nsMailServer.prototype = {
 
     // Note: must use main thread here, or we might get a GC that will cause
     //       threadsafety assertions.  We really need to fix XPConnect so that
     //       you can actually do things in multi-threaded JS.  :-(
     input.asyncWait(reader, 0, 0, Services.tm.mainThread);
     this._test = true;
   },
 
-  onStopListening : function (socket, status) {
+  onStopListening(socket, status) {
     if (this._debug != fsDebugNone)
-      dump("Connection Lost " + status + '\n');
+      dump("Connection Lost " + status + "\n");
 
     this._socketClosed = true;
     // We've been killed or we've stopped, reset the handler to the original
     // state (e.g. to require authentication again).
     for (var i = 0; i < this._readers.length; i++) {
       this._readers[i]._handler.resetTest();
       this._readers[i]._realCloseSocket();
     }
   },
 
-  setDebugLevel : function (debug) {
+  setDebugLevel(debug) {
     this._debug = debug;
     for (var i = 0; i < this._readers.length; i++)
       this._readers[i].setDebugLevel(debug);
   },
 
-  start : function (port=-1) {
+  start(port = -1) {
     if (this._socket)
       throw Cr.NS_ERROR_ALREADY_INITIALIZED;
 
     if (port > 0)
       this._port = port;
     this._socketClosed = false;
 
     var socket = new ServerSocket(this._port,
                                   true, // loopback only
                                   -1);  // default number of pending connections
 
     socket.asyncListen(this);
     this._socket = socket;
   },
 
-  stop : function () {
+  stop() {
     if (!this._socket)
       return;
 
     this._socket.close();
     this._socket = null;
 
     for (let reader of this._readers)
       reader._realCloseSocket();
 
-    if (this._readers.some(function (e) { return e.observer.forced }))
+    if (this._readers.some(function(e) { return e.observer.forced; }))
       return;
 
     // spin an event loop and wait for the socket-close notification
     let thr = Services.tm.currentThread;
     while (!this._socketClosed)
       // Don't wait for the next event, just in case there isn't one.
       thr.processNextEvent(false);
   },
-  stopTest : function () {
+  stopTest() {
     this._test = false;
   },
 
   get port() {
     if (this._port == -1) {
       this._port = this._socket.port;
     }
     return this._port;
@@ -217,71 +217,70 @@ nsMailServer.prototype = {
 
   // NON-XPCOM PUBLIC API
 
   /**
    * Returns true if this server is not running (and is not in the process of
    * serving any requests still to be processed when the server was last
    * stopped after being run).
    */
-  isStopped : function () {
+  isStopped() {
     return this._socketClosed;
   },
 
   /**
    * Runs the test. It will not exit until the test has finished.
    */
-  performTest : function (watchWord) {
+  performTest(watchWord) {
     this._watchWord = watchWord;
 
     let thread = Services.tm.currentThread;
     while (!this.isTestFinished())
       thread.processNextEvent(false);
   },
 
   /**
    * Returns true if the current processing test has finished.
    */
-  isTestFinished : function() {
+  isTestFinished() {
     return this._readers.length > 0 && !this._test;
   },
 
   /**
    * Returns the commands run between the server and client.
    * The return is an object with two variables (us and them), both of which
    * are arrays returning the commands given by each server.
    */
-  playTransaction : function() {
-    if (this._readers.some(function (e) { return e.observer.forced; }))
+  playTransaction() {
+    if (this._readers.some(function(e) { return e.observer.forced; }))
       throw "Server timed out!";
     if (this._readers.length == 1)
       return this._readers[0].transaction;
-    else
-      return this._readers.map(function (e) { return e.transaction; });
+    return this._readers.map(function(e) { return e.transaction; });
   },
 
   /**
    * Prepares for the next test.
    */
-  resetTest : function() {
-    this._readers = this._readers.filter(function (reader) {
+  resetTest() {
+    this._readers = this._readers.filter(function(reader) {
       return reader._isRunning;
     });
     this._test = true;
     for (var i = 0; i < this._readers.length; i++)
       this._readers[i]._handler.resetTest();
-  }
+  },
 };
 
 function readTo(input, count, arr) {
   var old = new BinaryInputStream(input).readByteArray(count);
   Array.prototype.push.apply(arr, old);
 }
 
-/******************************************************************************
+/**
  * The nsMailReader service, which reads and handles the lines.
  * All specific handling is passed off to the handler, which is responsible
  * for maintaining its own state. The following commands are required for the
  * handler object:
  * onError       Called when handler[command] does not exist with both the
  *               command and rest-of-line as arguments
  * onStartup     Called on initialization with no arguments
  * onMultiline   Called when in multiline with the entire line as an argument
@@ -296,82 +295,82 @@ function readTo(input, count, arr) {
  *
  * The return of postCommand is ignored. The return of onMultiline is a bit
  * complicated: it may or may not return a response string (returning one is
  * necessary to trigger the postCommand handler).
  *
  * This object has the following supplemental functions for use by handlers:
  * closeSocket  Performs a server-side socket closing
  * setMultiline Sets the multiline mode based on the argument
- *****************************************************************************/
+ */
 function nsMailReader(server, handler, transport, debug, logTransaction) {
   this._debug = debug;
   this._server = server;
   this._buffer = [];
   this._lines = [];
   this._handler = handler;
   this._transport = transport;
   // We don't seem to properly handle large streams when the buffer gets
   // exhausted, which causes issues trying to test large messages. So just
   // allow a really big buffer.
   var output = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 1024, 4096);
   this._output = output;
   if (logTransaction)
-    this.transaction = { us : [], them : [] };
+    this.transaction = { us: [], them: [] };
   else
     this.transaction = null;
 
   // Send response line
   var response = this._handler.onStartup();
-  response = response.replace(/([^\r])\n/g,"$1\r\n");
-  if (!response.endsWith('\n'))
+  response = response.replace(/([^\r])\n/g, "$1\r\n");
+  if (!response.endsWith("\n"))
     response = response + "\r\n";
   if (this.transaction)
     this.transaction.us.push(response);
   this._output.write(response, response.length);
   this._output.flush();
 
   this._multiline = false;
 
   this._isRunning = true;
 
   this.observer = {
-    server : server,
-    forced : false,
-    notify : function (timer) {
+    server,
+    forced: false,
+    notify(timer) {
       this.forced = true;
       this.server.stopTest();
       this.server.stop();
     },
     QueryInterface: ChromeUtils.generateQI(["nsITimerCallback"]),
   };
   this.timer = Cc["@mozilla.org/timer;1"].createInstance()
                                          .QueryInterface(Ci.nsITimer);
   this.timer.initWithCallback(this.observer, TIMEOUT,
                               Ci.nsITimer.TYPE_ONE_SHOT);
 }
 nsMailReader.prototype = {
-  _findLines : function () {
+  _findLines() {
     var buf = this._buffer;
     for (var crlfLoc = buf.indexOf(13); crlfLoc >= 0;
         crlfLoc = buf.indexOf(13, crlfLoc + 1)) {
       if (buf[crlfLoc + 1] == 10)
         break;
     }
     if (crlfLoc == -1)
       // We failed to find a newline
       return;
 
     var line = String.fromCharCode.apply(null, buf.slice(0, crlfLoc));
     this._buffer = buf.slice(crlfLoc + 2);
     this._lines.push(line);
     this._findLines();
   },
 
-  onInputStreamReady : function (stream) {
+  onInputStreamReady(stream) {
     if (this.observer.forced)
       return;
 
     this.timer.cancel();
     try {
       var bytes = stream.available();
     } catch (e) {
       // Someone, not us, has closed the stream. This means we can't get any
@@ -381,90 +380,87 @@ nsMailReader.prototype = {
     }
     readTo(stream, bytes, this._buffer);
     this._findLines();
 
     while (this._lines.length > 0) {
       var line = this._lines.shift();
 
       if (this._debug != fsDebugNone)
-        dump("RECV: " + line + '\n');
+        dump("RECV: " + line + "\n");
 
       var response;
       try {
         if (this._multiline) {
           response = this._handler.onMultiline(line);
 
           if (response === undefined)
             continue;
         } else {
           // Record the transaction
           if (this.transaction)
             this.transaction.them.push(line);
 
           // Find the command and splice it out...
           var splitter = line.indexOf(" ");
-          var command = splitter == -1 ? line : line.substring(0,splitter);
-          var args = splitter == -1 ? "" : line.substring(splitter+1);
+          var command = splitter == -1 ? line : line.substring(0, splitter);
+          var args = splitter == -1 ? "" : line.substring(splitter + 1);
 
           // By convention, commands are uppercase
           command = command.toUpperCase();
 
           if (this._debug == fsDebugAll)
-            dump("Received command " + command + '\n');
+            dump("Received command " + command + "\n");
 
           if (command in this._handler)
             response = this._handler[command](args);
           else
             response = this._handler.onError(command, args);
         }
 
         this._preventLFMunge = false;
         this._handler.postCommand(this);
 
         if (this.watchWord && command == this.watchWord)
           this.stopTest();
       } catch (e) {
         response = this._handler.onServerFault(e);
         if (e instanceof Error) {
-          dump(e.name + ": " + e.message + '\n');
-          dump("File: " + e.fileName + " Line: " + e.lineNumber + '\n');
-          dump('Stack trace:\n' + e.stack);
+          dump(e.name + ": " + e.message + "\n");
+          dump("File: " + e.fileName + " Line: " + e.lineNumber + "\n");
+          dump("Stack trace:\n" + e.stack);
         } else {
-          dump("Exception caught: " + e + '\n');
+          dump("Exception caught: " + e + "\n");
         }
       }
 
       if (!this._preventLFMunge)
-        response = response.replace(/([^\r])\n/g,"$1\r\n");
+        response = response.replace(/([^\r])\n/g, "$1\r\n");
 
-      if (!response.endsWith('\n'))
+      if (!response.endsWith("\n"))
        response = response + "\r\n";
 
       if (this._debug == fsDebugRecvSend) {
-        dump("SEND: " + response.split(" ", 1)[0] + '\n');
-      }
-      else if (this._debug == fsDebugAll) {
+        dump("SEND: " + response.split(" ", 1)[0] + "\n");
+      } else if (this._debug == fsDebugAll) {
         var responses = response.split("\n");
-        responses.forEach(function (line) { dump("SEND: " + line + '\n'); });
+        responses.forEach(function(line) { dump("SEND: " + line + "\n"); });
       }
 
       if (this.transaction)
         this.transaction.us.push(response);
 
       try {
         this._output.write(response, response.length);
         this._output.flush();
-      }
-      catch (ex) {
+      } catch (ex) {
         if (ex.result == Cr.NS_BASE_STREAM_CLOSED) {
           dump("Stream closed whilst sending, this may be expected\n");
           this._realCloseSocket();
-        }
-        else {
+        } else {
           // Some other issue, let the test see it.
           throw ex;
         }
       }
 
       if (this._signalStop) {
         this._realCloseSocket();
         this._signalStop = false;
@@ -473,40 +469,40 @@ nsMailReader.prototype = {
 
     if (this._isRunning) {
       stream.asyncWait(this, 0, 0, Services.tm.currentThread);
       this.timer.initWithCallback(this.observer, TIMEOUT,
                                   Ci.nsITimer.TYPE_ONE_SHOT);
     }
   },
 
-  closeSocket : function () {
+  closeSocket() {
     this._signalStop = true;
   },
-  _realCloseSocket : function () {
+  _realCloseSocket() {
     this._isRunning = false;
     this._output.close();
     this._transport.close(Cr.NS_OK);
     this._server.stopTest();
   },
 
-  setMultiline : function (multi) {
+  setMultiline(multi) {
     this._multiline = multi;
   },
 
-  setDebugLevel : function (debug) {
+  setDebugLevel(debug) {
     this._debug = debug;
   },
 
-  preventLFMunge : function () {
+  preventLFMunge() {
     this._preventLFMunge = true;
   },
 
-  get watchWord () {
+  get watchWord() {
     return this._server._watchWord;
   },
 
-  stopTest : function () {
+  stopTest() {
     this._server.stopTest();
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIInputStreamCallback"]),
 };
--- a/mailnews/test/fakeserver/nntpd.js
+++ b/mailnews/test/fakeserver/nntpd.js
@@ -1,223 +1,219 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // This file implements test NNTP servers
 
 const {MimeParser} = ChromeUtils.import("resource:///modules/mimeParser.jsm");
 
 var EXPORTED_SYMBOLS = [
-  'nntpDaemon',
-  'newsArticle',
-  'NNTP_POSTABLE',
-  'NNTP_REAL_LENGTH',
-  'NNTP_RFC977_handler',
-  'NNTP_RFC2980_handler',
-  'NNTP_RFC3977_handler',
-  'NNTP_Giganews_handler',
-  'NNTP_RFC4643_extension'
+  "nntpDaemon",
+  "newsArticle",
+  "NNTP_POSTABLE",
+  "NNTP_REAL_LENGTH",
+  "NNTP_RFC977_handler",
+  "NNTP_RFC2980_handler",
+  "NNTP_RFC3977_handler",
+  "NNTP_Giganews_handler",
+  "NNTP_RFC4643_extension",
 ];
 
 function nntpDaemon(flags) {
   this._groups = {};
   this._messages = {};
   this._flags = flags;
 }
 nntpDaemon.prototype = {
-  addGroup : function(group, postable) {
+  addGroup(group, postable) {
     var flags = 0;
     if (postable)
       flags |= NNTP_POSTABLE;
-    this._groups[group] = { keys : [], flags : flags, nextKey : 1};
+    this._groups[group] = { keys: [], flags, nextKey: 1 };
   },
-  addArticle : function (article) {
+  addArticle(article) {
    this._messages[article.messageID] = article;
    for (let group of article.groups) {
      if (group in this._groups) {
        var key = this._groups[group].nextKey++;
        this._groups[group][key] = article;
-       this._groups[group]['keys'].push(key);
+       this._groups[group].keys.push(key);
      }
    }
   },
-  addArticleToGroup : function(article, group, key) {
+  addArticleToGroup(article, group, key) {
     this._groups[group][key] = article;
     this._messages[article.messageID] = article;
-    this._groups[group]['keys'].push(key);
+    this._groups[group].keys.push(key);
     if (this._groups[group].nextKey <= key)
-      this._groups[group].nextKey = key+1;
+      this._groups[group].nextKey = key + 1;
   },
-  getGroup : function(group) {
+  getGroup(group) {
     if (this._groups.hasOwnProperty(group))
       return this._groups[group];
     return null;
   },
-  getGroupStats : function (group) {
-    if (group['keys'].length == 0)
+  getGroupStats(group) {
+    if (group.keys.length == 0)
       return [0, 0, 0];
-    var min = 1<<30;
+    var min = 1 << 30;
     var max = 0;
-    group['keys'].forEach(function (key) {
+    group.keys.forEach(function(key) {
         if (key < min) min = key;
         if (key > max) max = key;
       });
 
     var length;
     if (hasFlag(this._flags, NNTP_REAL_LENGTH))
-      length = group['keys'].length;
+      length = group.keys.length;
     else
-      length = max-min+1;
+      length = max - min + 1;
 
     return [length, min, max];
   },
-  getArticle : function (msgid) {
+  getArticle(msgid) {
     if (msgid in this._messages)
       return this._messages[msgid];
     return null;
-  }
-}
+  },
+};
 
 function newsArticle(text) {
   this.headers = new Map();
   this.body = "";
   this.messageID = "";
   this.fullText = text;
 
   var headerMap;
   [headerMap, this.body] = MimeParser.extractHeadersAndBody(text);
   for (var [header, values] of headerMap._rawHeaders) {
     var value = values[0];
     this.headers.set(header, value);
     if (header == "message-id") {
-      var start = value.indexOf('<');
-      var end = value.indexOf('>', start);
-      this.messageID = value.substring(start, end+1);
+      var start = value.indexOf("<");
+      var end = value.indexOf(">", start);
+      this.messageID = value.substring(start, end + 1);
     } else if (header == "newsgroups") {
       this.groups = value.split(/[ \t]*,[ \t]*/);
     }
   }
 
   // Add in non-existent fields
-  if (!this.headers.has("lines"))
-  {
-    let lines = this.body.split('\n').length;
+  if (!this.headers.has("lines")) {
+    let lines = this.body.split("\n").length;
     this.headers.set("lines", lines);
   }
 }
 
 /**
  * This function converts an NNTP wildmat into a regular expression.
  *
  * I don't know how accurate it is wrt i18n characters, but its primary usage
  * right now is just XPAT, where i18n effects are utterly unspecified, so I am
  * not too concerned.
  *
  * This also neglects cases where special characters are in [] blocks.
  */
 function wildmat2regex(wildmat) {
   // Special characters in regex that aren't special in wildmat
-  wildmat = wildmat.replace(/[$+.()|{}^]/, function (str) {
+  wildmat = wildmat.replace(/[$+.()|{}^]/, function(str) {
       return "\\" + str;
   });
-  wildmat = wildmat.replace(/(\\*)([*?])/, function (str, p1, p2) {
+  wildmat = wildmat.replace(/(\\*)([*?])/, function(str, p1, p2) {
     // TODO: This function appears to be wrong on closer inspection.
     if (p1.length % 2 == 0)
-      return p2 == '*' ? '.*' : '.';
+      return p2 == "*" ? ".*" : ".";
     return str;
   });
   return new RegExp(wildmat);
 }
 
 // NNTP FLAGS
 var NNTP_POSTABLE = 0x0001;
 
 var NNTP_REAL_LENGTH = 0x0100;
 
 function hasFlag(flags, flag) {
   return (flags & flag) == flag;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//                              NNTP TEST SERVERS                             //
-////////////////////////////////////////////////////////////////////////////////
-// To be comprehensive about testing and fallback, we define these varying    //
-// levels of RFC-compliance:                                                  //
-// * RFC 977 solely (there's not a lot there!)                                //
-// * RFC 977 + 2980 (note that there are varying levels of this impl)         //
-// * RFC 3977 bare bones                                                      //
-// * RFC 3977 full                                                            //
-// * RFC 3977 + post-3977 extensions                                          //
-// * Giganews (Common newsserver for ISP stuff; highest importance)           //
-// * INN 2.4 (Gold standard common implementation; second highest importance) //
-// Note too that we want various levels of brokenness:                        //
-// * Perm errors that require login                                           //
-// * "I can't handle that" (e.g., news.mozilla.org only supports XOVER for    //
-//   searching with XHDR)                                                     //
-// * Naive group counts, missing articles                                     //
-// * Limitations on what can be posted                                        //
-////////////////////////////////////////////////////////////////////////////////
-
+// NNTP TEST SERVERS
+// -----------------
+// To be comprehensive about testing and fallback, we define these varying
+// levels of RFC-compliance:
+// * RFC 977 solely (there's not a lot there!)
+// * RFC 977 + 2980 (note that there are varying levels of this impl)
+// * RFC 3977 bare bones
+// * RFC 3977 full
+// * RFC 3977 + post-3977 extensions
+// * Giganews (Common newsserver for ISP stuff; highest importance)
+// * INN 2.4 (Gold standard common implementation; second highest importance)
+// Note too that we want various levels of brokenness:
+// * Perm errors that require login
+// * "I can't handle that" (e.g., news.mozilla.org only supports XOVER for
+//   searching with XHDR)
+// * Naive group counts, missing articles
+// * Limitations on what can be posted
 
 // This handler implements the bare minimum required by RFC 977. Actually, not
 // even that much: IHAVE and SLAVE are not implemented, as those two are
 // explicitly server implementations.
 function NNTP_RFC977_handler(daemon) {
   this._daemon = daemon;
   this.closing = false;
   this.resetTest();
 }
 NNTP_RFC977_handler.prototype = {
-  resetTest : function() {
+  resetTest() {
     this.extraCommands = "";
     this.articleKey = null;
     this.group = null;
   },
-  ARTICLE : function (args) {
+  ARTICLE(args) {
      var info = this._selectArticle(args, 220);
      if (info[0] == null)
        return info[1];
 
-     var response = info[1]+'\n';
+     var response = info[1] + "\n";
      response += info[0].fullText.replace("(?=\n).", "..");
      response += ".";
      return response;
   },
-  BODY : function (args) {
+  BODY(args) {
      var info = this._selectArticle(args, 222);
      if (info[0] == null)
        return info[1];
 
-     var response = info[1]+'\n';
-     response += info[0].body.replace("(?=\n).","..");
+     var response = info[1] + "\n";
+     response += info[0].body.replace("(?=\n).", "..");
      response += ".";
      return response;
   },
-  GROUP : function(args) {
+  GROUP(args) {
     var group = this._daemon.getGroup(args);
     if (group == null)
       return "411 no such news group";
 
     this.group = group;
     this.articleKey = 0 in this.group.keys ? this.group.keys[0] : null;
 
     var stats = this._daemon.getGroupStats(group);
     return "211 " + stats[0] + " " + stats[1] + " " + stats[2] + " " + args +
            " group selected";
   },
-  HEAD : function (args) {
+  HEAD(args) {
      var info = this._selectArticle(args, 221);
      if (info[0] == null)
        return info[1];
 
-     var response = info[1]+'\n';
+     var response = info[1] + "\n";
      for (let [header, value] of info[0].headers)
        response += header + ": " + value + "\n";
      response += ".";
      return response;
   },
-  HELP : function (args) {
+  HELP(args) {
     var response = "100 Why certainly, here is my help:\n";
     response += "Mozilla fake NNTP RFC 977 testing server";
     response += "Commands supported:\n";
     response += "\tARTICLE <message-id> | [nnn]\n";
     response += "\tBODY\n";
     response += "\tGROUP group\n";
     response += "\tHEAD\n";
     response += "\tHELP\n";
@@ -228,131 +224,131 @@ NNTP_RFC977_handler.prototype = {
     response += "\tNEXT\n";
     response += "\tPOST\n";
     response += "\tQUIT\n";
     response += "\tSTAT\n";
     response += this.extraCommands;
     response += ".";
     return response;
   },
-  LAST : function (args) {
+  LAST(args) {
     if (this.group == null)
       return "412 no newsgroup selected";
     if (this.articleKey == null)
       return "420 no current article has been selected";
     return "502 Command not implemented";
   },
-  LIST : function (args) {
+  LIST(args) {
     var response = "215 list of newsgroup follows\n";
     for (let groupname in this._daemon._groups) {
       let group = this._daemon._groups[groupname];
       let stats = this._daemon.getGroupStats(group);
       response += groupname + " " + stats[1] + " " + stats[0] + " " +
                   (hasFlag(group.flags, NNTP_POSTABLE) ? "y" : "n") + "\n";
     }
     response += ".";
     return response;
   },
-  NEWGROUPS : function (args) {
+  NEWGROUPS(args) {
     return "502 Command not implemented";
   },
-  NEWNEWS : function (args) {
+  NEWNEWS(args) {
     return "502 Command not implemented";
   },
-  NEXT : function (args) {
+  NEXT(args) {
     if (this.group == null)
       return "412 no newsgroup selected";
     if (this.articleKey == null)
       return "420 no current article has been selected";
     return "502 Command not implemented";
   },
-  POST : function(args) {
+  POST(args) {
     this.posting = true;
     this.post = "";
     return "340 Please continue";
   },
-  QUIT : function(args) {
+  QUIT(args) {
     this.closing = true;
     return "205 closing connection - goodbye!";
   },
-  STAT : function (args) {
+  STAT(args) {
      var info = this._selectArticle(args, 223);
      return info[1];
   },
-  LISTGROUP : function (args) {
+  LISTGROUP(args) {
     // Yes, I know this isn't RFC 977, but I doubt that mailnews will ever drop
     // its requirement for this, so I'll stuff it in here anyways...
     var group = (args == "" ? this.group : this._daemon.getGroup(args));
     if (group == null)
       return "411 This newsgroup does not exist";
 
     var response = "211 Articles follow:\n";
-    for (let key of group['keys'])
+    for (let key of group.keys)
       response += key + "\n";
     response += ".\n";
     return response;
   },
 
 
-  onError : function (command, args) {
+  onError(command, args) {
     return "500 command not recognized";
   },
-  onServerFault: function (e) {
+  onServerFault(e) {
     return "500 internal server error: " + e;
   },
-  onStartup : function () {
+  onStartup() {
     this.closing = false;
     this.group = null;
     this.article = null;
     this.posting = false;
     return "200 posting allowed";
   },
-  onMultiline : function (line) {
+  onMultiline(line) {
     if (line == ".") {
       if (this.posting) {
         var article = new newsArticle(this.post);
         this._daemon.addArticle(article);
         this.posting = false;
         return "240 Wonderful article, your style is gorgeous!";
       }
     }
 
     if (this.posting) {
-      if (line.startsWith('.'))
+      if (line.startsWith("."))
         line = line.substring(1);
 
-      this.post += line+'\n';
+      this.post += line + "\n";
     }
 
     return undefined;
   },
-  postCommand : function (reader) {
+  postCommand(reader) {
     if (this.closing)
       reader.closeSocket();
     reader.setMultiline(this.posting);
   },
 
   /**
    * Selects an article based on args.
    *
    * Returns an array of objects consisting of:
    * # The selected article (or null if non was selected
    * # The first line response
    */
-  _selectArticle : function (args, responseCode) {
+  _selectArticle(args, responseCode) {
     var art, key;
     if (args == "") {
       if (this.group == null)
         return [null, "412 no newsgroup has been selected"];
       if (this.articleKey == null)
         return [null, "420 no current article has been selected"];
 
       art = this.group[this.articleKey];
       key = this.articleKey;
-    } else if (args.startsWith('<')) {
+    } else if (args.startsWith("<")) {
       art = this._daemon.getArticle(args);
       key = 0;
 
       if (art == null)
         return [null, "430 no such article found"];
     } else {
       if (this.group == null)
         return [null, "412 no newsgroup has been selected"];
@@ -364,18 +360,18 @@ NNTP_RFC977_handler.prototype = {
       } else {
         return [null, "423 no such article number in this group"];
       }
     }
 
     var respCode = responseCode + " " + key + " " + art.messageID +
       " article selected";
     return [art, respCode];
-  }
-}
+  },
+};
 
 /**
  * Utility method to define a subclass
  *
  * @param sub   The function object of the subclass
  * @param super The function object of the superclass
  * @param def   The object definition of the subclass prototype.
  */
@@ -383,153 +379,153 @@ function subclass(sub, sup, def) {
   sub.prototype = new sup();
   for (let obj in def) {
     sub.prototype[obj] = def[obj];
   }
 }
 function subconstructor(sub, sup, ...aArgs) {
   sup.apply(sub, aArgs);
   sub.parent = new Proxy(sub, {
-    get: function (target, name) {
+    get(target, name) {
       let res = sup.prototype[name];
       if (typeof res === "function")
         return res.bind(sub);
       return res;
     }});
 }
 function NNTP_RFC2980_handler(daemon) {
   subconstructor(this, NNTP_RFC977_handler, daemon);
 }
 subclass(NNTP_RFC2980_handler, NNTP_RFC977_handler, {
-//NNTP_RFC2980_handler.prototype = new NNTP_RFC977_handler();
-//var subprototype = {
-  DATE : function (args) {
+// NNTP_RFC2980_handler.prototype = new NNTP_RFC977_handler();
+// var subprototype = {
+  DATE(args) {
     return "502 Command not implemented";
   },
-  LIST : function (args) {
+  LIST(args) {
     var index = args.indexOf(" ");
-    var command = index == -1 ? args : args.substring(0,index);
-    args = index == -1 ? "" : args.substring(index+1);
+    var command = index == -1 ? args : args.substring(0, index);
+    args = index == -1 ? "" : args.substring(index + 1);
     command = command.toUpperCase();
-    if ("LIST_"+command in this)
-      return this["LIST_"+command](args);
-    return this.parent.LIST(command+" "+args);
+    if ("LIST_" + command in this)
+      return this["LIST_" + command](args);
+    return this.parent.LIST(command + " " + args);
   },
-  LIST_ACTIVE : function (args) {
+  LIST_ACTIVE(args) {
     return this.parent.LIST(args);
   },
-  MODE : function (args) {
+  MODE(args) {
     if (args == "READER")
       return this.onStartup();
     return "500 What do you think you're trying to pull here?";
   },
-  XHDR : function (args) {
+  XHDR(args) {
     if (!this.group)
       return "412 No group selected";
 
     args = args.split(" ");
     var header = args[0].toLowerCase();
     var found = false;
     var response = "221 Headers abound\n";
     for (let key of this._filterRange(args[1], this.group.keys)) {
       if (!this.group[key].headers.has(header))
         continue;
       found = true;
-      response += key + " " + this.group[key].headers.get(header) + '\n';
+      response += key + " " + this.group[key].headers.get(header) + "\n";
     }
     if (!found)
       return "420 No such article";
-    response += '.';
+    response += ".";
     return response;
   },
-  XOVER : function (args) {
+  XOVER(args) {
     if (!this.group)
       return "412 No group selected";
 
     args = args.split(/ +/, 3);
     var response = "224 List of articles\n";
     for (let key of this._filterRange(args[0], this.group.keys)) {
       response += key + "\t";
       var article = this.group[key];
       response += article.headers.get("subject") + "\t" +
                   article.headers.get("from") + "\t" +
                   article.headers.get("date") + "\t" +
                   article.headers.get("message-id") + "\t" +
                   (article.headers.get("references") || "") + "\t" +
-                  article.fullText.replace(/\r?\n/,'\r\n').length + "\t" +
+                  article.fullText.replace(/\r?\n/, "\r\n").length + "\t" +
                   article.body.split(/\r?\n/).length + "\t" +
                   (article.headers.get("xref") || "") + "\n";
     }
-    response += '.\n';
+    response += ".\n";
     return response;
   },
-  XPAT : function (args) {
+  XPAT(args) {
     if (!this.group)
       return "412 No group selected";
 
     /* XPAT header range ... */
     args = args.split(/ +/, 3);
     let header = args[0].toLowerCase();
     let regex = wildmat2regex(args[2]);
 
     let response = "221 Results follow\n";
     for (let key of this._filterRange(args[1], this.group.keys)) {
       let article = this.group[key];
       if (article.headers.has(header) &&
           regex.test(article.headers.get(header))) {
-        response += key + ' ' + article.headers.get(header) + '\n';
+        response += key + " " + article.headers.get(header) + "\n";
       }
     }
-    return response + '.';
+    return response + ".";
   },
 
-  _filterRange: function (range, keys) {
-    let dash = range.indexOf('-');
+  _filterRange(range, keys) {
+    let dash = range.indexOf("-");
     let low, high;
     if (dash < 0) {
       low = high = parseInt(range);
     } else {
       low = parseInt(range.substring(0, dash));
       if (dash < range.length - 1)
         high = range.substring(dash + 1);
       else
         high = 1.0 / 0.0; // Everything is less than this
     }
-    return keys.filter(function (e) { return low <= e && e <= high; });
-  }
+    return keys.filter(function(e) { return low <= e && e <= high; });
+  },
 });
 
 function NNTP_Giganews_handler(daemon) {
   subconstructor(this, NNTP_RFC2980_handler, daemon);
 }
 subclass(NNTP_Giganews_handler, NNTP_RFC2980_handler, {
-  XHDR : function (args) {
+  XHDR(args) {
     var header = args.split(" ")[0].toLowerCase();
     if (header in ["subject", "from", "xref", "date", "message-id",
                    "references"]) {
       return this.parent.XHDR(args);
     }
     return "503 unsupported header field";
-  }
+  },
 });
 
 function NNTP_RFC4643_extension(daemon) {
   subconstructor(this, NNTP_RFC2980_handler, daemon);
 
   this.extraCommands += "\tAUTHINFO USER\n";
   this.extraCommands += "\tAUTHINFO PASS\n";
 }
 subclass(NNTP_RFC4643_extension, NNTP_RFC2980_handler, {
-  expectedUsername : "testnews",
-  expectedPassword : "newstest",
-  requireBoth : true,
+  expectedUsername: "testnews",
+  expectedPassword: "newstest",
+  requireBoth: true,
   authenticated: false,
   usernameReceived: false,
 
-  AUTHINFO : function (args) {
+  AUTHINFO(args) {
     if (this.authenticated)
       return "502 Command unavailable";
 
     var argSplit = args.split(" ");
     var action = argSplit[0];
     var param = argSplit[1];
 
     if (action == "user") {
@@ -543,41 +539,40 @@ subclass(NNTP_RFC4643_extension, NNTP_RF
         return "481 Authentication failed";
 
       this.usernameReceived = true;
       if (this.requireBoth)
         return "381 Password required";
 
       this.authenticated = this.lastGroupTried ? this.lastGroupTried : true;
       return "281 Authentication Accepted";
-    }
-    else if (action == "pass") {
+    } else if (action == "pass") {
       if (!this.requireBoth || !this.usernameReceived)
         return "482 Authentication commands issued out of sequence";
 
       this.usernameReceived = false;
 
       var expectPassword = this.lastGroupTried
         ? this._daemon.groupCredentials[this.lastGroupTried][1]
         : this.expectedPassword;
       if (param != expectPassword)
         return "481 Authentication failed";
 
       this.authenticated = this.lastGroupTried ? this.lastGroupTried : true;
       return "281 Authentication Accepted";
     }
     return "502 Invalid Command";
   },
-  LIST : function (args) {
+  LIST(args) {
     if (this.authenticated) {
       return this.parent.LIST(args);
     }
     return "480 Authentication required";
   },
-  GROUP : function (args) {
+  GROUP(args) {
     if ((this._daemon.groupCredentials != null && this.authenticated == args)
         || (this._daemon.groupCredentials == null && this.authenticated))
       return this.parent.GROUP(args);
     if (this._daemon.groupCredentials != null)
       this.lastGroupTried = args;
     return "480 Authentication required";
-  }
+  },
 });
--- a/mailnews/test/fakeserver/pop3d.js
+++ b/mailnews/test/fakeserver/pop3d.js
@@ -2,20 +2,20 @@
 /**
  * Contributors:
  *   Ben Bucksch <ben.bucksch beonex.com> <http://business.beonex.com> (RFC 5034 Authentication)
  */
 /* This file implements test POP3 servers
  */
 
 var EXPORTED_SYMBOLS = [
-  'pop3Daemon',
-  'POP3_RFC1939_handler',
-  'POP3_RFC2449_handler',
-  'POP3_RFC5034_handler'
+  "pop3Daemon",
+  "POP3_RFC1939_handler",
+  "POP3_RFC2449_handler",
+  "POP3_RFC5034_handler",
 ];
 
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var {IOUtils} = ChromeUtils.import("resource:///modules/IOUtils.js");
 var {
   AuthPLAIN,
   AuthLOGIN,
   AuthCRAM,
@@ -36,26 +36,25 @@ function readFile(fileName) {
   let cwd = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
 
   // Try to find the file relative to either the data directory or to the
   // current working directory.
   let file = cwd.clone();
   if ("@mozilla.org/windows-registry-key;1" in Cc) {
     // Windows doesn't allow '..' in appendRelativePath,
     // so we'll have to do this the long way.
-    if (fileName.includes('/')) {
-      let parts = fileName.split('/');
+    if (fileName.includes("/")) {
+      let parts = fileName.split("/");
       for (let part of parts) {
         if (part == "..")
           file = file.parent;
         else
           file.append(part);
       }
-    }
-    else {
+    } else {
       file.append("data");
       file.append(fileName);
     }
   } else {
     file.appendRelativePath("data/" + fileName);
     if (!file.exists()) {
       file = cwd.clone();
       file.appendRelativePath(fileName);
@@ -77,49 +76,46 @@ pop3Daemon.prototype = {
 
   /**
    * Set the messages that the POP3 daemon will provide to its clients.
    *
    * @param messages An array of either 1) strings that are filenames whose
    *     contents will be loaded from the files or 2) objects with a "fileData"
    *     attribute whose value is the content of the file.
    */
-  setMessages: function(messages) {
+  setMessages(messages) {
     this._messages = [];
     this._totalMessageSize = 0;
 
     function addMessage(element) {
       // if it's a string, then it's a file-name.
       if (typeof element == "string")
-        this._messages.push( { fileData: readFile(element), size: -1 });
+        this._messages.push({ fileData: readFile(element), size: -1 });
       // otherwise it's an object as dictionary already
       else
         this._messages.push(element);
     }
     messages.forEach(addMessage, this);
 
     for (var i = 0; i < this._messages.length; ++i) {
       this._messages[i].size = this._messages[i].fileData.length;
       this._messages[i].uidl = "UIDL" + gUIDLCount++;
       this._totalMessageSize += this._messages[i].size;
     }
   },
-  getTotalMessages: function() {
+  getTotalMessages() {
     return this._messages.length;
   },
-  getTotalMessageSize: function() {
+  getTotalMessageSize() {
     return this._totalMessageSize;
-  }
+  },
 };
 
-///////////////////////////////////////////////////////////////////////////////
-//                              POP3 TEST SERVERS                            //
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
+// POP3 TEST SERVERS
+// -----------------
 
 var kStateAuthNeeded = 1; // Not authenticated yet, need username and password
 var kStateAuthPASS = 2; // got command USER, expecting command PASS
 var kStateTransaction = 3; // Authenticated, can fetch and delete mail
 
 /**
  * This handler implements the bare minimum required by RFC 1939.
  * If dropOnAuthFailure is set, the server will drop the connection
@@ -131,206 +127,206 @@ function POP3_RFC1939_handler(daemon) {
   this.dropOnAuthFailure = false;
   this._multiline = false;
   this.resetTest();
 }
 POP3_RFC1939_handler.prototype = {
   kUsername: "fred",
   kPassword: "wilma",
 
-  resetTest : function() {
+  resetTest() {
     this._state = kStateAuthNeeded;
   },
 
-  USER: function (args) {
+  USER(args) {
     if (this._state != kStateAuthNeeded)
       return "-ERR invalid state";
 
     if (args == this.kUsername) {
       this._state = kStateAuthPASS;
       return "+OK user recognized";
     }
 
     return "-ERR sorry, no such mailbox";
   },
-  PASS: function (args) {
+  PASS(args) {
     if (this._state != kStateAuthPASS)
       return "-ERR invalid state";
 
     if (args == this.kPassword) {
       this._state = kStateTransaction;
       return "+OK maildrop locked and ready";
     }
 
     this._state = kStateAuthNeeded;
     if (this.dropOnAuthFailure)
       this.closing = true;
     return "-ERR invalid password";
   },
-  STAT: function (args) {
+  STAT(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
 
     return "+OK " + this._daemon.getTotalMessages() + " " +
            this._daemon.getTotalMessageSize();
   },
-  LIST: function (args) {
+  LIST(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
 
     var result = "+OK " + this._daemon._messages.length + " messages\r\n";
     for (var i = 0; i < this._daemon._messages.length; ++i)
       result += (i + 1) + " " + this._daemon._messages[i].size + "\r\n";
 
     result += ".";
     return result;
   },
-  UIDL: function (args) {
+  UIDL(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
     let result = "+OK\r\n";
     for (let i = 0; i < this._daemon._messages.length; ++i)
       result += (i + 1) + " " + this._daemon._messages[i].uidl + "\r\n";
 
     result += ".";
     return result;
   },
-  RETR: function (args) {
+  RETR(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
 
     var result = "+OK " + this._daemon._messages[args - 1].size + "\r\n";
     result += this._daemon._messages[args - 1].fileData;
     result += ".";
     return result;
   },
-  DELE: function (args) {
+  DELE(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
     return "+OK";
   },
-  NOOP: function (args) {
+  NOOP(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
     return "+OK";
   },
-  RSET: function (args) {
+  RSET(args) {
     if (this._state != kStateTransaction)
       return "-ERR invalid state";
     this._state = kStateAuthNeeded;
     return "+OK";
   },
-  QUIT: function (args) {
+  QUIT(args) {
     // Let the client close the socket
-    //this.closing = true;
+    // this.closing = true;
     return "+OK fakeserver signing off";
   },
-  onStartup: function () {
+  onStartup() {
     this.closing = false;
     this._state = kStateAuthNeeded;
     return "+OK Fake POP3 server ready";
   },
-  onError: function (command, args) {
+  onError(command, args) {
     return "-ERR command " + command + " not implemented";
   },
-  onServerFault: function (e) {
+  onServerFault(e) {
     return "-ERR internal server error: " + e;
   },
-  postCommand: function(reader) {
+  postCommand(reader) {
     reader.setMultiline(this._multiline);
     if (this.closing)
       reader.closeSocket();
-  }
+  },
 };
 
 
 /**
  * This implements CAPA
  * @see RFC 2449
  *
  * Not yet implemented, but desired are: TOP, UIDL, ...
  */
 function POP3_RFC2449_handler(daemon) {
   POP3_RFC1939_handler.call(this, daemon);
 }
 POP3_RFC2449_handler.prototype = {
-  __proto__ : POP3_RFC1939_handler.prototype, // inherit
+  __proto__: POP3_RFC1939_handler.prototype, // inherit
 
   kCapabilities: ["UIDL"], // the test may adapt this as necessary
 
-  CAPA: function (args) {
+  CAPA(args) {
     var capa = "+OK List of our wanna-be capabilities follows:\r\n";
     for (var i = 0; i < this.kCapabilities.length; i++)
       capa += this.kCapabilities[i] + "\r\n";
     if (this.capaAdditions)
       capa += this.capaAdditions();
-    capa += "IMPLEMENTATION fakeserver\r\n" + ".";
+    capa += "IMPLEMENTATION fakeserver\r\n.";
     return capa;
   },
 };
 
 
 /**
  * This implements the AUTH command, i.e. authentication using CRAM-MD5 etc.
  * @see RFC 5034
  * @author Ben Bucksch <ben.bucksch beonex.com> <http://business.beonex.com>
  */
 function POP3_RFC5034_handler(daemon) {
   POP3_RFC2449_handler.call(this, daemon);
 
   this._kAuthSchemeStartFunction = {};
   this._kAuthSchemeStartFunction["CRAM-MD5"] = this.authCRAMStart;
-  this._kAuthSchemeStartFunction["PLAIN"] = this.authPLAINStart;
-  this._kAuthSchemeStartFunction["LOGIN"] = this.authLOGINStart;
+  this._kAuthSchemeStartFunction.PLAIN = this.authPLAINStart;
+  this._kAuthSchemeStartFunction.LOGIN = this.authLOGINStart;
 }
 POP3_RFC5034_handler.prototype = {
-  __proto__ : POP3_RFC2449_handler.prototype, // inherit
+  __proto__: POP3_RFC2449_handler.prototype, // inherit
 
   kAuthSchemes: [ "CRAM-MD5", "PLAIN", "LOGIN" ], // the test may adapt this as necessary
 
-  _usedCRAMMD5Challenge : null, // not base64-encoded
+  _usedCRAMMD5Challenge: null, // not base64-encoded
 
   // called by this.CAPA()
-  capaAdditions : function() {
+  capaAdditions() {
     var capa = "";
     if (this.kAuthSchemes.length > 0) {
       capa += "SASL";
       for (var i = 0; i < this.kAuthSchemes.length; i++)
         capa += " " + this.kAuthSchemes[i];
       capa += "\r\n";
     }
     return capa;
   },
-  AUTH: function (lineRest) {
+  AUTH(lineRest) {
     // |lineRest| is a string containing the rest of line after "AUTH "
     if (this._state != kStateAuthNeeded)
       return "-ERR invalid state";
 
     // AUTH without arguments returns a list of supported schemes
     if (!lineRest) {
       var capa = "+OK I like:\r\n";
       for (var i = 0; i < this.kAuthSchemes.length; i++)
         capa += this.kAuthSchemes[i] + "\r\n";
       capa += ".\r\n";
       return capa;
     }
 
     var args = lineRest.split(" ");
     var scheme = args[0].toUpperCase();
     // |scheme| contained in |kAuthSchemes|?
-    if (!this.kAuthSchemes.some(function (s) { return s == scheme; }))
+    if (!this.kAuthSchemes.some(function(s) { return s == scheme; }))
       return "-ERR AUTH " + scheme + " not supported";
 
     var func = this._kAuthSchemeStartFunction[scheme];
     if (!func || typeof(func) != "function")
       return "-ERR I just pretended to implement AUTH " + scheme + ", but I don't";
     return func.call(this, "1" in args ? args[1] : undefined);
   },
 
-  onMultiline: function(line) {
+  onMultiline(line) {
     if (this._nextAuthFunction) {
       var func = this._nextAuthFunction;
       this._multiline = false;
       this._nextAuthFunction = undefined;
       if (line == "*") {
         return "-ERR Okay, as you wish. Chicken";
       }
       if (!func || typeof(func) != "function") {
@@ -342,92 +338,78 @@ POP3_RFC5034_handler.prototype = {
     }
 
     if (POP3_RFC2449_handler.prototype.onMultiline)
       return POP3_RFC2449_handler.prototype.onMultiline.call(this, line); // call parent
     return undefined;
   },
 
 
-  authPLAINStart : function (lineRest)
-  {
+  authPLAINStart(lineRest) {
     this._nextAuthFunction = this.authPLAINCred;
     this._multiline = true;
 
     return "+";
   },
-  authPLAINCred : function (line)
-  {
+  authPLAINCred(line) {
     var req = AuthPLAIN.decodeLine(line);
     if (req.username == this.kUsername &&
         req.password == this.kPassword) {
       this._state = kStateTransaction;
       return "+OK Hello friend! Friends give friends good advice: Next time, use CRAM-MD5";
     }
-    else {
       if (this.dropOnAuthFailure)
         this.closing = true;
       return "-ERR Wrong username or password, crook!";
-    }
   },
 
-  authCRAMStart : function (lineRest)
-  {
+  authCRAMStart(lineRest) {
     this._nextAuthFunction = this.authCRAMDigest;
     this._multiline = true;
 
     this._usedCRAMMD5Challenge = AuthCRAM.createChallenge("localhost");
     return "+ " + this._usedCRAMMD5Challenge;
   },
-  authCRAMDigest : function (line)
-  {
+  authCRAMDigest(line) {
     var req = AuthCRAM.decodeLine(line);
     var expectedDigest = AuthCRAM.encodeCRAMMD5(
         this._usedCRAMMD5Challenge, this.kPassword);
     if (req.username == this.kUsername &&
         req.digest == expectedDigest) {
       this._state = kStateTransaction;
       return "+OK Hello friend!";
     }
-    else {
       if (this.dropOnAuthFailure)
         this.closing = true;
       return "-ERR Wrong username or password, crook!";
-    }
   },
 
-  authLOGINStart : function (lineRest)
-  {
+  authLOGINStart(lineRest) {
     this._nextAuthFunction = this.authLOGINUsername;
     this._multiline = true;
 
     return "+ " + btoa("Username:");
   },
-  authLOGINUsername : function (line)
-  {
+  authLOGINUsername(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kUsername)
       this._nextAuthFunction = this.authLOGINPassword;
     else // Don't return error yet, to not reveal valid usernames
       this._nextAuthFunction = this.authLOGINBadUsername;
     this._multiline = true;
     return "+ " + btoa("Password:");
   },
-  authLOGINBadUsername : function (line)
-  {
+  authLOGINBadUsername(line) {
     if (this.dropOnAuthFailure)
       this.closing = true;
     return "-ERR Wrong username or password, crook!";
   },
-  authLOGINPassword : function (line)
-  {
+  authLOGINPassword(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kPassword) {
       this._state = kStateTransaction;
       return "+OK Hello friend! Where did you pull out this old auth scheme?";
     }
-    else {
       if (this.dropOnAuthFailure)
         this.closing = true;
       return "-ERR Wrong username or password, crook!";
-    }
   },
 };
--- a/mailnews/test/fakeserver/smtpd.js
+++ b/mailnews/test/fakeserver/smtpd.js
@@ -1,32 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // This file implements test SMTP servers
 
 var EXPORTED_SYMBOLS = [
-  'smtpDaemon',
-  'SMTP_RFC2821_handler',
+  "smtpDaemon",
+  "SMTP_RFC2821_handler",
 ];
 
 var {
   AuthPLAIN,
   AuthLOGIN,
   AuthCRAM,
 } = ChromeUtils.import("resource://testing-common/mailnews/auth.js");
 
 function smtpDaemon(flags) {
   this._messages = {};
 }
 smtpDaemon.prototype = {
-}
+};
 
-///////////////////////////////////////////////////////////////////////////////
-//                              SMTP TEST SERVERS                            //
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
+// SMTP TEST SERVERS
+// -----------------
 
 var kStateAuthNeeded = 0;
 var kStateAuthOptional = 2;
 var kStateAuthenticated = 3;
 
 /**
  * This handler implements the bare minimum required by RFC 2821.
  * @see RFC 2821
@@ -35,199 +33,185 @@ var kStateAuthenticated = 3;
  */
 function SMTP_RFC2821_handler(daemon) {
   this._daemon = daemon;
   this.closing = false;
   this.dropOnAuthFailure = false;
 
   this._kAuthSchemeStartFunction = {};
   this._kAuthSchemeStartFunction["CRAM-MD5"] = this.authCRAMStart;
-  this._kAuthSchemeStartFunction["PLAIN"] = this.authPLAINStart;
-  this._kAuthSchemeStartFunction["LOGIN"] = this.authLOGINStart;
+  this._kAuthSchemeStartFunction.PLAIN = this.authPLAINStart;
+  this._kAuthSchemeStartFunction.LOGIN = this.authLOGINStart;
 
   this.resetTest();
 }
 SMTP_RFC2821_handler.prototype = {
-  kAuthRequired : false,
-  kUsername : "testsmtp",
-  kPassword : "smtptest",
-  kAuthSchemes : [ "CRAM-MD5", "PLAIN", "LOGIN" ],
-  kCapabilities : [ "8BITMIME", "SIZE" ],
-  _nextAuthFunction : undefined,
+  kAuthRequired: false,
+  kUsername: "testsmtp",
+  kPassword: "smtptest",
+  kAuthSchemes: [ "CRAM-MD5", "PLAIN", "LOGIN" ],
+  kCapabilities: [ "8BITMIME", "SIZE" ],
+  _nextAuthFunction: undefined,
 
-  resetTest : function() {
+  resetTest() {
     this._state = this.kAuthRequired ? kStateAuthNeeded : kStateAuthOptional;
     this._nextAuthFunction = undefined;
     this._multiline = false;
     this.expectingData = false;
   },
-  EHLO: function (args) {
+  EHLO(args) {
     var capa = "250-fakeserver greets you";
     if (this.kCapabilities.length > 0)
       capa += "\n250-" + this.kCapabilities.join("\n250-");
     if (this.kAuthSchemes.length > 0)
       capa += "\n250-AUTH " + this.kAuthSchemes.join(" ");
     capa += "\n250 HELP"; // the odd one: no "-", per RFC 2821
     return capa;
   },
-  AUTH: function (lineRest) {
+  AUTH(lineRest) {
     if (this._state == kStateAuthenticated)
       return "503 You're already authenticated";
     var args = lineRest.split(" ");
     var scheme = args[0].toUpperCase();
     // |scheme| contained in |kAuthSchemes|?
-    if (!this.kAuthSchemes.some(function (s) { return s == scheme; }))
+    if (!this.kAuthSchemes.some(function(s) { return s == scheme; }))
       return "504 AUTH " + scheme + " not supported";
     var func = this._kAuthSchemeStartFunction[scheme];
     if (!func || typeof(func) != "function")
       return "504 I just pretended to implement AUTH " + scheme + ", but I don't";
     dump("Starting AUTH " + scheme + "\n");
     return func.call(this, ((args.length > 1) ? args[1] : undefined));
   },
-  MAIL: function (args) {
+  MAIL(args) {
     if (this._state == kStateAuthNeeded)
       return "530 5.7.0 Authentication required";
     return "250 ok";
   },
-  RCPT: function(args) {
+  RCPT(args) {
     if (this._state == kStateAuthNeeded)
       return "530 5.7.0 Authentication required";
     return "250 ok";
   },
-  DATA: function(args) {
+  DATA(args) {
     if (this._state == kStateAuthNeeded)
       return "530 5.7.0 Authentication required";
     this.expectingData = true;
     this._daemon.post = "";
     return "354 ok\n";
   },
-  RSET: function (args) {
+  RSET(args) {
     return "250 ok\n";
   },
-  VRFY: function (args) {
+  VRFY(args) {
     if (this._state == kStateAuthNeeded)
       return "530 5.7.0 Authentication required";
     return "250 ok\n";
   },
-  EXPN: function (args) {
+  EXPN(args) {
     return "250 ok\n";
   },
-  HELP: function (args) {
+  HELP(args) {
     return "211 ok\n";
   },
-  NOOP: function (args) {
+  NOOP(args) {
     return "250 ok\n";
   },
-  QUIT: function (args) {
+  QUIT(args) {
     this.closing = true;
     return "221 done";
   },
-  onStartup: function () {
+  onStartup() {
     this.closing = false;
     return "220 ok";
   },
 
   /**
    * AUTH implementations
    * @see RFC 4954
    */
-  authPLAINStart : function (lineRest)
-  {
+  authPLAINStart(lineRest) {
     if (lineRest) // all in one command, called initial client response, see RFC 4954
       return this.authPLAINCred(lineRest);
 
     this._nextAuthFunction = this.authPLAINCred;
     this._multiline = true;
 
     return "334 ";
   },
-  authPLAINCred : function (line)
-  {
+  authPLAINCred(line) {
     var req = AuthPLAIN.decodeLine(line);
     if (req.username == this.kUsername &&
         req.password == this.kPassword) {
       this._state = kStateAuthenticated;
       return "235 2.7.0 Hello friend! Friends give friends good advice: Next time, use CRAM-MD5";
     }
-    else {
       if (this.dropOnAuthFailure)
         this.closing = true;
       return "535 5.7.8 Wrong username or password, crook!";
-    }
   },
 
-  authCRAMStart : function (lineRest)
-  {
+  authCRAMStart(lineRest) {
     this._nextAuthFunction = this.authCRAMDigest;
     this._multiline = true;
 
     this._usedCRAMMD5Challenge = AuthCRAM.createChallenge("localhost");
     return "334 " + this._usedCRAMMD5Challenge;
   },
-  authCRAMDigest : function (line)
-  {
+  authCRAMDigest(line) {
     var req = AuthCRAM.decodeLine(line);
     var expectedDigest = AuthCRAM.encodeCRAMMD5(
         this._usedCRAMMD5Challenge, this.kPassword);
     if (req.username == this.kUsername &&
         req.digest == expectedDigest) {
       this._state = kStateAuthenticated;
       return "235 2.7.0 Hello friend!";
     }
-    else {
-      if (this.dropOnAuthFailure)
-        this.closing = true;
-      return "535 5.7.8 Wrong username or password, crook!";
-    }
+    if (this.dropOnAuthFailure)
+      this.closing = true;
+    return "535 5.7.8 Wrong username or password, crook!";
   },
 
-  authLOGINStart : function (lineRest)
-  {
+  authLOGINStart(lineRest) {
     this._nextAuthFunction = this.authLOGINUsername;
     this._multiline = true;
 
     return "334 " + btoa("Username:");
   },
-  authLOGINUsername : function (line)
-  {
+  authLOGINUsername(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kUsername)
       this._nextAuthFunction = this.authLOGINPassword;
     else // Don't return error yet, to not reveal valid usernames
       this._nextAuthFunction = this.authLOGINBadUsername;
     this._multiline = true;
     return "334 " + btoa("Password:");
   },
-  authLOGINBadUsername : function (line)
-  {
+  authLOGINBadUsername(line) {
     if (this.dropOnAuthFailure)
       this.closing = true;
     return "535 5.7.8 Wrong username or password, crook!";
   },
-  authLOGINPassword : function (line)
-  {
+  authLOGINPassword(line) {
     var req = AuthLOGIN.decodeLine(line);
     if (req == this.kPassword) {
       this._state = kStateAuthenticated;
       return "235 2.7.0 Hello friend! Where did you pull out this old auth scheme?";
     }
-    else {
-      if (this.dropOnAuthFailure)
-        this.closing = true;
-      return "535 5.7.8 Wrong username or password, crook!";
-    }
+    if (this.dropOnAuthFailure)
+      this.closing = true;
+    return "535 5.7.8 Wrong username or password, crook!";
   },
 
-  onError: function (command, args) {
+  onError(command, args) {
     return "500 Command " + command + " not recognized\n";
   },
-  onServerFault: function (e) {
+  onServerFault(e) {
     return "451 Internal server error: " + e;
   },
-  onMultiline: function(line) {
+  onMultiline(line) {
     if (this._nextAuthFunction) {
       var func = this._nextAuthFunction;
       this._multiline = false;
       this._nextAuthFunction = undefined;
       if (line == "*") { // abort, per RFC 4954 and others
         return "501 Okay, as you wish. Chicken";
       }
       if (!func || typeof(func) != "function") {
@@ -241,21 +225,21 @@ SMTP_RFC2821_handler.prototype = {
       if (this.expectingData) {
         this.expectingData = false;
         return "250 Wonderful article, your style is gorgeous!";
       }
       return "503 Huch? How did you get here?";
     }
 
     if (this.expectingData) {
-      if (line.startsWith('.'))
+      if (line.startsWith("."))
         line = line.substring(1);
       // This uses CR LF to match with the specification
-      this._daemon.post += line + '\r\n';
+      this._daemon.post += line + "\r\n";
     }
     return undefined;
   },
-  postCommand: function(reader) {
+  postCommand(reader) {
     if (this.closing)
       reader.closeSocket();
     reader.setMultiline(this._multiline || this.expectingData);
-  }
-}
+  },
+};