Merge "ES6ify /gr-confirm-rebase-dialog/*"
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/IoUtil.java b/gerrit-common/src/main/java/com/google/gerrit/common/IoUtil.java
index 1ac42d1..624bcea 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/IoUtil.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/IoUtil.java
@@ -56,6 +56,10 @@
   }
 
   public static void loadJARs(Collection<Path> jars) {
+    if (jars.isEmpty()) {
+      return;
+    }
+
     ClassLoader cl = IoUtil.class.getClassLoader();
     if (!(cl instanceof URLClassLoader)) {
       throw noAddURL("Not loaded by URLClassLoader", null);
diff --git a/gerrit-plugin-api/BUILD b/gerrit-plugin-api/BUILD
index ebc5619..2e768ee 100644
--- a/gerrit-plugin-api/BUILD
+++ b/gerrit-plugin-api/BUILD
@@ -19,6 +19,7 @@
     "//gerrit-extension-api:api",
     "//gerrit-gwtexpui:server",
     "//gerrit-reviewdb:server",
+    "//gerrit-server/src/main/prolog:common",
     "//lib/commons:lang",
     "//lib/commons:lang3",
     "//lib/dropwizard:dropwizard-core",
diff --git a/lib/prolog/BUILD b/lib/prolog/BUILD
index 875f135..f6b4c5f 100644
--- a/lib/prolog/BUILD
+++ b/lib/prolog/BUILD
@@ -6,6 +6,13 @@
 )
 
 java_library(
+    name = "runtime-neverlink",
+    data = ["//lib:LICENSE-prologcafe"],
+    visibility = ["//visibility:public"],
+    exports = ["@prolog_runtime//jar:neverlink"],
+)
+
+java_library(
     name = "compiler",
     data = ["//lib:LICENSE-prologcafe"],
     visibility = ["//visibility:public"],
diff --git a/lib/prolog/prolog.bzl b/lib/prolog/prolog.bzl
index cae85ad..43a8bab 100644
--- a/lib/prolog/prolog.bzl
+++ b/lib/prolog/prolog.bzl
@@ -12,14 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("//tools/bzl:genrule2.bzl", "genrule2")
-
 def prolog_cafe_library(
     name,
     srcs,
     deps = [],
     **kwargs):
-  genrule2(
+  native.genrule(
     name = name + '__pl2j',
     cmd = '$(location //lib/prolog:compiler_bin) ' +
       '$$(dirname $@) $@ ' +
@@ -31,6 +29,6 @@
   native.java_library(
     name = name,
     srcs = [':' + name + '__pl2j'],
-    deps = ['//lib/prolog:runtime'] + deps,
+    deps = ['//lib/prolog:runtime-neverlink'] + deps,
     **kwargs
   )
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
index 1c5dd59..ae45da4 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
@@ -40,76 +40,76 @@
 </test-fixture>
 
 <script>
-  suite('gr-change-metadata integration tests', function() {
-    var sandbox;
-    var element;
+  suite('gr-change-metadata integration tests', () => {
+    let sandbox;
+    let element;
 
-    var sectionSelectors = [
+    const sectionSelectors = [
       'section.assignee',
       'section.labelStatus',
       'section.strategy',
       'section.topic',
     ];
 
-    var getStyle = function(selector, name) {
+    const getStyle = function(selector, name) {
       return window.getComputedStyle(
           Polymer.dom(element.root).querySelector(selector))[name];
     };
 
-    setup(function() {
+    setup(() => {
       sandbox = sinon.sandbox.create();
       stub('gr-change-metadata', {
-        _computeShowLabelStatus: function() { return true; },
-        _computeShowReviewersByState: function() { return true; },
-        ready: function() {
+        _computeShowLabelStatus() { return true; },
+        _computeShowReviewersByState() { return true; },
+        ready() {
           this.change = {labels: []};
           this.serverConfig = {};
         },
       });
     });
 
-    teardown(function() {
+    teardown(() => {
       Gerrit._pluginsPending = -1;
       Gerrit._allPluginsPromise = undefined;
       sandbox.restore();
     });
 
-    suite('by default', function() {
-      setup(function(done) {
+    suite('by default', () => {
+      setup(done => {
         element = fixture('element');
         flush(done);
       });
 
-      sectionSelectors.forEach(function(sectionSelector) {
-        test(sectionSelector + ' does not have display: none', function() {
+      for (const sectionSelector of sectionSelectors) {
+        test(sectionSelector + ' does not have display: none', () => {
           assert.notEqual(getStyle(sectionSelector, 'display'), 'none');
         });
-      });
+      }
     });
 
-    suite('with plugin style', function() {
-      setup(function(done) {
-        var pluginHost = fixture('plugin-host');
+    suite('with plugin style', () => {
+      setup(done => {
+        const pluginHost = fixture('plugin-host');
         pluginHost.config = {
           js_resource_paths: [],
           html_resource_paths: [
             new URL('test/plugin.html', window.location.href).toString(),
-          ]
+          ],
         };
         element = fixture('element');
-        var importSpy = sandbox.spy(element.$.externalStyle, '_import');
-        Gerrit.awaitPluginsLoaded().then(function() {
-          Promise.all(importSpy.returnValues).then(function() {
+        const importSpy = sandbox.spy(element.$.externalStyle, '_import');
+        Gerrit.awaitPluginsLoaded().then(() => {
+          Promise.all(importSpy.returnValues).then(() => {
             flush(done);
           });
         });
       });
 
-      sectionSelectors.forEach(function(sectionSelector) {
-        test(sectionSelector + ' may have display: none', function() {
+      for (const sectionSelector of sectionSelectors) {
+        test(sectionSelector + ' may have display: none', () => {
           assert.equal(getStyle(sectionSelector, 'display'), 'none');
         });
-      });
+      }
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 4527104..62fe5ed 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -14,7 +14,7 @@
 (function() {
   'use strict';
 
-  var SubmitTypeLabel = {
+  const SubmitTypeLabel = {
     FAST_FORWARD_ONLY: 'Fast Forward Only',
     MERGE_IF_NECESSARY: 'Merge if Necessary',
     REBASE_IF_NECESSARY: 'Rebase if Necessary',
@@ -61,15 +61,15 @@
       '_assigneeChanged(_assignee.*)',
     ],
 
-    _changeChanged: function(change) {
+    _changeChanged(change) {
       this._assignee = change.assignee ? [change.assignee] : [];
     },
 
-    _assigneeChanged: function(assigneeRecord) {
+    _assigneeChanged(assigneeRecord) {
       if (!this.change) { return; }
-      var assignee = assigneeRecord.base;
+      const assignee = assigneeRecord.base;
       if (assignee.length) {
-        var acct = assignee[0];
+        const acct = assignee[0];
         if (this.change.assignee &&
             acct._account_id === this.change.assignee._account_id) { return; }
         this.set(['change', 'assignee'], acct);
@@ -81,7 +81,7 @@
       }
     },
 
-    _computeHideStrategy: function(change) {
+    _computeHideStrategy(change) {
       return !this.changeIsOpen(change.status);
     },
 
@@ -89,7 +89,7 @@
      * This is a whitelist of web link types that provide direct links to
      * the commit in the url property.
      */
-    _isCommitWebLink: function(link) {
+    _isCommitWebLink(link) {
       return link.name === 'gitiles' || link.name === 'gitweb';
     },
 
@@ -99,34 +99,34 @@
      * an existential check can be used to hide or show the webLinks
      * section.
      */
-    _computeWebLinks: function(commitInfo) {
-      if (!commitInfo || !commitInfo.web_links) { return null }
+    _computeWebLinks(commitInfo) {
+      if (!commitInfo || !commitInfo.web_links) { return null; }
       // We are already displaying these types of links elsewhere,
       // don't include in the metadata links section.
-      var webLinks = commitInfo.web_links.filter(
-          function(l) {return !this._isCommitWebLink(l); }.bind(this));
+      const webLinks = commitInfo.web_links.filter(
+          l => {return !this._isCommitWebLink(l); });
 
       return webLinks.length ? webLinks : null;
     },
 
-    _computeStrategy: function(change) {
+    _computeStrategy(change) {
       return SubmitTypeLabel[change.submit_type];
     },
 
-    _computeLabelNames: function(labels) {
+    _computeLabelNames(labels) {
       return Object.keys(labels).sort();
     },
 
-    _computeLabelValues: function(labelName, _labels) {
-      var result = [];
-      var labels = _labels.base;
-      var t = labels[labelName];
+    _computeLabelValues(labelName, _labels) {
+      const result = [];
+      const labels = _labels.base;
+      const t = labels[labelName];
       if (!t) { return result; }
-      var approvals = t.all || [];
-      approvals.forEach(function(label) {
+      const approvals = t.all || [];
+      for (const label of approvals) {
         if (label.value && label.value != labels[labelName].default_value) {
-          var labelClassName;
-          var labelValPrefix = '';
+          let labelClassName;
+          let labelValPrefix = '';
           if (label.value > 0) {
             labelValPrefix = '+';
             labelClassName = 'approved';
@@ -139,35 +139,35 @@
             account: label,
           });
         }
-      });
+      }
       return result;
     },
 
-    _computeValueTooltip: function(score, labelName) {
-      var values = this.change.labels[labelName].values;
+    _computeValueTooltip(score, labelName) {
+      const values = this.change.labels[labelName].values;
       return values[score];
     },
 
-    _handleTopicChanged: function(e, topic) {
+    _handleTopicChanged(e, topic) {
       if (!topic.length) { topic = null; }
       this.$.restAPI.setChangeTopic(this.change._number, topic);
     },
 
-    _computeTopicReadOnly: function(mutable, change) {
+    _computeTopicReadOnly(mutable, change) {
       return !mutable || !change.actions.topic || !change.actions.topic.enabled;
     },
 
-    _computeAssigneeReadOnly: function(mutable, change) {
+    _computeAssigneeReadOnly(mutable, change) {
       return !mutable ||
           !change.actions.assignee ||
           !change.actions.assignee.enabled;
     },
 
-    _computeTopicPlaceholder: function(_topicReadOnly) {
+    _computeTopicPlaceholder(_topicReadOnly) {
       return _topicReadOnly ? 'No Topic' : 'Click to add topic';
     },
 
-    _computeShowReviewersByState: function(serverConfig) {
+    _computeShowReviewersByState(serverConfig) {
       return !!serverConfig.note_db_enabled;
     },
 
@@ -181,9 +181,9 @@
      * @param {boolean} mutable this.mutable describes whether the
      *     change-metadata section is modifiable by the current user.
      */
-    _computeCanDeleteVote: function(reviewer, mutable) {
+    _computeCanDeleteVote(reviewer, mutable) {
       if (!mutable) { return false; }
-      for (var i = 0; i < this.change.removable_reviewers.length; i++) {
+      for (let i = 0; i < this.change.removable_reviewers.length; i++) {
         if (this.change.removable_reviewers[i]._account_id ===
             reviewer._account_id) {
           return true;
@@ -192,20 +192,20 @@
       return false;
     },
 
-    _onDeleteVote: function(e) {
+    _onDeleteVote(e) {
       e.preventDefault();
-      var target = Polymer.dom(e).rootTarget;
-      var labelName = target.labelName;
-      var accountID = parseInt(target.getAttribute('data-account-id'), 10);
+      const target = Polymer.dom(e).rootTarget;
+      const labelName = target.labelName;
+      const accountID = parseInt(target.getAttribute('data-account-id'), 10);
       this._xhrPromise =
           this.$.restAPI.deleteVote(this.change.id, accountID, labelName)
-          .then(function(response) {
+          .then(response => {
             if (!response.ok) { return response; }
-            var label = this.change.labels[labelName];
-            var labels = label.all || [];
-            for (var i = 0; i < labels.length; i++) {
+            const label = this.change.labels[labelName];
+            const labels = label.all || [];
+            for (let i = 0; i < labels.length; i++) {
               if (labels[i]._account_id === accountID) {
-                for (var key in label) {
+                for (const key in label) {
                   if (label.hasOwnProperty(key) &&
                       label[key]._account_id === accountID) {
                     // Remove special label field, keeping change label values
@@ -217,19 +217,20 @@
                 break;
               }
             }
-          }.bind(this));
+          });
     },
 
-    _computeShowLabelStatus: function(change) {
-      var isNewChange = change.status === this.ChangeStatus.NEW;
-      var hasLabels = Object.keys(change.labels).length > 0;
+    _computeShowLabelStatus(change) {
+      const isNewChange = change.status === this.ChangeStatus.NEW;
+      const hasLabels = Object.keys(change.labels).length > 0;
       return isNewChange && hasLabels;
     },
 
-    _computeMissingLabels: function(labels) {
-      var missingLabels = [];
-      for (var label in labels) {
-        var obj = labels[label];
+    _computeMissingLabels(labels) {
+      const missingLabels = [];
+      for (const label in labels) {
+        if (!labels.hasOwnProperty(label)) { continue; }
+        const obj = labels[label];
         if (!obj.optional && !obj.approved) {
           missingLabels.push(label);
         }
@@ -237,26 +238,26 @@
       return missingLabels;
     },
 
-    _computeMissingLabelsHeader: function(labels) {
+    _computeMissingLabelsHeader(labels) {
       return 'Needs label' +
           (this._computeMissingLabels(labels).length > 1 ? 's' : '') + ':';
     },
 
-    _showMissingLabels: function(labels) {
+    _showMissingLabels(labels) {
       return !!this._computeMissingLabels(labels).length;
     },
 
-    _showMissingRequirements: function(labels, workInProgress) {
+    _showMissingRequirements(labels, workInProgress) {
       return workInProgress || this._showMissingLabels(labels);
     },
 
-    _computeProjectURL: function(project) {
+    _computeProjectURL(project) {
       return this.getBaseUrl() + '/q/project:' +
         this.encodeURL(project, false);
     },
 
-    _computeBranchURL: function(project, branch) {
-      var status;
+    _computeBranchURL(project, branch) {
+      let status;
       if (this.change.status == this.ChangeStatus.NEW) {
         status = 'open';
       } else {
@@ -268,13 +269,13 @@
               ' status:' + this.encodeURL(status, false);
     },
 
-    _computeTopicURL: function(topic) {
+    _computeTopicURL(topic) {
       return this.getBaseUrl() + '/q/topic:' +
           this.encodeURL('"' + topic + '"', false) +
             '+(status:open OR status:merged)';
     },
 
-    _handleTopicRemoved: function() {
+    _handleTopicRemoved() {
       this.set(['change', 'topic'], '');
       this.$.restAPI.setChangeTopic(this.change._number, null);
     },
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index 2840c1f..5003a68 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -33,25 +33,25 @@
 </test-fixture>
 
 <script>
-  suite('gr-change-metadata tests', function() {
-    var element;
-    var sandbox;
+  suite('gr-change-metadata tests', () => {
+    let element;
+    let sandbox;
 
-    setup(function() {
+    setup(() => {
       sandbox = sinon.sandbox.create();
       stub('gr-rest-api-interface', {
-        getConfig: function() { return Promise.resolve({}); },
-        getLoggedIn: function() { return Promise.resolve(false); },
+        getConfig() { return Promise.resolve({}); },
+        getLoggedIn() { return Promise.resolve(false); },
       });
 
       element = fixture('basic');
     });
 
-    teardown(function() {
+    teardown(() => {
       sandbox.restore();
     });
 
-    test('computed fields', function() {
+    test('computed fields', () => {
       assert.isFalse(element._computeHideStrategy({status: 'NEW'}));
       assert.isFalse(element._computeHideStrategy({status: 'DRAFT'}));
       assert.isTrue(element._computeHideStrategy({status: 'MERGED'}));
@@ -60,22 +60,22 @@
           'Cherry Pick');
     });
 
-    test('show strategy for open change', function() {
+    test('show strategy for open change', () => {
       element.change = {status: 'NEW', submit_type: 'CHERRY_PICK', labels: {}};
       flushAsynchronousOperations();
-      var strategy = element.$$('.strategy');
+      const strategy = element.$$('.strategy');
       assert.ok(strategy);
       assert.isFalse(strategy.hasAttribute('hidden'));
       assert.equal(strategy.children[1].innerHTML, 'Cherry Pick');
     });
 
-    test('hide strategy for closed change', function() {
+    test('hide strategy for closed change', () => {
       element.change = {status: 'MERGED', labels: {}};
       flushAsynchronousOperations();
       assert.isTrue(element.$$('.strategy').hasAttribute('hidden'));
     });
 
-    test('show CC section when NoteDb enabled', function() {
+    test('show CC section when NoteDb enabled', () => {
       function hasCc() {
         return element._showReviewersByState;
       }
@@ -87,9 +87,9 @@
       assert.isTrue(hasCc());
     });
 
-    test('computes submit status', function() {
-      var showMissingLabels = false;
-      sandbox.stub(element, '_showMissingLabels', function() {
+    test('computes submit status', () => {
+      let showMissingLabels = false;
+      sandbox.stub(element, '_showMissingLabels', () => {
         return showMissingLabels;
       });
       assert.isFalse(element._showMissingRequirements(null, false));
@@ -98,8 +98,8 @@
       assert.isTrue(element._showMissingRequirements(null, false));
     });
 
-    test('show missing labels', function() {
-      var labels = {};
+    test('show missing labels', () => {
+      let labels = {};
       assert.isFalse(element._showMissingLabels(labels));
       labels = {test: {}};
       assert.isTrue(element._showMissingLabels(labels));
@@ -116,25 +116,25 @@
           ['test', 'test2']);
     });
 
-    test('weblinks hidden when no weblinks', function() {
+    test('weblinks hidden when no weblinks', () => {
       element.commitInfo = {};
       flushAsynchronousOperations();
-      var webLinks = element.$.webLinks;
+      const webLinks = element.$.webLinks;
       assert.isTrue(webLinks.hasAttribute('hidden'));
     });
 
-    test('weblinks hidden when only gitiles weblink', function() {
+    test('weblinks hidden when only gitiles weblink', () => {
       element.commitInfo = {web_links: [{name: 'gitiles', url: '#'}]};
       flushAsynchronousOperations();
-      var webLinks = element.$.webLinks;
+      const webLinks = element.$.webLinks;
       assert.isTrue(webLinks.hasAttribute('hidden'));
       assert.equal(element._computeWebLinks(element.commitInfo), null);
     });
 
-    test('weblinks are visible when other weblinks', function() {
+    test('weblinks are visible when other weblinks', () => {
       element.commitInfo = {web_links: [{name: 'test', url: '#'}]};
       flushAsynchronousOperations();
-      var webLinks = element.$.webLinks;
+      const webLinks = element.$.webLinks;
       assert.isFalse(webLinks.hasAttribute('hidden'));
       assert.equal(element._computeWebLinks(element.commitInfo).length, 1);
       // With two non-gitiles weblinks, there are two returned.
@@ -143,18 +143,18 @@
       assert.equal(element._computeWebLinks(element.commitInfo).length, 2);
     });
 
-    test('weblinks are visible when gitiles and other weblinks', function() {
+    test('weblinks are visible when gitiles and other weblinks', () => {
       element.commitInfo = {
         web_links: [{name: 'test', url: '#'}, {name: 'gitiles', url: '#'}]};
       flushAsynchronousOperations();
-      var webLinks = element.$.webLinks;
+      const webLinks = element.$.webLinks;
       assert.isFalse(webLinks.hasAttribute('hidden'));
       // Only the non-gitiles weblink is returned.
       assert.equal(element._computeWebLinks(element.commitInfo).length, 1);
     });
 
-    test('determines whether to show "Ready to Submit" label', function() {
-      var showMissingSpy = sandbox.spy(element, '_showMissingRequirements');
+    test('determines whether to show "Ready to Submit" label', () => {
+      const showMissingSpy = sandbox.spy(element, '_showMissingRequirements');
       element.change = {status: 'NEW', submit_type: 'CHERRY_PICK', labels: {
         test: {
           all: [{_account_id: 1, name: 'bojack', value: 1}],
@@ -166,9 +166,9 @@
       assert.isTrue(showMissingSpy.called);
     });
 
-    suite('Topic removal', function() {
-      var change;
-      setup(function() {
+    suite('Topic removal', () => {
+      let change;
+      setup(() => {
         change = {
           _number: 'the number',
           actions: {
@@ -189,8 +189,8 @@
         };
       });
 
-      test('_computeTopicReadOnly', function() {
-        var mutable = false;
+      test('_computeTopicReadOnly', () => {
+        let mutable = false;
         assert.isTrue(element._computeTopicReadOnly(mutable, change));
         mutable = true;
         assert.isTrue(element._computeTopicReadOnly(mutable, change));
@@ -200,26 +200,26 @@
         assert.isTrue(element._computeTopicReadOnly(mutable, change));
       });
 
-      test('topic read only hides delete button', function() {
+      test('topic read only hides delete button', () => {
         element.mutable = false;
         element.change = change;
         flushAsynchronousOperations();
-        var button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.$$('gr-linked-chip').$$('gr-button');
         assert.isTrue(button.hasAttribute('hidden'));
       });
 
-      test('topic not read only does not hide delete button', function() {
+      test('topic not read only does not hide delete button', () => {
         element.mutable = true;
         change.actions.topic.enabled = true;
         element.change = change;
         flushAsynchronousOperations();
-        var button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.$$('gr-linked-chip').$$('gr-button');
         assert.isFalse(button.hasAttribute('hidden'));
       });
     });
 
-    suite('remove reviewer votes', function() {
-      setup(function() {
+    suite('remove reviewer votes', () => {
+      setup(() => {
         sandbox.stub(element, '_computeValueTooltip').returns('');
         sandbox.stub(element, '_computeTopicReadOnly').returns(true);
         element.change = {
@@ -240,30 +240,39 @@
         };
       });
 
-      test('_computeCanDeleteVote hides delete button', function() {
+      test('_computeCanDeleteVote hides delete button', () => {
         flushAsynchronousOperations();
-        var button = element.$$('gr-account-chip').$$('gr-button');
+        const button = element.$$('gr-account-chip').$$('gr-button');
         assert.isTrue(button.hasAttribute('hidden'));
         element.mutable = true;
         assert.isTrue(button.hasAttribute('hidden'));
       });
 
-      test('_computeCanDeleteVote shows delete button', function() {
+      test('_computeCanDeleteVote shows delete button', () => {
         element.change.removable_reviewers = [
           {
             _account_id: 1,
             name: 'bojack',
-          }
+          },
         ];
         element.mutable = true;
         flushAsynchronousOperations();
-        var button = element.$$('gr-account-chip').$$('gr-button');
+        const button = element.$$('gr-account-chip').$$('gr-button');
         assert.isFalse(button.hasAttribute('hidden'));
       });
 
-      test('deletes votes', function(done) {
+      test('deletes votes', done => {
         sandbox.stub(element.$.restAPI, 'deleteVote')
-            .returns(Promise.resolve({'ok': true}));
+            .returns(Promise.resolve({ok: true}));
+        const spliceStub = sandbox.stub(element, 'splice', (path, index,
+            length) => {
+          assert.deepEqual(path, ['change.labels', 'test', 'all']);
+          assert.equal(index, 0);
+          assert.equal(length, 1);
+          assert.notOk(element.change.labels.test.recommended);
+          spliceStub.restore();
+          done();
+        });
         element.change.removable_reviewers = [
           {
             _account_id: 1,
@@ -273,70 +282,60 @@
         element.change.labels.test.recommended = {_account_id: 1};
         element.mutable = true;
         flushAsynchronousOperations();
-        var button = element.$$('gr-account-chip').$$('gr-button');
+        const button = element.$$('gr-account-chip').$$('gr-button');
         MockInteractions.tap(button);
-        flushAsynchronousOperations();
-        var spliceStub = sinon.stub(element, 'splice',
-            function(path, index, length) {
-          assert.deepEqual(path, ['change.labels', 'test', 'all']);
-          assert.equal(index, 0);
-          assert.equal(length, 1);
-          assert.notOk(element.change.labels.test.recommended);
-          spliceStub.restore();
-          done();
-        });
       });
 
-      test('changing topic calls setChangeTopic', function() {
-        var topicStub = sandbox.stub(element.$.restAPI, 'setChangeTopic',
-            function() {});
+      test('changing topic calls setChangeTopic', () => {
+        const topicStub = sandbox.stub(element.$.restAPI, 'setChangeTopic',
+            () => {});
         element._handleTopicChanged({}, 'the new topic');
         assert.isTrue(topicStub.calledWith('the number', 'the new topic'));
       });
 
-      test('topic href has quotes', function() {
-        var hrefArr = element._computeTopicURL('test')
+      test('topic href has quotes', () => {
+        const hrefArr = element._computeTopicURL('test')
             .split('%2522'); // Double-escaped quote.
         assert.equal(hrefArr[1], 'test');
       });
 
-      test('clicking x on topic chip removes topic', function() {
-        var topicStub = sandbox.stub(element.$.restAPI, 'setChangeTopic');
+      test('clicking x on topic chip removes topic', () => {
+        const topicStub = sandbox.stub(element.$.restAPI, 'setChangeTopic');
         flushAsynchronousOperations();
-        var remove = element.$$('gr-linked-chip').$.remove;
+        const remove = element.$$('gr-linked-chip').$.remove;
         MockInteractions.tap(remove);
         assert.equal(element.change.topic, '');
         assert.isTrue(topicStub.called);
       });
 
-      suite('assignee field', function() {
-        var dummyAccount = {
+      suite('assignee field', () => {
+        const dummyAccount = {
           _account_id: 1,
           name: 'bojack',
         };
-        var change = {
+        const change = {
           actions: {
             assignee: {enabled: false},
           },
           assignee: dummyAccount,
         };
-        var deleteStub;
-        var setStub;
+        let deleteStub;
+        let setStub;
 
-        setup(function() {
+        setup(() => {
           deleteStub = sandbox.stub(element.$.restAPI, 'deleteAssignee');
           setStub = sandbox.stub(element.$.restAPI, 'setAssignee');
         });
 
-        test('changing change recomputes _assignee', function() {
+        test('changing change recomputes _assignee', () => {
           assert.isFalse(!!element._assignee.length);
-          var change = element.change;
+          const change = element.change;
           change.assignee = dummyAccount;
           element._changeChanged(change);
           assert.deepEqual(element._assignee[0], dummyAccount);
         });
 
-        test('modifying _assignee calls API', function() {
+        test('modifying _assignee calls API', () => {
           assert.isFalse(!!element._assignee.length);
           element.set('_assignee', [dummyAccount]);
           assert.isTrue(setStub.calledOnce);
@@ -350,8 +349,8 @@
           assert.isTrue(deleteStub.calledOnce);
         });
 
-        test('_computeAssigneeReadOnly', function() {
-          var mutable = false;
+        test('_computeAssigneeReadOnly', () => {
+          let mutable = false;
           assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
           mutable = true;
           assert.isTrue(element._computeAssigneeReadOnly(mutable, change));
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/test/plugin.html b/polygerrit-ui/app/elements/change/gr-change-metadata/test/plugin.html
index 1cd3138..d0ed4a1 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/test/plugin.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/test/plugin.html
@@ -1,6 +1,6 @@
 <dom-module id="my-plugin">
   <script>
-    Gerrit.install(function(plugin) {
+    Gerrit.install(plugin => {
       plugin.registerStyleModule('change-metadata', 'my-plugin-style');
     });
   </script>
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
index 98a2508..ab2ad11 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.js
@@ -14,8 +14,8 @@
 (function() {
   'use strict';
 
-  var COMMIT_MESSAGE_PATH = '/COMMIT_MSG';
-  var MERGE_LIST_PATH = '/MERGE_LIST';
+  const COMMIT_MESSAGE_PATH = '/COMMIT_MSG';
+  const MERGE_LIST_PATH = '/MERGE_LIST';
 
   Polymer({
     is: 'gr-comment-list',
@@ -32,17 +32,16 @@
       projectConfig: Object,
     },
 
-    _computeFilesFromComments: function(comments) {
-      var arr = Object.keys(comments || {});
+    _computeFilesFromComments(comments) {
+      const arr = Object.keys(comments || {});
       return arr.sort(this.specialFilePathCompare);
     },
 
-    _computeFileDiffURL: function(file, changeNum, patchNum) {
-      return this.getBaseUrl() + '/c/' + changeNum +
-        '/' + patchNum + '/' + file;
+    _computeFileDiffURL(file, changeNum, patchNum) {
+      return `${this.getBaseUrl()}/c/${changeNum}/${patchNum}/${file}`;
     },
 
-    _computeFileDisplayName: function(path) {
+    _computeFileDisplayName(path) {
       if (path === COMMIT_MESSAGE_PATH) {
         return 'Commit message';
       } else if (path === MERGE_LIST_PATH) {
@@ -51,12 +50,12 @@
       return path;
     },
 
-    _isOnParent: function(comment) {
+    _isOnParent(comment) {
       return comment.side === 'PARENT';
     },
 
-    _computeDiffLineURL: function(file, changeNum, patchNum, comment) {
-      var diffURL = this._computeFileDiffURL(file, changeNum, patchNum);
+    _computeDiffLineURL(file, changeNum, patchNum, comment) {
+      let diffURL = this._computeFileDiffURL(file, changeNum, patchNum);
       if (comment.line) {
         diffURL += '#';
         if (this._isOnParent(comment)) { diffURL += 'b'; }
@@ -65,18 +64,18 @@
       return diffURL;
     },
 
-    _computeCommentsForFile: function(comments, file) {
+    _computeCommentsForFile(comments, file) {
       // Changes are not picked up by the dom-repeat due to the array instance
       // identity not changing even when it has elements added/removed from it.
       return (comments[file] || []).slice();
     },
 
-    _computePatchDisplayName: function(comment) {
+    _computePatchDisplayName(comment) {
       if (this._isOnParent(comment)) {
         return 'Base, ';
       }
       if (comment.patch_set != this.patchNum) {
-        return 'PS' + comment.patch_set + ', ';
+        return `PS${comment.patch_set}, `;
       }
       return '';
     },
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
index e27bad0..5275f48 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
@@ -31,41 +31,42 @@
 </test-fixture>
 
 <script>
-  suite('gr-comment-list tests', function() {
-    var element;
+  suite('gr-comment-list tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
     });
 
-    test('_computeFilesFromComments w/ special file path sorting', function() {
-      var comments = {
+    test('_computeFilesFromComments w/ special file path sorting', () => {
+      const comments = {
         'file_b.html': [],
         'file_c.css': [],
         'file_a.js': [],
         'test.cc': [],
         'test.h': [],
       };
-      var expected = [
+      const expected = [
         'file_a.js',
         'file_b.html',
         'file_c.css',
         'test.h',
-        'test.cc'
+        'test.cc',
       ];
-      var actual = element._computeFilesFromComments(comments);
+      const actual = element._computeFilesFromComments(comments);
       assert.deepEqual(actual, expected);
 
       assert.deepEqual(element._computeFilesFromComments(null), []);
     });
 
-    test('_computeFileDiffURL', function() {
-      var expected = '/c/<change>/<patch>/<file>';
-      var actual = element._computeFileDiffURL('<file>', '<change>', '<patch>');
+    test('_computeFileDiffURL', () => {
+      const expected = '/c/<change>/<patch>/<file>';
+      const actual =
+          element._computeFileDiffURL('<file>', '<change>', '<patch>');
       assert.equal(actual, expected);
     });
 
-    test('_computeFileDisplayName', function() {
+    test('_computeFileDisplayName', () => {
       assert.equal(element._computeFileDisplayName('/COMMIT_MSG'),
           'Commit message');
       assert.equal(element._computeFileDisplayName('/MERGE_LIST'),
@@ -74,10 +75,10 @@
           '/foo/bar/baz');
     });
 
-    test('_computeDiffLineURL', function() {
-      var comment = {line: 123, side: 'REVISION', patch_set: 10};
-      var expected = '/c/<change>/<patch>/<file>#123';
-      var actual = element._computeDiffLineURL('<file>', '<change>', '<patch>',
+    test('_computeDiffLineURL', () => {
+      const comment = {line: 123, side: 'REVISION', patch_set: 10};
+      let expected = '/c/<change>/<patch>/<file>#123';
+      let actual = element._computeDiffLineURL('<file>', '<change>', '<patch>',
           comment);
       assert.equal(actual, expected);
 
@@ -89,8 +90,8 @@
           comment);
     });
 
-    test('_computePatchDisplayName', function() {
-      var comment = {line: 123, side: 'REVISION', patch_set: 10};
+    test('_computePatchDisplayName', () => {
+      const comment = {line: 123, side: 'REVISION', patch_set: 10};
 
       element.patchNum = 10;
       assert.equal(element._computePatchDisplayName(comment), '');
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
index 5aa8601..c55e8c7 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.js
@@ -31,13 +31,13 @@
       },
     },
 
-    _isWebLink: function(link) {
+    _isWebLink(link) {
       // This is a whitelist of web link types that provide direct links to
       // the commit in the url property.
       return link.name === 'gitiles' || link.name === 'gitweb';
     },
 
-    _computeShowWebLink: function(change, commitInfo, serverConfig) {
+    _computeShowWebLink(change, commitInfo, serverConfig) {
       if (serverConfig.gitweb && serverConfig.gitweb.url &&
           serverConfig.gitweb.type && serverConfig.gitweb.type.revision) {
         return true;
@@ -47,8 +47,8 @@
         return false;
       }
 
-      for (var i = 0; i < commitInfo.web_links.length; i++) {
-        if (this._isWebLink(commitInfo.web_links[i])) {
+      for (const link of commitInfo.web_links) {
+        if (this._isWebLink(link)) {
           return true;
         }
       }
@@ -56,7 +56,7 @@
       return false;
     },
 
-    _computeWebLink: function(change, commitInfo, serverConfig) {
+    _computeWebLink(change, commitInfo, serverConfig) {
       if (!this._computeShowWebLink(change, commitInfo, serverConfig)) {
         return;
       }
@@ -69,10 +69,10 @@
                 .replace('${commit}', commitInfo.commit);
       }
 
-      var webLink = null;
-      for (var i = 0; i < commitInfo.web_links.length; i++) {
-        if (this._isWebLink(commitInfo.web_links[i])) {
-          webLink = commitInfo.web_links[i].url;
+      let webLink = null;
+      for (const link of commitInfo.web_links) {
+        if (this._isWebLink(link)) {
+          webLink = link.url;
           break;
         }
       }
@@ -88,7 +88,7 @@
       return webLink;
     },
 
-    _computeShortHash: function(commitInfo) {
+    _computeShortHash(commitInfo) {
       if (!commitInfo || !commitInfo.commit) {
         return;
       }
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
index c8faff5..fc45f2a 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
@@ -33,14 +33,14 @@
 </test-fixture>
 
 <script>
-  suite('gr-commit-info tests', function() {
-    var element;
+  suite('gr-commit-info tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
     });
 
-    test('no web link when unavailable', function() {
+    test('no web link when unavailable', () => {
       element.commitInfo = {};
       element.serverConfig = {};
       element.change = {labels: []};
@@ -49,7 +49,7 @@
           element.commitInfo, element.serverConfig));
     });
 
-    test('use web link when available', function() {
+    test('use web link when available', () => {
       element.commitInfo = {web_links: [{name: 'gitweb', url: 'link-url'}]};
       element.serverConfig = {};
 
@@ -59,9 +59,9 @@
           element.serverConfig), '../../link-url');
     });
 
-    test('does not relativize web links that begin with scheme', function() {
+    test('does not relativize web links that begin with scheme', () => {
       element.commitInfo = {
-        web_links: [{name: 'gitweb', url: 'https://link-url'}]
+        web_links: [{name: 'gitweb', url: 'https://link-url'}],
       };
       element.serverConfig = {};
 
@@ -71,7 +71,7 @@
           element.serverConfig), 'https://link-url');
     });
 
-    test('use gitweb when available', function() {
+    test('use gitweb when available', () => {
       element.commitInfo = {commit: 'commit-sha'};
       element.serverConfig = {gitweb: {
         url: 'url-base/',
@@ -80,7 +80,7 @@
       element.change = {
         project: 'project-name',
         labels: [],
-        current_revision: element.commitInfo.commit
+        current_revision: element.commitInfo.commit,
       };
 
       assert.isOk(element._computeShowWebLink(element.change,
@@ -90,10 +90,10 @@
           element.serverConfig), 'url-base/xx project-name xx commit-sha xx');
     });
 
-    test('prefer gitweb when both are available', function() {
+    test('prefer gitweb when both are available', () => {
       element.commitInfo = {
         commit: 'commit-sha',
-        web_links: [{url: 'link-url'}]
+        web_links: [{url: 'link-url'}],
       };
       element.serverConfig = {gitweb: {
         url: 'url-base/',
@@ -102,20 +102,20 @@
       element.change = {
         project: 'project-name',
         labels: [],
-        current_revision: element.commitInfo.commit
+        current_revision: element.commitInfo.commit,
       };
 
       assert.isOk(element._computeShowWebLink(element.change,
           element.commitInfo, element.serverConfig));
 
-      var link = element._computeWebLink(element.change, element.commitInfo,
+      const link = element._computeWebLink(element.change, element.commitInfo,
           element.serverConfig);
 
       assert.equal(link, 'url-base/xx project-name xx commit-sha xx');
       assert.notEqual(link, '../../link-url');
     });
 
-    test('ignore web links that are neither gitweb nor gitiles', function() {
+    test('ignore web links that are neither gitweb nor gitiles', () => {
       element.commitInfo = {
         commit: 'commit-sha',
         web_links: [
@@ -126,7 +126,7 @@
           {
             name: 'gitiles',
             url: 'https://link-url',
-          }
+          },
         ],
       };
       element.serverConfig = {};
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
index 716e29c..48a3f76 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.js
@@ -41,8 +41,8 @@
       '_computeMessage(changeStatus, commitNum, commitMessage)',
     ],
 
-    _computeMessage: function(changeStatus, commitNum, commitMessage) {
-      var newMessage = commitMessage;
+    _computeMessage(changeStatus, commitNum, commitMessage) {
+      let newMessage = commitMessage;
 
       if (changeStatus === 'MERGED') {
         newMessage += '(cherry picked from commit ' + commitNum + ')';
@@ -50,12 +50,12 @@
       this.message = newMessage;
     },
 
-    _handleConfirmTap: function(e) {
+    _handleConfirmTap(e) {
       e.preventDefault();
       this.fire('confirm', null, {bubbles: false});
     },
 
-    _handleCancelTap: function(e) {
+    _handleCancelTap(e) {
       e.preventDefault();
       this.fire('cancel', null, {bubbles: false});
     },
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
index 3c1cf2b..2d6defd 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
@@ -33,42 +33,41 @@
 </test-fixture>
 
 <script>
-  suite('gr-confirm-cherrypick-dialog tests', function() {
-    var element;
+  suite('gr-confirm-cherrypick-dialog tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
     });
 
-    test('with merged change', function() {
+    test('with merged change', () => {
       element.changeStatus = 'MERGED';
       element.commitMessage = 'message\n';
       element.commitNum = '123';
       element.branch = 'master';
       flushAsynchronousOperations();
-      var expectedMessage = 'message\n(cherry picked from commit 123)';
+      const expectedMessage = 'message\n(cherry picked from commit 123)';
       assert.equal(element.message, expectedMessage);
     });
 
-    test('with unmerged change', function() {
+    test('with unmerged change', () => {
       element.changeStatus = 'OPEN';
       element.commitMessage = 'message\n';
       element.commitNum = '123';
       element.branch = 'master';
       flushAsynchronousOperations();
-      var expectedMessage = 'message\n';
+      const expectedMessage = 'message\n';
       assert.equal(element.message, expectedMessage);
     });
 
-    test('with updated commit message', function() {
+    test('with updated commit message', () => {
       element.changeStatus = 'OPEN';
       element.commitMessage = 'message\n';
       element.commitNum = '123';
       element.branch = 'master';
-      var myNewMessage = 'updated commit message';
+      const myNewMessage = 'updated commit message';
       element.message = myNewMessage;
       flushAsynchronousOperations();
-      var expectedMessage = 'message\n';
       assert.equal(element.message, myNewMessage);
     });
   });
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
index 8f621f0..4a1bbb8 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.js
@@ -33,27 +33,26 @@
       message: String,
     },
 
-    populateRevertMessage: function(message, commitHash) {
+    populateRevertMessage(message, commitHash) {
       // Figure out what the revert title should be.
-      var originalTitle = message.split('\n')[0];
-      var revertTitle = 'Revert "' + originalTitle + '"';
+      const originalTitle = message.split('\n')[0];
+      const revertTitle = `Revert "${originalTitle}"`;
       if (!commitHash) {
         alert('Unable to find the commit hash of this change.');
         return;
       }
-      var revertCommitText = 'This reverts commit ' + commitHash + '.';
+      const revertCommitText = `This reverts commit ${commitHash}.`;
 
-      this.message = revertTitle + '\n\n' +
-                     revertCommitText + '\n\n' +
-                     'Reason for revert: <INSERT REASONING HERE>\n';
+      this.message = `${revertTitle}\n\n${revertCommitText}\n\n` +
+          `Reason for revert: <INSERT REASONING HERE>\n`;
     },
 
-    _handleConfirmTap: function(e) {
+    _handleConfirmTap(e) {
       e.preventDefault();
       this.fire('confirm', null, {bubbles: false});
     },
 
-    _handleCancelTap: function(e) {
+    _handleCancelTap(e) {
       e.preventDefault();
       this.fire('cancel', null, {bubbles: false});
     },
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
index d5c459b..78b0dfc 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
@@ -33,62 +33,62 @@
 </test-fixture>
 
 <script>
-  suite('gr-confirm-revert-dialog tests', function() {
-    var element;
+  suite('gr-confirm-revert-dialog tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
     });
 
-    test('no match', function() {
+    test('no match', () => {
       assert.isNotOk(element.message);
-      var alertStub = sinon.stub(window, 'alert');
+      const alertStub = sinon.stub(window, 'alert');
       element.populateRevertMessage('not a commitHash in sight', undefined);
       assert.isTrue(alertStub.calledOnce);
       alertStub.restore();
     });
 
-    test('single line', function() {
+    test('single line', () => {
       assert.isNotOk(element.message);
       element.populateRevertMessage(
           'one line commit\n\nChange-Id: abcdefg\n',
           'abcd123');
-      var expected = 'Revert "one line commit"\n\n' +
-                     'This reverts commit abcd123.\n\n' +
-                     'Reason for revert: <INSERT REASONING HERE>\n';
+      const expected = 'Revert "one line commit"\n\n' +
+          'This reverts commit abcd123.\n\n' +
+          'Reason for revert: <INSERT REASONING HERE>\n';
       assert.equal(element.message, expected);
     });
 
-    test('multi line', function() {
+    test('multi line', () => {
       assert.isNotOk(element.message);
       element.populateRevertMessage(
           'many lines\ncommit\n\nmessage\n\nChange-Id: abcdefg\n',
           'abcd123');
-      var expected = 'Revert "many lines"\n\n' +
-                     'This reverts commit abcd123.\n\n' +
-                     'Reason for revert: <INSERT REASONING HERE>\n';
+      const expected = 'Revert "many lines"\n\n' +
+          'This reverts commit abcd123.\n\n' +
+          'Reason for revert: <INSERT REASONING HERE>\n';
       assert.equal(element.message, expected);
     });
 
-    test('issue above change id', function() {
+    test('issue above change id', () => {
       assert.isNotOk(element.message);
       element.populateRevertMessage(
           'much lines\nvery\n\ncommit\n\nBug: Issue 42\nChange-Id: abcdefg\n',
           'abcd123');
-      var expected = 'Revert "much lines"\n\n' +
-                     'This reverts commit abcd123.\n\n' +
-                     'Reason for revert: <INSERT REASONING HERE>\n';
+      const expected = 'Revert "much lines"\n\n' +
+          'This reverts commit abcd123.\n\n' +
+          'Reason for revert: <INSERT REASONING HERE>\n';
       assert.equal(element.message, expected);
     });
 
-    test('revert a revert', function() {
+    test('revert a revert', () => {
       assert.isNotOk(element.message);
       element.populateRevertMessage(
           'Revert "one line commit"\n\nChange-Id: abcdefg\n',
           'abcd123');
-      var expected = 'Revert "Revert "one line commit""\n\n' +
-                     'This reverts commit abcd123.\n\n' +
-                     'Reason for revert: <INSERT REASONING HERE>\n';
+      const expected = 'Revert "Revert "one line commit""\n\n' +
+          'This reverts commit abcd123.\n\n' +
+          'Reason for revert: <INSERT REASONING HERE>\n';
       assert.equal(element.message, expected);
     });
   });
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
index f843ee8..b26802d 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
@@ -35,7 +35,7 @@
 
       _schemes: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
         computed: '_computeSchemes(change, patchNum)',
         observer: '_schemesChanged',
       },
@@ -50,7 +50,7 @@
       Gerrit.RESTClientBehavior,
     ],
 
-    focus: function() {
+    focus() {
       if (this._schemes.length) {
         this.$$('.copyToClipboard').focus();
       } else {
@@ -58,59 +58,60 @@
       }
     },
 
-    getFocusStops: function() {
-      var links = this.$$('#archives').querySelectorAll('a');
+    getFocusStops() {
+      const links = this.$$('#archives').querySelectorAll('a');
       return {
         start: this.$.closeButton,
         end: links[links.length - 1],
       };
     },
 
-    _loggedInChanged: function(loggedIn) {
+    _loggedInChanged(loggedIn) {
       if (!loggedIn) { return; }
-      this.$.restAPI.getPreferences().then(function(prefs) {
+      this.$.restAPI.getPreferences().then(prefs => {
         if (prefs.download_scheme) {
           // Note (issue 5180): normalize the download scheme with lower-case.
           this._selectedScheme = prefs.download_scheme.toLowerCase();
         }
-      }.bind(this));
+      });
     },
 
-    _computeDownloadCommands: function(change, patchNum, _selectedScheme) {
-      var commandObj;
-      for (var rev in change.revisions) {
+    _computeDownloadCommands(change, patchNum, _selectedScheme) {
+      let commandObj;
+      for (const rev in change.revisions) {
         if (change.revisions[rev]._number === patchNum &&
             change.revisions[rev].fetch.hasOwnProperty(_selectedScheme)) {
           commandObj = change.revisions[rev].fetch[_selectedScheme].commands;
           break;
         }
       }
-      var commands = [];
-      for (var title in commandObj) {
+      const commands = [];
+      for (const title in commandObj) {
+        if (!commandObj.hasOwnProperty(title)) { continue; }
         commands.push({
-          title: title,
+          title,
           command: commandObj[title],
         });
       }
       return commands;
     },
 
-    _computeZipDownloadLink: function(change, patchNum) {
+    _computeZipDownloadLink(change, patchNum) {
       return this._computeDownloadLink(change, patchNum, true);
     },
 
-    _computeZipDownloadFilename: function(change, patchNum) {
+    _computeZipDownloadFilename(change, patchNum) {
       return this._computeDownloadFilename(change, patchNum, true);
     },
 
-    _computeDownloadLink: function(change, patchNum, zip) {
+    _computeDownloadLink(change, patchNum, zip) {
       return this.changeBaseURL(change._number, patchNum) + '/patch?' +
           (zip ? 'zip' : 'download');
     },
 
-    _computeDownloadFilename: function(change, patchNum, zip) {
-      var shortRev;
-      for (var rev in change.revisions) {
+    _computeDownloadFilename(change, patchNum, zip) {
+      let shortRev;
+      for (const rev in change.revisions) {
         if (change.revisions[rev]._number === patchNum) {
           shortRev = rev.substr(0, 7);
           break;
@@ -119,15 +120,15 @@
       return shortRev + '.diff.' + (zip ? 'zip' : 'base64');
     },
 
-    _computeArchiveDownloadLink: function(change, patchNum, format) {
+    _computeArchiveDownloadLink(change, patchNum, format) {
       return this.changeBaseURL(change._number, patchNum) +
           '/archive?format=' + format;
     },
 
-    _computeSchemes: function(change, patchNum) {
-      for (var rev in change.revisions) {
+    _computeSchemes(change, patchNum) {
+      for (const rev in change.revisions) {
         if (change.revisions[rev]._number === patchNum) {
-          var fetch = change.revisions[rev].fetch;
+          const fetch = change.revisions[rev].fetch;
           if (fetch) {
             return Object.keys(fetch).sort();
           }
@@ -137,47 +138,47 @@
       return [];
     },
 
-    _computePatchSetQuantity: function(revisions) {
+    _computePatchSetQuantity(revisions) {
       if (!revisions) { return 0; }
       return Object.keys(revisions).length;
     },
 
-    _computeSchemeSelected: function(scheme, selectedScheme) {
+    _computeSchemeSelected(scheme, selectedScheme) {
       return scheme === selectedScheme;
     },
 
-    _handleSchemeTap: function(e) {
+    _handleSchemeTap(e) {
       e.preventDefault();
-      var el = Polymer.dom(e).rootTarget;
+      const el = Polymer.dom(e).rootTarget;
       this._selectedScheme = el.getAttribute('data-scheme');
       if (this.loggedIn) {
         this.$.restAPI.savePreferences({download_scheme: this._selectedScheme});
       }
     },
 
-    _handleInputTap: function(e) {
+    _handleInputTap(e) {
       e.preventDefault();
       Polymer.dom(e).rootTarget.select();
     },
 
-    _handleCloseTap: function(e) {
+    _handleCloseTap(e) {
       e.preventDefault();
       this.fire('close', null, {bubbles: false});
     },
 
-    _schemesChanged: function(schemes) {
+    _schemesChanged(schemes) {
       if (schemes.length === 0) { return; }
-      if (schemes.indexOf(this._selectedScheme) === -1) {
+      if (!schemes.includes(this._selectedScheme)) {
         this._selectedScheme = schemes.sort()[0];
       }
     },
 
-    _copyToClipboard: function(e) {
+    _copyToClipboard(e) {
       e.target.parentElement.querySelector('.copyCommand').select();
       document.execCommand('copy');
       getSelection().removeAllRanges();
       e.target.textContent = 'done';
-      setTimeout(function() { e.target.textContent = 'copy'; }, 1000);
+      setTimeout(() => { e.target.textContent = 'copy'; }, 1000);
     },
   });
 })();
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
index 0635d6d..4a8d2d9 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
@@ -48,8 +48,8 @@
           fetch: {
             repo: {
               commands: {
-                repo: 'repo download test-project 5/1'
-              }
+                repo: 'repo download test-project 5/1',
+              },
             },
             ssh: {
               commands: {
@@ -69,8 +69,8 @@
                 'Pull':
                   'git pull ' +
                   'ssh://andybons@localhost:29418/test-project ' +
-                  'refs/changes/05/5/1'
-              }
+                  'refs/changes/05/5/1',
+              },
             },
             http: {
               commands: {
@@ -90,12 +90,12 @@
                 'Pull':
                   'git pull ' +
                   'http://andybons@localhost:8080/a/test-project ' +
-                  'refs/changes/05/5/1'
-              }
-            }
-          }
-        }
-      }
+                  'refs/changes/05/5/1',
+              },
+            },
+          },
+        },
+      },
     };
   }
 
@@ -106,74 +106,74 @@
         '34685798fe548b6d17d1e8e5edc43a26d055cc72': {
           _number: 1,
           fetch: {},
-        }
-      }
+        },
+      },
     };
   }
 
-  suite('gr-download-dialog tests with no fetch options', function() {
-    var element;
+  suite('gr-download-dialog tests with no fetch options', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
       element.change = getChangeObjectNoFetch();
       element.patchNum = 1;
       element.config = {
         schemes: {
           'anonymous http': {},
-          http: {},
-          repo: {},
-          ssh: {},
+          'http': {},
+          'repo': {},
+          'ssh': {},
         },
         archives: ['tgz', 'tar', 'tbz2', 'txz'],
       };
     });
 
-    test('focuses on first download link if no copy links', function() {
+    test('focuses on first download link if no copy links', () => {
       flushAsynchronousOperations();
-      var focusStub = sinon.stub(element.$.download, 'focus');
+      const focusStub = sinon.stub(element.$.download, 'focus');
       element.focus();
       assert.isTrue(focusStub.called);
       focusStub.restore();
     });
   });
 
-  suite('gr-download-dialog tests', function() {
-    var element;
+  suite('gr-download-dialog tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
       element.change = getChangeObject();
       element.patchNum = 1;
       element.config = {
         schemes: {
           'anonymous http': {},
-          http: {},
-          repo: {},
-          ssh: {},
+          'http': {},
+          'repo': {},
+          'ssh': {},
         },
         archives: ['tgz', 'tar', 'tbz2', 'txz'],
       };
     });
 
-    test('focuses on first copy link', function() {
+    test('focuses on first copy link', () => {
       flushAsynchronousOperations();
-      var focusStub = sinon.stub(element.$$('.copyToClipboard'), 'focus');
+      const focusStub = sinon.stub(element.$$('.copyToClipboard'), 'focus');
       element.focus();
       flushAsynchronousOperations();
       assert.isTrue(focusStub.called);
       focusStub.restore();
     });
 
-    test('copy to clipboard', function() {
+    test('copy to clipboard', () => {
       flushAsynchronousOperations();
-      var clipboardSpy = sinon.spy(element, '_copyToClipboard');
-      var copyBtn = element.$$('.copyToClipboard');
+      const clipboardSpy = sinon.spy(element, '_copyToClipboard');
+      const copyBtn = element.$$('.copyToClipboard');
       MockInteractions.tap(copyBtn);
       assert.isTrue(clipboardSpy.called);
     });
 
-    test('element visibility', function() {
+    test('element visibility', () => {
       assert.isFalse(element.$$('ul').hasAttribute('hidden'));
       assert.isFalse(element.$$('main').hasAttribute('hidden'));
       assert.isFalse(element.$$('.archivesContainer').hasAttribute('hidden'));
@@ -182,40 +182,40 @@
       assert.isTrue(element.$$('.archivesContainer').hasAttribute('hidden'));
     });
 
-    test('computed fields', function() {
+    test('computed fields', () => {
       assert.equal(element._computeArchiveDownloadLink(
           {_number: 123}, 2, 'tgz'),
           '/changes/123/revisions/2/archive?format=tgz');
     });
 
-    test('close event', function(done) {
-      element.addEventListener('close', function() {
+    test('close event', done => {
+      element.addEventListener('close', () => {
         done();
       });
       MockInteractions.tap(element.$$('.closeButtonContainer gr-button'));
     });
 
-    test('tab selection', function() {
+    test('tab selection', () => {
       flushAsynchronousOperations();
-      var el = element.$$('[data-scheme="http"]').parentElement;
+      let el = element.$$('[data-scheme="http"]').parentElement;
       assert.isTrue(el.hasAttribute('selected'));
-      ['repo', 'ssh'].forEach(function(scheme) {
-        var el = element.$$('[data-scheme="' + scheme + '"]').parentElement;
+      for (const scheme of ['repo', 'ssh']) {
+        const el = element.$$('[data-scheme="' + scheme + '"]').parentElement;
         assert.isFalse(el.hasAttribute('selected'));
-      });
+      }
 
       MockInteractions.tap(element.$$('[data-scheme="ssh"]'));
       el = element.$$('[data-scheme="ssh"]').parentElement;
       assert.isTrue(el.hasAttribute('selected'));
-      ['http', 'repo'].forEach(function(scheme) {
-        var el = element.$$('[data-scheme="' + scheme + '"]').parentElement;
+      for (const scheme of ['http', 'repo']) {
+        const el = element.$$('[data-scheme="' + scheme + '"]').parentElement;
         assert.isFalse(el.hasAttribute('selected'));
-      });
+      }
     });
 
-    test('loads scheme from preferences w/o initial login', function(done) {
+    test('loads scheme from preferences w/o initial login', done => {
       stub('gr-rest-api-interface', {
-        getPreferences: function() {
+        getPreferences() {
           return Promise.resolve({download_scheme: 'repo'});
         },
       });
@@ -223,19 +223,19 @@
       element.loggedIn = true;
 
       assert.isTrue(element.$.restAPI.getPreferences.called);
-      element.$.restAPI.getPreferences.lastCall.returnValue.then(function() {
+      element.$.restAPI.getPreferences.lastCall.returnValue.then(() => {
         assert.equal(element._selectedScheme, 'repo');
         done();
       });
     });
   });
 
-  suite('gr-download-dialog tests', function() {
-    var element;
+  suite('gr-download-dialog tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       stub('gr-rest-api-interface', {
-        getPreferences: function() {
+        getPreferences() {
           return Promise.resolve({download_scheme: 'repo'});
         },
       });
@@ -246,28 +246,28 @@
       element.config = {
         schemes: {
           'anonymous http': {},
-          http: {},
-          repo: {},
-          ssh: {},
+          'http': {},
+          'repo': {},
+          'ssh': {},
         },
         archives: ['tgz', 'tar', 'tbz2', 'txz'],
       };
     });
 
-    test('loads scheme from preferences', function(done) {
-      element.$.restAPI.getPreferences.lastCall.returnValue.then(function() {
+    test('loads scheme from preferences', done => {
+      element.$.restAPI.getPreferences.lastCall.returnValue.then(() => {
         assert.equal(element._selectedScheme, 'repo');
         done();
       });
     });
 
-    test('saves scheme to preferences', function() {
-      var savePrefsStub = sinon.stub(element.$.restAPI, 'savePreferences',
-          function() { return Promise.resolve(); });
+    test('saves scheme to preferences', () => {
+      const savePrefsStub = sinon.stub(element.$.restAPI, 'savePreferences',
+          () => { return Promise.resolve(); });
 
       Polymer.dom.flush();
 
-      var firstSchemeButton = element.$$('li gr-button[data-scheme]');
+      const firstSchemeButton = element.$$('li gr-button[data-scheme]');
 
       MockInteractions.tap(firstSchemeButton);
 
@@ -277,9 +277,9 @@
     });
   });
 
-  test('normalize scheme from preferences', function(done) {
+  test('normalize scheme from preferences', done => {
     stub('gr-rest-api-interface', {
-      getPreferences: function() {
+      getPreferences() {
         return Promise.resolve({download_scheme: 'REPO'});
       },
     });
@@ -287,10 +287,10 @@
     element.change = getChangeObject();
     element.patchNum = 1;
     element.config = {
-      schemes: {'anonymous http': {}, http: {}, repo: {}, ssh: {}},
+      schemes: {'anonymous http': {}, 'http': {}, 'repo': {}, 'ssh': {}},
       archives: ['tgz', 'tar', 'tbz2', 'txz'],
     };
-    element.$.restAPI.getPreferences.lastCall.returnValue.then(function() {
+    element.$.restAPI.getPreferences.lastCall.returnValue.then(() => {
       assert.equal(element._selectedScheme, 'repo');
       done();
     });
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.js b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
index 5467af9..919ef6b 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
@@ -30,7 +30,7 @@
      */
 
     listeners: {
-      'tap': '_handleTap',
+      tap: '_handleTap',
     },
 
     properties: {
@@ -86,16 +86,16 @@
       '_updateExpandedClass(message.expanded)',
     ],
 
-    ready: function() {
-      this.$.restAPI.getConfig().then(function(config) {
+    ready() {
+      this.$.restAPI.getConfig().then(config => {
         this.config = config;
-      }.bind(this));
-      this.$.restAPI.getLoggedIn().then(function(loggedIn) {
+      });
+      this.$.restAPI.getLoggedIn().then(loggedIn => {
         this._loggedIn = loggedIn;
-      }.bind(this));
+      });
     },
 
-    _updateExpandedClass: function(expanded) {
+    _updateExpandedClass(expanded) {
       if (expanded) {
         this.classList.add('expanded');
       } else {
@@ -103,25 +103,25 @@
       }
     },
 
-    _computeAuthor: function(message) {
+    _computeAuthor(message) {
       return message.author || message.updated_by;
     },
 
-    _computeShowAvatar: function(author, config) {
+    _computeShowAvatar(author, config) {
       return !!(author && config && config.plugin && config.plugin.has_avatars);
     },
 
-    _computeShowOnBehalfOf: function(message) {
-      var author = message.author || message.updated_by;
+    _computeShowOnBehalfOf(message) {
+      const author = message.author || message.updated_by;
       return !!(author && message.real_author &&
           author._account_id != message.real_author._account_id);
     },
 
-    _computeShowReplyButton: function(message, loggedIn) {
+    _computeShowReplyButton(message, loggedIn) {
       return !!message.message && loggedIn;
     },
 
-    _computeExpanded: function(expanded) {
+    _computeExpanded(expanded) {
       return expanded;
     },
 
@@ -130,54 +130,54 @@
      * should be true or not, then _expanded is set to true if there are
      * inline comments (otherwise false).
      */
-    _commentsChanged: function(value) {
+    _commentsChanged(value) {
       if (this.message && this.message.expanded === undefined) {
         this.set('message.expanded', Object.keys(value || {}).length > 0);
       }
     },
 
-    _handleTap: function(e) {
+    _handleTap(e) {
       if (this.message.expanded) { return; }
       e.stopPropagation();
       this.set('message.expanded', true);
     },
 
-    _handleAuthorTap: function(e) {
+    _handleAuthorTap(e) {
       if (!this.message.expanded) { return; }
       e.stopPropagation();
       this.set('message.expanded', false);
     },
 
-    _computeIsAutomated: function(message) {
+    _computeIsAutomated(message) {
       return !!(message.reviewer ||
-          (message.tag && message.tag.indexOf('autogenerated') === 0));
+          (message.tag && message.tag.startsWith('autogenerated')));
     },
 
-    _computeIsHidden: function(hideAutomated, isAutomated) {
+    _computeIsHidden(hideAutomated, isAutomated) {
       return hideAutomated && isAutomated;
     },
 
-    _computeIsReviewerUpdate: function(event) {
+    _computeIsReviewerUpdate(event) {
       return event.type === 'REVIEWER_UPDATE';
     },
 
-    _computeClass: function(expanded, showAvatar) {
-      var classes = [];
+    _computeClass(expanded, showAvatar) {
+      const classes = [];
       classes.push(expanded ? 'expanded' : 'collapsed');
       classes.push(showAvatar ? 'showAvatar' : 'hideAvatar');
       return classes.join(' ');
     },
 
-    _computeMessageHash: function(message) {
+    _computeMessageHash(message) {
       return '#message-' + message.id;
     },
 
-    _handleLinkTap: function(e) {
+    _handleLinkTap(e) {
       e.preventDefault();
 
       this.fire('scroll-to', {message: this.message}, {bubbles: false});
 
-      var hash = this._computeMessageHash(this.message);
+      const hash = this._computeMessageHash(this.message);
       // Don't add the hash to the window history if it's already there.
       // Otherwise you mess up expected back button behavior.
       if (window.location.hash == hash) { return; }
@@ -186,7 +186,7 @@
       page.show(window.location.pathname + hash, null, false);
     },
 
-    _handleReplyTap: function(e) {
+    _handleReplyTap(e) {
       e.preventDefault();
       this.fire('reply', {message: this.message});
     },
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
index 72c09d9..5f8b312 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
@@ -33,30 +33,30 @@
 </test-fixture>
 
 <script>
-  suite('gr-message tests', function() {
-    var element;
+  suite('gr-message tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       stub('gr-rest-api-interface', {
-        getLoggedIn: function() { return Promise.resolve(false); },
+        getLoggedIn() { return Promise.resolve(false); },
       });
       element = fixture('basic');
     });
 
-    test('reply event', function(done) {
+    test('reply event', done => {
       element.message = {
-        'id': '47c43261_55aa2c41',
-        'author': {
-          '_account_id': 1115495,
-          'name': 'Andrew Bonventre',
-          'email': 'andybons@chromium.org',
+        id: '47c43261_55aa2c41',
+        author: {
+          _account_id: 1115495,
+          name: 'Andrew Bonventre',
+          email: 'andybons@chromium.org',
         },
-        'date': '2016-01-12 20:24:49.448000000',
-        'message': 'Uploaded patch set 1.',
-        '_revision_number': 1
+        date: '2016-01-12 20:24:49.448000000',
+        message: 'Uploaded patch set 1.',
+        _revision_number: 1,
       };
 
-      element.addEventListener('reply', function(e) {
+      element.addEventListener('reply', e => {
         assert.deepEqual(e.detail.message, element.message);
         done();
       });
@@ -64,38 +64,38 @@
       MockInteractions.tap(element.$$('.replyContainer gr-button'));
     });
 
-    test('reviewer update', function() {
-      var author = {
+    test('reviewer update', () => {
+      const author = {
         _account_id: 1115495,
         name: 'Andrew Bonventre',
         email: 'andybons@chromium.org',
       };
-      var reviewer = {
+      const reviewer = {
         _account_id: 123456,
         name: 'Foo Bar',
         email: 'barbar@chromium.org',
       };
       element.message = {
         id: 0xDEADBEEF,
-        author: author,
-        reviewer: reviewer,
+        author,
+        reviewer,
         date: '2016-01-12 20:24:49.448000000',
         type: 'REVIEWER_UPDATE',
         updates: [
           {
             message: 'Added to CC:',
             reviewers: [reviewer],
-          }
+          },
         ],
       };
       flushAsynchronousOperations();
-      var content = element.$$('.contentContainer');
+      const content = element.$$('.contentContainer');
       assert.isOk(content);
       assert.strictEqual(element.$$('gr-account-chip').account, reviewer);
       assert.equal(author.name, element.$$('.author > .name').textContent);
     });
 
-    test('autogenerated prefix hiding', function() {
+    test('autogenerated prefix hiding', () => {
       element.message = {
         tag: 'autogenerated:gerrit:test',
         updated: '2016-01-12 20:24:49.448000000',
@@ -109,7 +109,7 @@
       assert.isTrue(element.hidden);
     });
 
-    test('reviewer message treated as autogenerated', function() {
+    test('reviewer message treated as autogenerated', () => {
       element.message = {
         tag: 'autogenerated:gerrit:test',
         updated: '2016-01-12 20:24:49.448000000',
@@ -124,7 +124,7 @@
       assert.isTrue(element.hidden);
     });
 
-    test('tag that is not autogenerated prefix does not hide', function() {
+    test('tag that is not autogenerated prefix does not hide', () => {
       element.message = {
         tag: 'something',
         updated: '2016-01-12 20:24:49.448000000',
@@ -138,16 +138,16 @@
       assert.isFalse(element.hidden);
     });
 
-    test('reply button hidden unless logged in', function() {
-      var message = {
-        'message': 'Uploaded patch set 1.',
+    test('reply button hidden unless logged in', () => {
+      const message = {
+        message: 'Uploaded patch set 1.',
       };
       assert.isFalse(element._computeShowReplyButton(message, false));
       assert.isTrue(element._computeShowReplyButton(message, true));
     });
 
-    test('_computeShowOnBehalfOf', function() {
-      var message = {
+    test('_computeShowOnBehalfOf', () => {
+      const message = {
         message: '...',
       };
       assert.isNotOk(element._computeShowOnBehalfOf(message));
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
index 8501b20..fe35c7f 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
@@ -41,23 +41,23 @@
       },
       _relatedResponse: {
         type: Object,
-        value: function() { return {changes: []}; },
+        value() { return {changes: []}; },
       },
       _submittedTogether: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
       },
       _conflicts: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
       },
       _cherryPicks: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
       },
       _sameTopic: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
       },
     },
 
@@ -71,53 +71,52 @@
           '_conflicts, _cherryPicks, _sameTopic)',
     ],
 
-    clear: function() {
+    clear() {
       this.loading = true;
       this.hidden = true;
     },
 
-    reload: function() {
+    reload() {
       if (!this.change || !this.patchNum) {
         return Promise.resolve();
       }
       this.loading = true;
-      var promises = [
-        this._getRelatedChanges().then(function(response) {
+      const promises = [
+        this._getRelatedChanges().then(response => {
           this._relatedResponse = response;
 
           this.hasParent = this._calculateHasParent(this.change.change_id,
               response.changes);
-
-        }.bind(this)),
-        this._getSubmittedTogether().then(function(response) {
+        }),
+        this._getSubmittedTogether().then(response => {
           this._submittedTogether = response;
-        }.bind(this)),
-        this._getCherryPicks().then(function(response) {
+        }),
+        this._getCherryPicks().then(response => {
           this._cherryPicks = response;
-        }.bind(this)),
+        }),
       ];
 
       // Get conflicts if change is open and is mergeable.
       if (this.changeIsOpen(this.change.status) && this.change.mergeable) {
-        promises.push(this._getConflicts().then(function(response) {
+        promises.push(this._getConflicts().then(response => {
           this._conflicts = response;
-        }.bind(this)));
+        }));
       }
 
-      promises.push(this._getServerConfig().then(function(config) {
+      promises.push(this._getServerConfig().then(config => {
         if (this.change.topic && !config.change.submit_whole_topic) {
-          return this._getChangesWithSameTopic().then(function(response) {
+          return this._getChangesWithSameTopic().then(response => {
             this._sameTopic = response;
-          }.bind(this));
+          });
         } else {
           this._sameTopic = [];
         }
         return this._sameTopic;
-      }.bind(this)));
+      }));
 
-      return Promise.all(promises).then(function() {
+      return Promise.all(promises).then(() => {
         this.loading = false;
-      }.bind(this));
+      });
     },
 
     /**
@@ -128,62 +127,62 @@
      * @param  {Array} relatedChanges
      * @return {Boolean}
      */
-    _calculateHasParent: function(currentChangeId, relatedChanges) {
+    _calculateHasParent(currentChangeId, relatedChanges) {
       return relatedChanges.length > 0 &&
           relatedChanges[relatedChanges.length - 1].change_id !==
           currentChangeId;
     },
 
-    _getRelatedChanges: function() {
+    _getRelatedChanges() {
       return this.$.restAPI.getRelatedChanges(this.change._number,
           this.patchNum);
     },
 
-    _getSubmittedTogether: function() {
+    _getSubmittedTogether() {
       return this.$.restAPI.getChangesSubmittedTogether(this.change._number);
     },
 
-    _getServerConfig: function() {
+    _getServerConfig() {
       return this.$.restAPI.getConfig();
     },
 
-    _getConflicts: function() {
+    _getConflicts() {
       return this.$.restAPI.getChangeConflicts(this.change._number);
     },
 
-    _getCherryPicks: function() {
+    _getCherryPicks() {
       return this.$.restAPI.getChangeCherryPicks(this.change.project,
           this.change.change_id, this.change._number);
     },
 
-    _getChangesWithSameTopic: function() {
+    _getChangesWithSameTopic() {
       return this.$.restAPI.getChangesWithSameTopic(this.change.topic);
     },
 
-    _computeChangeURL: function(changeNum, patchNum) {
-      var urlStr = this.getBaseUrl() + '/c/' + changeNum;
+    _computeChangeURL(changeNum, patchNum) {
+      let urlStr = this.getBaseUrl() + '/c/' + changeNum;
       if (patchNum != null) {
         urlStr += '/' + patchNum;
       }
       return urlStr;
     },
 
-    _computeChangeContainerClass: function(currentChange, relatedChange) {
-      var classes = ['changeContainer'];
+    _computeChangeContainerClass(currentChange, relatedChange) {
+      const classes = ['changeContainer'];
       if (relatedChange.change_id === currentChange.change_id) {
         classes.push('thisChange');
       }
       return classes.join(' ');
     },
 
-    _computeLinkClass: function(change) {
+    _computeLinkClass(change) {
       if (change.status == this.ChangeStatus.ABANDONED) {
         return 'strikethrough';
       }
     },
 
-    _computeChangeStatusClass: function(change) {
-      var classes = ['status'];
+    _computeChangeStatusClass(change) {
+      const classes = ['status'];
       if (change._revision_number != change._current_revision_number) {
         classes.push('notCurrent');
       } else if (this._isIndirectAncestor(change)) {
@@ -196,7 +195,7 @@
       return classes.join(' ');
     },
 
-    _computeChangeStatus: function(change) {
+    _computeChangeStatus(change) {
       switch (change.status) {
         case this.ChangeStatus.MERGED:
           return 'Merged';
@@ -215,16 +214,16 @@
       return '';
     },
 
-    _resultsChanged: function(related, submittedTogether, conflicts,
+    _resultsChanged(related, submittedTogether, conflicts,
         cherryPicks, sameTopic) {
-      var results = [
+      const results = [
         related,
         submittedTogether,
         conflicts,
         cherryPicks,
         sameTopic,
       ];
-      for (var i = 0; i < results.length; i++) {
+      for (let i = 0; i < results.length; i++) {
         if (results[i].length > 0) {
           this.hidden = false;
           this.fire('update', null, {bubbles: false});
@@ -234,23 +233,23 @@
       this.hidden = true;
     },
 
-    _isIndirectAncestor: function(change) {
-      return this._connectedRevisions.indexOf(change.commit.commit) == -1;
+    _isIndirectAncestor(change) {
+      return !this._connectedRevisions.includes(change.commit.commit);
     },
 
-    _computeConnectedRevisions: function(change, patchNum, relatedChanges) {
-      var connected = [];
-      var changeRevision;
-      for (var rev in change.revisions) {
+    _computeConnectedRevisions(change, patchNum, relatedChanges) {
+      const connected = [];
+      let changeRevision;
+      for (const rev in change.revisions) {
         if (change.revisions[rev]._number == patchNum) {
           changeRevision = rev;
         }
       }
-      var commits = relatedChanges.map(function(c) { return c.commit; });
-      var pos = commits.length - 1;
+      const commits = relatedChanges.map(c => { return c.commit; });
+      let pos = commits.length - 1;
 
       while (pos >= 0) {
-        var commit = commits[pos].commit;
+        const commit = commits[pos].commit;
         connected.push(commit);
         if (commit == changeRevision) {
           break;
@@ -258,8 +257,8 @@
         pos--;
       }
       while (pos >= 0) {
-        for (var i = 0; i < commits[pos].parents.length; i++) {
-          if (connected.indexOf(commits[pos].parents[i].commit) != -1) {
+        for (let i = 0; i < commits[pos].parents.length; i++) {
+          if (connected.includes(commits[pos].parents[i].commit)) {
             connected.push(commits[pos].commit);
             break;
           }
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
index 171f758..4a25405 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
@@ -33,21 +33,21 @@
 </test-fixture>
 
 <script>
-  suite('gr-related-changes-list tests', function() {
-    var element;
-    var sandbox;
+  suite('gr-related-changes-list tests', () => {
+    let element;
+    let sandbox;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
       sandbox = sinon.sandbox.create();
     });
 
-    teardown(function() {
+    teardown(() => {
       sandbox.restore();
     });
 
-    test('connected revisions', function() {
-      var change = {
+    test('connected revisions', () => {
+      const change = {
         revisions: {
           'e3c6d60783bfdec9ebae7dcfec4662360433449e': {
             _number: 1,
@@ -72,8 +72,8 @@
           },
         },
       };
-      var patchNum = 7;
-      var relatedChanges = [
+      let patchNum = 7;
+      let relatedChanges = [
         {
           commit: {
             commit: '2cebeedfb1e80f4b872d0a13ade529e70652c0c8',
@@ -136,7 +136,7 @@
         },
       ];
 
-      var connectedChanges =
+      let connectedChanges =
           element._computeConnectedRevisions(change, patchNum, relatedChanges);
       assert.deepEqual(connectedChanges, [
         '613bc4f81741a559c6667ac08d71dcc3348f73ce',
@@ -222,9 +222,9 @@
       ]);
     });
 
-    test('_computeChangeContainerClass', function() {
-      var change1 = {change_id: 123};
-      var change2 = {change_id: 456};
+    test('_computeChangeContainerClass', () => {
+      const change1 = {change_id: 123};
+      const change2 = {change_id: 456};
 
       assert.notEqual(element._computeChangeContainerClass(
           change1, change1).indexOf('thisChange'), -1);
@@ -232,26 +232,25 @@
           change1, change2).indexOf('thisChange'), -1);
     });
 
-    suite('get conflicts tests', function() {
-      var element;
-      var conflictsStub;
+    suite('get conflicts tests', () => {
+      let element;
+      let conflictsStub;
 
-      setup(function() {
+      setup(() => {
         element = fixture('basic');
 
-        sandbox.stub(element, '_getRelatedChanges',
-            function() {
-              return Promise.resolve({changes: []});
-            });
+        sandbox.stub(element, '_getRelatedChanges', () => {
+          return Promise.resolve({changes: []});
+        });
         sandbox.stub(element, '_getSubmittedTogether',
-            function() { return Promise.resolve(); });
+            () => { return Promise.resolve(); });
         sandbox.stub(element, '_getCherryPicks',
-            function() { return Promise.resolve(); });
+            () => { return Promise.resolve(); });
         conflictsStub = sandbox.stub(element, '_getConflicts',
-            function() { return Promise.resolve(['test data']); });
+            () => { return Promise.resolve(['test data']); });
       });
 
-      test('request conflicts if open and mergeable', function() {
+      test('request conflicts if open and mergeable', () => {
         element.patchNum = 7;
         element.change = {
           change_id: 123,
@@ -262,7 +261,7 @@
         assert.isTrue(conflictsStub.called);
       });
 
-      test('does not request conflicts if closed and mergeable', function() {
+      test('does not request conflicts if closed and mergeable', () => {
         element.patchNum = 7;
         element.change = {
           change_id: 123,
@@ -273,7 +272,7 @@
         assert.isFalse(conflictsStub.called);
       });
 
-      test('does not request conflicts if open and not mergeable', function() {
+      test('does not request conflicts if open and not mergeable', () => {
         element.patchNum = 7;
         element.change = {
           change_id: 123,
@@ -284,7 +283,7 @@
         assert.isFalse(conflictsStub.called);
       });
 
-      test('doesnt request conflicts if closed and not mergeable', function() {
+      test('doesnt request conflicts if closed and not mergeable', () => {
         element.patchNum = 7;
         element.change = {
           change_id: 123,
@@ -296,9 +295,9 @@
       });
     });
 
-    test('_calculateHasParent', function() {
-      var changeId = 123;
-      var relatedChanges = [];
+    test('_calculateHasParent', () => {
+      const changeId = 123;
+      const relatedChanges = [];
 
       assert.equal(element._calculateHasParent(changeId, relatedChanges),
           false);
@@ -310,10 +309,9 @@
       relatedChanges.push({change_id: 234});
       assert.equal(element._calculateHasParent(changeId, relatedChanges),
           true);
-
     });
 
-    test('clear hides', function() {
+    test('clear hides', () => {
       element.loading = false;
       element.hidden = false;
       element.clear();
@@ -321,8 +319,8 @@
       assert.isTrue(element.hidden);
     });
 
-    test('update fires', function() {
-      var updateHandler = sandbox.stub();
+    test('update fires', () => {
+      const updateHandler = sandbox.stub();
       element.addEventListener('update', updateHandler);
 
       element._resultsChanged([], [], [], [], []);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
index be88e476..20b89c2 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread.js
@@ -14,8 +14,8 @@
 (function() {
   'use strict';
 
-  var UNRESOLVED_EXPAND_COUNT = 5;
-  var NEWLINE_PATTERN = /\n/g;
+  const UNRESOLVED_EXPAND_COUNT = 5;
+  const NEWLINE_PATTERN = /\n/g;
 
   Polymer({
     is: 'gr-diff-comment-thread',
@@ -30,12 +30,12 @@
       changeNum: String,
       comments: {
         type: Array,
-        value: function() { return []; },
+        value() { return []; },
       },
       locationRange: String,
       keyEventTarget: {
         type: Object,
-        value: function() { return document.body; },
+        value() { return document.body; },
       },
       commentSide: String,
       patchNum: String,
@@ -71,17 +71,17 @@
       'e shift+e': '_handleEKey',
     },
 
-    attached: function() {
-      this._getLoggedIn().then(function(loggedIn) {
+    attached() {
+      this._getLoggedIn().then(loggedIn => {
         this._showActions = loggedIn;
-      }.bind(this));
+      });
       this._setInitialExpandedState();
     },
 
-    addOrEditDraft: function(opt_lineNum, opt_range) {
-      var lastComment = this.comments[this.comments.length - 1] || {};
+    addOrEditDraft(opt_lineNum, opt_range) {
+      const lastComment = this.comments[this.comments.length - 1] || {};
       if (lastComment.__draft) {
-        var commentEl = this._commentElWithDraftID(
+        const commentEl = this._commentElWithDraftID(
             lastComment.id || lastComment.__draftID);
         commentEl.editing = true;
 
@@ -89,25 +89,25 @@
         // actions are available.
         commentEl.collapsed = false;
       } else {
-        var range = opt_range ? opt_range :
+        const range = opt_range ? opt_range :
             lastComment ? lastComment.range : undefined;
-        var unresolved = lastComment ? lastComment.unresolved : undefined;
+        const unresolved = lastComment ? lastComment.unresolved : undefined;
         this.addDraft(opt_lineNum, range, unresolved);
       }
     },
 
-    addDraft: function(opt_lineNum, opt_range, opt_unresolved) {
-      var draft = this._newDraft(opt_lineNum, opt_range);
+    addDraft(opt_lineNum, opt_range, opt_unresolved) {
+      const draft = this._newDraft(opt_lineNum, opt_range);
       draft.__editing = true;
       draft.unresolved = opt_unresolved === false ? opt_unresolved : true;
       this.push('comments', draft);
     },
 
-    _getLoggedIn: function() {
+    _getLoggedIn() {
       return this.$.restAPI.getLoggedIn();
     },
 
-    _commentsChanged: function(changeRecord) {
+    _commentsChanged(changeRecord) {
       this._orderedComments = this._sortedComments(this.comments);
       if (this._orderedComments.length) {
         this._lastComment = this._getLastComment();
@@ -115,15 +115,15 @@
       }
     },
 
-    _hideActions: function(_showActions, _lastComment) {
+    _hideActions(_showActions, _lastComment) {
       return !_showActions || !_lastComment || !!_lastComment.__draft;
     },
 
-    _getLastComment: function() {
+    _getLastComment() {
       return this._orderedComments[this._orderedComments.length - 1] || {};
     },
 
-    _handleEKey: function(e) {
+    _handleEKey(e) {
       if (this.shouldSuppressKeyboardShortcut(e)) { return; }
 
       // Don’t preventDefault in this case because it will render the event
@@ -136,12 +136,12 @@
       }
     },
 
-    _expandCollapseComments: function(actionIsCollapse) {
-      var comments =
+    _expandCollapseComments(actionIsCollapse) {
+      const comments =
           Polymer.dom(this.root).querySelectorAll('gr-diff-comment');
-      comments.forEach(function(comment) {
+      for (const comment of comments) {
         comment.collapsed = actionIsCollapse;
-      });
+      }
     },
 
     /**
@@ -149,33 +149,32 @@
      * {UNRESOLVED_EXPAND_COUNT} comments expanded by default if the
      * thread is unresolved.
      */
-    _setInitialExpandedState: function() {
-      var comment;
+    _setInitialExpandedState() {
+      let comment;
       if (this._orderedComments) {
-        for (var i = 0; i < this._orderedComments.length; i++) {
+        for (let i = 0; i < this._orderedComments.length; i++) {
           comment = this._orderedComments[i];
           comment.collapsed =
               this._orderedComments.length - i - 1 >= UNRESOLVED_EXPAND_COUNT ||
               !this._unresolved;
         }
       }
-
     },
 
-    _sortedComments: function(comments) {
-      return comments.slice().sort(function(c1, c2) {
-        var c1Date = c1.__date || util.parseDate(c1.updated);
-        var c2Date = c2.__date || util.parseDate(c2.updated);
-        var dateCompare = c1Date - c2Date;
+    _sortedComments(comments) {
+      return comments.slice().sort((c1, c2) => {
+        const c1Date = c1.__date || util.parseDate(c1.updated);
+        const c2Date = c2.__date || util.parseDate(c2.updated);
+        const dateCompare = c1Date - c2Date;
         if (!c1.id || !c1.id.localeCompare) { return 0; }
         // If same date, fall back to sorting by id.
         return dateCompare ? dateCompare : c1.id.localeCompare(c2.id);
       });
     },
 
-    _createReplyComment: function(parent, content, opt_isEditing,
+    _createReplyComment(parent, content, opt_isEditing,
         opt_unresolved) {
-      var reply = this._newReply(
+      const reply = this._newReply(
           this._orderedComments[this._orderedComments.length - 1].id,
           parent.line,
           content,
@@ -184,7 +183,7 @@
 
       // If there is currently a comment in an editing state, add an attribute
       // so that the gr-diff-comment knows not to populate the draft text.
-      for (var i = 0; i < this.comments.length; i++) {
+      for (let i = 0; i < this.comments.length; i++) {
         if (this.comments[i].__editing) {
           reply.__otherEditing = true;
           break;
@@ -199,62 +198,62 @@
 
       if (!opt_isEditing) {
         // Allow the reply to render in the dom-repeat.
-        this.async(function() {
-          var commentEl = this._commentElWithDraftID(reply.__draftID);
+        this.async(() => {
+          const commentEl = this._commentElWithDraftID(reply.__draftID);
           commentEl.save();
         }, 1);
       }
     },
 
-    _processCommentReply: function(opt_quote) {
-      var comment = this._lastComment;
-      var quoteStr;
+    _processCommentReply(opt_quote) {
+      const comment = this._lastComment;
+      let quoteStr;
       if (opt_quote) {
-        var msg = comment.message;
+        const msg = comment.message;
         quoteStr = '> ' + msg.replace(NEWLINE_PATTERN, '\n> ') + '\n\n';
       }
       this._createReplyComment(comment, quoteStr, true, comment.unresolved);
     },
 
-    _handleCommentReply: function(e) {
+    _handleCommentReply(e) {
       this._processCommentReply();
     },
 
-    _handleCommentQuote: function(e) {
+    _handleCommentQuote(e) {
       this._processCommentReply(true);
     },
 
-    _handleCommentAck: function(e) {
-      var comment = this._lastComment;
+    _handleCommentAck(e) {
+      const comment = this._lastComment;
       this._createReplyComment(comment, 'Ack', false, false);
     },
 
-    _handleCommentDone: function(e) {
-      var comment = this._lastComment;
+    _handleCommentDone(e) {
+      const comment = this._lastComment;
       this._createReplyComment(comment, 'Done', false, false);
     },
 
-    _handleCommentFix: function(e) {
-      var comment = e.detail.comment;
-      var msg = comment.message;
-      var quoteStr = '> ' + msg.replace(NEWLINE_PATTERN, '\n> ') + '\n\n';
-      var response = quoteStr + 'Please Fix';
+    _handleCommentFix(e) {
+      const comment = e.detail.comment;
+      const msg = comment.message;
+      const quoteStr = '> ' + msg.replace(NEWLINE_PATTERN, '\n> ') + '\n\n';
+      const response = quoteStr + 'Please Fix';
       this._createReplyComment(comment, response, false, true);
     },
 
-    _commentElWithDraftID: function(id) {
-      var els = Polymer.dom(this.root).querySelectorAll('gr-diff-comment');
-      for (var i = 0; i < els.length; i++) {
-        if (els[i].comment.id === id || els[i].comment.__draftID === id) {
-          return els[i];
+    _commentElWithDraftID(id) {
+      const els = Polymer.dom(this.root).querySelectorAll('gr-diff-comment');
+      for (const el of els) {
+        if (el.comment.id === id || el.comment.__draftID === id) {
+          return el;
         }
       }
       return null;
     },
 
-    _newReply: function(inReplyTo, opt_lineNum, opt_message, opt_unresolved,
-          opt_range) {
-      var d = this._newDraft(opt_lineNum);
+    _newReply(inReplyTo, opt_lineNum, opt_message, opt_unresolved,
+        opt_range) {
+      const d = this._newDraft(opt_lineNum);
       d.in_reply_to = inReplyTo;
       d.range = opt_range;
       if (opt_message != null) {
@@ -266,8 +265,8 @@
       return d;
     },
 
-    _newDraft: function(opt_lineNum, opt_range) {
-      var d = {
+    _newDraft(opt_lineNum, opt_range) {
+      const d = {
         __draft: true,
         __draftID: Math.random().toString(36),
         __date: new Date(),
@@ -290,15 +289,15 @@
       return d;
     },
 
-    _getSide: function(isOnParent) {
+    _getSide(isOnParent) {
       if (isOnParent) { return 'PARENT'; }
       return 'REVISION';
     },
 
-    _handleCommentDiscard: function(e) {
-      var diffCommentEl = Polymer.dom(e).rootTarget;
-      var comment = diffCommentEl.comment;
-      var idx = this._indexOf(comment, this.comments);
+    _handleCommentDiscard(e) {
+      const diffCommentEl = Polymer.dom(e).rootTarget;
+      const comment = diffCommentEl.comment;
+      const idx = this._indexOf(comment, this.comments);
       if (idx == -1) {
         throw Error('Cannot find comment ' +
             JSON.stringify(diffCommentEl.comment));
@@ -310,23 +309,23 @@
 
       // Check to see if there are any other open comments getting edited and
       // set the local storage value to its message value.
-      for (var i = 0; i < this.comments.length; i++) {
-        if (this.comments[i].__editing) {
-          var commentLocation = {
+      for (const changeComment of this.comments) {
+        if (changeComment.__editing) {
+          const commentLocation = {
             changeNum: this.changeNum,
             patchNum: this.patchNum,
-            path: this.comments[i].path,
-            line: this.comments[i].line,
+            path: changeComment.path,
+            line: changeComment.line,
           };
           return this.$.storage.setDraftComment(commentLocation,
-              this.comments[i].message);
+              changeComment.message);
         }
       }
     },
 
-    _handleCommentUpdate: function(e) {
-      var comment = e.detail.comment;
-      var index = this._indexOf(comment, this.comments);
+    _handleCommentUpdate(e) {
+      const comment = e.detail.comment;
+      const index = this._indexOf(comment, this.comments);
       if (index === -1) {
         // This should never happen: comment belongs to another thread.
         console.warn('Comment update for another comment thread.');
@@ -335,9 +334,9 @@
       this.set(['comments', index], comment);
     },
 
-    _indexOf: function(comment, arr) {
-      for (var i = 0; i < arr.length; i++) {
-        var c = arr[i];
+    _indexOf(comment, arr) {
+      for (let i = 0; i < arr.length; i++) {
+        const c = arr[i];
         if ((c.__draftID != null && c.__draftID == comment.__draftID) ||
             (c.id != null && c.id == comment.id)) {
           return i;
@@ -346,7 +345,7 @@
       return -1;
     },
 
-    _computeHostClass: function(unresolved) {
+    _computeHostClass(unresolved) {
       return unresolved ? 'unresolved' : '';
     },
   });
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
index 546308e..85beca6 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html
@@ -40,25 +40,25 @@
 </test-fixture>
 
 <script>
-  suite('gr-diff-comment-thread tests', function() {
-    var element;
-    var sandbox;
+  suite('gr-diff-comment-thread tests', () => {
+    let element;
+    let sandbox;
 
-    setup(function() {
+    setup(() => {
       sandbox = sinon.sandbox.create();
       stub('gr-rest-api-interface', {
-        getLoggedIn: function() { return Promise.resolve(false); },
+        getLoggedIn() { return Promise.resolve(false); },
       });
       sandbox = sinon.sandbox.create();
       element = fixture('basic');
     });
 
-    teardown(function() {
+    teardown(() => {
       sandbox.restore();
     });
 
-    test('comments are sorted correctly', function() {
-      var comments = [
+    test('comments are sorted correctly', () => {
+      const comments = [
         {
           id: 'jacks_reply',
           message: 'i like you, too',
@@ -86,9 +86,9 @@
           id: 'sallys_mission',
           message: 'i have to find santa',
           updated: '2015-12-24 15:00:20.396000000',
-        }
+        },
       ];
-      var results = element._sortedComments(comments);
+      const results = element._sortedComments(comments);
       assert.deepEqual(results, [
         {
           id: 'sally_to_dr_finklestein',
@@ -117,11 +117,11 @@
           message: 'i like you, too',
           in_reply_to: 'sallys_confession',
           updated: '2015-12-25 15:00:20.396000000',
-        }
+        },
       ]);
     });
 
-    test('addOrEditDraft w/ edit draft', function() {
+    test('addOrEditDraft w/ edit draft', () => {
       element.comments = [{
         id: 'jacks_reply',
         message: 'i like you, too',
@@ -129,9 +129,9 @@
         updated: '2015-12-25 15:00:20.396000000',
         __draft: true,
       }];
-      var commentElStub = sandbox.stub(element, '_commentElWithDraftID',
-          function() { return {}; });
-      var addDraftStub = sandbox.stub(element, 'addDraft');
+      const commentElStub = sandbox.stub(element, '_commentElWithDraftID',
+          () => { return {}; });
+      const addDraftStub = sandbox.stub(element, 'addDraft');
 
       element.addOrEditDraft(123);
 
@@ -139,11 +139,11 @@
       assert.isFalse(addDraftStub.called);
     });
 
-    test('addOrEditDraft w/o edit draft', function() {
+    test('addOrEditDraft w/o edit draft', () => {
       element.comments = [];
-      var commentElStub = sandbox.stub(element, '_commentElWithDraftID',
-          function() { return {}; });
-      var addDraftStub = sandbox.stub(element, 'addDraft');
+      const commentElStub = sandbox.stub(element, '_commentElWithDraftID',
+          () => { return {}; });
+      const addDraftStub = sandbox.stub(element, 'addDraft');
 
       element.addOrEditDraft(123);
 
@@ -151,40 +151,41 @@
       assert.isTrue(addDraftStub.called);
     });
 
-    test('_hideActions', function() {
-      var showActions = true;
-      var lastComment = {};
+    test('_hideActions', () => {
+      let showActions = true;
+      const lastComment = {};
       assert.equal(element._hideActions(showActions, lastComment), false);
       showActions = false;
       assert.equal(element._hideActions(showActions, lastComment), true);
-      var showActions = true;
+      showActions = true;
       lastComment.__draft = true;
       assert.equal(element._hideActions(showActions, lastComment), true);
     });
   });
 
-  suite('comment action tests', function() {
-    var element;
+  suite('comment action tests', () => {
+    let element;
 
-    setup(function() {
+    setup(() => {
       stub('gr-rest-api-interface', {
-        getLoggedIn: function() { return Promise.resolve(false); },
-        saveDiffDraft: function() {
+        getLoggedIn() { return Promise.resolve(false); },
+        saveDiffDraft() {
           return Promise.resolve({
             ok: true,
-            text: function() { return Promise.resolve(')]}\'\n' +
-                JSON.stringify({
-                  id: '7afa4931_de3d65bd',
-                  path: '/path/to/file.txt',
-                  line: 5,
-                  in_reply_to: 'baf0414d_60047215',
-                  updated: '2015-12-21 02:01:10.850000000',
-                  message: 'Done',
-                }));
+            text() {
+              return Promise.resolve(')]}\'\n' +
+                  JSON.stringify({
+                    id: '7afa4931_de3d65bd',
+                    path: '/path/to/file.txt',
+                    line: 5,
+                    in_reply_to: 'baf0414d_60047215',
+                    updated: '2015-12-21 02:01:10.850000000',
+                    message: 'Done',
+                  }));
             },
           });
         },
-        deleteDiffDraft: function() { return Promise.resolve({ok: true}); },
+        deleteDiffDraft() { return Promise.resolve({ok: true}); },
       });
       element = fixture('withComment');
       element.comments = [{
@@ -200,15 +201,15 @@
       flushAsynchronousOperations();
     });
 
-    test('reply', function(done) {
-      var commentEl = element.$$('gr-diff-comment');
+    test('reply', done => {
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
 
-      var replyBtn = element.$.replyBtn;
+      const replyBtn = element.$.replyBtn;
       MockInteractions.tap(replyBtn);
       flushAsynchronousOperations();
 
-      var drafts = element._orderedComments.filter(function(c) {
+      const drafts = element._orderedComments.filter(c => {
         return c.__draft == true;
       });
       assert.equal(drafts.length, 1);
@@ -217,16 +218,16 @@
       done();
     });
 
-    test('quote reply', function(done) {
-      var commentEl = element.$$('gr-diff-comment');
+    test('quote reply', done => {
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
 
-      var quoteBtn = element.$.quoteBtn;
+      const quoteBtn = element.$.quoteBtn;
       MockInteractions.tap(quoteBtn);
       flushAsynchronousOperations();
 
-      var drafts = element._orderedComments.filter(function(c) {
-          return c.__draft == true;
+      const drafts = element._orderedComments.filter(c => {
+        return c.__draft == true;
       });
       assert.equal(drafts.length, 1);
       assert.equal(drafts[0].message, '> is this a crossover episode!?\n\n');
@@ -234,7 +235,7 @@
       done();
     });
 
-    test('quote reply multiline', function(done) {
+    test('quote reply multiline', done => {
       element.comments = [{
         author: {
           name: 'Mr. Peanutbutter',
@@ -247,14 +248,14 @@
       }];
       flushAsynchronousOperations();
 
-      var commentEl = element.$$('gr-diff-comment');
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
 
-      var quoteBtn = element.$.quoteBtn;
+      const quoteBtn = element.$.quoteBtn;
       MockInteractions.tap(quoteBtn);
       flushAsynchronousOperations();
 
-      var drafts = element._orderedComments.filter(function(c) {
+      const drafts = element._orderedComments.filter(c => {
         return c.__draft == true;
       });
       assert.equal(drafts.length, 1);
@@ -264,17 +265,17 @@
       done();
     });
 
-    test('ack', function(done) {
+    test('ack', done => {
       element.changeNum = '42';
       element.patchNum = '1';
 
-      var commentEl = element.$$('gr-diff-comment');
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
 
-      var ackBtn = element.$.ackBtn;
+      const ackBtn = element.$.ackBtn;
       MockInteractions.tap(ackBtn);
-      flush(function() {
-        var drafts = element.comments.filter(function(c) {
+      flush(() => {
+        const drafts = element.comments.filter(c => {
           return c.__draft == true;
         });
         assert.equal(drafts.length, 1);
@@ -285,16 +286,16 @@
       });
     });
 
-    test('done', function(done) {
+    test('done', done => {
       element.changeNum = '42';
       element.patchNum = '1';
-      var commentEl = element.$$('gr-diff-comment');
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
 
-      var doneBtn = element.$.doneBtn;
+      const doneBtn = element.$.doneBtn;
       MockInteractions.tap(doneBtn);
-      flush(function() {
-        var drafts = element.comments.filter(function(c) {
+      flush(() => {
+        const drafts = element.comments.filter(c => {
           return c.__draft == true;
         });
         assert.equal(drafts.length, 1);
@@ -305,13 +306,13 @@
       });
     });
 
-    test('please fix', function(done) {
+    test('please fix', done => {
       element.changeNum = '42';
       element.patchNum = '1';
-      var commentEl = element.$$('gr-diff-comment');
+      const commentEl = element.$$('gr-diff-comment');
       assert.ok(commentEl);
-      commentEl.addEventListener('create-fix-comment', function() {
-        var drafts = element._orderedComments.filter(function(c) {
+      commentEl.addEventListener('create-fix-comment', () => {
+        const drafts = element._orderedComments.filter(c => {
           return c.__draft == true;
         });
         assert.equal(drafts.length, 1);
@@ -325,21 +326,21 @@
           {bubbles: false});
     });
 
-    test('discard', function(done) {
+    test('discard', done => {
       element.changeNum = '42';
       element.patchNum = '1';
       element.push('comments', element._newReply(
-        element.comments[0].id,
-        element.comments[0].line,
-        element.comments[0].path,
-        'it’s pronouced jiff, not giff'));
+          element.comments[0].id,
+          element.comments[0].line,
+          element.comments[0].path,
+          'it’s pronouced jiff, not giff'));
       flushAsynchronousOperations();
 
-      var draftEl =
+      const draftEl =
           Polymer.dom(element.root).querySelectorAll('gr-diff-comment')[1];
       assert.ok(draftEl);
-      draftEl.addEventListener('comment-discard', function() {
-        var drafts = element.comments.filter(function(c) {
+      draftEl.addEventListener('comment-discard', () => {
+        const drafts = element.comments.filter(c => {
           return c.__draft == true;
         });
         assert.equal(drafts.length, 0);
@@ -348,9 +349,7 @@
       draftEl.fire('comment-discard', null, {bubbles: false});
     });
 
-    test('first editing comment does not add __otherEditing attribute',
-        function() {
-      var commentEl = element.$$('gr-diff-comment');
+    test('first editing comment does not add __otherEditing attribute', () => {
       element.comments = [{
         author: {
           name: 'Mr. Peanutbutter',
@@ -363,19 +362,19 @@
         __draft: true,
       }];
 
-      var replyBtn = element.$.replyBtn;
+      const replyBtn = element.$.replyBtn;
       MockInteractions.tap(replyBtn);
       flushAsynchronousOperations();
 
-      var editing = element._orderedComments.filter(function(c) {
+      const editing = element._orderedComments.filter(c => {
         return c.__editing == true;
       });
       assert.equal(editing.length, 1);
       assert.equal(!!editing[0].__otherEditing, false);
     });
 
-    test('When not editing other comments, local storage not set after discard',
-        function(done) {
+    test('When not editing other comments, local storage not set' +
+        ' after discard', done => {
       element.changeNum = '42';
       element.patchNum = '1';
       element.comments = [{
@@ -413,13 +412,13 @@
         updated: '2015-12-08 19:48:33.843000000',
         __draft: true,
       }];
-      var storageStub = sinon.stub(element.$.storage, 'setDraftComment');
+      const storageStub = sinon.stub(element.$.storage, 'setDraftComment');
       flushAsynchronousOperations();
 
-      var draftEl =
-          Polymer.dom(element.root).querySelectorAll('gr-diff-comment')[1];
+      const draftEl =
+      Polymer.dom(element.root).querySelectorAll('gr-diff-comment')[1];
       assert.ok(draftEl);
-      draftEl.addEventListener('comment-discard', function() {
+      draftEl.addEventListener('comment-discard', () => {
         assert.isFalse(storageStub.called);
         storageStub.restore();
         done();
@@ -427,9 +426,9 @@
       draftEl.fire('comment-discard', null, {bubbles: false});
     });
 
-    test('comment-update', function() {
-      var commentEl = element.$$('gr-diff-comment');
-      var updatedComment = {
+    test('comment-update', () => {
+      const commentEl = element.$$('gr-diff-comment');
+      const updatedComment = {
         id: element.comments[0].id,
         foo: 'bar',
       };
@@ -437,88 +436,81 @@
       assert.strictEqual(element.comments[0], updatedComment);
     });
 
-    suite('jack and sally comment data test consolidation', function() {
-      var getComments = function() {
-        return Polymer.dom(element.root).querySelectorAll('gr-diff-comment');
-      };
-
-      setup(function() {
+    suite('jack and sally comment data test consolidation', () => {
+      setup(() => {
         element.comments = [
-        {
-          id: 'jacks_reply',
-          message: 'i like you, too',
-          in_reply_to: 'sallys_confession',
-          updated: '2015-12-25 15:00:20.396000000',
-          unresolved: false,
-        }, {
-          id: 'sallys_confession',
-          in_reply_to: 'nonexistent_comment',
-          message: 'i like you, jack',
-          updated: '2015-12-24 15:00:20.396000000',
-        }, {
-          id: 'sally_to_dr_finklestein',
-          in_reply_to: 'nonexistent_comment',
-          message: 'i’m running away',
-          updated: '2015-10-31 09:00:20.396000000',
-        }, {
-          id: 'sallys_defiance',
-          message: 'i will poison you so i can get away',
-          updated: '2015-10-31 15:00:20.396000000',
-        }];
+          {
+            id: 'jacks_reply',
+            message: 'i like you, too',
+            in_reply_to: 'sallys_confession',
+            updated: '2015-12-25 15:00:20.396000000',
+            unresolved: false,
+          }, {
+            id: 'sallys_confession',
+            in_reply_to: 'nonexistent_comment',
+            message: 'i like you, jack',
+            updated: '2015-12-24 15:00:20.396000000',
+          }, {
+            id: 'sally_to_dr_finklestein',
+            in_reply_to: 'nonexistent_comment',
+            message: 'i’m running away',
+            updated: '2015-10-31 09:00:20.396000000',
+          }, {
+            id: 'sallys_defiance',
+            message: 'i will poison you so i can get away',
+            updated: '2015-10-31 15:00:20.396000000',
+          }];
       });
 
-      test('orphan replies', function() {
+      test('orphan replies', () => {
         assert.equal(4, element._orderedComments.length);
       });
 
-      test('keyboard shortcuts', function() {
-        var expandCollapseStub = sinon.stub(element, '_expandCollapseComments');
+      test('keyboard shortcuts', () => {
+        const expandCollapseStub =
+            sinon.stub(element, '_expandCollapseComments');
         MockInteractions.pressAndReleaseKeyOn(element, 69, null, 'e');
         assert.isTrue(expandCollapseStub.lastCall.calledWith(false));
 
         MockInteractions.pressAndReleaseKeyOn(element, 69, 'shift', 'e');
         assert.isTrue(expandCollapseStub.lastCall.calledWith(true));
-        expandCollapseStub.restore();
       });
 
-      test('comment in_reply_to is either null or most recent comment id',
-          function() {
+      test('comment in_reply_to is either null or most recent comment', () => {
         element._createReplyComment(element.comments[3], 'dummy', true);
         flushAsynchronousOperations();
         assert.equal(element._orderedComments.length, 5);
         assert.equal(element._orderedComments[4].in_reply_to, 'jacks_reply');
       });
 
-      test('resolvable comments', function() {
+      test('resolvable comments', () => {
         assert.isFalse(element._unresolved);
         element._createReplyComment(element.comments[3], 'dummy', true, true);
         flushAsynchronousOperations();
         assert.isTrue(element._unresolved);
       });
 
-      test('_setInitialExpandedState', function() {
+      test('_setInitialExpandedState', () => {
         element._unresolved = true;
         element._setInitialExpandedState();
-        var comments = getComments();
-        for (var i = 0; i < element.comments.length; i++) {
+        for (let i = 0; i < element.comments.length; i++) {
           assert.isFalse(element.comments[i].collapsed);
         }
         element._unresolved = false;
         element._setInitialExpandedState();
-        var comments = getComments();
-        for (var i = 0; i < element.comments.length; i++) {
+        for (let i = 0; i < element.comments.length; i++) {
           assert.isTrue(element.comments[i].collapsed);
         }
       });
     });
 
-    test('_computeHostClass', function() {
+    test('_computeHostClass', () => {
       assert.equal(element._computeHostClass(true), 'unresolved');
       assert.equal(element._computeHostClass(false), '');
     });
 
-    test('addDraft sets unresolved state correctly', function() {
-      var unresolved = true;
+    test('addDraft sets unresolved state correctly', () => {
+      let unresolved = true;
       element.comments = [];
       element.addDraft(null, null, unresolved);
       assert.equal(element.comments[0].unresolved, true);
@@ -533,15 +525,15 @@
       assert.equal(element.comments[0].unresolved, true);
     });
 
-    test('_newDraft', function() {
+    test('_newDraft', () => {
       element.commentSide = 'left';
       element.patchNum = 3;
-      var draft = element._newDraft();
+      const draft = element._newDraft();
       assert.equal(draft.__commentSide, 'left');
       assert.equal(draft.patchNum, 3);
     });
 
-    test('new comment gets created', function() {
+    test('new comment gets created', () => {
       element.comments = [];
       element.addOrEditDraft(1);
       assert.equal(element.comments.length, 1);
@@ -552,7 +544,7 @@
       assert.equal(element.comments.length, 2);
     });
 
-    test('unresolved label', function() {
+    test('unresolved label', () => {
       element._unresolved = false;
       assert.isTrue(element.$.unresolvedLabel.hasAttribute('hidden'));
       element._unresolved = true;
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
index 520f24d..75b00e8 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader.js
@@ -14,8 +14,8 @@
 (function() {
   'use strict';
 
-  var HLJS_PATH = 'bower_components/highlightjs/highlight.min.js';
-  var LIB_ROOT_PATTERN = /(.+\/)elements\/gr-app\.html/;
+  const HLJS_PATH = 'bower_components/highlightjs/highlight.min.js';
+  const LIB_ROOT_PATTERN = /(.+\/)elements\/gr-app\.html/;
 
   Polymer({
     is: 'gr-syntax-lib-loader',
@@ -30,11 +30,11 @@
           loading: false,
           callbacks: [],
         },
-      }
+      },
     },
 
-    get: function() {
-      return new Promise(function(resolve) {
+    get() {
+      return new Promise(resolve => {
         // If the lib is totally loaded, resolve immediately.
         if (this._state.loaded) {
           resolve(this._getHighlightLib());
@@ -48,27 +48,29 @@
         }
 
         this._state.callbacks.push(resolve);
-      }.bind(this));
+      });
     },
 
-    _onLibLoaded: function() {
-      var lib = this._getHighlightLib();
+    _onLibLoaded() {
+      const lib = this._getHighlightLib();
       this._state.loaded = true;
       this._state.loading = false;
-      this._state.callbacks.forEach(function(cb) { cb(lib); });
+      for (const cb of this._state.callbacks) {
+        cb(lib);
+      }
       this._state.callbacks = [];
     },
 
-    _getHighlightLib: function() {
+    _getHighlightLib() {
       return window.hljs;
     },
 
-    _configureHighlightLib: function() {
+    _configureHighlightLib() {
       this._getHighlightLib().configure(
           {classPrefix: 'gr-diff gr-syntax gr-syntax-'});
     },
 
-    _getLibRoot: function() {
+    _getLibRoot() {
       if (this._cachedLibRoot) { return this._cachedLibRoot; }
 
       return this._cachedLibRoot = document.head
@@ -78,16 +80,16 @@
     },
     _cachedLibRoot: null,
 
-    _loadHLJS: function() {
-      return new Promise(function(resolve) {
-        var script = document.createElement('script');
+    _loadHLJS() {
+      return new Promise(resolve => {
+        const script = document.createElement('script');
         script.src = this._getLibRoot() + HLJS_PATH;
         script.onload = function() {
           this._configureHighlightLib();
           resolve();
         }.bind(this);
         Polymer.dom(document.head).appendChild(script);
-      }.bind(this));
+      });
     },
   });
 })();
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
index 985fc6d..0a916d0 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html
@@ -32,26 +32,24 @@
 </test-fixture>
 
 <script>
-  suite('gr-syntax-lib-loader tests', function() {
-    var element;
-    var resolveLoad;
-    var loadStub;
+  suite('gr-syntax-lib-loader tests', () => {
+    let element;
+    let resolveLoad;
+    let loadStub;
 
-    setup(function() {
+    setup(() => {
       element = fixture('basic');
 
-      loadStub = sinon.stub(element, '_loadHLJS', function() {
-        return new Promise(function(resolve) {
-          resolveLoad = resolve;
-        });
-      });
+      loadStub = sinon.stub(element, '_loadHLJS', () =>
+        new Promise(resolve => resolveLoad = resolve)
+      );
 
       // Assert preconditions:
       assert.isFalse(element._state.loaded);
       assert.isFalse(element._state.loading);
     });
 
-    teardown(function() {
+    teardown(() => {
       if (window.hljs) {
         delete window.hljs;
       }
@@ -63,8 +61,8 @@
       element._state.callbacks = [];
     });
 
-    test('only load once', function(done) {
-      var firstCallHandler = sinon.stub();
+    test('only load once', done => {
+      const firstCallHandler = sinon.stub();
       element.get().then(firstCallHandler);
 
       // It should now be in the loading state.
@@ -73,7 +71,7 @@
       assert.isFalse(element._state.loaded);
       assert.isFalse(firstCallHandler.called);
 
-      var secondCallHandler = sinon.stub();
+      const secondCallHandler = sinon.stub();
       element.get().then(secondCallHandler);
 
       // No change in state.
@@ -84,7 +82,7 @@
 
       // Now load the library.
       resolveLoad();
-      flush(function() {
+      flush(() => {
         // The state should be loaded and both handlers called.
         assert.isFalse(element._state.loading);
         assert.isTrue(element._state.loaded);