Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/static_src/autolink.js b/static_src/autolink.js
index 5419d9c..d7ac843 100644
--- a/static_src/autolink.js
+++ b/static_src/autolink.js
@@ -1,9 +1,10 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 'use strict';
 import {prpcClient} from 'prpc-client-instance.js';
+import {generateProjectIssueURL} from 'shared/helpers.js'
 
 /* eslint-disable max-len */
 // When crbug links don't specify a project, the default project is Chromium.
@@ -325,10 +326,12 @@
 // Create custom textrun functions.
 function createIssueRefRun(projectName, localId, summary, isClosed, content,
     commentId) {
+  const params = {'id': localId};
+  const href = generateProjectIssueURL(projectName, '/detail', params)
   return {
     tag: 'a',
     css: isClosed ? 'strike-through' : '',
-    href: `/p/${projectName}/issues/detail?id=${localId}${commentId}`,
+    href: href + commentId,
     title: summary || '',
     content: content,
   };
diff --git a/static_src/elements/chdir/mr-activity-table/mr-activity-table.js b/static_src/elements/chdir/mr-activity-table/mr-activity-table.js
index a0f4715..fed9acd 100644
--- a/static_src/elements/chdir/mr-activity-table/mr-activity-table.js
+++ b/static_src/elements/chdir/mr-activity-table/mr-activity-table.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-activity-table/mr-activity-table.test.js b/static_src/elements/chdir/mr-activity-table/mr-activity-table.test.js
index 0eb9d30..7476a13 100644
--- a/static_src/elements/chdir/mr-activity-table/mr-activity-table.test.js
+++ b/static_src/elements/chdir/mr-activity-table/mr-activity-table.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-activity-table/mr-day-icon.js b/static_src/elements/chdir/mr-activity-table/mr-day-icon.js
index 82f62b3..98f30e9 100644
--- a/static_src/elements/chdir/mr-activity-table/mr-day-icon.js
+++ b/static_src/elements/chdir/mr-activity-table/mr-day-icon.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-activity-table/mr-day-icon.test.js b/static_src/elements/chdir/mr-activity-table/mr-day-icon.test.js
index 3c35a10..a813d64 100644
--- a/static_src/elements/chdir/mr-activity-table/mr-day-icon.test.js
+++ b/static_src/elements/chdir/mr-activity-table/mr-day-icon.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-comment-table/mr-comment-table.js b/static_src/elements/chdir/mr-comment-table/mr-comment-table.js
index a6d0f19..5fe2e2e 100644
--- a/static_src/elements/chdir/mr-comment-table/mr-comment-table.js
+++ b/static_src/elements/chdir/mr-comment-table/mr-comment-table.js
@@ -1,11 +1,11 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 import {LitElement, html, css} from 'lit-element';
 import 'elements/framework/mr-comment-content/mr-comment-content.js';
 import 'elements/chops/chops-timestamp/chops-timestamp.js';
-
+import {generateProjectIssueURL} from 'shared/helpers.js';
 /**
  * `<mr-comment-table>`
  *
@@ -51,6 +51,7 @@
   /** @override */
   render() {
     const comments = this._displayedComments(this.selectedDate, this.comments);
+    const params = {'id': comments.localId};
     // TODO(zhangtiff): render deltas for comment changes.
     return html`
       <table cellspacing="0" cellpadding="0">
@@ -77,7 +78,7 @@
                 ></mr-comment-content>
               </td>
               <td class="no-wrap">
-                <a href="/p/${comment.projectName}/issues/detail?id=${comment.localId}">
+                <a href="${generateProjectIssueURL(comment.projectName, '/detail', params)}">
                   Issue ${comment.localId}
                 </a>
               </td>
diff --git a/static_src/elements/chdir/mr-comment-table/mr-comment-table.test.js b/static_src/elements/chdir/mr-comment-table/mr-comment-table.test.js
index 6925dc4..ef7906a 100644
--- a/static_src/elements/chdir/mr-comment-table/mr-comment-table.test.js
+++ b/static_src/elements/chdir/mr-comment-table/mr-comment-table.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-profile-page/mr-profile-page.js b/static_src/elements/chdir/mr-profile-page/mr-profile-page.js
index 5fadff6..326f2f2 100644
--- a/static_src/elements/chdir/mr-profile-page/mr-profile-page.js
+++ b/static_src/elements/chdir/mr-profile-page/mr-profile-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chdir/mr-profile-page/mr-profile-page.test.js b/static_src/elements/chdir/mr-profile-page/mr-profile-page.test.js
index c967704..ef1060c 100644
--- a/static_src/elements/chdir/mr-profile-page/mr-profile-page.test.js
+++ b/static_src/elements/chdir/mr-profile-page/mr-profile-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-announcement/chops-announcement.js b/static_src/elements/chops/chops-announcement/chops-announcement.js
index 477e7d2..5d5a9d6 100644
--- a/static_src/elements/chops/chops-announcement/chops-announcement.js
+++ b/static_src/elements/chops/chops-announcement/chops-announcement.js
@@ -1,8 +1,13 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {LitElement, html, css} from 'lit-element';
+import { LitElement, html, css } from 'lit-element';
+import 'elements/framework/mr-comment-content/mr-comment-content.js';
+
+import { connectStore } from 'reducers/base.js';
+import * as projectV0 from 'reducers/projectV0.js';
+import * as userV0 from 'reducers/userV0.js';
 
 // URL where announcements are fetched from.
 const ANNOUNCEMENT_SERVICE =
@@ -20,9 +25,25 @@
 export const REFRESH_TIME_MS = 5 * 60 * 1000;
 
 /**
+ * @type {Array<Announcement>} A list of hardcodded announcements for Monorail.
+ */
+export const HARDCODED_ANNOUNCEMENTS = [{
+  "messageContent": "The Chromium project will be migrating to Buganizer on " +
+    " February 5  (go/chrome-buganizer). Please test your workflows for this " +
+    "transition with these instructions: go/cob-buv-quick-start",
+  "projects": ["chromium"],
+  "groups": ["everyone@google.com", "googlers@chromium.org"],
+}];
+
+/**
  * @typedef {Object} Announcement
- * @property {string} id
+ * @property {string=} id
  * @property {string} messageContent
+ * @property {Array<string>=} projects Monorail extension for hard-coded
+ *    announcements. Specifies the names of projects the announcement will
+ *    occur in.
+ * @property {Array<string>=} groups Monorail extension for hard-coded
+ *    announcements. Specifies email groups the announces will show up in.
  */
 
 /**
@@ -36,7 +57,7 @@
  *
  * @customElement chops-announcement
  */
-export class ChopsAnnouncement extends LitElement {
+class _ChopsAnnouncement extends LitElement {
   /** @override */
   static get styles() {
     return css`
@@ -44,7 +65,7 @@
         display: block;
         width: 100%;
       }
-      p {
+      mr-comment-content {
         display: block;
         color: #222;
         font-size: 13px;
@@ -65,17 +86,29 @@
       return html`<p><strong>Error: </strong>${this._error}</p>`;
     }
     return html`
-      ${this._announcements.map(
-      ({messageContent}) => html`<p>${messageContent}</p>`)}
+      ${this._processedAnnouncements().map(
+      ({ messageContent }) => html`
+          <mr-comment-content
+            .content=${messageContent}>
+          </mr-comment-content>`)}
     `;
   }
 
   /** @override */
   static get properties() {
     return {
-      service: {type: String},
-      _error: {type: String},
-      _announcements: {type: Array},
+      service: { type: String },
+      additionalAnnouncements: { type: Array },
+
+      // Properties from the currently logged in user, usually feched through
+      // Redux.
+      currentUserName: { type: String },
+      userGroups: { type: Array },
+      currentProject: { type: String },
+
+      // Private properties managing state from requests to Chops Dash.
+      _error: { type: String },
+      _announcements: { type: Array },
     };
   }
 
@@ -85,6 +118,13 @@
 
     /** @type {string} */
     this.service = undefined;
+    /** @type {Array<Announcement>} */
+    this.additionalAnnouncements = HARDCODED_ANNOUNCEMENTS;
+
+    this.currentUserName = '';
+    this.userGroups = [];
+    this.currentProject = '';
+
     /** @type {string} */
     this._error = undefined;
     /** @type {Array<Announcement>} */
@@ -135,12 +175,12 @@
    */
   async refresh() {
     try {
-      const {announcements = []} = await this.fetch(this.service);
+      const { announcements = [] } = await this.fetch(this.service);
       this._error = undefined;
       this._announcements = announcements;
     } catch (e) {
       this._error = e.message;
-      this._announcements = [];
+      this._announcements = HARDCODED_ANNOUNCEMENTS;
     }
   }
 
@@ -176,6 +216,64 @@
 
     return JSON.parse(text.substr(XSSI_PREFIX.length));
   }
+
+  _processedAnnouncements() {
+    const announcements = [...this.additionalAnnouncements, ...this._announcements];
+
+    // Only show announcements relevant to the project the user is viewing and
+    // the group the user is part of, if applicable.
+    return announcements.filter(({ groups, projects }) => {
+      if (groups && groups.length && !this._isUserInGroups(groups,
+        this.userGroups, this.currentUserName)) {
+        return false;
+      }
+      if (projects && projects.length && !this._isViewingProject(projects,
+        this.currentProject)) {
+        return false;
+      }
+      return true;
+    });
+  }
+
+  /**
+   * Helper to check if the user is a member of the allowed groups.
+   * @param {Array<string>} allowedGroups
+   * @param {Array<{{userId: string, displayName: string}}>} userGroups
+   * @param {string} userEmail
+   */
+  _isUserInGroups(allowedGroups, userGroups, userEmail) {
+    const userGroupSet = new Set(userGroups.map(
+        ({ displayName }) => displayName.toLowerCase()));
+    return allowedGroups.find((group) => {
+      group = group.toLowerCase();
+
+      // Handle custom groups in Monorail like everyone@google.com
+      if (group.startsWith('everyone@')) {
+        let [_, suffix] = group.split('@');
+        suffix = '@' + suffix;
+        return userEmail.endsWith(suffix);
+      }
+
+      return userGroupSet.has(group);
+    });
+  }
+
+  _isViewingProject(projects, currentProject) {
+    return projects.find((project = "") => project.toLowerCase() === currentProject.toLowerCase());
+  }
 }
 
+/** Redux-connected version of _ChopsAnnouncement. */
+export class ChopsAnnouncement extends connectStore(_ChopsAnnouncement) {
+  /** @override */
+  stateChanged(state) {
+    const { displayName, groups } = userV0.currentUser(state);
+    this.currentUserName = displayName;
+    this.userGroups = groups;
+
+    this.currentProject = projectV0.viewedProjectName(state);
+  }
+}
+
+customElements.define('chops-announcement-base', _ChopsAnnouncement);
 customElements.define('chops-announcement', ChopsAnnouncement);
diff --git a/static_src/elements/chops/chops-announcement/chops-announcement.test.js b/static_src/elements/chops/chops-announcement/chops-announcement.test.js
index fa9643f..bed36f5 100644
--- a/static_src/elements/chops/chops-announcement/chops-announcement.test.js
+++ b/static_src/elements/chops/chops-announcement/chops-announcement.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
@@ -9,11 +9,22 @@
 let element;
 let clock;
 
+function assertRendersMessage(message) {
+  const messageContainer = element.shadowRoot.querySelector('mr-comment-content');
+  assert.include(messageContainer.content, message);
+}
+
+function assertDoesNotRender() {
+  assert.equal(0, element.shadowRoot.children.length);
+}
+
 describe('chops-announcement', () => {
   beforeEach(() => {
-    element = document.createElement('chops-announcement');
+    element = document.createElement('chops-announcement-base');
     document.body.appendChild(element);
 
+    element.additionalAnnouncements = [];
+
     clock = sinon.useFakeTimers({
       now: new Date(0),
       shouldAdvanceTime: false,
@@ -32,10 +43,6 @@
     window.fetch.restore();
   });
 
-  it('initializes', () => {
-    assert.instanceOf(element, ChopsAnnouncement);
-  });
-
   it('does not request announcements when no service specified', async () => {
     sinon.stub(element, 'fetch');
 
@@ -139,7 +146,8 @@
 
     assert.deepEqual(element._announcements,
         [{id: '1234', messageContent: 'test thing'}]);
-    assert.include(element.shadowRoot.textContent, 'test thing');
+
+    assertRendersMessage('test thing');
   });
 
   it('renders empty on empty announcement', async () => {
@@ -154,7 +162,7 @@
     await element.updateComplete;
 
     assert.deepEqual(element._announcements, []);
-    assert.equal(0, element.shadowRoot.children.length);
+    assertDoesNotRender()
   });
 
   it('fetch returns response data', async () => {
@@ -191,4 +199,85 @@
           'Something went wrong while fetching announcements');
     }
   });
+
+  describe('additional announcement handlings', () => {
+    beforeEach(() => {
+      sinon.stub(element, 'fetch');
+      element.fetch.returns({});
+      element.service = 'monorail';
+    });
+
+    it('renders additional announcement', async () => {
+      element.additionalAnnouncements = [{'messageContent': 'test thing'}];
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('renders when user is in group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['hello@group.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@group.com"}];
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not render when user is not in group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['hello@group.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@othergroup.com"}];
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+
+    it('renders when user is in everyone@ group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['everyone@world.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@group.com"}];
+      element.currentUserName = "hello@world.com";
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not renders when user is not in everyone@ group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['everyone@word.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@world.com"}];
+      element.currentUserName = "hello@world.com";
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+
+    it('renders when viewing referenced project', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'projects': ['chromium']}];
+      element.currentProject = 'chromium';
+
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not render when not viewing referenced project', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'projects': ['chromium']}];
+      element.currentProject = 'chrome';
+
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+  });
 });
diff --git a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
index dab8f85..974cadd 100644
--- a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
+++ b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
index e470312..75df329 100644
--- a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
+++ b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-button/chops-button.js b/static_src/elements/chops/chops-button/chops-button.js
index 2139e22..0172d27 100644
--- a/static_src/elements/chops/chops-button/chops-button.js
+++ b/static_src/elements/chops/chops-button/chops-button.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-button/chops-button.test.js b/static_src/elements/chops/chops-button/chops-button.test.js
index 4487564..56ddea7 100644
--- a/static_src/elements/chops/chops-button/chops-button.test.js
+++ b/static_src/elements/chops/chops-button/chops-button.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-checkbox/chops-checkbox.js b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
index d752347..b8be2ee 100644
--- a/static_src/elements/chops/chops-checkbox/chops-checkbox.js
+++ b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js b/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
index 5a11111..12e50be 100644
--- a/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
+++ b/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-chip/chops-chip.js b/static_src/elements/chops/chops-chip/chops-chip.js
index ce8319e..b99c8f3 100644
--- a/static_src/elements/chops/chops-chip/chops-chip.js
+++ b/static_src/elements/chops/chops-chip/chops-chip.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-chip/chops-chip.test.js b/static_src/elements/chops/chops-chip/chops-chip.test.js
index 843000b..ce012b4 100644
--- a/static_src/elements/chops/chops-chip/chops-chip.test.js
+++ b/static_src/elements/chops/chops-chip/chops-chip.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
index e300588..4176489 100644
--- a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
+++ b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
index e529735..58407f1 100644
--- a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
+++ b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/chops/chops-collapse/chops-collapse.js b/static_src/elements/chops/chops-collapse/chops-collapse.js
index 0df3e21..de71d7e 100644
--- a/static_src/elements/chops/chops-collapse/chops-collapse.js
+++ b/static_src/elements/chops/chops-collapse/chops-collapse.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-collapse/chops-collapse.test.js b/static_src/elements/chops/chops-collapse/chops-collapse.test.js
index 7058b65..80dcd8e 100644
--- a/static_src/elements/chops/chops-collapse/chops-collapse.test.js
+++ b/static_src/elements/chops/chops-collapse/chops-collapse.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-dialog/chops-dialog.js b/static_src/elements/chops/chops-dialog/chops-dialog.js
index 0d40aa2..0f4e488 100644
--- a/static_src/elements/chops/chops-dialog/chops-dialog.js
+++ b/static_src/elements/chops/chops-dialog/chops-dialog.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-dialog/chops-dialog.test.js b/static_src/elements/chops/chops-dialog/chops-dialog.test.js
index 376496a..c8f75e8 100644
--- a/static_src/elements/chops/chops-dialog/chops-dialog.test.js
+++ b/static_src/elements/chops/chops-dialog/chops-dialog.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
index 3bcc0c6..3f9193a 100644
--- a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
+++ b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
index 3fd2671..4836927 100644
--- a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
+++ b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-snackbar/chops-snackbar.js b/static_src/elements/chops/chops-snackbar/chops-snackbar.js
index aea71b8..01857df 100644
--- a/static_src/elements/chops/chops-snackbar/chops-snackbar.js
+++ b/static_src/elements/chops/chops-snackbar/chops-snackbar.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js b/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
index fa45d68..ee9450c 100644
--- a/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
+++ b/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
index 2fa1dc2..baa96ac 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
index 5fe344b..5f42a6f 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp.js b/static_src/elements/chops/chops-timestamp/chops-timestamp.js
index b7f157f..dbd7529 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js b/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
index 21c227d..fcd9e81 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-toggle/chops-toggle.js b/static_src/elements/chops/chops-toggle/chops-toggle.js
index 52868bd..608373a 100644
--- a/static_src/elements/chops/chops-toggle/chops-toggle.js
+++ b/static_src/elements/chops/chops-toggle/chops-toggle.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-toggle/chops-toggle.test.js b/static_src/elements/chops/chops-toggle/chops-toggle.test.js
index 423c993..5a1c333 100644
--- a/static_src/elements/chops/chops-toggle/chops-toggle.test.js
+++ b/static_src/elements/chops/chops-toggle/chops-toggle.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-app-base.js b/static_src/elements/ezt/ezt-app-base.js
index 0dc3eae..7813a16 100644
--- a/static_src/elements/ezt/ezt-app-base.js
+++ b/static_src/elements/ezt/ezt-app-base.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-app-base.test.js b/static_src/elements/ezt/ezt-app-base.test.js
index 86eb5b1..78f70ee 100644
--- a/static_src/elements/ezt/ezt-app-base.test.js
+++ b/static_src/elements/ezt/ezt-app-base.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-element-package.js b/static_src/elements/ezt/ezt-element-package.js
index 90ffadb..fabb453 100644
--- a/static_src/elements/ezt/ezt-element-package.js
+++ b/static_src/elements/ezt/ezt-element-package.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-footer-scripts-package.js b/static_src/elements/ezt/ezt-footer-scripts-package.js
index 85eeaa0..8f492be 100644
--- a/static_src/elements/ezt/ezt-footer-scripts-package.js
+++ b/static_src/elements/ezt/ezt-footer-scripts-package.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-show-columns-connector.js b/static_src/elements/ezt/ezt-show-columns-connector.js
index c6b3347..c13aefb 100644
--- a/static_src/elements/ezt/ezt-show-columns-connector.js
+++ b/static_src/elements/ezt/ezt-show-columns-connector.js
@@ -1,7 +1,7 @@
 /**
  * @fileoverview Description of this file.
  */
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/ezt-show-columns-connector.test.js b/static_src/elements/ezt/ezt-show-columns-connector.test.js
index 62bd13b..b68c72f 100644
--- a/static_src/elements/ezt/ezt-show-columns-connector.test.js
+++ b/static_src/elements/ezt/ezt-show-columns-connector.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.js b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.js
index d9318fc..ef877cb 100644
--- a/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.js
+++ b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js
index a0689e1..78e4224 100644
--- a/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js
+++ b/static_src/elements/ezt/mr-bulk-approval-update/mr-bulk-approval-update.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.js b/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.js
index a7870f6..faaaa63 100644
--- a/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.js
+++ b/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.test.js b/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.test.js
index 82e529d..4739650 100644
--- a/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.test.js
+++ b/static_src/elements/framework/dialogs/mr-change-columns/mr-change-columns.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.js
index 54565cf..1ee898a 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.test.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.test.js
index 911c1a0..52c4f44 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.test.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-issue-hotlists-dialog.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.js
index e7c1cd3..312f84a 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.test.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.test.js
index 7a2dd5c..ab8aeb7 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.test.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-move-issue-hotlists-dialog.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.js
index 08a8b25..d9ede34 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.test.js b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.test.js
index 954b8b9..bf54bdd 100644
--- a/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.test.js
+++ b/static_src/elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.js b/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.js
index 690bd6a..3fff0f5 100644
--- a/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.js
+++ b/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.js
@@ -1,9 +1,9 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 import {LitElement, html, css} from 'lit-element';
-
+import {generateProjectIssueURL} from 'shared/helpers.js';
 /**
  * `<mr-crbug-link>`
  *
@@ -75,8 +75,9 @@
         issue.projectName == 'chromium' ? '' : issue.projectName + '/');
       return `https://crbug.com/${projectPart}${issue.localId}`;
     }
-    const issueType = issue.approvalValues ? 'approval' : 'detail';
-    return `/p/${issue.projectName}/issues/${issueType}?id=${issue.localId}`;
+    const issueType = issue.approvalValues ? '/approval' : '/detail';
+    const params = {'id': issue.localId};
+    return generateProjectIssueURL(issue.projectName, issueType, params);
   }
 
   _getHost() {
diff --git a/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.test.js b/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.test.js
index aa7f21f..85a1b0c 100644
--- a/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.test.js
+++ b/static_src/elements/framework/links/mr-crbug-link/mr-crbug-link.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.js b/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.js
index 1f8b01a..970849d 100644
--- a/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.js
+++ b/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.test.js b/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.test.js
index 7071b77..c0b97a4 100644
--- a/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.test.js
+++ b/static_src/elements/framework/links/mr-hotlist-link/mr-hotlist-link.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/links/mr-issue-link/mr-issue-link.js b/static_src/elements/framework/links/mr-issue-link/mr-issue-link.js
index 029de6c..0aaa998 100644
--- a/static_src/elements/framework/links/mr-issue-link/mr-issue-link.js
+++ b/static_src/elements/framework/links/mr-issue-link/mr-issue-link.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,8 +6,6 @@
 import {ifDefined} from 'lit-html/directives/if-defined';
 import {issueRefToString, issueRefToUrl} from 'shared/convertersV0.js';
 import {SHARED_STYLES} from 'shared/shared-styles.js';
-import '../../mr-dropdown/mr-dropdown.js';
-import '../../../help/mr-cue/mr-fed-ref-cue.js';
 
 /**
  * `<mr-issue-link>`
@@ -24,41 +22,19 @@
         a[is-closed] {
           text-decoration: line-through;
         }
-        mr-dropdown {
-          width: var(--chops-main-font-size);
-          --mr-dropdown-icon-font-size: var(--chops-main-font-size);
-          --mr-dropdown-menu-min-width: 100px;
-        }
       `,
     ];
   }
 
   /** @override */
   render() {
-    let fedRefInfo;
-    if (this.issue && this.issue.extIdentifier) {
-      fedRefInfo = html`
-        <!-- TODO(jeffcarp): Figure out CSS to enable menuAlignment=left -->
-        <mr-dropdown
-          label="Federated Reference Info"
-          icon="info_outline"
-          menuAlignment="right"
-        >
-          <mr-fed-ref-cue
-            cuePrefName="federated_reference"
-            fedRefShortlink=${this.issue.extIdentifier}
-            nondismissible>
-          </mr-fed-ref-cue>
-        </mr-dropdown>
-      `;
-    }
     return html`
       <a
         id="bugLink"
         href=${this.href}
         title=${ifDefined(this.issue && this.issue.summary)}
         ?is-closed=${this.isClosed}
-      >${this._linkText}</a>${fedRefInfo}`;
+      >${this._linkText}</a>`;
   }
 
   /** @override */
diff --git a/static_src/elements/framework/links/mr-issue-link/mr-issue-link.test.js b/static_src/elements/framework/links/mr-issue-link/mr-issue-link.test.js
index 1bd3ae9..7e5f899 100644
--- a/static_src/elements/framework/links/mr-issue-link/mr-issue-link.test.js
+++ b/static_src/elements/framework/links/mr-issue-link/mr-issue-link.test.js
@@ -1,14 +1,16 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 import {assert} from 'chai';
 import {MrIssueLink} from './mr-issue-link.js';
+import sinon from 'sinon';
 
 let element;
 
 describe('mr-issue-link', () => {
   beforeEach(() => {
+    window.ga = sinon.stub();
     element = document.createElement('mr-issue-link');
     document.body.appendChild(element);
   });
@@ -97,42 +99,6 @@
     assert.equal(link.title, '');
   });
 
-  it('displays an icon for federated references', async () => {
-    element.issue = {
-      extIdentifier: 'b/5678',
-    };
-
-    await element.updateComplete;
-
-    const dropdown = element.shadowRoot.querySelector('mr-dropdown');
-    assert.isNotNull(dropdown);
-    const anchor = dropdown.shadowRoot.querySelector('.anchor');
-    assert.isNotNull(anchor);
-    assert.include(anchor.innerText, 'info_outline');
-  });
-
-  it('displays an info popup for federated references', async () => {
-    element.issue = {
-      extIdentifier: 'b/5678',
-    };
-
-    await element.updateComplete;
-
-    const dropdown = element.shadowRoot.querySelector('mr-dropdown');
-    const anchor = dropdown.shadowRoot.querySelector('.anchor');
-    anchor.click();
-
-    await dropdown.updateComplete;
-
-    assert.isTrue(dropdown.opened);
-
-    const cue = dropdown.querySelector('mr-fed-ref-cue');
-    assert.isNotNull(cue);
-    const message = cue.shadowRoot.querySelector('#message');
-    assert.isNotNull(message);
-    assert.include(message.innerText, 'Buganizer issue tracker');
-  });
-
   it('shows title when summary is defined', async () => {
     element.issue = {
       projectName: 'test',
diff --git a/static_src/elements/framework/links/mr-user-link/mr-user-link.js b/static_src/elements/framework/links/mr-user-link/mr-user-link.js
index 8e5be27..7cb15ef 100644
--- a/static_src/elements/framework/links/mr-user-link/mr-user-link.js
+++ b/static_src/elements/framework/links/mr-user-link/mr-user-link.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/links/mr-user-link/mr-user-link.test.js b/static_src/elements/framework/links/mr-user-link/mr-user-link.test.js
index ec84074..8b3331b 100644
--- a/static_src/elements/framework/links/mr-user-link/mr-user-link.test.js
+++ b/static_src/elements/framework/links/mr-user-link/mr-user-link.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-autocomplete/mr-autocomplete.js b/static_src/elements/framework/mr-autocomplete/mr-autocomplete.js
index c37eb42..b5bdc14 100644
--- a/static_src/elements/framework/mr-autocomplete/mr-autocomplete.js
+++ b/static_src/elements/framework/mr-autocomplete/mr-autocomplete.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-autocomplete/mr-autocomplete.test.js b/static_src/elements/framework/mr-autocomplete/mr-autocomplete.test.js
index 0c4e3ae..b3aaba8 100644
--- a/static_src/elements/framework/mr-autocomplete/mr-autocomplete.test.js
+++ b/static_src/elements/framework/mr-autocomplete/mr-autocomplete.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-button-bar/mr-button-bar.js b/static_src/elements/framework/mr-button-bar/mr-button-bar.js
index 8cff503..d586042 100644
--- a/static_src/elements/framework/mr-button-bar/mr-button-bar.js
+++ b/static_src/elements/framework/mr-button-bar/mr-button-bar.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-button-bar/mr-button-bar.test.js b/static_src/elements/framework/mr-button-bar/mr-button-bar.test.js
index 349a8df..ef4471a 100644
--- a/static_src/elements/framework/mr-button-bar/mr-button-bar.test.js
+++ b/static_src/elements/framework/mr-button-bar/mr-button-bar.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-comment-content/mr-attachment.js b/static_src/elements/framework/mr-comment-content/mr-attachment.js
index c435dfd..5db8017 100644
--- a/static_src/elements/framework/mr-comment-content/mr-attachment.js
+++ b/static_src/elements/framework/mr-comment-content/mr-attachment.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-comment-content/mr-attachment.test.js b/static_src/elements/framework/mr-comment-content/mr-attachment.test.js
index ec79c66..976e85c 100644
--- a/static_src/elements/framework/mr-comment-content/mr-attachment.test.js
+++ b/static_src/elements/framework/mr-comment-content/mr-attachment.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-comment-content/mr-comment-content.js b/static_src/elements/framework/mr-comment-content/mr-comment-content.js
index c2bf3e8..0b490e4 100644
--- a/static_src/elements/framework/mr-comment-content/mr-comment-content.js
+++ b/static_src/elements/framework/mr-comment-content/mr-comment-content.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-comment-content/mr-comment-content.test.js b/static_src/elements/framework/mr-comment-content/mr-comment-content.test.js
index 4eeaab5..d5bf499 100644
--- a/static_src/elements/framework/mr-comment-content/mr-comment-content.test.js
+++ b/static_src/elements/framework/mr-comment-content/mr-comment-content.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-comment-content/mr-description.js b/static_src/elements/framework/mr-comment-content/mr-description.js
index 89ae105..9244e82 100644
--- a/static_src/elements/framework/mr-comment-content/mr-description.js
+++ b/static_src/elements/framework/mr-comment-content/mr-description.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -55,6 +55,7 @@
   /** @override */
   render() {
     const selectedDescription = this.selectedDescription;
+    const author = selectedDescription.commenter ?  selectedDescription.commenter.displayName: '';
 
     return html`
       <div class="select-container">
@@ -67,7 +68,7 @@
       </div>
       <mr-comment-content
         .content=${selectedDescription.content}
-        .author=${selectedDescription.commenter.displayName}
+        .author=${author}
       ></mr-comment-content>
       <div>
         ${(selectedDescription.attachments || []).map((attachment) => html`
diff --git a/static_src/elements/framework/mr-comment-content/mr-description.test.js b/static_src/elements/framework/mr-comment-content/mr-description.test.js
index 9d39149..98b4fe8 100644
--- a/static_src/elements/framework/mr-comment-content/mr-description.test.js
+++ b/static_src/elements/framework/mr-comment-content/mr-description.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-dropdown/mr-account-dropdown.js b/static_src/elements/framework/mr-dropdown/mr-account-dropdown.js
index 15c3e7c..ed27db7 100644
--- a/static_src/elements/framework/mr-dropdown/mr-account-dropdown.js
+++ b/static_src/elements/framework/mr-dropdown/mr-account-dropdown.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-dropdown/mr-account-dropdown.test.js b/static_src/elements/framework/mr-dropdown/mr-account-dropdown.test.js
index f365823..f857507 100644
--- a/static_src/elements/framework/mr-dropdown/mr-account-dropdown.test.js
+++ b/static_src/elements/framework/mr-dropdown/mr-account-dropdown.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-dropdown/mr-dropdown.js b/static_src/elements/framework/mr-dropdown/mr-dropdown.js
index 4564ab0..e6fe543 100644
--- a/static_src/elements/framework/mr-dropdown/mr-dropdown.js
+++ b/static_src/elements/framework/mr-dropdown/mr-dropdown.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-dropdown/mr-dropdown.test.js b/static_src/elements/framework/mr-dropdown/mr-dropdown.test.js
index 51f8ce9..ec340ed 100644
--- a/static_src/elements/framework/mr-dropdown/mr-dropdown.test.js
+++ b/static_src/elements/framework/mr-dropdown/mr-dropdown.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-error/mr-error.js b/static_src/elements/framework/mr-error/mr-error.js
index 084a326..2af7e6f 100644
--- a/static_src/elements/framework/mr-error/mr-error.js
+++ b/static_src/elements/framework/mr-error/mr-error.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-header/mr-header.js b/static_src/elements/framework/mr-header/mr-header.js
index 5b9defa..b29db00 100644
--- a/static_src/elements/framework/mr-header/mr-header.js
+++ b/static_src/elements/framework/mr-header/mr-header.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -15,6 +15,7 @@
 import '../mr-dropdown/mr-account-dropdown.js';
 import './mr-search-bar.js';
 
+import {generateProjectIssueURL} from 'shared/helpers.js';
 import {SHARED_STYLES} from 'shared/shared-styles.js';
 
 import {logEvent} from 'monitoring/client-logger.js';
@@ -147,7 +148,7 @@
         .queryParams=${this.queryParams}
         .issueEntryUrl=${this.issueEntryUrl}
       ></mr-keystrokes>
-      <a href="/p/${this.projectName}/issues/list" class="home-link">
+      <a href="${generateProjectIssueURL(this.projectName, '/list')}" class="home-link">
         ${this.projectThumbnailUrl ? html`
           <img
             class="project-logo"
@@ -338,9 +339,9 @@
     const mayBeRedirectedToWizard = role === projectRoles.NONE;
     if (!this.userDisplayName || !config || !config.customIssueEntryUrl ||
         !mayBeRedirectedToWizard) {
-      return `/p/${this.projectName}/issues/entry`;
+      return generateProjectIssueURL(this.projectName, '/entry');
     }
-
+    //TODO(monorail/12012) redirec to tracker once new chromium wizard is ready.
     return `/p/${this.projectName}/issues/wizard`;
   }
 
@@ -365,7 +366,7 @@
       items.push({text: 'My Projects', separator: true});
 
       projects.forEach((project) => {
-        items.push({text: project, url: `/p/${project}/issues/list`});
+        items.push({text: project, url: generateProjectIssueURL(project, '/list')});
       });
     }
 
@@ -374,7 +375,7 @@
       items.push({text: 'Starred Projects', separator: true});
 
       starredProjects.forEach((project) => {
-        items.push({text: project, url: `/p/${project}/issues/list`});
+        items.push({text: project, url: generateProjectIssueURL(project, '/list')});
       });
     }
 
diff --git a/static_src/elements/framework/mr-header/mr-header.test.js b/static_src/elements/framework/mr-header/mr-header.test.js
index e290584..49e7bab 100644
--- a/static_src/elements/framework/mr-header/mr-header.test.js
+++ b/static_src/elements/framework/mr-header/mr-header.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -161,12 +161,13 @@
     });
   });
 
+  // TODO(b/283983843): Prefix project names with "mock".
   it('_projectDropdownItems computes projects for user', () => {
     element.userProjects = {
       ownerOf: ['chromium'],
       memberOf: ['v8'],
-      contributorTo: ['skia'],
-      starredProjects: ['gerrit'],
+      contributorTo: ['mockskia'],
+      starredProjects: ['mockgerrit'],
     };
     element.userDisplayName = 'test@example.com';
 
@@ -177,13 +178,13 @@
     // My Projects
     assert.equal(items[1].text, 'chromium');
     assert.equal(items[1].url, '/p/chromium/issues/list');
-    assert.equal(items[2].text, 'skia');
-    assert.equal(items[2].url, '/p/skia/issues/list');
+    assert.equal(items[2].text, 'mockskia');
+    assert.equal(items[2].url, '/p/mockskia/issues/list');
     assert.equal(items[3].text, 'v8');
     assert.equal(items[3].url, '/p/v8/issues/list');
 
     // Starred Projects
-    assert.equal(items[5].text, 'gerrit');
-    assert.equal(items[5].url, '/p/gerrit/issues/list');
+    assert.equal(items[5].text, 'mockgerrit');
+    assert.equal(items[5].url, '/p/mockgerrit/issues/list');
   });
 });
diff --git a/static_src/elements/framework/mr-header/mr-search-bar.js b/static_src/elements/framework/mr-header/mr-search-bar.js
index 536dfcf..5156c01 100644
--- a/static_src/elements/framework/mr-header/mr-search-bar.js
+++ b/static_src/elements/framework/mr-header/mr-search-bar.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-header/mr-search-bar.test.js b/static_src/elements/framework/mr-header/mr-search-bar.test.js
index c758a41..d8db788 100644
--- a/static_src/elements/framework/mr-header/mr-search-bar.test.js
+++ b/static_src/elements/framework/mr-header/mr-search-bar.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.js b/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.js
index 13f8267..14329b3 100644
--- a/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.js
+++ b/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.test.js b/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.test.js
index cd124a5..894e7c6 100644
--- a/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.test.js
+++ b/static_src/elements/framework/mr-issue-list/list-to-csv-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-list/mr-issue-list.js b/static_src/elements/framework/mr-issue-list/mr-issue-list.js
index 3e0a279..d788da8 100644
--- a/static_src/elements/framework/mr-issue-list/mr-issue-list.js
+++ b/static_src/elements/framework/mr-issue-list/mr-issue-list.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-list/mr-issue-list.test.js b/static_src/elements/framework/mr-issue-list/mr-issue-list.test.js
index 3861e32..b7a3b70 100644
--- a/static_src/elements/framework/mr-issue-list/mr-issue-list.test.js
+++ b/static_src/elements/framework/mr-issue-list/mr-issue-list.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js
index 5d6a97b..96b81be 100644
--- a/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js
+++ b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {css} from 'lit-element';
diff --git a/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.test.js b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.test.js
index 495ffe2..4469471 100644
--- a/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.test.js
+++ b/static_src/elements/framework/mr-issue-list/mr-show-columns-dropdown.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-slo/mr-issue-slo.js b/static_src/elements/framework/mr-issue-slo/mr-issue-slo.js
index 5a3e42c..ac3dc1b 100644
--- a/static_src/elements/framework/mr-issue-slo/mr-issue-slo.js
+++ b/static_src/elements/framework/mr-issue-slo/mr-issue-slo.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-slo/mr-issue-slo.test.js b/static_src/elements/framework/mr-issue-slo/mr-issue-slo.test.js
index 28d23eb..eeb55c7 100644
--- a/static_src/elements/framework/mr-issue-slo/mr-issue-slo.test.js
+++ b/static_src/elements/framework/mr-issue-slo/mr-issue-slo.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-slo/slo-rules.js b/static_src/elements/framework/mr-issue-slo/slo-rules.js
index e351ae0..09f2b6c 100644
--- a/static_src/elements/framework/mr-issue-slo/slo-rules.js
+++ b/static_src/elements/framework/mr-issue-slo/slo-rules.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-issue-slo/slo-rules.test.js b/static_src/elements/framework/mr-issue-slo/slo-rules.test.js
index a48e5e2..2b370b6 100644
--- a/static_src/elements/framework/mr-issue-slo/slo-rules.test.js
+++ b/static_src/elements/framework/mr-issue-slo/slo-rules.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-keystrokes/mr-keystrokes.js b/static_src/elements/framework/mr-keystrokes/mr-keystrokes.js
index 9e932d6..1a61fae 100644
--- a/static_src/elements/framework/mr-keystrokes/mr-keystrokes.js
+++ b/static_src/elements/framework/mr-keystrokes/mr-keystrokes.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-keystrokes/mr-keystrokes.test.js b/static_src/elements/framework/mr-keystrokes/mr-keystrokes.test.js
index 0d7468f..8cc5085 100644
--- a/static_src/elements/framework/mr-keystrokes/mr-keystrokes.test.js
+++ b/static_src/elements/framework/mr-keystrokes/mr-keystrokes.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.js b/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.js
index a5f9d7a..28c13b6 100644
--- a/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.js
+++ b/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.test.js b/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.test.js
index b6dbb41..5350989 100644
--- a/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.test.js
+++ b/static_src/elements/framework/mr-pref-toggle/mr-pref-toggle.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-site-banner/mr-site-banner.js b/static_src/elements/framework/mr-site-banner/mr-site-banner.js
index 2a98a5c..263633e 100644
--- a/static_src/elements/framework/mr-site-banner/mr-site-banner.js
+++ b/static_src/elements/framework/mr-site-banner/mr-site-banner.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-site-banner/mr-site-banner.test.js b/static_src/elements/framework/mr-site-banner/mr-site-banner.test.js
index 527b942..0ee6b46 100644
--- a/static_src/elements/framework/mr-site-banner/mr-site-banner.test.js
+++ b/static_src/elements/framework/mr-site-banner/mr-site-banner.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-star/mr-issue-star.js b/static_src/elements/framework/mr-star/mr-issue-star.js
index 5255820..20420e2 100644
--- a/static_src/elements/framework/mr-star/mr-issue-star.js
+++ b/static_src/elements/framework/mr-star/mr-issue-star.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {connectStore, store} from 'reducers/base.js';
diff --git a/static_src/elements/framework/mr-star/mr-issue-star.test.js b/static_src/elements/framework/mr-star/mr-issue-star.test.js
index bb618f7..bd43354 100644
--- a/static_src/elements/framework/mr-star/mr-issue-star.test.js
+++ b/static_src/elements/framework/mr-star/mr-issue-star.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-star/mr-project-star.js b/static_src/elements/framework/mr-star/mr-project-star.js
index 14b2c73..9b72076 100644
--- a/static_src/elements/framework/mr-star/mr-project-star.js
+++ b/static_src/elements/framework/mr-star/mr-project-star.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {connectStore, store} from 'reducers/base.js';
diff --git a/static_src/elements/framework/mr-star/mr-project-star.test.js b/static_src/elements/framework/mr-star/mr-project-star.test.js
index 6afd982..796f35d 100644
--- a/static_src/elements/framework/mr-star/mr-project-star.test.js
+++ b/static_src/elements/framework/mr-star/mr-project-star.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-star/mr-star.js b/static_src/elements/framework/mr-star/mr-star.js
index fe509be..406811e 100644
--- a/static_src/elements/framework/mr-star/mr-star.js
+++ b/static_src/elements/framework/mr-star/mr-star.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-star/mr-star.test.js b/static_src/elements/framework/mr-star/mr-star.test.js
index 4db7877..0f39f81 100644
--- a/static_src/elements/framework/mr-star/mr-star.test.js
+++ b/static_src/elements/framework/mr-star/mr-star.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import sinon from 'sinon';
diff --git a/static_src/elements/framework/mr-tabs/mr-tabs.js b/static_src/elements/framework/mr-tabs/mr-tabs.js
index d14688e..0c40305 100644
--- a/static_src/elements/framework/mr-tabs/mr-tabs.js
+++ b/static_src/elements/framework/mr-tabs/mr-tabs.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-tabs/mr-tabs.test.js b/static_src/elements/framework/mr-tabs/mr-tabs.test.js
index 1d55c39..195cb5f 100644
--- a/static_src/elements/framework/mr-tabs/mr-tabs.test.js
+++ b/static_src/elements/framework/mr-tabs/mr-tabs.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-upload/mr-upload.js b/static_src/elements/framework/mr-upload/mr-upload.js
index 5fee672..bbc8318 100644
--- a/static_src/elements/framework/mr-upload/mr-upload.js
+++ b/static_src/elements/framework/mr-upload/mr-upload.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-upload/mr-upload.test.js b/static_src/elements/framework/mr-upload/mr-upload.test.js
index 0a0b1e8..1586634 100644
--- a/static_src/elements/framework/mr-upload/mr-upload.test.js
+++ b/static_src/elements/framework/mr-upload/mr-upload.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/framework/mr-warning/mr-warning.js b/static_src/elements/framework/mr-warning/mr-warning.js
index 51de376..75adae0 100644
--- a/static_src/elements/framework/mr-warning/mr-warning.js
+++ b/static_src/elements/framework/mr-warning/mr-warning.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-click-throughs/mr-click-throughs.js b/static_src/elements/help/mr-click-throughs/mr-click-throughs.js
index 6925367..7e4b55d 100644
--- a/static_src/elements/help/mr-click-throughs/mr-click-throughs.js
+++ b/static_src/elements/help/mr-click-throughs/mr-click-throughs.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-click-throughs/mr-click-throughs.test.js b/static_src/elements/help/mr-click-throughs/mr-click-throughs.test.js
index e735380..b1dc497 100644
--- a/static_src/elements/help/mr-click-throughs/mr-click-throughs.test.js
+++ b/static_src/elements/help/mr-click-throughs/mr-click-throughs.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-cue/cue-helpers.js b/static_src/elements/help/mr-cue/cue-helpers.js
index 4aa30d7..0d0a65e 100644
--- a/static_src/elements/help/mr-cue/cue-helpers.js
+++ b/static_src/elements/help/mr-cue/cue-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-cue/cue-helpers.test.js b/static_src/elements/help/mr-cue/cue-helpers.test.js
index 3bc084a..c8d34bf 100644
--- a/static_src/elements/help/mr-cue/cue-helpers.test.js
+++ b/static_src/elements/help/mr-cue/cue-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-cue/mr-cue.js b/static_src/elements/help/mr-cue/mr-cue.js
index 5c39d2b..3a27faa 100644
--- a/static_src/elements/help/mr-cue/mr-cue.js
+++ b/static_src/elements/help/mr-cue/mr-cue.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-cue/mr-cue.test.js b/static_src/elements/help/mr-cue/mr-cue.test.js
index 2722076..20ae68d 100644
--- a/static_src/elements/help/mr-cue/mr-cue.test.js
+++ b/static_src/elements/help/mr-cue/mr-cue.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/help/mr-cue/mr-fed-ref-cue.js b/static_src/elements/help/mr-cue/mr-fed-ref-cue.js
deleted file mode 100644
index 8e8626f..0000000
--- a/static_src/elements/help/mr-cue/mr-fed-ref-cue.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {html, css} from 'lit-element';
-import * as userV0 from 'reducers/userV0.js';
-import * as issueV0 from 'reducers/issueV0.js';
-import {store} from 'reducers/base.js';
-import 'elements/chops/chops-button/chops-button.js';
-import 'elements/chops/chops-dialog/chops-dialog.js';
-import {fromShortlink, GoogleIssueTrackerIssue} from 'shared/federated.js';
-import {MrCue} from './mr-cue.js';
-
-/**
- * `<mr-fed-ref-cue>`
- *
- * Displays information and login/logout links for the federated references
- * info popup.
- *
- */
-export class MrFedRefCue extends MrCue {
-  /** @override */
-  static get properties() {
-    return {
-      ...MrCue.properties,
-      fedRefShortlink: {type: String},
-    };
-  }
-
-  /** @override */
-  static get styles() {
-    return [
-      ...MrCue.styles,
-      css`
-        :host {
-          margin: 0;
-          width: 120px;
-          font-size: 11px;
-        }
-      `,
-    ];
-  }
-
-  get message() {
-    const fedRef = fromShortlink(this.fedRefShortlink);
-    if (fedRef && fedRef instanceof GoogleIssueTrackerIssue) {
-      let authLink;
-      if (this.user && this.user.gapiEmail) {
-        authLink = html`
-          <br /><br />
-          <a href="#"
-            @click=${() => store.dispatch(userV0.initGapiLogout())}
-          >Sign out</a>
-          <br />
-          (for references only)
-        `;
-      } else {
-        const clickLoginHandler = async () => {
-          await store.dispatch(userV0.initGapiLogin(this.issue));
-          // Re-fetch related issues.
-          store.dispatch(issueV0.fetchRelatedIssues(this.issue));
-        };
-        authLink = html`
-          <br /><br />
-          Googlers, to enable viewing status & title,
-          <a href="#"
-            @click=${clickLoginHandler}
-            >sign in here</a> with your Google email.
-        `;
-      }
-      return html`
-        This references an issue in the ${fedRef.trackerName} issue tracker.
-        ${authLink}
-      `;
-    } else {
-      return html`
-        This references an issue in another tracker. Status not displayed.
-      `;
-    }
-  }
-}
-
-customElements.define('mr-fed-ref-cue', MrFedRefCue);
diff --git a/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.js b/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.js
index b7087a9..12e3ee1 100644
--- a/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.js
+++ b/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.test.js b/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.test.js
index 9321d59..8f306b2 100644
--- a/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.test.js
+++ b/static_src/elements/hotlist/mr-hotlist-header/mr-hotlist-header.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.js b/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.js
index fa76477..45f42a9 100644
--- a/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.js
+++ b/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.test.js b/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.test.js
index a651578..f51a5f6 100644
--- a/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.test.js
+++ b/static_src/elements/hotlist/mr-hotlist-issues-page/mr-hotlist-issues-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.js b/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.js
index c317d39..0e5a1ff 100644
--- a/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.js
+++ b/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.test.js b/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.test.js
index b7dd6dc..620ed49 100644
--- a/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.test.js
+++ b/static_src/elements/hotlist/mr-hotlist-people-page/mr-hotlist-people-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.js b/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.js
index 4f4d90d..08630f4 100644
--- a/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.js
+++ b/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.test.js b/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.test.js
index 987fff2..b0ffd40 100644
--- a/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.test.js
+++ b/static_src/elements/hotlist/mr-hotlist-settings-page/mr-hotlist-settings-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.js b/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.js
index 8da3083..3295b3e 100644
--- a/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.js
+++ b/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.test.js b/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.test.js
index b68e274..9c59ea6 100644
--- a/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.test.js
+++ b/static_src/elements/issue-detail/dialogs/mr-convert-issue/mr-convert-issue.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.js b/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.js
index 0bee4d8..cd27676 100644
--- a/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.js
+++ b/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.test.js b/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.test.js
index e3fe9d2..e633037 100644
--- a/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.test.js
+++ b/static_src/elements/issue-detail/dialogs/mr-edit-description/mr-edit-description.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.js b/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.js
index e97f203..63eab69 100644
--- a/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.js
+++ b/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -10,6 +10,7 @@
 import 'elements/framework/mr-autocomplete/mr-autocomplete.js';
 import 'elements/chops/chops-button/chops-button.js';
 import 'elements/chops/chops-dialog/chops-dialog.js';
+import {generateProjectIssueURL} from 'shared/helpers.js';
 import {SHARED_STYLES} from 'shared/shared-styles.js';
 import {prpcClient} from 'prpc-client-instance.js';
 
@@ -118,7 +119,8 @@
     }).then((response) => {
       const projectName = response.newIssueRef.projectName;
       const localId = response.newIssueRef.localId;
-      page(`/p/${projectName}/issues/detail?id=${localId}`);
+      const params = {'id': localId};
+      page(generateProjectIssueURL(projectName, '/detail', params));
       this.cancel();
     }, (error) => {
       this._targetProjectError = error;
diff --git a/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.test.js b/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.test.js
index 5fdfb39..98c5b5d 100644
--- a/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.test.js
+++ b/static_src/elements/issue-detail/dialogs/mr-move-copy-issue/mr-move-copy-issue.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.js b/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.js
index e859bef..dd2ce00 100644
--- a/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.js
+++ b/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.test.js b/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.test.js
index 69ce7ee..063714e 100644
--- a/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.test.js
+++ b/static_src/elements/issue-detail/dialogs/mr-related-issues/mr-related-issues.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.js
index 18bd963..be5a06d 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.test.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.test.js
index a718203..deeb660 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-field.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.js
index 5303c57..42bef4b 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.test.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.test.js
index ffa25e5..53a1ac7 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-edit-status.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.js
index 881cced..15c1671 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.test.js b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.test.js
index 33cce9e..5e95f44 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-field/mr-multi-checkbox.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.js b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.js
index 248c7d5..aaccbf2 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -353,7 +353,7 @@
    */
    get _migratedLink() {
     if (this.migratedType === migratedTypes.BUGANIZER_TYPE) {
-      const link = 
+      const link =
         html`<a href="https://issuetracker.google.com/issues/${this.migratedId}">b/${this.migratedId}</a>`;
       return html`<p>This issue has moved to ${link}. Updates should be posted in ${link}.</p>`;
     } else {
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.test.js b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.test.js
index e781328..a73794e 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-issue.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.js b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.js
index 7877007..8b00dfa 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.test.js b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.test.js
index 2e4554f..b89720e 100644
--- a/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -1075,4 +1075,3 @@
     assert.isNull(previewMarkdown);
   });
 });
-
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.js
index ba68c39..484267e 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.test.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.test.js
index e334841..fdbbc4f 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-field-values.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.js
index 60d570c..3fee448 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.test.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.test.js
index c328057..42e3e3b 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-issue-metadata.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.js
index 0ce172d..8dbe2df 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.test.js b/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.test.js
index d9dcd25..2149e2c 100644
--- a/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.test.js
+++ b/static_src/elements/issue-detail/metadata/mr-metadata/mr-metadata.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.js b/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.js
index 2d74c10..1c53098 100644
--- a/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.js
+++ b/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.test.js b/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.test.js
index 0424c21..1451118 100644
--- a/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.test.js
+++ b/static_src/elements/issue-detail/mr-approval-card/mr-approval-card.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.js b/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.js
index aad9a8a..121e64b 100644
--- a/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.js
+++ b/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.test.js b/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.test.js
index 548b7a7..91b4da7 100644
--- a/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.test.js
+++ b/static_src/elements/issue-detail/mr-comment-list/mr-comment-list.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-comment-list/mr-comment.js b/static_src/elements/issue-detail/mr-comment-list/mr-comment.js
index e56bef3..ba14d72 100644
--- a/static_src/elements/issue-detail/mr-comment-list/mr-comment.js
+++ b/static_src/elements/issue-detail/mr-comment-list/mr-comment.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-comment-list/mr-comment.test.js b/static_src/elements/issue-detail/mr-comment-list/mr-comment.test.js
index 6933825..63aca77 100644
--- a/static_src/elements/issue-detail/mr-comment-list/mr-comment.test.js
+++ b/static_src/elements/issue-detail/mr-comment-list/mr-comment.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-flipper/mr-flipper.js b/static_src/elements/issue-detail/mr-flipper/mr-flipper.js
index 8159e01..955670a 100644
--- a/static_src/elements/issue-detail/mr-flipper/mr-flipper.js
+++ b/static_src/elements/issue-detail/mr-flipper/mr-flipper.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-flipper/mr-flipper.test.js b/static_src/elements/issue-detail/mr-flipper/mr-flipper.test.js
index 183a8d5..9cc815c 100644
--- a/static_src/elements/issue-detail/mr-flipper/mr-flipper.test.js
+++ b/static_src/elements/issue-detail/mr-flipper/mr-flipper.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.js b/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.js
index bd88b3f..b187234 100644
--- a/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.js
+++ b/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.test.js b/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.test.js
index 3919e15..70c552d 100644
--- a/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.test.js
+++ b/static_src/elements/issue-detail/mr-issue-details/mr-issue-details.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.js b/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.js
index a2b2ef1..558245e 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -241,6 +241,9 @@
     const riskyOptions = [];
     const isSpam = this.issue.isSpam;
     const isRestricted = this.isRestricted;
+    // Projects that allow some restricted issues to move.
+    // Context: https://crbug.com/monorail/11894
+    const projectsAllowedToMove = ['chromium', 'webrtc'];
 
     const permissions = this.issuePermissions;
     const templates = this.projectTemplates;
@@ -264,11 +267,14 @@
         text: 'Delete issue',
         handler: this._deleteIssue.bind(this),
       });
-      if (!isRestricted) {
+      if (!isRestricted ||
+          projectsAllowedToMove.includes(this.projectName.toLowerCase())) {
         editOptions.push({
           text: 'Move issue',
           handler: this._openMoveCopyIssue.bind(this, 'Move'),
         });
+      }
+      if (!isRestricted) {
         editOptions.push({
           text: 'Copy issue',
           handler: this._openMoveCopyIssue.bind(this, 'Copy'),
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.test.js b/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.test.js
index 25ab0e7..d6b5096 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.test.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-issue-header.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -99,6 +99,7 @@
   });
 
   it('_issueOptions toggles move and copy', () => {
+    element.projectName = '';
     element.issuePermissions = [ISSUE_DELETE_PERMISSION];
     assert.isDefined(findOptionWithText(element._issueOptions,
         'Move issue'));
@@ -109,7 +110,25 @@
     assert.isUndefined(findOptionWithText(element._issueOptions,
         'Move issue'));
     assert.isUndefined(findOptionWithText(element._issueOptions,
-        'Copy issue'));
+      'Copy issue'));
+
+    element.projectName = 'Chromium';
+    assert.isDefined(findOptionWithText(element._issueOptions,
+        'Move issue'));
+    assert.isUndefined(findOptionWithText(element._issueOptions,
+      'Copy issue'));
+
+    element.projectName = 'Monkeyrail';
+    assert.isUndefined(findOptionWithText(element._issueOptions,
+        'Move issue'));
+    assert.isUndefined(findOptionWithText(element._issueOptions,
+      'Copy issue'));
+
+    element.projectName = 'webrtc';
+    assert.isDefined(findOptionWithText(element._issueOptions,
+        'Move issue'));
+    assert.isUndefined(findOptionWithText(element._issueOptions,
+      'Copy issue'));
 
     element.issuePermissions = [];
 
@@ -155,7 +174,7 @@
     element.projectName = 'monkeyrail';
 
     await element.updateComplete;
-    
+
     const chopsToggles = element.shadowRoot.querySelectorAll('mr-pref-toggle');
     const markdownButton = chopsToggles[1];
     assert.equal("true", markdownButton.getAttribute('initialvalue'));
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.js b/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.js
index 88cb92c..1cd8041 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -19,6 +19,7 @@
 import * as sitewide from 'reducers/sitewide.js';
 
 import {ISSUE_DELETE_PERMISSION} from 'shared/consts/permissions.js';
+import {generateProjectIssueURL} from 'shared/helpers.js';
 
 // eslint-disable-next-line max-len
 import 'elements/framework/dialogs/mr-issue-hotlists-action/mr-update-issue-hotlists-dialog.js';
@@ -215,6 +216,7 @@
     }
 
     if (movedToRef && movedToRef.localId) {
+      const params = {'id': movedToRef.localId};
       return html`
         <div class="container-no-issue" id="moved">
           <h2>Issue has moved.</h2>
@@ -222,7 +224,7 @@
             This issue was moved to ${movedToRef.projectName}.
             <a
               class="new-location"
-              href="/p/${movedToRef.projectName}/issues/detail?id=${movedToRef.localId}"
+              href="${generateProjectIssueURL(movedToRef.projectName, '/detail', params)}"
             >
               Go to issue</a>.
           </p>
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.test.js b/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.test.js
index 31edd4c..97a7181 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.test.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-issue-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.js b/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.js
index fe4ba3c..7b8f79a 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -100,7 +100,7 @@
    */
   get _link() {
     if (this.migratedType === migratedTypes.BUGANIZER_TYPE) {
-      const link = 
+      const link =
         html`<a href="https://issuetracker.google.com/issues/${this.migratedId}">b/${this.migratedId}</a>`;
       return html`<p>This issue has moved to ${link}. Updates should be posted in ${link}.</p>`;
     } else {
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.test.js b/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.test.js
index 2114b61..7ed57c7 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.test.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-migrated-banner.test.js
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -60,4 +60,4 @@
     const link = element.shadowRoot.querySelector('p');
     assert.include(link.textContent, 'This issue has been migrated to Launch, see link in final comment below');
   });
-});
\ No newline at end of file
+});
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.js b/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.js
index af558a4..b472545 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.test.js b/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.test.js
index 3afbbcb..b82bac4 100644
--- a/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.test.js
+++ b/static_src/elements/issue-detail/mr-issue-page/mr-restriction-indicator.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.js b/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.js
index 741baaa..8754e8c 100644
--- a/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.js
+++ b/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.test.js b/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.test.js
index 3e2ff46..bfaf05d 100644
--- a/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.test.js
+++ b/static_src/elements/issue-detail/mr-launch-overview/mr-launch-overview.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-launch-overview/mr-phase.js b/static_src/elements/issue-detail/mr-launch-overview/mr-phase.js
index a81be65..6b00608 100644
--- a/static_src/elements/issue-detail/mr-launch-overview/mr-phase.js
+++ b/static_src/elements/issue-detail/mr-launch-overview/mr-phase.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-detail/mr-launch-overview/mr-phase.test.js b/static_src/elements/issue-detail/mr-launch-overview/mr-phase.test.js
index d55897e..d849a0c 100644
--- a/static_src/elements/issue-detail/mr-launch-overview/mr-phase.test.js
+++ b/static_src/elements/issue-detail/mr-launch-overview/mr-phase.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-entry/mr-issue-entry-page.js b/static_src/elements/issue-entry/mr-issue-entry-page.js
index b1cc2ef..c8dd2bd 100644
--- a/static_src/elements/issue-entry/mr-issue-entry-page.js
+++ b/static_src/elements/issue-entry/mr-issue-entry-page.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-entry/mr-issue-entry-page.test.js b/static_src/elements/issue-entry/mr-issue-entry-page.test.js
index 013a3a4..2a762d6 100644
--- a/static_src/elements/issue-entry/mr-issue-entry-page.test.js
+++ b/static_src/elements/issue-entry/mr-issue-entry-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-chart-page/mr-chart-page.js b/static_src/elements/issue-list/mr-chart-page/mr-chart-page.js
index 06ff7a4..fcf380d 100644
--- a/static_src/elements/issue-list/mr-chart-page/mr-chart-page.js
+++ b/static_src/elements/issue-list/mr-chart-page/mr-chart-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-chart/chops-chart.js b/static_src/elements/issue-list/mr-chart/chops-chart.js
index a74255a..4e3de5e 100644
--- a/static_src/elements/issue-list/mr-chart/chops-chart.js
+++ b/static_src/elements/issue-list/mr-chart/chops-chart.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-chart/chops-chart.test.js b/static_src/elements/issue-list/mr-chart/chops-chart.test.js
index bf05012..e45932d 100644
--- a/static_src/elements/issue-list/mr-chart/chops-chart.test.js
+++ b/static_src/elements/issue-list/mr-chart/chops-chart.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-chart/mr-chart.js b/static_src/elements/issue-list/mr-chart/mr-chart.js
index a4c4189..d251898 100644
--- a/static_src/elements/issue-list/mr-chart/mr-chart.js
+++ b/static_src/elements/issue-list/mr-chart/mr-chart.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/extract-grid-data.js b/static_src/elements/issue-list/mr-grid-page/extract-grid-data.js
index ebfa510..f0f859b 100644
--- a/static_src/elements/issue-list/mr-grid-page/extract-grid-data.js
+++ b/static_src/elements/issue-list/mr-grid-page/extract-grid-data.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/extract-grid-data.test.js b/static_src/elements/issue-list/mr-grid-page/extract-grid-data.test.js
index 41d5c70..9a6c89e 100644
--- a/static_src/elements/issue-list/mr-grid-page/extract-grid-data.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/extract-grid-data.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.js
index 2fe01ea..7ef2ed7 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.test.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.test.js
index d6d7fbf..8c579bc 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-controls.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.js
index 2fc05b6..ea98c0a 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -69,4 +69,3 @@
 };
 
 customElements.define('mr-grid-dropdown', MrGridDropdown);
-
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.test.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.test.js
index fcd480d..854457b 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-dropdown.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-page.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-page.js
index d96e566..2fee893 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-page.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-page.test.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-page.test.js
index 241091b..77ba397 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-page.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.js
index 57ee474..d63e63c 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.test.js b/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.test.js
index c9577c6..90e59b9 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid-tile.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid.js b/static_src/elements/issue-list/mr-grid-page/mr-grid.js
index f459489..5c49d63 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-grid-page/mr-grid.test.js b/static_src/elements/issue-list/mr-grid-page/mr-grid.test.js
index eb430de..a7e1e8a 100644
--- a/static_src/elements/issue-list/mr-grid-page/mr-grid.test.js
+++ b/static_src/elements/issue-list/mr-grid-page/mr-grid.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/issue-list/mr-list-page/mr-list-page.js b/static_src/elements/issue-list/mr-list-page/mr-list-page.js
index 809c3fc..0b568f8 100644
--- a/static_src/elements/issue-list/mr-list-page/mr-list-page.js
+++ b/static_src/elements/issue-list/mr-list-page/mr-list-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/issue-list/mr-list-page/mr-list-page.test.js b/static_src/elements/issue-list/mr-list-page/mr-list-page.test.js
index 0f1d4ac..197ef9b 100644
--- a/static_src/elements/issue-list/mr-list-page/mr-list-page.test.js
+++ b/static_src/elements/issue-list/mr-list-page/mr-list-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import sinon from 'sinon';
diff --git a/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.js b/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.js
index 8876402..1265e48 100644
--- a/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.js
+++ b/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.js
@@ -1,10 +1,10 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import page from 'page';
 import {ChopsChoiceButtons} from
   'elements/chops/chops-choice-buttons/chops-choice-buttons.js';
-import {urlWithNewParams} from 'shared/helpers.js';
+import {urlWithNewParams, generateProjectIssueURL} from 'shared/helpers.js';
 
 /**
  * Component for showing the chips to switch between List, Grid, and Chart modes
@@ -45,7 +45,7 @@
   }
 
   _newListViewPath(mode) {
-    const basePath = `/p/${this.projectName}/issues/list`;
+    const basePath = generateProjectIssueURL(this.projectName, '/list',{});
     const deletedParams = mode ? undefined : ['mode'];
     return urlWithNewParams(basePath, this.queryParams, {mode}, deletedParams);
   }
diff --git a/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.test.js b/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.test.js
index 07166d6..70b9b54 100644
--- a/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.test.js
+++ b/static_src/elements/issue-list/mr-mode-selector/mr-mode-selector.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/mr-app/mr-app.js b/static_src/elements/mr-app/mr-app.js
index 7c7e002..f461413 100644
--- a/static_src/elements/mr-app/mr-app.js
+++ b/static_src/elements/mr-app/mr-app.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -79,6 +79,13 @@
           position: static;
           margin-top: 0.5em;
         }
+        .project-alert {
+          background: var(--chops-orange-50);
+          color: var(--chops-field-error-color);
+          display: block;
+          font-weight: bold;
+          text-align: center;
+        }
       </style>
       <mr-header
         .userDisplayName=${this.userDisplayName}
@@ -87,6 +94,9 @@
       ></mr-header>
       <mr-site-banner></mr-site-banner>
       <mr-vulnz-banner></mr-vulnz-banner>
+      <div class="project-alert" ?hidden=${!this.projectAlert}>
+        ${this.projectAlert}
+      </div>
       <mr-cue
         cuePrefName=${cueNames.SWITCH_TO_PARENT_ACCOUNT}
         .loginUrl=${this.loginUrl}
@@ -191,6 +201,10 @@
        */
       versionBase: {type: String},
       /**
+       * A string explaining the project state.
+       */
+      projectAlert: {type: String},
+      /**
        * A String identifier for the page that the user is viewing.
        */
       page: {type: String},
diff --git a/static_src/elements/mr-app/mr-app.test.js b/static_src/elements/mr-app/mr-app.test.js
index 47b953b..7a26c3d 100644
--- a/static_src/elements/mr-app/mr-app.test.js
+++ b/static_src/elements/mr-app/mr-app.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/projects/mr-projects-page/helpers.js b/static_src/elements/projects/mr-projects-page/helpers.js
index 5c12ae8..25a34d9 100644
--- a/static_src/elements/projects/mr-projects-page/helpers.js
+++ b/static_src/elements/projects/mr-projects-page/helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/projects/mr-projects-page/helpers.test.js b/static_src/elements/projects/mr-projects-page/helpers.test.js
index 9e3c5a2..56184d3 100644
--- a/static_src/elements/projects/mr-projects-page/helpers.test.js
+++ b/static_src/elements/projects/mr-projects-page/helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/projects/mr-projects-page/mr-projects-page.js b/static_src/elements/projects/mr-projects-page/mr-projects-page.js
index df0c823..63f12a8 100644
--- a/static_src/elements/projects/mr-projects-page/mr-projects-page.js
+++ b/static_src/elements/projects/mr-projects-page/mr-projects-page.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -13,7 +13,7 @@
 import {users} from 'reducers/users.js';
 import {stars} from 'reducers/stars.js';
 import {computeRoleByProjectName} from './helpers.js';
-
+import {generateProjectIssueURL} from 'shared/helpers.js';
 
 /**
  * `<mr-projects-page>`
@@ -232,7 +232,7 @@
    */
   _renderProject(project, role) {
     return html`
-      <a href="/p/${project.displayName}/issues/list" class="project">
+      <a href="${generateProjectIssueURL(project.displayName, '/list')}" class="project">
         <div class="project-header">
           <span class="project-title">
             <h3>${project.displayName}</h3>
diff --git a/static_src/elements/projects/mr-projects-page/mr-projects-page.test.js b/static_src/elements/projects/mr-projects-page/mr-projects-page.test.js
index 1a9a1e4..1cb391b 100644
--- a/static_src/elements/projects/mr-projects-page/mr-projects-page.test.js
+++ b/static_src/elements/projects/mr-projects-page/mr-projects-page.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/monitoring/client-logger.js b/static_src/monitoring/client-logger.js
index 37959c0..3d62198 100644
--- a/static_src/monitoring/client-logger.js
+++ b/static_src/monitoring/client-logger.js
@@ -1,8 +1,6 @@
-/* Copyright 2018 The Chromium Authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
+// Copyright 2018 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 import MonorailTSMon from './monorail-ts-mon.js';
 
diff --git a/static_src/monitoring/monorail-ts-mon.js b/static_src/monitoring/monorail-ts-mon.js
index 2d90e3e..ebbd2b4 100644
--- a/static_src/monitoring/monorail-ts-mon.js
+++ b/static_src/monitoring/monorail-ts-mon.js
@@ -1,8 +1,6 @@
-/* Copyright 2018 The Chromium Authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
+// Copyright 2018 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 import {TSMonClient} from '@chopsui/tsmon-client';
 
diff --git a/static_src/monitoring/track-copy.js b/static_src/monitoring/track-copy.js
index 7123965..f204dcc 100644
--- a/static_src/monitoring/track-copy.js
+++ b/static_src/monitoring/track-copy.js
@@ -1,8 +1,6 @@
-/* Copyright 2018 The Chromium Authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
+// Copyright 2018 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 // This counts copy and paste events.
 
diff --git a/static_src/prpc-client-instance.js b/static_src/prpc-client-instance.js
index 103b9c6..c6631cb 100644
--- a/static_src/prpc-client-instance.js
+++ b/static_src/prpc-client-instance.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/prpc.js b/static_src/prpc.js
index 5b36c7a..1c1131b 100644
--- a/static_src/prpc.js
+++ b/static_src/prpc.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/IssueWizard.test.tsx b/static_src/react/IssueWizard.test.tsx
index 7584ff6..4b6e25d 100644
--- a/static_src/react/IssueWizard.test.tsx
+++ b/static_src/react/IssueWizard.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/IssueWizard.tsx b/static_src/react/IssueWizard.tsx
index ecb6664..08b72d1 100644
--- a/static_src/react/IssueWizard.tsx
+++ b/static_src/react/IssueWizard.tsx
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/ReactAutocomplete.test.tsx b/static_src/react/ReactAutocomplete.test.tsx
index 3253892..d0e905e 100644
--- a/static_src/react/ReactAutocomplete.test.tsx
+++ b/static_src/react/ReactAutocomplete.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/react/ReactAutocomplete.tsx b/static_src/react/ReactAutocomplete.tsx
index 60284a8..1e0ae4f 100644
--- a/static_src/react/ReactAutocomplete.tsx
+++ b/static_src/react/ReactAutocomplete.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/AttachmentUploader.tsx b/static_src/react/issue-wizard/AttachmentUploader.tsx
index a207ef5..f25bba8 100644
--- a/static_src/react/issue-wizard/AttachmentUploader.tsx
+++ b/static_src/react/issue-wizard/AttachmentUploader.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/ConfirmBackModal.tsx b/static_src/react/issue-wizard/ConfirmBackModal.tsx
index 0d07b83..ce16aa2 100644
--- a/static_src/react/issue-wizard/ConfirmBackModal.tsx
+++ b/static_src/react/issue-wizard/ConfirmBackModal.tsx
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionInput.tsx b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionInput.tsx
index aa7fdd0..6f78cbd 100644
--- a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionInput.tsx
+++ b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionInput.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionSelector.tsx b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionSelector.tsx
index bb855a3..771ccfb 100644
--- a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionSelector.tsx
+++ b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionSelector.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionTextarea.tsx b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionTextarea.tsx
index fdbdf1f..762e478 100644
--- a/static_src/react/issue-wizard/CustomQuestions/CustomQuestionTextarea.tsx
+++ b/static_src/react/issue-wizard/CustomQuestions/CustomQuestionTextarea.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/CustomQuestionsStep.tsx b/static_src/react/issue-wizard/CustomQuestionsStep.tsx
index 9e1ef72..8b65f08 100644
--- a/static_src/react/issue-wizard/CustomQuestionsStep.tsx
+++ b/static_src/react/issue-wizard/CustomQuestionsStep.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/DetailsStep.test.tsx b/static_src/react/issue-wizard/DetailsStep.test.tsx
index e53c3a9..617825d 100644
--- a/static_src/react/issue-wizard/DetailsStep.test.tsx
+++ b/static_src/react/issue-wizard/DetailsStep.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/DetailsStep.tsx b/static_src/react/issue-wizard/DetailsStep.tsx
index ae968c1..861d0fd 100644
--- a/static_src/react/issue-wizard/DetailsStep.tsx
+++ b/static_src/react/issue-wizard/DetailsStep.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/DotMobileStepper.test.tsx b/static_src/react/issue-wizard/DotMobileStepper.test.tsx
index b7c9aa4..ce5e3a3 100644
--- a/static_src/react/issue-wizard/DotMobileStepper.test.tsx
+++ b/static_src/react/issue-wizard/DotMobileStepper.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/DotMobileStepper.tsx b/static_src/react/issue-wizard/DotMobileStepper.tsx
index 9aa3fa8..8cd788a 100644
--- a/static_src/react/issue-wizard/DotMobileStepper.tsx
+++ b/static_src/react/issue-wizard/DotMobileStepper.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/Header.tsx b/static_src/react/issue-wizard/Header.tsx
index e8dfdd9..2582182 100644
--- a/static_src/react/issue-wizard/Header.tsx
+++ b/static_src/react/issue-wizard/Header.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -23,4 +23,4 @@
   );
 
 
-}
\ No newline at end of file
+}
diff --git a/static_src/react/issue-wizard/IssueWizardConfig.ts b/static_src/react/issue-wizard/IssueWizardConfig.ts
index b7f1c17..3c5a3f5 100644
--- a/static_src/react/issue-wizard/IssueWizardConfig.ts
+++ b/static_src/react/issue-wizard/IssueWizardConfig.ts
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -322,6 +322,7 @@
           "Blink>Vibration",
           "Blink>ViewSource",
           "Blink>WebAudio",
+          "Blink>WebAuthentication",
           "Blink>WebComponents",
           "Blink>WebCrypto",
           "Blink>WebFonts",
@@ -330,7 +331,7 @@
           "Blink>WebMIDI",
           "Blink>WebRTC",
           "Blink>WebShare",
-          "Blink>WebVR",
+          "Blink>WebXR",
           "Blink>WindowDialog",
           "Blink>Workers",
           "Blink>XML",
diff --git a/static_src/react/issue-wizard/IssueWizardDescriptionsUtils.tsx b/static_src/react/issue-wizard/IssueWizardDescriptionsUtils.tsx
index 1baf35b..8afb320 100644
--- a/static_src/react/issue-wizard/IssueWizardDescriptionsUtils.tsx
+++ b/static_src/react/issue-wizard/IssueWizardDescriptionsUtils.tsx
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/IssueWizardFeedback.tsx b/static_src/react/issue-wizard/IssueWizardFeedback.tsx
index 0dff09b..19b75f1 100644
--- a/static_src/react/issue-wizard/IssueWizardFeedback.tsx
+++ b/static_src/react/issue-wizard/IssueWizardFeedback.tsx
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/IssueWizardTypes.tsx b/static_src/react/issue-wizard/IssueWizardTypes.tsx
index 3f43bce..a7b0920 100644
--- a/static_src/react/issue-wizard/IssueWizardTypes.tsx
+++ b/static_src/react/issue-wizard/IssueWizardTypes.tsx
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/IssueWizardUtils.tsx b/static_src/react/issue-wizard/IssueWizardUtils.tsx
index e709115..f94ab3a 100644
--- a/static_src/react/issue-wizard/IssueWizardUtils.tsx
+++ b/static_src/react/issue-wizard/IssueWizardUtils.tsx
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -126,18 +126,20 @@
 
 export function buildIssueLabels(category: string, osName: string, chromeVersion: string, configLabels: Array<string> | null | undefined): Array<any> {
   const labels = [
-    {label:'via-wizard-'+category},
+    {label:'Via-Wizard'},
     {label:'Pri-2'},
   ];
 
   const os = osName.split(' ')[0];
-  if (os !== 'Unknown/Other') {
+  if (os !== 'Unknown/Other' && category !== 'Security') {
     labels.push({
       label: 'OS-'+os
     })
   }
   const mainChromeVersion = chromeVersion.split('.').length > 0 ? chromeVersion.split('.')[0] : null;
-  if (mainChromeVersion !== null) {
+  // Label creation is frozen for Chromium in Monorail, and Needs-Triage-M121 and up don't exist.
+  // So, don't add it in that case.
+  if (mainChromeVersion !== null && parseInt(mainChromeVersion) < 121) {
     labels.push({
       label:'Needs-Triage-M'+mainChromeVersion
     });
diff --git a/static_src/react/issue-wizard/LandingStep.tsx b/static_src/react/issue-wizard/LandingStep.tsx
index 3a83b2c..9eaf8ae 100644
--- a/static_src/react/issue-wizard/LandingStep.tsx
+++ b/static_src/react/issue-wizard/LandingStep.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/RadioDescription/RadioDescription.test.tsx b/static_src/react/issue-wizard/RadioDescription/RadioDescription.test.tsx
index 6d1398f..cfda50f 100644
--- a/static_src/react/issue-wizard/RadioDescription/RadioDescription.test.tsx
+++ b/static_src/react/issue-wizard/RadioDescription/RadioDescription.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/RadioDescription/RadioDescription.tsx b/static_src/react/issue-wizard/RadioDescription/RadioDescription.tsx
index d371ef7..a2f6894 100644
--- a/static_src/react/issue-wizard/RadioDescription/RadioDescription.tsx
+++ b/static_src/react/issue-wizard/RadioDescription/RadioDescription.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/RadioDescription/RoleSelection/RoleSelection.tsx b/static_src/react/issue-wizard/RadioDescription/RoleSelection/RoleSelection.tsx
index f1f1933..683776e 100644
--- a/static_src/react/issue-wizard/RadioDescription/RoleSelection/RoleSelection.tsx
+++ b/static_src/react/issue-wizard/RadioDescription/RoleSelection/RoleSelection.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -92,4 +92,3 @@
     </div>
   )
 }
-
diff --git a/static_src/react/issue-wizard/SelectMenu.test.tsx b/static_src/react/issue-wizard/SelectMenu.test.tsx
index b25baea..51609ef 100644
--- a/static_src/react/issue-wizard/SelectMenu.test.tsx
+++ b/static_src/react/issue-wizard/SelectMenu.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/SelectMenu.tsx b/static_src/react/issue-wizard/SelectMenu.tsx
index f440d55..3dec29c 100644
--- a/static_src/react/issue-wizard/SelectMenu.tsx
+++ b/static_src/react/issue-wizard/SelectMenu.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/issue-wizard/SubmitSuccessStep.tsx b/static_src/react/issue-wizard/SubmitSuccessStep.tsx
index 7654b7c..cf5cef9 100644
--- a/static_src/react/issue-wizard/SubmitSuccessStep.tsx
+++ b/static_src/react/issue-wizard/SubmitSuccessStep.tsx
@@ -1,4 +1,4 @@
- // Copyright 2021 The Chromium Authors. All rights reserved.
+ // Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/mr-react-autocomplete.test.ts b/static_src/react/mr-react-autocomplete.test.ts
index 21d6c9e..0c4bf69 100644
--- a/static_src/react/mr-react-autocomplete.test.ts
+++ b/static_src/react/mr-react-autocomplete.test.ts
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/mr-react-autocomplete.tsx b/static_src/react/mr-react-autocomplete.tsx
index c9a17ff..24eebd7 100644
--- a/static_src/react/mr-react-autocomplete.tsx
+++ b/static_src/react/mr-react-autocomplete.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/tests/AttachmentUploader.test.tsx b/static_src/react/tests/AttachmentUploader.test.tsx
index 344822e..7c515fc 100644
--- a/static_src/react/tests/AttachmentUploader.test.tsx
+++ b/static_src/react/tests/AttachmentUploader.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/tests/ConfirmBackModal.test.tsx b/static_src/react/tests/ConfirmBackModal.test.tsx
index 94856d4..c0bd79d 100644
--- a/static_src/react/tests/ConfirmBackModal.test.tsx
+++ b/static_src/react/tests/ConfirmBackModal.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/tests/CustomQuestionsStep.test.tsx b/static_src/react/tests/CustomQuestionsStep.test.tsx
index 0b43dee..a08f14b 100644
--- a/static_src/react/tests/CustomQuestionsStep.test.tsx
+++ b/static_src/react/tests/CustomQuestionsStep.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx b/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx
index 6e5edae..7b2932b 100644
--- a/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx
+++ b/static_src/react/tests/IssueWizardDescriptionUtils.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/react/tests/IssueWizardUtils.test.tsx b/static_src/react/tests/IssueWizardUtils.test.tsx
index 4211160..2aa773a 100644
--- a/static_src/react/tests/IssueWizardUtils.test.tsx
+++ b/static_src/react/tests/IssueWizardUtils.test.tsx
@@ -1,4 +1,4 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
+// Copyright 2021 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/base.js b/static_src/reducers/base.js
index f4603b7..9035123 100644
--- a/static_src/reducers/base.js
+++ b/static_src/reducers/base.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/hotlists.js b/static_src/reducers/hotlists.js
index 95989cc..a46bbfa 100644
--- a/static_src/reducers/hotlists.js
+++ b/static_src/reducers/hotlists.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/hotlists.test.js b/static_src/reducers/hotlists.test.js
index 4aa42a2..d9a68c9 100644
--- a/static_src/reducers/hotlists.test.js
+++ b/static_src/reducers/hotlists.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/issueV0.js b/static_src/reducers/issueV0.js
index 8f670c9..5ffafd9 100644
--- a/static_src/reducers/issueV0.js
+++ b/static_src/reducers/issueV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -30,6 +30,13 @@
 
 /** @typedef {import('redux').AnyAction} AnyAction */
 
+
+const RESTRICT_VIEW_PREFIX = 'restrict-view-';
+const RESTRICT_EDIT_PREFIX = 'restrict-editissue-';
+const RESTRICT_COMMENT_PREFIX = 'restrict-addissuecomment-';
+const MIGRATED_BUGANIZER_ISSUE_PREFIXES = ['migrated-to-b-', 'copybara-migration-complete-', 'cob-migrated-to-b-'];
+const MIGRATED_LAUNCH_ISSUE_PREFIXES = ['migrated-to-launch-'];
+
 // Actions
 export const VIEW_ISSUE = 'VIEW_ISSUE';
 
@@ -490,12 +497,6 @@
 });
 
 // Selectors
-const RESTRICT_VIEW_PREFIX = 'restrict-view-';
-const RESTRICT_EDIT_PREFIX = 'restrict-editissue-';
-const RESTRICT_COMMENT_PREFIX = 'restrict-addissuecomment-';
-const MIGRATED_ISSUE_PREFIX = 'migrated-to-';
-const MIGRATED_BUGANIZER_ISSUE_PREFIX = 'migrated-to-b-';
-const MIGRATED_LAUNCH_ISSUE_PREFIX = 'migrated-to-launch-';
 
 /**
  * Selector to retrieve all normalized Issue data in the Redux store,
@@ -706,48 +707,60 @@
     },
 );
 
+/**
+ * Helper to find the issue ID for a migration label if one exists, otherwise
+ * returns undefined.
+ * @param {Array<LabelRef>} labelRefs
+ * @param {Array<string>} validPrefixes
+ * @return {string?} issue referenced in label or undefined if none found.
+ */
+function extractIdFromLabels(labelRefs, validPrefixes) {
+  // Assume that there's only one migrated-to-* label. Or at least drop any
+  // labels besides the first one.
+  const migrationLabel = labelRefs.find((labelRef) => validPrefixes.find(
+    (prefix) => labelRef.label.toLowerCase().startsWith(prefix)));
+
+  if (!migrationLabel) return undefined;
+
+  const {label} = migrationLabel;
+
+  const matchedPrefix = validPrefixes.find((prefix) => label.startsWith(prefix));
+
+  return migrationLabel.label.substring(matchedPrefix.length);
+}
+
 // Gets the Issue Tracker or Launch ID of a moved issue.
 export const migratedId = createSelector(
+  viewedIssue,
   labelRefs,
-  (labelRefs) => {
+  (issue, labelRefs) => {
+    if (issue && issue.migratedId) return issue.migratedId;
     if (!labelRefs) return '';
 
-    // Assume that there's only one migrated-to-* label. Or at least drop any
-    // labels besides the first one.
-    const migrationLabel = labelRefs.find((labelRef) => {
-      return labelRef.label.toLowerCase().startsWith(MIGRATED_ISSUE_PREFIX);
-    });
-    
-    if (migrationLabel) {
-      if (migrationLabel.label.toLowerCase().startsWith(MIGRATED_BUGANIZER_ISSUE_PREFIX)) {
-        return migrationLabel.label.substring(MIGRATED_BUGANIZER_ISSUE_PREFIX.length);
-      } else if (migrationLabel.label.toLowerCase().startsWith(MIGRATED_LAUNCH_ISSUE_PREFIX)) {
-        return migrationLabel.label.substring(MIGRATED_LAUNCH_ISSUE_PREFIX.length);
-      }
-    }
+    const launchIssue = extractIdFromLabels(labelRefs, MIGRATED_LAUNCH_ISSUE_PREFIXES);
+    if (launchIssue) return launchIssue;
+
+    const bIssue = extractIdFromLabels(labelRefs, MIGRATED_BUGANIZER_ISSUE_PREFIXES);
+    if (bIssue) return bIssue;
+
     return '';
   },
 );
 
 // Gets the Issue Migrated Type of a moved issue.
 export const migratedType = createSelector(
+  viewedIssue,
   labelRefs,
-  (labelRefs) => {
+  (issue, labelRefs) => {
+    if (issue && issue.migratedId) return migratedTypes.BUGANIZER_TYPE;
     if (!labelRefs) return migratedTypes.NONE;
 
-    // Assume that there's only one migrated-to-* label. Or at least drop any
-    // labels besides the first one.
-    const migrationLabel = labelRefs.find((labelRef) => {
-      return labelRef.label.toLowerCase().startsWith(MIGRATED_ISSUE_PREFIX);
-    });
+    const launchIssue = extractIdFromLabels(labelRefs, MIGRATED_LAUNCH_ISSUE_PREFIXES);
+    if (launchIssue) return migratedTypes.LAUNCH_TYPE;
 
-    if (migrationLabel) {
-      if (migrationLabel.label.toLowerCase().startsWith(MIGRATED_BUGANIZER_ISSUE_PREFIX)) {
-        return migratedTypes.BUGANIZER_TYPE;
-      } else if (migrationLabel.label.toLowerCase().startsWith(MIGRATED_LAUNCH_ISSUE_PREFIX)) {
-        return migratedTypes.LAUNCH_TYPE;
-      }
-    }
+    const bIssue = extractIdFromLabels(labelRefs, MIGRATED_BUGANIZER_ISSUE_PREFIXES);
+    if (bIssue) return migratedTypes.BUGANIZER_TYPE;
+
     return migratedTypes.NONE;
   },
 );
diff --git a/static_src/reducers/issueV0.test.js b/static_src/reducers/issueV0.test.js
index b79cdb5..9e9a0b1 100644
--- a/static_src/reducers/issueV0.test.js
+++ b/static_src/reducers/issueV0.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -300,72 +300,103 @@
     });
   });
 
-  it('migratedId', () => {
-    assert.equal(issueV0.migratedId(wrapIssue()), '');
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: []})), '');
+  describe('migratedId', () => {
+    it('no id on empty labels', () => {
+      assert.equal(issueV0.migratedId(wrapIssue()), '');
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: []})), '');
+    });
 
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'IgnoreThis'},
-      {label: 'IgnoreThis2'},
-    ]})), '');
+    it('ignores irrelevant labels', () => {
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'IgnoreThis2'},
+      ]})), '');
 
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'IgnoreThis'},
-      {label: 'IgnoreThis2'},
-      {label: 'migrated-to-b-6789'},
-    ]})), '6789');
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'IgnoreThis2'},
+        {label: 'migrated-to-b-6789'},
+      ]})), '6789');
+    });
 
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'migrated-to-b-1234'},
-    ]})), '1234');
+    it('finds first relevant label', () => {
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'migrated-to-b-1234'},
+      ]})), '1234');
 
-    // We assume there's only one migrated-to-b-* label.
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'migrated-to-b-1234'},
-      {label: 'migrated-to-b-6789'},
-    ]})), '1234');
+      // We assume there's only one migrated-to-b-* label.
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'migrated-to-b-1234'},
+        {label: 'migrated-to-b-6789'},
+      ]})), '1234');
+    });
 
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'IgnoreThis'},
-      {label: 'IgnoreThis2'},
-      {label: 'migrated-to-launch-6789'},
-    ]})), '6789');
+    it('finds copybara labels', () => {
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'copybara-migration-complete-1234'},
+      ]})), '1234');
 
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'migrated-to-launch-1234'},
-    ]})), '1234');
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'copybara-migration-complete-1234'},
+        {label: 'migrated-to-b-6789'},
+      ]})), '1234');
+    });
 
-    // We assume there's only one migrated-to-* label.
-    assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
-      {label: 'migrated-to-launch-1234'},
-      {label: 'migrated-to-b-6789'},
-    ]})), '1234');
+    it('finds launch labels', () => {
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'IgnoreThis2'},
+        {label: 'migrated-to-launch-6789'},
+      ]})), '6789');
+
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'migrated-to-launch-1234'},
+      ]})), '1234');
+
+      assert.equal(issueV0.migratedId(wrapIssue({labelRefs: [
+        {label: 'migrated-to-launch-1234'},
+        {label: 'migrated-to-b-6789'},
+      ]})), '1234');
+    });
   });
 
-  it('migratedType', () => {
-    assert.equal(issueV0.migratedType(wrapIssue()), migratedTypes.NONE);
-    assert.equal(issueV0.migratedType(wrapIssue({labelRefs: []})), migratedTypes.NONE);
+ describe('migratedType', () => {
+    it('none type on empty labels', () => {
+      assert.equal(issueV0.migratedType(wrapIssue()), migratedTypes.NONE);
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: []})), migratedTypes.NONE);
+    });
 
-    assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
-      {label: 'IgnoreThis'},
-      {label: 'IgnoreThis2'},
-    ]})), migratedTypes.NONE);
+    it('none type on irrelevant labels', () => {
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'IgnoreThis2'},
+      ]})), migratedTypes.NONE);
+    });
 
-    assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
-      {label: 'IgnoreThis'},
-      {label: 'IgnoreThis2'},
-      {label: 'migrated-to-b-6789'},
-    ]})), migratedTypes.BUGANIZER_TYPE);
+    it('buganizer type for buganizer labels', () => {
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'IgnoreThis2'},
+        {label: 'migrated-to-b-6789'},
+      ]})), migratedTypes.BUGANIZER_TYPE);
 
-    assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
-      {label: 'migrated-to-launch-1234'},
-    ]})), migratedTypes.LAUNCH_TYPE);
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
+        {label: 'IgnoreThis'},
+        {label: 'copybara-migration-complete-1234'},
+      ]})), migratedTypes.BUGANIZER_TYPE);
+    });
 
-    // We assume there's only one migrated-to-b-* label.
-    assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
-      {label: 'migrated-to-launch-1234'},
-      {label: 'migrated-to-b-6789'},
-    ]})), migratedTypes.LAUNCH_TYPE);
+    it('launch type for launch labels', () => {
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
+        {label: 'migrated-to-launch-1234'},
+      ]})), migratedTypes.LAUNCH_TYPE);
+
+      // We assume there's only one migrated-to-b-* label.
+      assert.equal(issueV0.migratedType(wrapIssue({labelRefs: [
+        {label: 'migrated-to-launch-1234'},
+        {label: 'migrated-to-b-6789'},
+      ]})), migratedTypes.LAUNCH_TYPE);
+    });
   });
 
 
diff --git a/static_src/reducers/permissions.js b/static_src/reducers/permissions.js
index 2f0101b..3809f9f 100644
--- a/static_src/reducers/permissions.js
+++ b/static_src/reducers/permissions.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/permissions.test.js b/static_src/reducers/permissions.test.js
index 3c29076..2d63308 100644
--- a/static_src/reducers/permissions.test.js
+++ b/static_src/reducers/permissions.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/projectV0.js b/static_src/reducers/projectV0.js
index 5101ff8..c8bd80a 100644
--- a/static_src/reducers/projectV0.js
+++ b/static_src/reducers/projectV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/projectV0.test.js b/static_src/reducers/projectV0.test.js
index fb1f051..772e29d 100644
--- a/static_src/reducers/projectV0.test.js
+++ b/static_src/reducers/projectV0.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/projects.js b/static_src/reducers/projects.js
index 955dfea..f9ab04c 100644
--- a/static_src/reducers/projects.js
+++ b/static_src/reducers/projects.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/projects.test.js b/static_src/reducers/projects.test.js
index 0a9dee4..5b2bab5 100644
--- a/static_src/reducers/projects.test.js
+++ b/static_src/reducers/projects.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/redux-helpers.js b/static_src/reducers/redux-helpers.js
index ce80d60..2a6964a 100644
--- a/static_src/reducers/redux-helpers.js
+++ b/static_src/reducers/redux-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/redux-helpers.test.js b/static_src/reducers/redux-helpers.test.js
index 93f0e0a..eb9105d 100644
--- a/static_src/reducers/redux-helpers.test.js
+++ b/static_src/reducers/redux-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/sitewide.js b/static_src/reducers/sitewide.js
index f7e20d7..e4ee775 100644
--- a/static_src/reducers/sitewide.js
+++ b/static_src/reducers/sitewide.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/sitewide.test.js b/static_src/reducers/sitewide.test.js
index 114ecaf..401cee2 100644
--- a/static_src/reducers/sitewide.test.js
+++ b/static_src/reducers/sitewide.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/stars.js b/static_src/reducers/stars.js
index b67ff9d..051d99a 100644
--- a/static_src/reducers/stars.js
+++ b/static_src/reducers/stars.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/stars.test.js b/static_src/reducers/stars.test.js
index 3437723..14f234f 100644
--- a/static_src/reducers/stars.test.js
+++ b/static_src/reducers/stars.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/ui.js b/static_src/reducers/ui.js
index 871cf87..7ebc1f6 100644
--- a/static_src/reducers/ui.js
+++ b/static_src/reducers/ui.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/ui.test.js b/static_src/reducers/ui.test.js
index 587bc0c..c110e16 100644
--- a/static_src/reducers/ui.test.js
+++ b/static_src/reducers/ui.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/userV0.js b/static_src/reducers/userV0.js
index 33252c5..e561ad9 100644
--- a/static_src/reducers/userV0.js
+++ b/static_src/reducers/userV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/userV0.test.js b/static_src/reducers/userV0.test.js
index aab7989..30cc311 100644
--- a/static_src/reducers/userV0.test.js
+++ b/static_src/reducers/userV0.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/users.js b/static_src/reducers/users.js
index af8609c..f8a0306 100644
--- a/static_src/reducers/users.js
+++ b/static_src/reducers/users.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/reducers/users.test.js b/static_src/reducers/users.test.js
index ea0ce61..fe02b33 100644
--- a/static_src/reducers/users.test.js
+++ b/static_src/reducers/users.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/consts/approval.js b/static_src/shared/consts/approval.js
index 772025d..73db792 100644
--- a/static_src/shared/consts/approval.js
+++ b/static_src/shared/consts/approval.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/consts/index.js b/static_src/shared/consts/index.js
index bb196b3..f296dc6 100644
--- a/static_src/shared/consts/index.js
+++ b/static_src/shared/consts/index.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 export const SERVER_LIST_ISSUES_LIMIT = 100000;
diff --git a/static_src/shared/consts/permissions.js b/static_src/shared/consts/permissions.js
index 8c8ef1b..71677b6 100644
--- a/static_src/shared/consts/permissions.js
+++ b/static_src/shared/consts/permissions.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/converters.js b/static_src/shared/converters.js
index 308df2d..758eb17 100644
--- a/static_src/shared/converters.js
+++ b/static_src/shared/converters.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 // Based on: https://source.chromium.org/chromium/infra/infra/+/main:appengine/monorail/project/project_constants.py;l=13
diff --git a/static_src/shared/converters.test.js b/static_src/shared/converters.test.js
index 428a74d..8700a99 100644
--- a/static_src/shared/converters.test.js
+++ b/static_src/shared/converters.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/convertersV0.js b/static_src/shared/convertersV0.js
index ffb8a36..5a50d8a 100644
--- a/static_src/shared/convertersV0.js
+++ b/static_src/shared/convertersV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -14,7 +14,7 @@
 
 import qs from 'qs';
 
-import {equalsIgnoreCase, capitalizeFirst} from './helpers.js';
+import {equalsIgnoreCase, capitalizeFirst, generateProjectIssueURL} from './helpers.js';
 import {fromShortlink} from 'shared/federated.js';
 import {UserInputError} from 'shared/errors.js';
 import './typedef.js';
@@ -522,14 +522,11 @@
     return extRef.toURL();
   }
 
-  let paramString = '';
   if (Object.keys(queryParamsCopy).length) {
     delete queryParamsCopy.id;
-
-    paramString = `&${qs.stringify(queryParamsCopy)}`;
   }
-
-  return `/p/${ref.projectName}/issues/detail?id=${ref.localId}${paramString}`;
+  const params = {'id': ref.localId, ...queryParamsCopy};
+  return generateProjectIssueURL(ref.projectName, '/detail', params);
 }
 
 /**
diff --git a/static_src/shared/convertersV0.test.js b/static_src/shared/convertersV0.test.js
index 2e34622..cf20b59 100644
--- a/static_src/shared/convertersV0.test.js
+++ b/static_src/shared/convertersV0.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/cron.js b/static_src/shared/cron.js
index bd67507..dec83ab 100644
--- a/static_src/shared/cron.js
+++ b/static_src/shared/cron.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/cron.test.js b/static_src/shared/cron.test.js
index e2f9a8e..85d07c6 100644
--- a/static_src/shared/cron.test.js
+++ b/static_src/shared/cron.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/dom-helpers.js b/static_src/shared/dom-helpers.js
index 81dec80..545ffa2 100644
--- a/static_src/shared/dom-helpers.js
+++ b/static_src/shared/dom-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/dom-helpers.test.js b/static_src/shared/dom-helpers.test.js
index 78d535a..e500ceb 100644
--- a/static_src/shared/dom-helpers.test.js
+++ b/static_src/shared/dom-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/errors.js b/static_src/shared/errors.js
index 81c0035..4b4a7a8 100644
--- a/static_src/shared/errors.js
+++ b/static_src/shared/errors.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/experiments.js b/static_src/shared/experiments.js
index 1528a00..50934e6 100644
--- a/static_src/shared/experiments.js
+++ b/static_src/shared/experiments.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/experiments.test.js b/static_src/shared/experiments.test.js
index d5f96b7..929060d 100644
--- a/static_src/shared/experiments.test.js
+++ b/static_src/shared/experiments.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/federated.js b/static_src/shared/federated.js
index e5b7567..7b4af3c 100644
--- a/static_src/shared/federated.js
+++ b/static_src/shared/federated.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/federated.test.js b/static_src/shared/federated.test.js
index 011b924..95da053 100644
--- a/static_src/shared/federated.test.js
+++ b/static_src/shared/federated.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/ga-helpers.js b/static_src/shared/ga-helpers.js
index 52d1176..7dc1c44 100644
--- a/static_src/shared/ga-helpers.js
+++ b/static_src/shared/ga-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/ga-helpers.test.js b/static_src/shared/ga-helpers.test.js
index 1876a27..e12c9e1 100644
--- a/static_src/shared/ga-helpers.test.js
+++ b/static_src/shared/ga-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/gapi-loader.js b/static_src/shared/gapi-loader.js
index 5249d68..7a93b6d 100644
--- a/static_src/shared/gapi-loader.js
+++ b/static_src/shared/gapi-loader.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/gapi-loader.test.js b/static_src/shared/gapi-loader.test.js
index d385861..481c026 100644
--- a/static_src/shared/gapi-loader.test.js
+++ b/static_src/shared/gapi-loader.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/helpers.js b/static_src/shared/helpers.js
index 362b4ec..968d05e 100644
--- a/static_src/shared/helpers.js
+++ b/static_src/shared/helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -211,3 +211,29 @@
 export const shouldWaitForDefaultQuery = (queryParams) => {
   return !queryParams.hasOwnProperty('q');
 };
+
+// constant value for required redirect project
+const redirectProjects = Object.freeze(['pigweed', 'git', 'gerrit', 'skia', 'fuchsia']);
+
+/**
+ * Generate the url link for issue in project.
+ * @param {string} projectName Name of the project.
+ * @param {string} subUrl the sub URL without query params.
+ * @param {Object} params the query params.
+ * @return {string} the new URL
+ */
+export function generateProjectIssueURL(projectName, subPath, params = {}) {
+  const queryString = window.location.search;
+  const urlParams = new URLSearchParams(queryString);
+  const noRedirect = urlParams.has('no_tracker_redirect');
+  let baseUrl = '';
+  if (!noRedirect && redirectProjects.includes(projectName)) {
+    // Full url path will trigger backend service call to handle redirect.
+    baseUrl = 'https://bugs.chromium.org/p/' + projectName + '/issues' + subPath;
+    return urlWithNewParams(baseUrl, params, {}, undefined)
+  } else {
+    baseUrl = '/p/' + projectName + '/issues' + subPath;
+    const noRedirectParam = noRedirect ? {'no_tracker_redirect' : 1} : undefined
+    return urlWithNewParams(baseUrl, params, noRedirectParam, undefined)
+  }
+}
\ No newline at end of file
diff --git a/static_src/shared/helpers.test.js b/static_src/shared/helpers.test.js
index 7c40ed5..e05a9a2 100644
--- a/static_src/shared/helpers.test.js
+++ b/static_src/shared/helpers.test.js
@@ -1,12 +1,11 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 import {assert} from 'chai';
 import {arrayDifference, setHasAny, capitalizeFirst, hasPrefix, objectToMap,
   objectValuesForKeys, equalsIgnoreCase, immutableSplice, userIsMember,
-  urlWithNewParams, createObjectComparisonFunc} from './helpers.js';
-
+  urlWithNewParams, createObjectComparisonFunc, generateProjectIssueURL} from './helpers.js';
 
 describe('arrayDifference', () => {
   it('empty array stays empty', () => {
@@ -359,3 +358,15 @@
     });
   });
 });
+
+describe('generateProjectIssueURL', () => {
+  it('no redirect required and no param', () => {
+    assert.equal(generateProjectIssueURL('project', '/list'), '/p/project/issues/list');
+  });
+
+  it('no redirect required and with param', () => {
+    assert.equal(generateProjectIssueURL('project', '/detail', {'id': 123}), '/p/project/issues/detail?id=123');
+  });
+
+  //TODO(crbug.com/monorail/12029): add more unit test.
+});
\ No newline at end of file
diff --git a/static_src/shared/issue-fields.js b/static_src/shared/issue-fields.js
index 0acbe60..09322e8 100644
--- a/static_src/shared/issue-fields.js
+++ b/static_src/shared/issue-fields.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/issue-fields.test.js b/static_src/shared/issue-fields.test.js
index c37faa9..091f7c8 100644
--- a/static_src/shared/issue-fields.test.js
+++ b/static_src/shared/issue-fields.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/math.js b/static_src/shared/math.js
index 36e2d75..2208997 100644
--- a/static_src/shared/math.js
+++ b/static_src/shared/math.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/math.test.js b/static_src/shared/math.test.js
index 4b4c153..88e1df0 100644
--- a/static_src/shared/math.test.js
+++ b/static_src/shared/math.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/metadata-helpers.js b/static_src/shared/metadata-helpers.js
index 5735557..ae20919 100644
--- a/static_src/shared/metadata-helpers.js
+++ b/static_src/shared/metadata-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/metadata-helpers.test.js b/static_src/shared/metadata-helpers.test.js
index fd04806..55f8c59 100644
--- a/static_src/shared/metadata-helpers.test.js
+++ b/static_src/shared/metadata-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/settings.js b/static_src/shared/settings.js
index 0b5fc3c..3a4aa49 100644
--- a/static_src/shared/settings.js
+++ b/static_src/shared/settings.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/shared-styles.js b/static_src/shared/shared-styles.js
index c00f639..b01898e 100644
--- a/static_src/shared/shared-styles.js
+++ b/static_src/shared/shared-styles.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -200,4 +200,4 @@
     min-height: 5vh;
     max-height: 15vh;
   }
-`;
\ No newline at end of file
+`;
diff --git a/static_src/shared/test/constants-hotlists.js b/static_src/shared/test/constants-hotlists.js
index a496905..c6c5b45 100644
--- a/static_src/shared/test/constants-hotlists.js
+++ b/static_src/shared/test/constants-hotlists.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-issueV0.js b/static_src/shared/test/constants-issueV0.js
index 4f52aef..0051949 100644
--- a/static_src/shared/test/constants-issueV0.js
+++ b/static_src/shared/test/constants-issueV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-permissions.js b/static_src/shared/test/constants-permissions.js
index f4b09c0..0ac763e 100644
--- a/static_src/shared/test/constants-permissions.js
+++ b/static_src/shared/test/constants-permissions.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-projectV0.js b/static_src/shared/test/constants-projectV0.js
index 4a46af8..02e91b9 100644
--- a/static_src/shared/test/constants-projectV0.js
+++ b/static_src/shared/test/constants-projectV0.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-projects.js b/static_src/shared/test/constants-projects.js
index c25f46b..6bd852e 100644
--- a/static_src/shared/test/constants-projects.js
+++ b/static_src/shared/test/constants-projects.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-stars.js b/static_src/shared/test/constants-stars.js
index 42e7012..57ede35 100644
--- a/static_src/shared/test/constants-stars.js
+++ b/static_src/shared/test/constants-stars.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/constants-users.js b/static_src/shared/test/constants-users.js
index 0a9bbf8..f29f588 100644
--- a/static_src/shared/test/constants-users.js
+++ b/static_src/shared/test/constants-users.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -40,4 +40,3 @@
   name: 'projects/proj/members/1234',
   role: 'CONTRIBUTOR',
 });
-
diff --git a/static_src/shared/test/fakes.js b/static_src/shared/test/fakes.js
index d506f6a..f63cc46 100644
--- a/static_src/shared/test/fakes.js
+++ b/static_src/shared/test/fakes.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/shared/test/helpers.js b/static_src/shared/test/helpers.js
index 63a1e12..e7eba6f 100644
--- a/static_src/shared/test/helpers.js
+++ b/static_src/shared/test/helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -54,4 +54,3 @@
 
   fireEvent.keyDown(input, {key: 'Enter', code: 'Enter'});
 }
-
diff --git a/static_src/shared/typedef.js b/static_src/shared/typedef.js
index 923e1db..9b4aa0f 100644
--- a/static_src/shared/typedef.js
+++ b/static_src/shared/typedef.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/test/index.js b/static_src/test/index.js
index e38c23a..0dfb1f8 100644
--- a/static_src/test/index.js
+++ b/static_src/test/index.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/test/setup.js b/static_src/test/setup.js
index 7907cdd..621e6d3 100644
--- a/static_src/test/setup.js
+++ b/static_src/test/setup.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -13,4 +13,4 @@
   // We reset the Redux state before each test run to prevent Redux
   // state changes in previous tests from affecting results.
   store.dispatch(resetState());
-});
\ No newline at end of file
+});