Merge "Let cherrypick API optionally preserve reviewers/ccs"
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index e4a7218..4c1df8c 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -147,6 +147,17 @@
 [[style]]
 === Style
 
+This project has a policy of Eclipse's warning free code. Eclipse
+configuration is added to git and we expect the changes to be
+warnings free.
+
+We do not ask you to use Eclipse for editing, obviously.  We do ask you
+to provide Eclipse's warning free patches only. If for some reasons, you
+are not able to set up Eclipse and verify, that your patch hasn't
+introduced any new Eclipse warnings, mention this in a comment to your
+change, so that reviewers will do it for you. Yes, the way to go is to
+extend gerrit CI to take care of this, but it's not yet implemented.
+
 Gerrit generally follows the
 link:https://google.github.io/styleguide/javaguide.html[Google Java Style
 Guide].
diff --git a/WORKSPACE b/WORKSPACE
index 66729a9..55a4a60 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -637,15 +637,15 @@
 # https://issues.apache.org/jira/browse/SSHD-736
 maven_jar(
     name = "sshd",
-    artifact = "org.apache.sshd:sshd-core:1.4.0",
+    artifact = "org.apache.sshd:sshd-core:1.6.0",
     exclude = ["META-INF/services/java.nio.file.spi.FileSystemProvider"],
-    sha1 = "c8f3d7457fc9979d1b9ec319f0229b89793c8e56",
+    sha1 = "548e2da643e88cda9d313efb2564a74f9943e491",
 )
 
 maven_jar(
     name = "eddsa",
-    artifact = "net.i2p.crypto:eddsa:0.1.0",
-    sha1 = "8f5a3b165164e222da048d8136b21428ee0b9122",
+    artifact = "net.i2p.crypto:eddsa:0.2.0",
+    sha1 = "0856a92559c4daf744cb27c93cd8b7eb1f8c4780",
 )
 
 maven_jar(
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 773ad44..bcf62bd 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -62,6 +62,7 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.git.ReceiveCommits;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.project.Util;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -454,16 +455,52 @@
     assertThat(r.getChange().change().isWorkInProgress()).isFalse();
 
     // Make the change work-in-progress again.
-    r = pushTo("refs/for/master%wip");
+    r = amendChange(r.getChangeId(), "refs/for/master%wip");
     r.assertOkStatus();
     assertThat(r.getChange().change().isWorkInProgress()).isTrue();
 
     // Can't use --wip and --ready together.
-    r = pushTo("refs/for/master%wip,ready");
+    r = amendChange(r.getChangeId(), "refs/for/master%wip,ready");
     r.assertErrorStatus();
   }
 
   @Test
+  public void pushWorkInProgressChangeWhenNotOwner() throws Exception {
+    TestRepository<?> userRepo = cloneProject(project, user);
+    PushOneCommit.Result r =
+        pushFactory.create(db, user.getIdent(), userRepo).to("refs/for/master%wip");
+    r.assertOkStatus();
+    assertThat(r.getChange().change().getOwner()).isEqualTo(user.id);
+    assertThat(r.getChange().change().isWorkInProgress()).isTrue();
+
+    // Other user trying to move from WIP to ready should fail.
+    GitUtil.fetch(testRepo, r.getPatchSet().getRefName() + ":ps");
+    testRepo.reset("ps");
+    r = amendChange(r.getChangeId(), "refs/for/master%ready", admin, testRepo);
+    r.assertErrorStatus(ReceiveCommits.ONLY_OWNER_CAN_MODIFY_WIP);
+
+    // Other user trying to move from WIP to WIP should succeed.
+    r = amendChange(r.getChangeId(), "refs/for/master%wip", admin, testRepo);
+    r.assertOkStatus();
+    assertThat(r.getChange().change().isWorkInProgress()).isTrue();
+
+    // Push as change owner to move change from WIP to ready.
+    r = pushFactory.create(db, user.getIdent(), userRepo).to("refs/for/master%ready");
+    r.assertOkStatus();
+    assertThat(r.getChange().change().isWorkInProgress()).isFalse();
+
+    // Other user trying to move from ready to WIP should fail.
+    GitUtil.fetch(testRepo, r.getPatchSet().getRefName() + ":ps");
+    testRepo.reset("ps");
+    r = amendChange(r.getChangeId(), "refs/for/master%wip", admin, testRepo);
+    r.assertErrorStatus(ReceiveCommits.ONLY_OWNER_CAN_MODIFY_WIP);
+
+    // Other user trying to move from ready to ready should succeed.
+    r = amendChange(r.getChangeId(), "refs/for/master%ready", admin, testRepo);
+    r.assertOkStatus();
+  }
+
+  @Test
   public void pushForMasterAsDraft() throws Exception {
     // create draft by pushing to 'refs/drafts/'
     PushOneCommit.Result r = pushTo("refs/drafts/master");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 6b3f173..5cd2184 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -202,6 +202,9 @@
           + "Squash the commits with the same Change-Id or "
           + "ensure Change-Ids are unique for each commit";
 
+  public static final String ONLY_OWNER_CAN_MODIFY_WIP =
+      "only change owner can modify Work-in-Progress";
+
   private enum Error {
     CONFIG_UPDATE(
         "You are not allowed to perform this operation.\n"
@@ -2484,6 +2487,14 @@
         }
       }
 
+      if (magicBranch != null
+          && (magicBranch.workInProgress || magicBranch.ready)
+          && magicBranch.workInProgress != change.isWorkInProgress()
+          && !user.getAccountId().equals(change.getOwner())) {
+        reject(inputCommand, ONLY_OWNER_CAN_MODIFY_WIP);
+        return false;
+      }
+
       if (magicBranch != null && magicBranch.edit) {
         return newEdit();
       }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
index 4032c03..24bae37 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
@@ -309,7 +309,7 @@
           ctx.getWhen());
     }
 
-    private ChangeMessage generateChangeMessage(ChangeContext ctx) throws OrmException {
+    private ChangeMessage generateChangeMessage(ChangeContext ctx) {
       String changeMsg = "Patch Set " + psId.get() + ":";
       if (parsedComments.get(0).type == MailComment.CommentType.CHANGE_MESSAGE) {
         // Add a blank line after Patch Set to follow the default format
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailTransferException.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailTransferException.java
index 381907a..fdaba1d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailTransferException.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailTransferException.java
@@ -16,6 +16,7 @@
 
 /** An exception indicating a known transport-level exception. */
 public class MailTransferException extends Exception {
+  private static final long serialVersionUID = 1L;
 
   public MailTransferException(String message) {
     super(message);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/RawMailParser.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/RawMailParser.java
index 9c0c4b7..ea45212 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/RawMailParser.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/RawMailParser.java
@@ -140,8 +140,8 @@
    * Traverses a mime tree and parses out text and html parts. All other parts will be dropped.
    *
    * @param part {@code MimePart} to parse
-   * @param textBuilder {@link StringBuilder) to append all plaintext parts
-   * @param htmlBuilder {@link StringBuilder) to append all html parts
+   * @param textBuilder {@link StringBuilder} to append all plaintext parts
+   * @param htmlBuilder {@link StringBuilder} to append all html parts
    * @throws IOException in case of a failure while transforming the input to a {@link String}
    */
   private static void handleMimePart(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
index 2a22b1e..63134a9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
@@ -269,11 +269,16 @@
       return "project state does not permit write";
     }
 
+    String userId =
+        getUser().isIdentifiedUser()
+            ? "account " + getUser().getAccountId()
+            : "anonymous user";
+
     if (object instanceof RevCommit) {
       if (!canPerform(Permission.CREATE)) {
-        return "lacks permission: " + Permission.CREATE;
+        return userId + " lacks permission: " + Permission.CREATE;
       }
-      return canCreateCommit(repo, (RevCommit) object);
+      return canCreateCommit(repo, (RevCommit) object, userId);
     } else if (object instanceof RevTag) {
       final RevTag tag = (RevTag) object;
       try (RevWalk rw = new RevWalk(repo)) {
@@ -300,13 +305,13 @@
           valid = false;
         }
         if (!valid && !canForgeCommitter()) {
-          return "lacks permission: " + Permission.FORGE_COMMITTER;
+          return userId + " lacks permission: " + Permission.FORGE_COMMITTER;
         }
       }
 
       RevObject tagObject = tag.getObject();
       if (tagObject instanceof RevCommit) {
-        String rejectReason = canCreateCommit(repo, (RevCommit) tagObject);
+        String rejectReason = canCreateCommit(repo, (RevCommit) tagObject, userId);
         if (rejectReason != null) {
           return rejectReason;
         }
@@ -323,9 +328,11 @@
       if (tag.getFullMessage().contains("-----BEGIN PGP SIGNATURE-----\n")) {
         return canPerform(Permission.CREATE_SIGNED_TAG)
             ? null
-            : "lacks permission: " + Permission.CREATE_SIGNED_TAG;
+            : userId + " lacks permission: " + Permission.CREATE_SIGNED_TAG;
       }
-      return canPerform(Permission.CREATE_TAG) ? null : "lacks permission " + Permission.CREATE_TAG;
+      return canPerform(Permission.CREATE_TAG)
+          ? null
+          : userId + " lacks permission " + Permission.CREATE_TAG;
     }
 
     return null;
@@ -333,10 +340,11 @@
 
   /**
    * Check if the user is allowed to create a new commit object if this introduces a new commit to
-   * the project. If not allowed, returns a string describing why it's not allowed.
+   * the project. If not allowed, returns a string describing why it's not allowed. The userId
+   * argument is only used for the error message.
    */
   @Nullable
-  private String canCreateCommit(Repository repo, RevCommit commit) {
+  private String canCreateCommit(Repository repo, RevCommit commit, String userId) {
     if (canUpdate()) {
       // If the user has push permissions, they can create the ref regardless
       // of whether they are pushing any new objects along with the create.
@@ -348,7 +356,7 @@
       // even if they don't have push permission.
       return null;
     }
-    return "lacks permission " + Permission.PUSH + " for creating new commit object";
+    return userId + " lacks permission " + Permission.PUSH + " for creating new commit object";
   }
 
   private boolean isMergedIntoBranchOrTag(Repository repo, RevCommit commit) {
diff --git a/polygerrit-ui/app/.eslintrc.json b/polygerrit-ui/app/.eslintrc.json
index 2f77b42..2a33aa7 100644
--- a/polygerrit-ui/app/.eslintrc.json
+++ b/polygerrit-ui/app/.eslintrc.json
@@ -23,7 +23,8 @@
     "camelcase": "off",
     "comma-dangle": ["error", "always-multiline"],
     "eol-last": "off",
-    "indent": ["error", 2, {
+    "indent": "off",
+    "indent-legacy": ["error", 2, {
       "MemberExpression": 2,
       "FunctionDeclaration": {"body": 1, "parameters": 2},
       "FunctionExpression": {"body": 1, "parameters": 2},
@@ -42,6 +43,7 @@
     "new-cap": ["error", { "capIsNewExceptions": ["Polymer"] }],
     "no-console": "off",
     "no-undef": "off",
+    "no-useless-escape": "off",
     "no-var": "error",
     "object-shorthand": ["error", "always"],
     "prefer-arrow-callback": "error",
diff --git a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
index 0cf7bb4..de20568 100644
--- a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
@@ -142,9 +142,9 @@
         2: ['upload'],
         3: ['upload', clearWip],
         4: ['upload', setWip],
-      }).assertWip(1, false)  // Change was created with PS1 ready for review
-          .assertWip(2, true)   // PS2 was uploaded during WIP
-          .assertWip(3, false)  // PS3 was marked ready for review after upload
+      }).assertWip(1, false) // Change was created with PS1 ready for review
+          .assertWip(2, true) // PS2 was uploaded during WIP
+          .assertWip(3, false) // PS3 was marked ready for review after upload
           .assertWip(4, false); // PS4 was uploaded ready for review
 
       compute(false, {
@@ -154,10 +154,10 @@
         4: ['upload'],
         5: ['upload', clearWip],
         6: [uploadInWip],
-      }).assertWip(1, true)  // Change was created in WIP
-          .assertWip(2, true)  // PS2 was uploaded during WIP
+      }).assertWip(1, true) // Change was created in WIP
+          .assertWip(2, true) // PS2 was uploaded during WIP
           .assertWip(3, false) // PS3 was marked ready for review
-          .assertWip(4, true)  // PS4 was uploaded during WIP
+          .assertWip(4, true) // PS4 was uploaded during WIP
           .assertWip(5, false) // PS5 was marked ready for review
           .assertWip(6, true); // PS6 was uploaded with WIP option
     });
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-create-project/gr-admin-create-project.html b/polygerrit-ui/app/elements/admin/gr-admin-create-project/gr-admin-create-project.html
index 9fc7523..03fb8ab 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-create-project/gr-admin-create-project.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-create-project/gr-admin-create-project.html
@@ -72,25 +72,27 @@
             <section>
               <span class="title">Create initial empty commit</span>
               <span class="value">
-                <select
+                <gr-select
                     id="initalCommit"
-                    is="gr-select"
                     bind-value="{{_projectConfig.create_empty_commit}}">
-                  <option value="false">False</option>
-                  <option value="true">True</option>
-                </select>
+                  <select>
+                    <option value="false">False</option>
+                    <option value="true">True</option>
+                  </select>
+                </gr-select>
               </span>
             </section>
             <section>
               <span class="title">Only serve as parent for other projects</span>
               <span class="value">
-                <select
+                <gr-select
                     id="parentProject"
-                    is="gr-select"
                     bind-value="{{_projectConfig.permissions_only}}">
-                  <option value="false">False</option>
-                  <option value="true">True</option>
-                </select>
+                  <select>
+                    <option value="false">False</option>
+                    <option value="true">True</option>
+                  </select>
+                </gr-select>
               </span>
             </section>
           </fieldset>
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
index 458418a..74e1f80 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
@@ -27,14 +27,14 @@
 <link rel="import" href="../gr-admin-group-list/gr-admin-group-list.html">
 <link rel="import" href="../gr-admin-plugin-list/gr-admin-plugin-list.html">
 <link rel="import" href="../gr-admin-project-list/gr-admin-project-list.html">
-<link rel="import" href="../gr-admin-project/gr-admin-project.html">
+<link rel="import" href="../gr-project/gr-project.html">
 <link rel="import" href="../gr-project-detail-list/gr-project-detail-list.html">
 
 <dom-module id="gr-admin-view">
   <template>
     <style include="shared-styles"></style>
     <style include="gr-menu-page-styles"></style>
-    <gr-page-nav class$="[[_computeLoadingClass(_loading)]]">
+    <gr-page-nav>
       <ul class="sectionContent">
         <template id="adminNav" is="dom-repeat" items="[[_filteredLinks]]">
           <li class$="sectionTitle [[_computeSelectedClass(item.view, params)]]">
@@ -73,7 +73,7 @@
     </template>
     <template is="dom-if" if="[[_showProjectMain]]" restamp="true">
       <main>
-        <gr-admin-project project="[[params.project]]"></gr-admin-project>
+        <gr-project project="[[params.project]]"></gr-project>
       </main>
     </template>
     <template is="dom-if" if="[[_showGroupList]]" restamp="true">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index 3be1a2b..059b6b4 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -105,7 +105,7 @@
         if (linkCopy.name === 'Projects' && this._project) {
           linkCopy.subsection = {
             name: `${this._project}`,
-            view: 'gr-admin-project',
+            view: 'gr-project',
             url: `/admin/projects/${this.encodeURL(this._project, true)}`,
             children: [{
               name: 'Branches',
@@ -141,7 +141,7 @@
     _paramsChanged(params) {
       this.set('_showCreateProject',
           params.adminView === 'gr-admin-create-project');
-      this.set('_showProjectMain', params.adminView === 'gr-admin-project');
+      this.set('_showProjectMain', params.adminView === 'gr-project');
       this.set('_showProjectList',
           params.adminView === 'gr-admin-project-list');
       this.set('_showProjectDetailList',
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index acb3ba4..1692323 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -180,10 +180,10 @@
         return Promise.resolve({_id: 1});
       });
       sandbox.stub(element, 'reload');
-      element.params = {project: 'Test Project', adminView: 'gr-admin-project'};
+      element.params = {project: 'Test Project', adminView: 'gr-project'};
       assert.equal(element.reload.callCount, 1);
       element.params = {project: 'Test Project 2',
-        adminView: 'gr-admin-project'};
+        adminView: 'gr-project'};
       assert.equal(element.reload.callCount, 2);
     });
   });
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.html b/polygerrit-ui/app/elements/admin/gr-project/gr-project.html
similarity index 64%
rename from polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.html
rename to polygerrit-ui/app/elements/admin/gr-project/gr-project.html
index e149594..45f87c7 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.html
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project.html
@@ -24,7 +24,7 @@
 <link rel="import" href="../../../styles/gr-form-styles.html">
 <link rel="import" href="../../../styles/shared-styles.html">
 
-<dom-module id="gr-admin-project">
+<dom-module id="gr-project">
   <template>
     <style include="shared-styles">
       main {
@@ -79,44 +79,44 @@
                 <section>
                   <span class="title">State</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="stateSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.state}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat" items=[[_states]]>
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.state}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat" items=[[_states]]>
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
                   <span class="title">Submit type</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="submitTypeSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.submit_type}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat" items="[[_submitTypes]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.submit_type}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat" items="[[_submitTypes]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
                   <span class="title">Allow content merges</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="contentMergeSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.use_content_merge.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat"
-                          items="[[_formatBooleanSelect(_projectConfig.use_content_merge)]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.use_content_merge.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.use_content_merge)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
@@ -124,47 +124,47 @@
                     Create a new change for every commit not in the target branch
                   </span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="newChangeSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.create_new_change_for_all_not_in_target.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat"
-                          items="[[_formatBooleanSelect(_projectConfig.create_new_change_for_all_not_in_target)]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.create_new_change_for_all_not_in_target.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.create_new_change_for_all_not_in_target)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
                   <span class="title">Require Change-Id in commit message</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="requireChangeIdSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.require_change_id.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat"
-                          items="[[_formatBooleanSelect(_projectConfig.require_change_id)]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.require_change_id.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.require_change_id)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
                   <span class="title">
                     Reject implicit merges when changes are pushed for review</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="rejectImplicitMergesSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.reject_implicit_merges.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat"
-                          items="[[_formatBooleanSelect(_projectConfig.reject_implicit_merges)]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
-                    </select>
+                        bind-value="{{_projectConfig.reject_implicit_merges.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.reject_implicit_merges)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
@@ -181,16 +181,16 @@
                 <section>
                   <span class="title">Match authored date with committer date upon submit</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="matchAuthoredDateWithCommitterDateSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.match_author_to_committer_date.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                      <template is="dom-repeat"
-                          items="[[_formatBooleanSelect(_projectConfig.match_author_to_committer_date)]]">
-                        <option value="[[item.value]]">[[item.label]]</option>
-                      </template>
+                        bind-value="{{_projectConfig.match_author_to_committer_date.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.match_author_to_committer_date)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
                     </select>
+                    </gr-select>
                   </span>
                 </section>
               </fieldset>
@@ -200,31 +200,31 @@
                   <span class="title">
                     Require a valid contributor agreement to upload</span>
                   <span class="value">
-                    <select
+                    <gr-select
                         id="contributorAgreementSelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.use_contributor_agreements.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                    <template is="dom-repeat"
-                        items="[[_formatBooleanSelect(_projectConfig.use_contributor_agreements)]]">
-                      <option value="[[item.value]]">[[item.label]]</option>
-                    </template>
-                    </select>
+                        bind-value="{{_projectConfig.use_contributor_agreements.configured_value}}">
+                    <select disabled$="[[_readOnly]]">
+                      <template is="dom-repeat"
+                          items="[[_formatBooleanSelect(_projectConfig.use_contributor_agreements)]]">
+                        <option value="[[item.value]]">[[item.label]]</option>
+                      </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
                 <section>
                   <span class="title">Require Signed-off-by in commit message</span>
                   <span class="value">
-                    <select
-                        id="useSignedOffBySelect"
-                        is="gr-select"
-                        bind-value="{{_projectConfig.use_signed_off_by.configured_value}}"
-                        disabled$="[[_readOnly]]">
-                    <template is="dom-repeat"
-                        items="[[_formatBooleanSelect(_projectConfig.use_signed_off_by)]]">
-                      <option value="[[item.value]]">[[item.label]]</option>
-                    </template>
-                    </select>
+                    <gr-select
+                          id="useSignedOffBySelect"
+                          bind-value="{{_projectConfig.use_signed_off_by.configured_value}}">
+                      <select disabled$="[[_readOnly]]">
+                        <template is="dom-repeat"
+                            items="[[_formatBooleanSelect(_projectConfig.use_signed_off_by)]]">
+                          <option value="[[item.value]]">[[item.label]]</option>
+                        </template>
+                      </select>
+                    </gr-select>
                   </span>
                 </section>
               </fieldset>
@@ -238,5 +238,5 @@
       </main>
     <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
   </template>
-  <script src="gr-admin-project.js"></script>
+  <script src="gr-project.js"></script>
 </dom-module>
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.js b/polygerrit-ui/app/elements/admin/gr-project/gr-project.js
similarity index 99%
rename from polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.js
rename to polygerrit-ui/app/elements/admin/gr-project/gr-project.js
index 3422f17..1b8c9bd 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project.js
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project.js
@@ -48,7 +48,7 @@
   };
 
   Polymer({
-    is: 'gr-admin-project',
+    is: 'gr-project',
 
     properties: {
       params: Object,
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project_test.html b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
similarity index 97%
rename from polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project_test.html
rename to polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
index e3b809d..fe5557a 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-project/gr-admin-project_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
@@ -16,23 +16,23 @@
 -->
 
 <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-admin-project</title>
+<title>gr-project</title>
 
 <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
 <script src="../../../bower_components/web-component-tester/browser.js"></script>
 <link rel="import" href="../../../test/common-test-setup.html"/>
-<link rel="import" href="gr-admin-project.html">
+<link rel="import" href="gr-project.html">
 
 <script>void(0);</script>
 
 <test-fixture id="basic">
   <template>
-    <gr-admin-project></gr-admin-project>
+    <gr-project></gr-project>
   </template>
 </test-fixture>
 
 <script>
-  suite('gr-admin-project tests', () => {
+  suite('gr-project tests', () => {
     let element;
     let sandbox;
     const PROJECT = 'test-project';
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index aba32b03..378cd7b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -405,27 +405,27 @@
           'gr-change-list-item');
       assert.equal(elementItems.length, 9);
 
-      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
+      MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
       assert.equal(element.selectedIndex, 1);
-      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
+      MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
 
       const showStub = sinon.stub(page, 'show');
       assert.equal(element.selectedIndex, 2);
-      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
+      MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
       assert(showStub.lastCall.calledWithExactly('/c/2/'),
           'Should navigate to /c/2/');
 
-      MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
+      MockInteractions.pressAndReleaseKeyOn(element, 75); // 'k'
       assert.equal(element.selectedIndex, 1);
-      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
+      MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
       assert(showStub.lastCall.calledWithExactly('/c/1/'),
           'Should navigate to /c/1/');
 
-      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
-      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
-      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
+      MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
+      MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
+      MockInteractions.pressAndReleaseKeyOn(element, 74); // 'j'
       assert.equal(element.selectedIndex, 4);
-      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
+      MockInteractions.pressAndReleaseKeyOn(element, 13); // 'enter'
       assert(showStub.lastCall.calledWithExactly('/c/4/'),
           'Should navigate to /c/4/');
       showStub.restore();
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
index 4e32116..3700603 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -369,7 +369,7 @@
 
         element.$.confirmCherrypick.branch = 'master';
         element._handleCherrypickConfirm();
-        assert.equal(fireActionStub.callCount, 0);  // Still needs a message.
+        assert.equal(fireActionStub.callCount, 0); // Still needs a message.
 
         // Add attributes that are used to determine the message.
         element.$.confirmCherrypick.commitMessage = 'foo message';
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 5b5ece6..e29027b 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -454,24 +454,25 @@
             <label class="patchSelectLabel" for="patchSetSelect">
               Patch set
             </label>
-            <select
-                is="gr-select"
+            <gr-select
                 id="patchSetSelect"
                 bind-value="{{_selectedPatchSet}}"
                 class="patchSetSelect"
                 on-change="_handlePatchChange">
-              <template is="dom-repeat" items="[[_allPatchSets]]"
-                  as="patchNum">
-                <option value$="[[patchNum.num]]"
-                    disabled$="[[_computePatchSetDisabled(patchNum.num, _patchRange.basePatchNum)]]">
-                  [[patchNum.num]]
-                  /
-                  [[computeLatestPatchNum(_allPatchSets)]]
-                  [[_computePatchSetCommentsString(_comments, patchNum.num)]]
-                  [[_computePatchSetDescription(_change, patchNum.num)]]
-                </option>
-              </template>
-            </select>
+              <select>
+                <template is="dom-repeat" items="[[_allPatchSets]]"
+                    as="patchNum">
+                  <option value$="[[patchNum.num]]"
+                      disabled$="[[_computePatchSetDisabled(patchNum.num, _patchRange.basePatchNum)]]">
+                    [[patchNum.num]]
+                    /
+                    [[computeLatestPatchNum(_allPatchSets)]]
+                    [[_computePatchSetCommentsString(_comments, patchNum.num)]]
+                    [[_computePatchSetDescription(_change, patchNum.num)]]
+                  </option>
+                </template>
+              </select>
+            </gr-select>
             /
             <gr-commit-info
                 change="[[_change]]"
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index dcbab09..5d7062d 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -522,7 +522,7 @@
       element.viewState.diffMode = 'UNIFIED';
       flushAsynchronousOperations();
 
-      const selectEl = element.$$('.patchInfo-header select');
+      const selectEl = element.$$('.patchInfo-header gr-select');
       assert.ok(selectEl);
       const optionEls = Polymer.dom(element.root).querySelectorAll(
           '.patchInfo-header option');
@@ -540,16 +540,16 @@
         if (numEvents == 1) {
           assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
               element._change, 1, 'PARENT'));
-          selectEl.value = '3';
-          element.fire('change', {}, {node: selectEl});
+          selectEl.nativeSelect.value = '3';
+          element.fire('change', {}, {node: selectEl.nativeSelect});
         } else if (numEvents == 2) {
           assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
               element._change, 3, 'PARENT'));
           done();
         }
       });
-      selectEl.value = '1';
-      element.fire('change', {}, {node: selectEl});
+      selectEl.nativeSelect.value = '1';
+      element.fire('change', {}, {node: selectEl.nativeSelect});
     });
 
     test('patch num change with missing current_revision', done => {
@@ -570,7 +570,7 @@
         labels: {},
       };
       flushAsynchronousOperations();
-      const selectEl = element.$$('.patchInfo-header select');
+      const selectEl = element.$$('.patchInfo-header gr-select');
       assert.ok(selectEl);
       const optionEls = Polymer.dom(element.root).querySelectorAll(
           '.patchInfo-header option');
@@ -589,16 +589,16 @@
         if (numEvents == 1) {
           assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
               element._change, 1, 'PARENT'));
-          selectEl.value = '3';
-          element.fire('change', {}, {node: selectEl});
+          selectEl.nativeSelect.value = '3';
+          element.fire('change', {}, {node: selectEl.nativeSelect});
         } else if (numEvents == 2) {
           assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
               element._change, 3, 'PARENT'));
           done();
         }
       });
-      selectEl.value = '1';
-      element.fire('change', {}, {node: selectEl});
+      selectEl.nativeSelect.value = '1';
+      element.fire('change', {}, {node: selectEl.nativeSelect});
     });
 
     test('don’t reload entire page when patchRange changes', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index fdfda26..53293e9 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -210,31 +210,34 @@
           </div>
         </template>
         <span class="separator">/</span>
-        <select
+        <gr-select
             id="modeSelect"
-            is="gr-select"
             bind-value="{{diffViewMode}}">
-          <option value="SIDE_BY_SIDE">Side By Side</option>
-          <option value="UNIFIED_DIFF">Unified</option>
-        </select>
+          <select>
+            <option value="SIDE_BY_SIDE">Side By Side</option>
+            <option value="UNIFIED_DIFF">Unified</option>
+          </select>
+        </gr-select>
         <span class="separator">/</span>
         <label>
           Diff against
-          <select id="patchChange" bind-value="{{_diffAgainst}}" is="gr-select"
+          <gr-select id="patchChange" bind-value="{{_diffAgainst}}"
               class="patchSetSelect" on-change="_handlePatchChange">
-            <option value="PARENT">Base</option>
-            <template
-                is="dom-repeat"
-                items="[[computeAllPatchSets(change)]]"
-                as="patchNum">
-              <option
-                  disabled$="[[_computePatchSetDisabled(patchNum.num, patchRange.patchNum)]]"
-                  value$="[[patchNum.num]]">
-                [[patchNum.num]]
-                [[patchNum.desc]]
-              </option>
-            </template>
-          </select>
+            <select>
+              <option value="PARENT">Base</option>
+              <template
+                  is="dom-repeat"
+                  items="[[computeAllPatchSets(change)]]"
+                  as="patchNum">
+                <option
+                    disabled$="[[_computePatchSetDisabled(patchNum.num, patchRange.patchNum)]]"
+                    value$="[[patchNum.num]]">
+                  [[patchNum.num]]
+                  [[patchNum.desc]]
+                </option>
+              </template>
+            </select>
+          </gr-select>
         </label>
       </div>
     </header>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index 7cd96e6..2aab92e 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -648,17 +648,17 @@
       };
       flush(() => {
         const selectEl = element.$.patchChange;
-        assert.equal(selectEl.value, 'PARENT');
+        assert.equal(selectEl.nativeSelect.value, 'PARENT');
         assert.isTrue(element.$$('option[value="3"]').hasAttribute('disabled'));
         selectEl.addEventListener('change', () => {
-          assert.equal(selectEl.value, '2');
+          assert.equal(selectEl.nativeSelect.value, '2');
           assert(navStub.lastCall.calledWithExactly(element.change, '3', '2'),
               'Should navigate to /c/42/2..3');
           navStub.restore();
           done();
         });
-        selectEl.value = '2';
-        element.fire('change', {}, {node: selectEl});
+        selectEl.nativeSelect.value = '2';
+        element.fire('change', {}, {node: selectEl.nativeSelect});
       });
     });
 
@@ -729,12 +729,12 @@
       flushAsynchronousOperations();
 
       // At this point the diff mode doesn't yet have the user's preference.
-      assert.equal(select.value, 'SIDE_BY_SIDE');
+      assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
 
       // Receive the overriding preference.
       resolvePrefs({default_diff_view: 'UNIFIED'});
       flushAsynchronousOperations();
-      assert.equal(select.value, 'SIDE_BY_SIDE');
+      assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
       document.getElementById('blank').restore();
     });
 
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 2e3d30c..0ee7914 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -276,7 +276,7 @@
       app.params = {
         view: 'gr-admin-view',
         project: data.params[0],
-        adminView: 'gr-admin-project',
+        adminView: 'gr-project',
       };
     });
 
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
index 3cb1a39..d01f838 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.js
@@ -131,7 +131,7 @@
       if (groupStartLine === 0) { // Line was removed or added.
         groupStartLine = groupEndLine;
       }
-      if (groupEndLine === 0) {  // Line was removed or added.
+      if (groupEndLine === 0) { // Line was removed or added.
         groupEndLine = groupStartLine;
       }
       if (startLine <= groupEndLine && endLine >= groupStartLine) {
@@ -474,7 +474,7 @@
              html.charCodeAt(index) !== GrDiffBuilder.GREATER_THAN_CODE) {
         index++;
       }
-      index++;  // skip the ">" itself
+      index++; // skip the ">" itself
     }
     // An HTML entity (e.g., &lt;) counts as one character.
     if (index < html.length &&
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
index 15d5464..dcba80d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
@@ -95,7 +95,7 @@
         value: false,
       },
 
-      _xhrPromise: Object,  // Used for testing.
+      _xhrPromise: Object, // Used for testing.
       _messageText: {
         type: String,
         value: '',
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
index c4d1273..bdbf4f9 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
@@ -501,7 +501,7 @@
       element._messageText = 'is that the horse from horsing around??';
       MockInteractions.pressAndReleaseKeyOn(
           element.$.editTextarea.$.textarea.textarea,
-          83, 'ctrl');  // 'ctrl + s'
+          83, 'ctrl'); // 'ctrl + s'
     });
 
     test('draft saving/editing', done => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
index 5056927..627806c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
@@ -272,14 +272,15 @@
           </span>
         </div>
         <div>
-          <select
+          <gr-select
               id="modeSelect"
-              is="gr-select"
               bind-value="{{changeViewState.diffMode}}"
               hidden$="[[_computeModeSelectHidden(_isImageDiff)]]">
-            <option value="SIDE_BY_SIDE">Side By Side</option>
-            <option value="UNIFIED_DIFF">Unified</option>
-          </select>
+            <select>
+              <option value="SIDE_BY_SIDE">Side By Side</option>
+              <option value="UNIFIED_DIFF">Unified</option>
+            </select>
+          </gr-select>
           <span id="diffPrefsContainer"
               hidden$="[[_computePrefsButtonHidden(_prefs, _loggedIn)]]" hidden>
             <span class="preferences desktop">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index 0a7ed28..c9bd1f8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -510,21 +510,21 @@
       element._userPrefs = {default_diff_view: 'SIDE_BY_SIDE'};
 
       // The mode selected in the view state reflects the selected option.
-      assert.equal(element._getDiffViewMode(), select.value);
+      assert.equal(element._getDiffViewMode(), select.nativeSelect.value);
 
       // The mode selected in the view state reflects the view rednered in the
       // diff.
-      assert.equal(select.value, diffDisplay.viewMode);
+      assert.equal(select.nativeSelect.value, diffDisplay.viewMode);
 
       // We will simulate a user change of the selected mode.
       const newMode = 'UNIFIED_DIFF';
       // Set the actual value of the select, and simulate the change event.
-      select.value = newMode;
-      element.fire('change', {}, {node: select});
+      select.nativeSelect.value = newMode;
+      element.fire('change', {}, {node: select.nativeSelect});
 
       // Make sure the handler was called and the state is still coherent.
       assert.equal(element._getDiffViewMode(), newMode);
-      assert.equal(element._getDiffViewMode(), select.value);
+      assert.equal(element._getDiffViewMode(), select.nativeSelect.value);
       assert.equal(element._getDiffViewMode(), diffDisplay.viewMode);
     });
 
@@ -542,12 +542,12 @@
       flushAsynchronousOperations();
 
       // At this point the diff mode doesn't yet have the user's preference.
-      assert.equal(select.value, 'SIDE_BY_SIDE');
+      assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
 
       // Receive the overriding preference.
       resolvePrefs({default_diff_view: 'UNIFIED'});
       flushAsynchronousOperations();
-      assert.equal(select.value, 'SIDE_BY_SIDE');
+      assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');
     });
 
     test('_loadHash', () => {
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
index b74cbe2..636bfcd 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
@@ -42,17 +42,19 @@
     </style>
     Patch set:
     <span class="patchRange">
-      <select id="leftPatchSelect" bind-value="{{_leftSelected}}"
-          on-change="_handlePatchChange" is="gr-select">
-        <option value="PARENT">Base</option>
-        <template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
-          <option value$="[[patchNum]]"
-              disabled$="[[_computeLeftDisabled(patchNum, patchRange)]]">
-            [[patchNum]]
-            [[_computePatchSetDescription(revisions, patchNum)]]
-          </option>
-        </template>
-      </select>
+      <gr-select id="leftPatchSelect" bind-value="{{_leftSelected}}"
+          on-change="_handlePatchChange">
+        <select>
+          <option value="PARENT">Base</option>
+          <template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
+            <option value$="[[patchNum]]"
+                disabled$="[[_computeLeftDisabled(patchNum, patchRange)]]">
+              [[patchNum]]
+              [[_computePatchSetDescription(revisions, patchNum)]]
+            </option>
+          </template>
+        </select>
+      </gr-select>
     </span>
     <span is="dom-if" if="[[filesWeblinks.meta_a]]" class="filesWeblinks">
       <template is="dom-repeat" items="[[filesWeblinks.meta_a]]" as="weblink">
@@ -62,16 +64,18 @@
     </span>
     &rarr;
     <span class="patchRange">
-      <select id="rightPatchSelect" bind-value="{{_rightSelected}}"
-          on-change="_handlePatchChange" is="gr-select">
-        <template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
-          <option value$="[[patchNum]]"
-              disabled$="[[_computeRightDisabled(patchNum, patchRange)]]">
-            [[patchNum]]
-            [[_computePatchSetDescription(revisions, patchNum)]]
-          </option>
-        </template>
-      </select>
+      <gr-select id="rightPatchSelect" bind-value="{{_rightSelected}}"
+          on-change="_handlePatchChange">
+        <select>
+          <template is="dom-repeat" items="{{availablePatches}}" as="patchNum">
+            <option value$="[[patchNum]]"
+                disabled$="[[_computeRightDisabled(patchNum, patchRange)]]">
+              [[patchNum]]
+              [[_computePatchSetDescription(revisions, patchNum)]]
+            </option>
+          </template>
+        </select>
+      </gr-select>
       <span is="dom-if" if="[[filesWeblinks.meta_b]]" class="filesWeblinks">
         <template is="dom-repeat" items="[[filesWeblinks.meta_b]]" as="weblink">
           <a target="_blank"
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
index 162936c..abe3e5d 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
@@ -82,7 +82,7 @@
           assert(showStub.lastCall.calledWithExactly(
               '/c/42/3/path/to/file.txt'),
               'Should navigate to /c/42/3/path/to/file.txt');
-          leftSelectEl.value = '1';
+          leftSelectEl.nativeSelect.value = '1';
           element.fire('change', {}, {node: leftSelectEl});
           assert(blurSpy.called, 'Dropdown should be blurred after selection');
         } else if (numEvents == 2) {
@@ -93,8 +93,8 @@
           done();
         }
       });
-      leftSelectEl.value = 'PARENT';
-      rightSelectEl.value = '3';
+      leftSelectEl.nativeSelect.value = 'PARENT';
+      rightSelectEl.nativeSelect.value = '3';
       element.fire('change', {}, {node: leftSelectEl});
     });
 
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
index eeac221..34f0b16 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
@@ -69,16 +69,14 @@
         </section>
         <section>
           <div class="title">Preferred Email</div>
-          <select
-              is="gr-select"
-              id="email"
-              bind-value="{{_account.email}}"
-              disabled="[[_saving]]">
-            <option value="[[_account.email]]">[[_account.email]]</option>
-            <template is="dom-repeat" items="[[_account.secondary_emails]]">
-              <option value="[[item]]">[[item]]</option>
-            </template>
-          </select>
+          <gr-select id="email">
+            <select disabled="[[_saving]]">
+              <option value="[[_account.email]]">[[_account.email]]</option>
+              <template is="dom-repeat" items="[[_account.secondary_emails]]">
+                <option value="[[item]]">[[item]]</option>
+              </template>
+            </select>
+          </gr-select>
         </section>
       </main>
       <footer>
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
index b3ea3fa..bf8995e 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
@@ -139,7 +139,7 @@
     test('pressing enter saves name', done => {
       element.$.name.value = 'entered name';
       save(() => {
-        MockInteractions.pressAndReleaseKeyOn(element.$.name, 13);  // 'enter'
+        MockInteractions.pressAndReleaseKeyOn(element.$.name, 13); // 'enter'
       }).then(() => {
         assert.equal(account.name, 'entered name');
       }).then(done);
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
index ca2feb1..8679f98 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
@@ -90,68 +90,74 @@
           <section>
             <span class="title">Changes per page</span>
             <span class="value">
-              <select
-                  is="gr-select"
+              <gr-select
                   bind-value="{{_localPrefs.changes_per_page}}">
-                <option value="10">10 rows per page</option>
-                <option value="25">25 rows per page</option>
-                <option value="50">50 rows per page</option>
-                <option value="100">100 rows per page</option>
-              </select>
+                <select>
+                  <option value="10">10 rows per page</option>
+                  <option value="25">25 rows per page</option>
+                  <option value="50">50 rows per page</option>
+                  <option value="100">100 rows per page</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section>
             <span class="title">Date/time format</span>
             <span class="value">
-              <select
-                  is="gr-select"
+              <gr-select
                   bind-value="{{_localPrefs.date_format}}">
-                <option value="STD">Jun 3 ; Jun 3, 2016</option>
-                <option value="US">06/03 ; 06/03/16</option>
-                <option value="ISO">06-03 ; 2016-06-03</option>
-                <option value="EURO">3. Jun ; 03.06.2016</option>
-                <option value="UK">03/06 ; 03/06/2016</option>
-              </select>
-              <select
-                  is="gr-select"
+                <select>
+                  <option value="STD">Jun 3 ; Jun 3, 2016</option>
+                  <option value="US">06/03 ; 06/03/16</option>
+                  <option value="ISO">06-03 ; 2016-06-03</option>
+                  <option value="EURO">3. Jun ; 03.06.2016</option>
+                  <option value="UK">03/06 ; 03/06/2016</option>
+                </select>
+              </gr-select>
+              <gr-select
                   bind-value="{{_localPrefs.time_format}}">
-                <option value="HHMM_12">4:10 PM</option>
-                <option value="HHMM_24">16:10</option>
-              </select>
+                <select>
+                  <option value="HHMM_12">4:10 PM</option>
+                  <option value="HHMM_24">16:10</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section>
             <span class="title">Email notifications</span>
             <span class="value">
-              <select
-                  is="gr-select"
+              <gr-select
                   bind-value="{{_localPrefs.email_strategy}}">
-                <option value="CC_ON_OWN_COMMENTS">Every comment</option>
-                <option value="ENABLED">Only comments left by others</option>
-                <option value="DISABLED">None</option>
-              </select>
+                <select>
+                  <option value="CC_ON_OWN_COMMENTS">Every comment</option>
+                  <option value="ENABLED">Only comments left by others</option>
+                  <option value="DISABLED">None</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section hidden$="[[!_localPrefs.email_format]]">
             <span class="title">Email format</span>
             <span class="value">
-              <select
-                  is="gr-select"
+              <gr-select
                   bind-value="{{_localPrefs.email_format}}">
-                <option value="HTML_PLAINTEXT">HTML and plaintext</option>
-                <option value="PLAINTEXT">Plaintext only</option>
-              </select>
+                <select>
+                  <option value="HTML_PLAINTEXT">HTML and plaintext</option>
+                  <option value="PLAINTEXT">Plaintext only</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section>
             <span class="title">Diff view</span>
             <span class="value">
-              <select
-                  is="gr-select"
+              <gr-select
                   bind-value="{{_localPrefs.diff_view}}">
-                <option value="SIDE_BY_SIDE">Side by side</option>
-                <option value="UNIFIED_DIFF">Unified diff</option>
-              </select>
+                <select>
+                  <option value="SIDE_BY_SIDE">Side by side</option>
+                  <option value="UNIFIED_DIFF">Unified diff</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section>
@@ -188,17 +194,17 @@
           <section>
             <span class="title">Context</span>
             <span class="value">
-              <select
-                  is="gr-select"
-                  bind-value="{{_diffPrefs.context}}">
-                <option value="3">3 lines</option>
-                <option value="10">10 lines</option>
-                <option value="25">25 lines</option>
-                <option value="50">50 lines</option>
-                <option value="75">75 lines</option>
-                <option value="100">100 lines</option>
-                <option value="-1">Whole file</option>
-              </select>
+              <gr-select bind-value="{{_diffPrefs.context}}">
+                <select>
+                  <option value="3">3 lines</option>
+                  <option value="10">10 lines</option>
+                  <option value="25">25 lines</option>
+                  <option value="50">50 lines</option>
+                  <option value="75">75 lines</option>
+                  <option value="100">100 lines</option>
+                  <option value="-1">Whole file</option>
+                </select>
+              </gr-select>
             </span>
           </section>
           <section>
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
index 0e5ff04..f3c3767 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
@@ -23,7 +23,7 @@
         notify: true,
       },
 
-      _xhrPromise: Object,  // Used for testing.
+      _xhrPromise: Object, // Used for testing.
     },
 
     _computeStarClass(starred) {
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
index 70a9bf5..bcc764b 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
@@ -36,11 +36,11 @@
     properties: {
       _elements: {
         type: Object,
-        value: {},  // Shared across all instances.
+        value: {}, // Shared across all instances.
       },
       _eventCallbacks: {
         type: Object,
-        value: {},  // Shared across all instances.
+        value: {}, // Shared across all instances.
       },
     },
 
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index b710cfa..48a2a53 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -52,15 +52,15 @@
     properties: {
       _cache: {
         type: Object,
-        value: {},  // Intentional to share the object across instances.
+        value: {}, // Intentional to share the object across instances.
       },
       _sharedFetchPromises: {
         type: Object,
-        value: {},  // Intentional to share the object across instances.
+        value: {}, // Intentional to share the object across instances.
       },
       _pendingRequests: {
         type: Object,
-        value: {},  // Intentional to share the object across instances.
+        value: {}, // Intentional to share the object across instances.
       },
     },
 
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select.html b/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
index fed81bb..b0b6ea9 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
@@ -16,5 +16,6 @@
 
 <link rel="import" href="../../../bower_components/polymer/polymer.html">
 <dom-module id="gr-select">
+  <content></content>
   <script src="gr-select.js"></script>
 </dom-module>
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
index 09787cb..a8b8eef 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
@@ -16,7 +16,6 @@
 
   Polymer({
     is: 'gr-select',
-    extends: 'select',
     properties: {
       bindValue: {
         type: String,
@@ -30,19 +29,23 @@
       'dom-change': '_updateValue',
     },
 
+    get nativeSelect() {
+      return this.$$('select');
+    },
+
     _updateValue() {
       if (this.bindValue) {
-        this.value = this.bindValue;
+        this.nativeSelect.value = this.bindValue;
       }
     },
 
     _valueChanged() {
-      this.bindValue = this.value;
+      this.bindValue = this.nativeSelect.value;
     },
 
     ready() {
       // If not set via the property, set bind-value to the element value.
-      if (!this.bindValue) { this.bindValue = this.value; }
+      if (!this.bindValue) { this.bindValue = this.nativeSelect.value; }
     },
   });
 })();
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
index fa8a54c..e7a4965 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
@@ -27,11 +27,13 @@
 
 <test-fixture id="basic">
   <template>
-    <select is="gr-select">
-      <option value="1">One</option>
-      <option value="2">Two</option>
-      <option value="3">Three</option>
-    </select>
+    <gr-select>
+      <select>
+        <option value="1">One</option>
+        <option value="2">Two</option>
+        <option value="3">Three</option>
+      </select>
+    </gr-select>
   </template>
 </test-fixture>
 
@@ -48,7 +50,7 @@
       element.addEventListener('bind-value-changed', changeStub);
 
       // The selected element should be the first one by default.
-      assert.equal(element.value, '1');
+      assert.equal(element.nativeSelect.value, '1');
       assert.equal(element.bindValue, '1');
       assert.isFalse(changeStub.called);
 
@@ -56,7 +58,7 @@
       element.bindValue = '2';
 
       // It should be updated.
-      assert.equal(element.value, '2');
+      assert.equal(element.nativeSelect.value, '2');
       assert.equal(element.bindValue, '2');
       assert.isTrue(changeStub.called);
     });
@@ -66,16 +68,16 @@
       element.addEventListener('bind-value-changed', changeStub);
 
       // The selected element should be the first one by default.
-      assert.equal(element.value, '1');
+      assert.equal(element.nativeSelect.value, '1');
       assert.equal(element.bindValue, '1');
       assert.isFalse(changeStub.called);
 
       // Now change the value.
-      element.value = '3';
+      element.nativeSelect.value = '3';
       element.fire('change');
 
       // It should be updated.
-      assert.equal(element.value, '3');
+      assert.equal(element.nativeSelect.value, '3');
       assert.equal(element.bindValue, '3');
       assert.isTrue(changeStub.called);
     });
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index 1f51774..4ca8016 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -33,9 +33,9 @@
     'admin/gr-admin-create-project/gr-admin-create-project_test.html',
     'admin/gr-admin-group-list/gr-admin-group-list_test.html',
     'admin/gr-admin-plugin-list/gr-admin-plugin-list_test.html',
-    'admin/gr-admin-project/gr-admin-project_test.html',
     'admin/gr-admin-project-list/gr-admin-project-list_test.html',
     'admin/gr-admin-view/gr-admin-view_test.html',
+    'admin/gr-project/gr-project_test.html',
     'admin/gr-project-detail-list/gr-project-detail-list_test.html',
     'change-list/gr-change-list-item/gr-change-list-item_test.html',
     'change-list/gr-change-list-view/gr-change-list-view_test.html',