diff --git a/static/js/tracker/tracker-ac.js b/static/js/tracker/tracker-ac.js
new file mode 100644
index 0000000..4d98ac1
--- /dev/null
+++ b/static/js/tracker/tracker-ac.js
@@ -0,0 +1,1285 @@
+/* Copyright 2016 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 or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+/* eslint-disable camelcase */
+/* eslint-disable no-unused-vars */
+
+/**
+ * This file contains the autocomplete configuration logic that is
+ * specific to the issue fields of Monorail.  It depends on ac.js, our
+ * modified version of the autocomplete library.
+ */
+
+/**
+ * This is an autocomplete store that holds the hotlists of the current user.
+ */
+let TKR_hotlistsStore;
+
+/**
+ * This is an autocomplete store that holds well-known issue label
+ * values for the current project.
+ */
+let TKR_labelStore;
+
+/**
+ * Like TKR_labelStore but stores only label prefixes.
+ */
+let TKR_labelPrefixStore;
+
+/**
+ * Like TKR_labelStore but adds a trailing comma instead of replacing.
+ */
+let TKR_labelMultiStore;
+
+/**
+ * This is an autocomplete store that holds issue components.
+ */
+let TKR_componentStore;
+
+/**
+ * Like TKR_componentStore but adds a trailing comma instead of replacing.
+ */
+let TKR_componentListStore;
+
+/**
+ * This is an autocomplete store that holds many different kinds of
+ * items that can be shown in the artifact search autocomplete.
+ */
+let TKR_searchStore;
+
+/**
+ * This is similar to TKR_searchStore, but does not include any suggestions
+ * to use the "me" keyword. Using "me" is not a good idea for project canned
+ * queries and filter rules.
+ */
+let TKR_projectQueryStore;
+
+/**
+ * This is an autocomplete store that holds items for the quick edit
+ * autocomplete.
+ */
+// TODO(jrobbins): add options for fields and components.
+let TKR_quickEditStore;
+
+/**
+ * This is a list of label prefixes that each issue should only use once.
+ * E.g., each issue should only have one Priority-* label.  We do not prevent
+ * the user from using multiple such labels, we just warn the user before
+ * they submit.
+ */
+let TKR_exclPrefixes = [];
+
+/**
+ * This is an autocomplete store that holds custom permission names that
+ * have already been used in this project.
+ */
+let TKR_customPermissionsStore;
+
+
+/**
+ * This is an autocomplete store that holds well-known issue status
+ * values for the current project.
+ */
+let TKR_statusStore;
+
+
+/**
+ * This is an autocomplete store that holds the usernames of all the
+ * members of the current project.  This is used for autocomplete in
+ * the cc-list of an issue, where many user names can entered with
+ * commas between them.
+ */
+let TKR_memberListStore;
+
+
+/**
+ * This is an autocomplete store that holds the projects that the current
+ * user is contributor/member/owner of.
+ */
+let TKR_projectStore;
+
+/**
+ * This is an autocomplete store that holds the usernames of possible
+ * issue owners in the current project.  The list of possible issue
+ * owners is the same as the list of project members, but the behavior
+ * of this autocompete store is different because the issue owner text
+ * field can only accept one value.
+ */
+let TKR_ownerStore;
+
+
+/**
+ * This is an autocomplete store that holds any list of string for choices.
+ */
+let TKR_autoCompleteStore;
+
+
+/**
+ * An array of autocomplete stores used for user-type custom fields.
+ */
+const TKR_userAutocompleteStores = [];
+
+
+/**
+ * This boolean controls whether odd-ball status and labels are treated as
+ * a warning or an error.  Normally, it is False.
+ */
+// TODO(jrobbins): split this into one option for statuses and one for labels.
+let TKR_restrict_to_known;
+
+/**
+ * This substitute function should be used for multi-valued autocomplete fields
+ * that are delimited by commas. When we insert an autocomplete value, replace
+ * an entire search term. Add a comma and a space after it if it is a complete
+ * search term.
+ */
+function TKR_acSubstituteWithComma(inputValue, caret, completable, completion) {
+  let nextTerm = caret;
+
+  // Subtract one in case the cursor is at the end of the input, before a comma.
+  let prevTerm = caret - 1;
+  while (nextTerm < inputValue.length - 1 && inputValue.charAt(nextTerm) !== ',') {
+    nextTerm++;
+  }
+  // Set this at the position after the found comma.
+  nextTerm++;
+
+  while (prevTerm > 0 && ![',', ' '].includes(inputValue.charAt(prevTerm))) {
+    prevTerm--;
+  }
+  if (prevTerm > 0) {
+    // Set this boundary after the found space/comma if it's not the beginning
+    // of the field.
+    prevTerm++;
+  }
+
+  return inputValue.substring(0, prevTerm) +
+         completion.value + ', ' + inputValue.substring(nextTerm);
+}
+
+/**
+ * When the prefix starts with '*', return the complete set of all
+ * possible completions.
+ * @param {string} prefix If this starts with '*', return all possible
+ * completions.  Otherwise return null.
+ * @param {Array} labelDefs The array of label names and docstrings.
+ * @return Array of new _AC_Completions for each possible completion, or null.
+ */
+function TKR_fullComplete(prefix, labelDefs) {
+  if (!prefix.startsWith('*')) return null;
+  const out = [];
+  for (let i = 0; i < labelDefs.length; i++) {
+    out.push(new _AC_Completion(labelDefs[i].name,
+        labelDefs[i].name,
+        labelDefs[i].doc));
+  }
+  return out;
+}
+
+
+/**
+ * Constucts a list of all completions for both open and closed
+ * statuses, with a header for each group.
+ * @param {string} prefix If starts with '*', return all possible completions,
+ * else return null.
+ * @param {Array} openStatusDefs The array of open status values and
+ * docstrings.
+ * @param {Array} closedStatusDefs The array of closed status values
+ * and docstrings.
+ * @return Array of new _AC_Completions for each possible completion, or null.
+ */
+function TKR_openClosedComplete(prefix, openStatusDefs, closedStatusDefs) {
+  if (!prefix.startsWith('*')) return null;
+  const out = [];
+  out.push({heading: 'Open Statuses:'}); // TODO: i18n
+  for (var i = 0; i < openStatusDefs.length; i++) {
+    out.push(new _AC_Completion(openStatusDefs[i].name,
+        openStatusDefs[i].name,
+        openStatusDefs[i].doc));
+  }
+  out.push({heading: 'Closed Statuses:'}); // TODO: i18n
+  for (var i = 0; i < closedStatusDefs.length; i++) {
+    out.push(new _AC_Completion(closedStatusDefs[i].name,
+        closedStatusDefs[i].name,
+        closedStatusDefs[i].doc));
+  }
+  return out;
+}
+
+
+function TKR_setUpHotlistsStore(hotlists) {
+  const docdict = {};
+  const ref_strs = [];
+
+  for (let i = 0; i < hotlists.length; i++) {
+    ref_strs.push(hotlists[i]['ref_str']);
+    docdict[hotlists[i]['ref_str']] = hotlists[i]['summary'];
+  }
+
+  TKR_hotlistsStore = new _AC_SimpleStore(ref_strs, docdict);
+  TKR_hotlistsStore.substitute = TKR_acSubstituteWithComma;
+}
+
+
+/**
+ * An array of definitions of all well-known issue statuses.  Each
+ * definition has the name of the status value, and a docstring that
+ * describes its meaning.
+ */
+let TKR_statusWords = [];
+
+
+/**
+ * Constuct a new autocomplete store with all the well-known issue
+ * status values.  The store has some DIT-specific methods.
+ * TODO(jrobbins): would it be easier to define my own class to use
+ * instead of _AC_Simple_Store?
+ * @param {Array} openStatusDefs An array of definitions of the
+ * well-known open status values.  Each definition has a name and
+ * docstring.
+ * @param {Array} closedStatusDefs An array of definitions of the
+ * well-known closed status values.  Each definition has a name and
+ * docstring.
+ */
+function TKR_setUpStatusStore(openStatusDefs, closedStatusDefs) {
+  const docdict = {};
+  TKR_statusWords = [];
+  for (var i = 0; i < openStatusDefs.length; i++) {
+    var status = openStatusDefs[i];
+    TKR_statusWords.push(status.name);
+    docdict[status.name] = status.doc;
+  }
+  for (var i = 0; i < closedStatusDefs.length; i++) {
+    var status = closedStatusDefs[i];
+    TKR_statusWords.push(status.name);
+    docdict[status.name] = status.doc;
+  }
+
+  TKR_statusStore = new _AC_SimpleStore(TKR_statusWords, docdict);
+
+  TKR_statusStore.commaCompletes = false;
+
+  TKR_statusStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  TKR_statusStore.completable = function(inputValue, cursor) {
+    if (!ac_everTyped) return '*status';
+    return inputValue;
+  };
+
+  TKR_statusStore.completions = function(prefix, tofilter) {
+    const fullList = TKR_openClosedComplete(prefix,
+        openStatusDefs,
+        closedStatusDefs);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+}
+
+
+/**
+ * Simple function to add a given item to the list of items used to construct
+ * an "autocomplete store", and also update the docstring that describes
+ * that item.  They are stored separately for backward compatability with
+ * autocomplete store logic that preceeded the introduction of descriptions.
+ */
+function TKR_addACItem(items, docDict, item, docStr) {
+  items.push(item);
+  docDict[item] = docStr;
+}
+
+/**
+ * Adds a group of three items related to a date field.
+ */
+function TKR_addACDateItems(items, docDict, fieldName, humanReadable) {
+  const today = new Date();
+  const todayStr = (today.getFullYear() + '-' + (today.getMonth() + 1) + '-' +
+    today.getDate());
+  TKR_addACItem(items, docDict, fieldName + '>today-1',
+      humanReadable + ' within the last N days');
+  TKR_addACItem(items, docDict, fieldName + '>' + todayStr,
+      humanReadable + ' after the specified date');
+  TKR_addACItem(items, docDict, fieldName + '<today-1',
+      humanReadable + ' more than N days ago');
+}
+
+/**
+ * Add several autocomplete items to a word list that will be used to construct
+ * an autocomplete store.  Also, keep track of description strings for each
+ * item.  A search operator is prepended to the name of each item.  The opt_old
+ * and opt_new parameters are used to transform Key-Value labels into Key=Value
+ * search terms.
+ */
+function TKR_addACItemList(
+    items, docDict, searchOp, acDefs, opt_old, opt_new) {
+  let item;
+  for (let i = 0; i < acDefs.length; i++) {
+    const nameAndDoc = acDefs[i];
+    item = searchOp + nameAndDoc.name;
+    if (opt_old) {
+      // Preserve any leading minus-sign.
+      item = item.slice(0, 1) + item.slice(1).replace(opt_old, opt_new);
+    }
+    TKR_addACItem(items, docDict, item, nameAndDoc.doc);
+  }
+}
+
+
+/**
+ * Use information from an options feed to populate the artifact search
+ * autocomplete menu.  The order of sections is: custom fields, labels,
+ * components, people, status, special, dates.  Within each section,
+ * options are ordered semantically where possible, or alphabetically
+ * if there is no semantic ordering.  Negated options all come after
+ * all normal options.
+ */
+function TKR_setUpSearchStore(
+    labelDefs, memberDefs, openDefs, closedDefs, componentDefs, fieldDefs,
+    indMemberDefs) {
+  let searchWords = [];
+  const searchWordsNeg = [];
+  const docDict = {};
+
+  // Treat Key-Value and OneWord labels separately.
+  const keyValueLabelDefs = [];
+  const oneWordLabelDefs = [];
+  for (var i = 0; i < labelDefs.length; i++) {
+    const nameAndDoc = labelDefs[i];
+    if (nameAndDoc.name.indexOf('-') == -1) {
+      oneWordLabelDefs.push(nameAndDoc);
+    } else {
+      keyValueLabelDefs.push(nameAndDoc);
+    }
+  }
+
+  // Autocomplete for custom fields.
+  for (i = 0; i < fieldDefs.length; i++) {
+    const fieldName = fieldDefs[i]['field_name'];
+    const fieldType = fieldDefs[i]['field_type'];
+    if (fieldType == 'ENUM_TYPE') {
+      const choices = fieldDefs[i]['choices'];
+      TKR_addACItemList(searchWords, docDict, fieldName + '=', choices);
+      TKR_addACItemList(searchWordsNeg, docDict, '-' + fieldName + '=', choices);
+    } else if (fieldType == 'STR_TYPE') {
+      TKR_addACItem(searchWords, docDict, fieldName + ':',
+          fieldDefs[i]['docstring']);
+    } else if (fieldType == 'DATE_TYPE') {
+      TKR_addACItem(searchWords, docDict, fieldName + ':',
+          fieldDefs[i]['docstring']);
+      TKR_addACDateItems(searchWords, docDict, fieldName, fieldName);
+    } else {
+      TKR_addACItem(searchWords, docDict, fieldName + '=',
+          fieldDefs[i]['docstring']);
+    }
+    TKR_addACItem(searchWords, docDict, 'has:' + fieldName,
+        'Issues with any ' + fieldName + ' value');
+    TKR_addACItem(searchWordsNeg, docDict, '-has:' + fieldName,
+        'Issues with no ' + fieldName + ' value');
+  }
+
+  // Add suggestions with "me" first, because otherwise they may be impossible
+  // to reach in a project that has a lot of members with emails starting with
+  // "me".
+  if (CS_env['loggedInUserEmail']) {
+    TKR_addACItem(searchWords, docDict, 'owner:me', 'Issues owned by me');
+    TKR_addACItem(searchWordsNeg, docDict, '-owner:me', 'Issues not owned by me');
+    TKR_addACItem(searchWords, docDict, 'cc:me', 'Issues that CC me');
+    TKR_addACItem(searchWordsNeg, docDict, '-cc:me', 'Issues that don\'t CC me');
+    TKR_addACItem(searchWords, docDict, 'reporter:me', 'Issues I reported');
+    TKR_addACItem(searchWordsNeg, docDict, '-reporter:me', 'Issues reported by others');
+    TKR_addACItem(searchWords, docDict, 'commentby:me',
+        'Issues that I commented on');
+    TKR_addACItem(searchWordsNeg, docDict, '-commentby:me',
+        'Issues that I didn\'t comment on');
+  }
+
+  TKR_addACItemList(searchWords, docDict, '', keyValueLabelDefs, '-', '=');
+  TKR_addACItemList(searchWordsNeg, docDict, '-', keyValueLabelDefs, '-', '=');
+  TKR_addACItemList(searchWords, docDict, 'label:', oneWordLabelDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-label:', oneWordLabelDefs);
+
+  TKR_addACItemList(searchWords, docDict, 'component:', componentDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-component:', componentDefs);
+  TKR_addACItem(searchWords, docDict, 'has:component',
+      'Issues with any components specified');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:component',
+      'Issues with no components specified');
+
+  TKR_addACItemList(searchWords, docDict, 'owner:', indMemberDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-owner:', indMemberDefs);
+  TKR_addACItemList(searchWords, docDict, 'cc:', memberDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-cc:', memberDefs);
+  TKR_addACItem(searchWords, docDict, 'has:cc',
+      'Issues with any cc\'d users');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:cc',
+      'Issues with no cc\'d users');
+  TKR_addACItemList(searchWords, docDict, 'reporter:', memberDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-reporter:', memberDefs);
+  TKR_addACItemList(searchWords, docDict, 'status:', openDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-status:', openDefs);
+  TKR_addACItemList(searchWords, docDict, 'status:', closedDefs);
+  TKR_addACItemList(searchWordsNeg, docDict, '-status:', closedDefs);
+  TKR_addACItem(searchWords, docDict, 'has:status',
+      'Issues with any status');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:status',
+      'Issues with no status');
+
+  TKR_addACItem(searchWords, docDict, 'is:blocked',
+      'Issues that are blocked');
+  TKR_addACItem(searchWordsNeg, docDict, '-is:blocked',
+      'Issues that are not blocked');
+  TKR_addACItem(searchWords, docDict, 'has:blockedon',
+      'Issues that are blocked');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:blockedon',
+      'Issues that are not blocked');
+  TKR_addACItem(searchWords, docDict, 'has:blocking',
+      'Issues that are blocking other issues');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:blocking',
+      'Issues that are not blocking other issues');
+  TKR_addACItem(searchWords, docDict, 'has:mergedinto',
+      'Issues that were merged into other issues');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:mergedinto',
+      'Issues that were not merged into other issues');
+
+  TKR_addACItem(searchWords, docDict, 'is:starred',
+      'Starred by me');
+  TKR_addACItem(searchWordsNeg, docDict, '-is:starred',
+      'Not starred by me');
+  TKR_addACItem(searchWords, docDict, 'stars>10',
+      'More than 10 stars');
+  TKR_addACItem(searchWords, docDict, 'stars>100',
+      'More than 100 stars');
+  TKR_addACItem(searchWords, docDict, 'summary:',
+      'Search within the summary field');
+
+  TKR_addACItemList(searchWords, docDict, 'commentby:', memberDefs);
+  TKR_addACItem(searchWords, docDict, 'attachment:',
+      'Search within attachment names');
+  TKR_addACItem(searchWords, docDict, 'attachments>5',
+      'Has more than 5 attachments');
+  TKR_addACItem(searchWords, docDict, 'is:open', 'Issues that are open');
+  TKR_addACItem(searchWordsNeg, docDict, '-is:open', 'Issues that are closed');
+  TKR_addACItem(searchWords, docDict, 'has:owner',
+      'Issues with some owner');
+  TKR_addACItem(searchWordsNeg, docDict, '-has:owner',
+      'Issues with no owner');
+  TKR_addACItem(searchWords, docDict, 'has:attachments',
+      'Issues with some attachments');
+  TKR_addACItem(searchWords, docDict, 'id:1,2,3',
+      'Match only the specified issues');
+  TKR_addACItem(searchWords, docDict, 'id<100000',
+      'Issues with IDs under 100,000');
+  TKR_addACItem(searchWords, docDict, 'blockedon:1',
+      'Blocked on the specified issues');
+  TKR_addACItem(searchWords, docDict, 'blocking:1',
+      'Blocking the specified issues');
+  TKR_addACItem(searchWords, docDict, 'mergedinto:1',
+      'Merged into the specified issues');
+  TKR_addACItem(searchWords, docDict, 'is:ownerbouncing',
+      'Issues with owners we cannot contact');
+  TKR_addACItem(searchWords, docDict, 'is:spam', 'Issues classified as spam');
+  // We do not suggest -is:spam because it is implicit.
+
+  TKR_addACDateItems(searchWords, docDict, 'opened', 'Opened');
+  TKR_addACDateItems(searchWords, docDict, 'modified', 'Modified');
+  TKR_addACDateItems(searchWords, docDict, 'closed', 'Closed');
+  TKR_addACDateItems(searchWords, docDict, 'ownermodified', 'Owner field modified');
+  TKR_addACDateItems(searchWords, docDict, 'ownerlastvisit', 'Owner last visit');
+  TKR_addACDateItems(searchWords, docDict, 'statusmodified', 'Status field modified');
+  TKR_addACDateItems(
+      searchWords, docDict, 'componentmodified', 'Component field modified');
+
+  TKR_projectQueryStore = new _AC_SimpleStore(searchWords, docDict);
+
+  searchWords = searchWords.concat(searchWordsNeg);
+
+  TKR_searchStore = new _AC_SimpleStore(searchWords, docDict);
+
+  // When we insert an autocomplete value, replace an entire search term.
+  // Add just a space after it (not a comma) if it is a complete search term,
+  // or leave the caret immediately after the completion if we are just helping
+  // the user with the search operator.
+  TKR_searchStore.substitute =
+      function(inputValue, caret, completable, completion) {
+        let nextTerm = caret;
+        while (inputValue.charAt(nextTerm) != ' ' &&
+               nextTerm < inputValue.length) {
+          nextTerm++;
+        }
+        while (inputValue.charAt(nextTerm) == ' ' &&
+               nextTerm < inputValue.length) {
+          nextTerm++;
+        }
+        return inputValue.substring(0, caret - completable.length) +
+               completion.value + ' ' + inputValue.substring(nextTerm);
+      };
+  TKR_searchStore.autoselectFirstRow =
+      function() {
+        return false;
+      };
+
+  TKR_projectQueryStore.substitute = TKR_searchStore.substitute;
+  TKR_projectQueryStore.autoselectFirstRow = TKR_searchStore.autoselectFirstRow;
+}
+
+
+/**
+ * Use information from an options feed to populate the issue quick edit
+ * autocomplete menu.
+ */
+function TKR_setUpQuickEditStore(
+    labelDefs, memberDefs, openDefs, closedDefs, indMemberDefs) {
+  const qeWords = [];
+  const docDict = {};
+
+  // Treat Key-Value and OneWord labels separately.
+  const keyValueLabelDefs = [];
+  const oneWordLabelDefs = [];
+  for (let i = 0; i < labelDefs.length; i++) {
+    const nameAndDoc = labelDefs[i];
+    if (nameAndDoc.name.indexOf('-') == -1) {
+      oneWordLabelDefs.push(nameAndDoc);
+    } else {
+      keyValueLabelDefs.push(nameAndDoc);
+    }
+  }
+  TKR_addACItemList(qeWords, docDict, '', keyValueLabelDefs, '-', '=');
+  TKR_addACItemList(qeWords, docDict, '-', keyValueLabelDefs, '-', '=');
+  TKR_addACItemList(qeWords, docDict, '', oneWordLabelDefs);
+  TKR_addACItemList(qeWords, docDict, '-', oneWordLabelDefs);
+
+  TKR_addACItem(qeWords, docDict, 'owner=me', 'Make me the owner');
+  TKR_addACItem(qeWords, docDict, 'owner=----', 'Clear the owner field');
+  TKR_addACItem(qeWords, docDict, 'cc=me', 'CC me on this issue');
+  TKR_addACItem(qeWords, docDict, 'cc=-me', 'Remove me from CC list');
+  TKR_addACItemList(qeWords, docDict, 'owner=', indMemberDefs);
+  TKR_addACItemList(qeWords, docDict, 'cc=', memberDefs);
+  TKR_addACItemList(qeWords, docDict, 'cc=-', memberDefs);
+  TKR_addACItemList(qeWords, docDict, 'status=', openDefs);
+  TKR_addACItemList(qeWords, docDict, 'status=', closedDefs);
+  TKR_addACItem(qeWords, docDict, 'summary=""', 'Set the summary field');
+
+  TKR_quickEditStore = new _AC_SimpleStore(qeWords, docDict);
+
+  // When we insert an autocomplete value, replace an entire command part.
+  // Add just a space after it (not a comma) if it is a complete part,
+  // or leave the caret immediately after the completion if we are just helping
+  // the user with the command operator.
+  TKR_quickEditStore.substitute =
+      function(inputValue, caret, completable, completion) {
+        let nextTerm = caret;
+        while (inputValue.charAt(nextTerm) != ' ' &&
+               nextTerm < inputValue.length) {
+          nextTerm++;
+        }
+        while (inputValue.charAt(nextTerm) == ' ' &&
+               nextTerm < inputValue.length) {
+          nextTerm++;
+        }
+        return inputValue.substring(0, caret - completable.length) +
+               completion.value + ' ' + inputValue.substring(nextTerm);
+      };
+}
+
+
+/**
+ * Constuct a new autocomplete store with all the project
+ * custom permissions.
+ * @param {Array} customPermissions An array of custom permission names.
+ */
+function TKR_setUpCustomPermissionsStore(customPermissions) {
+  customPermissions = customPermissions || [];
+  const permWords = ['View', 'EditIssue', 'AddIssueComment', 'DeleteIssue'];
+  const docdict = {
+    'View': '', 'EditIssue': '', 'AddIssueComment': '', 'DeleteIssue': ''};
+  for (let i = 0; i < customPermissions.length; i++) {
+    permWords.push(customPermissions[i]);
+    docdict[customPermissions[i]] = '';
+  }
+
+  TKR_customPermissionsStore = new _AC_SimpleStore(permWords, docdict);
+
+  TKR_customPermissionsStore.commaCompletes = false;
+
+  TKR_customPermissionsStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+}
+
+
+/**
+ * Constuct a new autocomplete store with all the well-known project
+ * member user names and real names.  The store has some
+ * monorail-specific methods.
+ * TODO(jrobbins): would it be easier to define my own class to use
+ * instead of _AC_Simple_Store?
+ * @param {Array} memberDefs an array of member objects.
+ * @param {Array} nonGroupMemberDefs an array of member objects who are not groups.
+ */
+function TKR_setUpMemberStore(memberDefs, nonGroupMemberDefs) {
+  const memberWords = [];
+  const indMemberWords = [];
+  const docdict = {};
+
+  memberDefs.forEach((memberDef) => {
+    memberWords.push(memberDef.name);
+    docdict[memberDef.name] = null;
+  });
+  nonGroupMemberDefs.forEach((memberDef) => {
+    indMemberWords.push(memberDef.name);
+  });
+
+  TKR_memberListStore = new _AC_SimpleStore(memberWords, docdict);
+
+  TKR_memberListStore.completions = function(prefix, tofilter) {
+    const fullList = TKR_fullComplete(prefix, memberDefs);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+
+  TKR_memberListStore.completable = function(inputValue, cursor) {
+    if (inputValue == '') return '*member';
+    return _AC_SimpleStore.prototype.completable.call(this, inputValue, cursor);
+  };
+
+  TKR_memberListStore.substitute = TKR_acSubstituteWithComma;
+
+  TKR_ownerStore = new _AC_SimpleStore(indMemberWords, docdict);
+
+  TKR_ownerStore.commaCompletes = false;
+
+  TKR_ownerStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  TKR_ownerStore.completions = function(prefix, tofilter) {
+    const fullList = TKR_fullComplete(prefix, nonGroupMemberDefs);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+
+  TKR_ownerStore.completable = function(inputValue, cursor) {
+    if (!ac_everTyped) return '*owner';
+    return inputValue;
+  };
+}
+
+
+/**
+ * Constuct one new autocomplete store for each user-valued custom
+ * field that has a needs_perm validation requirement, and thus a
+ * list of allowed user indexes.
+ * TODO(jrobbins): would it be easier to define my own class to use
+ * instead of _AC_Simple_Store?
+ * @param {Array} fieldDefs An array of field definitions, only some
+ * of which have a 'user_indexes' entry.
+ */
+function TKR_setUpUserAutocompleteStores(fieldDefs) {
+  fieldDefs.forEach((fieldDef) => {
+    if (fieldDef.qualifiedMembers) {
+      const us = makeOneUserAutocompleteStore(fieldDef);
+      TKR_userAutocompleteStores['custom_' + fieldDef['field_id']] = us;
+    }
+  });
+}
+
+function makeOneUserAutocompleteStore(fieldDef) {
+  const memberWords = [];
+  const docdict = {};
+  for (const member of fieldDef.qualifiedMembers) {
+    memberWords.push(member.name);
+    docdict[member.name] = member.doc;
+  }
+
+  const userStore = new _AC_SimpleStore(memberWords, docdict);
+  userStore.commaCompletes = false;
+
+  userStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  userStore.completions = function(prefix, tofilter) {
+    const fullList = TKR_fullComplete(prefix, fieldDef.qualifiedMembers);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+
+  userStore.completable = function(inputValue, cursor) {
+    if (!ac_everTyped) return '*custom';
+    return inputValue;
+  };
+
+  return userStore;
+}
+
+
+/**
+ * Constuct a new autocomplete store with all the components.
+ * The store has some monorail-specific methods.
+ * @param {Array} componentDefs An array of definitions of components.
+ */
+function TKR_setUpComponentStore(componentDefs) {
+  const componentWords = [];
+  const docdict = {};
+  for (let i = 0; i < componentDefs.length; i++) {
+    const component = componentDefs[i];
+    componentWords.push(component.name);
+    docdict[component.name] = component.doc;
+  }
+
+  const completions = function(prefix, tofilter) {
+    const fullList = TKR_fullComplete(prefix, componentDefs);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+  const completable = function(inputValue, cursor) {
+    if (inputValue == '') return '*component';
+    return _AC_SimpleStore.prototype.completable.call(this, inputValue, cursor);
+  };
+
+  TKR_componentStore = new _AC_SimpleStore(componentWords, docdict);
+  TKR_componentStore.commaCompletes = false;
+  TKR_componentStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+  TKR_componentStore.completions = completions;
+  TKR_componentStore.completable = completable;
+
+  TKR_componentListStore = new _AC_SimpleStore(componentWords, docdict);
+  TKR_componentListStore.commaCompletes = false;
+  TKR_componentListStore.substitute = TKR_acSubstituteWithComma;
+  TKR_componentListStore.completions = completions;
+  TKR_componentListStore.completable = completable;
+}
+
+
+/**
+ * An array of definitions of all well-known issue labels.  Each
+ * definition has the name of the label, and a docstring that
+ * describes its meaning.
+ */
+let TKR_labelWords = [];
+
+
+/**
+ * Constuct a new autocomplete store with all the well-known issue
+ * labels for the current project.  The store has some DIT-specific methods.
+ * TODO(jrobbins): would it be easier to define my own class to use
+ * instead of _AC_Simple_Store?
+ * @param {Array} labelDefs An array of definitions of the project
+ * members.  Each definition has a name and docstring.
+ */
+function TKR_setUpLabelStore(labelDefs) {
+  TKR_labelWords = [];
+  const TKR_labelPrefixes = [];
+  const labelPrefs = new Set();
+  const docdict = {};
+  for (let i = 0; i < labelDefs.length; i++) {
+    const label = labelDefs[i];
+    TKR_labelWords.push(label.name);
+    TKR_labelPrefixes.push(label.name.split('-')[0]);
+    docdict[label.name] = label.doc;
+    labelPrefs.add(label.name.split('-')[0]);
+  }
+  const labelPrefArray = Array.from(labelPrefs);
+  const labelPrefDefs = labelPrefArray.map((s) => ({name: s, doc: ''}));
+
+  TKR_labelStore = new _AC_SimpleStore(TKR_labelWords, docdict);
+
+  TKR_labelStore.commaCompletes = false;
+  TKR_labelStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  TKR_labelPrefixStore = new _AC_SimpleStore(TKR_labelPrefixes);
+
+  TKR_labelPrefixStore.commaCompletes = false;
+  TKR_labelPrefixStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  TKR_labelMultiStore = new _AC_SimpleStore(TKR_labelWords, docdict);
+
+  TKR_labelMultiStore.substitute = TKR_acSubstituteWithComma;
+
+  const completable = function(inputValue, cursor) {
+    if (cursor === 0) {
+      return '*label'; // Show every well-known label that is not redundant.
+    }
+    let start = 0;
+    for (let i = cursor; --i >= 0;) {
+      const c = inputValue.charAt(i);
+      if (c === ' ' || c === ',') {
+        start = i + 1;
+        break;
+      }
+    }
+    const questionPos = inputValue.indexOf('?');
+    if (questionPos >= 0) {
+      // Ignore any "?" character and anything after it.
+      inputValue = inputValue.substring(start, questionPos);
+    }
+    let result = inputValue.substring(start, cursor);
+    if (inputValue.lastIndexOf('-') > 0 && !ac_everTyped) {
+      // Act like a menu: offer all alternative values for the same prefix.
+      result = inputValue.substring(
+          start, Math.min(cursor, inputValue.lastIndexOf('-')));
+    }
+    if (inputValue.startsWith('Restrict-') && !ac_everTyped) {
+      // If user is in the middle of 2nd part, use that to narrow the choices.
+      result = inputValue;
+      // If they completed 2nd part, give all choices matching 2-part prefix.
+      if (inputValue.lastIndexOf('-') > 8) {
+        result = inputValue.substring(
+            start, Math.min(cursor, inputValue.lastIndexOf('-') + 1));
+      }
+    }
+
+    return result;
+  };
+
+  const computeAvoid = function() {
+    const labelTextFields = Array.from(
+        document.querySelectorAll('.labelinput'));
+    const otherTextFields = labelTextFields.filter(
+        (tf) => (tf !== ac_focusedInput && tf.value));
+    return otherTextFields.map((tf) => tf.value);
+  };
+
+
+  const completions = function(labeldic) {
+    return function(prefix, tofilter) {
+      let comps = TKR_fullComplete(prefix, labeldic);
+      if (comps === null) {
+        comps = _AC_SimpleStore.prototype.completions.call(
+            this, prefix, tofilter);
+      }
+
+      const filteredComps = [];
+      for (const completion of comps) {
+        const completionLower = completion.value.toLowerCase();
+        const labelPrefix = completionLower.split('-')[0];
+        let alreadyUsed = false;
+        const isExclusive = FindInArray(TKR_exclPrefixes, labelPrefix) !== -1;
+        if (isExclusive) {
+          for (const usedLabel of ac_avoidValues) {
+            if (usedLabel.startsWith(labelPrefix + '-')) {
+              alreadyUsed = true;
+              break;
+            }
+          }
+        }
+        if (!alreadyUsed) {
+          filteredComps.push(completion);
+        }
+      }
+
+      return filteredComps;
+    };
+  };
+
+  TKR_labelStore.computeAvoid = computeAvoid;
+  TKR_labelStore.completable = completable;
+  TKR_labelStore.completions = completions(labelDefs);
+
+  TKR_labelPrefixStore.completable = completable;
+  TKR_labelPrefixStore.completions = completions(labelPrefDefs);
+
+  TKR_labelMultiStore.completable = completable;
+  TKR_labelMultiStore.completions = completions(labelDefs);
+}
+
+
+/**
+ * Constuct a new autocomplete store with the given strings as choices.
+ * @param {Array} choices An array of autocomplete choices.
+ */
+function TKR_setUpAutoCompleteStore(choices) {
+  TKR_autoCompleteStore = new _AC_SimpleStore(choices);
+  const choicesDefs = [];
+  for (let i = 0; i < choices.length; ++i) {
+    choicesDefs.push({'name': choices[i], 'doc': ''});
+  }
+
+  /**
+   * Override the default completions() function to return a list of
+   * available choices.  It proactively shows all choices when the user has
+   * not yet typed anything.  It stops offering choices if the text field
+   * has a pretty long string in it already.  It does not offer choices that
+   * have already been chosen.
+   */
+  TKR_autoCompleteStore.completions = function(prefix, tofilter) {
+    if (prefix.length > 18) {
+      return [];
+    }
+    let comps = TKR_fullComplete(prefix, choicesDefs);
+    if (comps == null) {
+      comps = _AC_SimpleStore.prototype.completions.call(
+          this, prefix, tofilter);
+    }
+
+    const usedComps = {};
+    const textFields = document.getElementsByTagName('input');
+    for (var i = 0; i < textFields.length; ++i) {
+      if (textFields[i].classList.contains('autocomplete')) {
+        usedComps[textFields[i].value] = true;
+      }
+    }
+    const unusedComps = [];
+    for (i = 0; i < comps.length; ++i) {
+      if (!usedComps[comps[i].value]) {
+        unusedComps.push(comps[i]);
+      }
+    }
+
+    return unusedComps;
+  };
+
+  /**
+   * Override the default completable() function with one that gives a
+   * special value when the user has not yet typed anything.  This
+   * causes TKR_fullComplete() to show all choices.  Also, always consider
+   * the whole textfield value as an input to completion matching.  Otherwise,
+   * it would only consider the part after the last comma (which makes sense
+   * for gmail To: and Cc: address fields).
+   */
+  TKR_autoCompleteStore.completable = function(inputValue, cursor) {
+    if (inputValue == '') {
+      return '*ac';
+    }
+    return inputValue;
+  };
+
+  /**
+   * Override the default substitute() function to completely replace the
+   * contents of the text field when the user selects a completion. Otherwise,
+   * it would append, much like the Gmail To: and Cc: fields append autocomplete
+   * selections.
+   */
+  TKR_autoCompleteStore.substitute =
+  function(inputValue, cursor, completable, completion) {
+    return completion.value;
+  };
+
+  /**
+   * We consider the whole textfield to be one value, not a comma separated
+   * list.  So, typing a ',' should not trigger an autocomplete selection.
+   */
+  TKR_autoCompleteStore.commaCompletes = false;
+}
+
+
+/**
+ * XMLHTTP object used to fetch autocomplete options from the server.
+ */
+const TKR_optionsXmlHttp = undefined;
+
+/**
+ * Contact the server to fetch the set of autocomplete options for the
+ * projects the user is contributor/member/owner of.
+ * @param {multiValue} boolean If set to true, the projectStore is configured to
+ * have support for multi-values (useful for example for saved queries where
+ * a query can apply to multiple projects).
+ */
+function TKR_fetchUserProjects(multiValue) {
+  // Set a request token to prevent XSRF leaking of user project lists.
+  const userRefs = [{displayName: window.CS_env.loggedInUserEmail}];
+  const userProjectsPromise = window.prpcClient.call(
+      'monorail.Users', 'GetUsersProjects', {userRefs});
+  userProjectsPromise.then((response) => {
+    const userProjects = response.usersProjects[0];
+    const projects = (userProjects.ownerOf || [])
+        .concat(userProjects.memberOf || [])
+        .concat(userProjects.contributorTo || []);
+    projects.sort();
+    if (projects) {
+      TKR_setUpProjectStore(projects, multiValue);
+    }
+  });
+}
+
+
+/**
+ * Constuct a new autocomplete store with all the projects that the
+ * current user has visibility into. The store has some monorail-specific
+ * methods.
+ * @param {Array} projects An array of project names.
+ * @param {boolean} multiValue Determines whether the store should support
+ *                  multiple values.
+ */
+function TKR_setUpProjectStore(projects, multiValue) {
+  const projectsDefs = [];
+  const docdict = {};
+  for (let i = 0; i < projects.length; ++i) {
+    projectsDefs.push({'name': projects[i], 'doc': ''});
+    docdict[projects[i]] = '';
+  }
+
+  TKR_projectStore = new _AC_SimpleStore(projects, docdict);
+  TKR_projectStore.commaCompletes = !multiValue;
+
+  if (multiValue) {
+    TKR_projectStore.substitute = TKR_acSubstituteWithComma;
+  } else {
+    TKR_projectStore.substitute =
+      function(inputValue, cursor, completable, completion) {
+        return completion.value;
+      };
+  }
+
+  TKR_projectStore.completions = function(prefix, tofilter) {
+    const fullList = TKR_fullComplete(prefix, projectsDefs);
+    if (fullList) return fullList;
+    return _AC_SimpleStore.prototype.completions.call(this, prefix, tofilter);
+  };
+
+  TKR_projectStore.completable = function(inputValue, cursor) {
+    if (inputValue == '') return '*project';
+    if (multiValue) {
+      return _AC_SimpleStore.prototype.completable.call(
+          this, inputValue, cursor);
+    } else {
+      return inputValue;
+    }
+  };
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Projects ListStatuses to
+ * the format expected by TKR_populateAutocomplete.
+ * @param {object} statusesResponse A pRPC ListStatusesResponse object.
+ */
+function TKR_convertStatuses(statusesResponse) {
+  const statusDefs = statusesResponse.statusDefs || [];
+  const jsonData = {};
+
+  // Split statusDefs into open and closed name-doc objects.
+  jsonData.open = [];
+  jsonData.closed = [];
+  for (const s of statusDefs) {
+    if (!s.deprecated) {
+      const item = {
+        name: s.status,
+        doc: s.docstring,
+      };
+      if (s.meansOpen) {
+        jsonData.open.push(item);
+      } else {
+        jsonData.closed.push(item);
+      }
+    }
+  }
+
+  jsonData.strict = statusesResponse.restrictToKnown;
+
+  return jsonData;
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Projects ListComponents to
+ * the format expected by TKR_populateAutocomplete.
+ * @param {object} componentsResponse A pRPC ListComponentsResponse object.
+ */
+function TKR_convertComponents(componentsResponse) {
+  const componentDefs = (componentsResponse.componentDefs || []);
+  const jsonData = {};
+
+  // Filter out deprecated components and normalize to name-doc object.
+  jsonData.components = [];
+  for (const c of componentDefs) {
+    if (!c.deprecated) {
+      jsonData.components.push({
+        name: c.path,
+        doc: c.docstring,
+      });
+    }
+  }
+
+  return jsonData;
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Projects GetLabelOptions
+ * call to the format expected by TKR_populateAutocomplete.
+ * @param {object} labelsResponse A pRPC GetLabelOptionsResponse.
+ * @param {Array<FieldDef>=} fieldDefs FieldDefs from a project config, used to
+ *   mask labels that are used to implement custom enum fields.
+ */
+function TKR_convertLabels(labelsResponse, fieldDefs = []) {
+  const labelDefs = (labelsResponse.labelDefs || []);
+  const exclusiveLabelPrefixes = (labelsResponse.exclusiveLabelPrefixes || []);
+  const jsonData = {};
+
+  const maskedLabels = new Set();
+  fieldDefs.forEach((fd) => {
+    if (fd.enumChoices) {
+      fd.enumChoices.forEach(({label}) => {
+        maskedLabels.add(`${fd.fieldRef.fieldName}-${label}`);
+      });
+    }
+  });
+
+  jsonData.labels = labelDefs.filter(({label}) => !maskedLabels.has(label)).map(
+      (label) => ({name: label.label, doc: label.docstring}));
+
+  jsonData.excl_prefixes = exclusiveLabelPrefixes.map(
+      (prefix) => prefix.toLowerCase());
+
+  return jsonData;
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Projects GetVisibleMembers
+ * call to the format expected by TKR_populateAutocomplete.
+ * @param {object?} visibleMembersResponse A pRPC GetVisibleMembersResponse.
+ * @return {{memberEmails: {name: string}, nonGroupEmails: {name: string}}}
+ */
+function TKR_convertVisibleMembers(visibleMembersResponse) {
+  if (!visibleMembersResponse) {
+    visibleMembersResponse = {};
+  }
+  const groupRefs = (visibleMembersResponse.groupRefs || []);
+  const userRefs = (visibleMembersResponse.userRefs || []);
+  const jsonData = {};
+
+  const groupEmails = new Set(groupRefs.map(
+      (groupRef) => groupRef.displayName));
+
+  jsonData.memberEmails = userRefs.map(
+      (userRef) => ({name: userRef.displayName}));
+  jsonData.nonGroupEmails = jsonData.memberEmails.filter(
+      (memberEmail) => !groupEmails.has(memberEmail));
+
+  return jsonData;
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Projects ListFields to
+ * the format expected by TKR_populateAutocomplete.
+ * @param {object} fieldsResponse A pRPC ListFieldsResponse object.
+ */
+function TKR_convertFields(fieldsResponse) {
+  const fieldDefs = (fieldsResponse.fieldDefs || []);
+  const jsonData = {};
+
+  jsonData.fields = fieldDefs.map((field) =>
+    ({
+      field_id: field.fieldRef.fieldId,
+      field_name: field.fieldRef.fieldName,
+      field_type: field.fieldRef.type,
+      docstring: field.docstring,
+      choices: (field.enumChoices || []).map(
+          (choice) => ({name: choice.label, doc: choice.docstring})),
+      qualifiedMembers: (field.userChoices || []).map(
+          (userRef) => ({name: userRef.displayName})),
+    }),
+  );
+
+  return jsonData;
+}
+
+
+/**
+ * Convert the object resulting of a monorail.Features ListHotlistsByUser
+ * call to the format expected by TKR_populateAutocomplete.
+ * @param {Array<HotlistV0>} hotlists A lists of hotlists
+ * @return {Array<{ref_str: string, summary: string}>}
+ */
+function TKR_convertHotlists(hotlists) {
+  if (hotlists === undefined) {
+    return [];
+  }
+
+  const seen = new Set();
+  const ambiguousNames = new Set();
+
+  hotlists.forEach((hotlist) => {
+    if (seen.has(hotlist.name)) {
+      ambiguousNames.add(hotlist.name);
+    }
+    seen.add(hotlist.name);
+  });
+
+  return hotlists.map((hotlist) => {
+    let ref_str = hotlist.name;
+    if (ambiguousNames.has(hotlist.name)) {
+      ref_str = hotlist.owner_ref.display_name + ':' + ref_str;
+    }
+    return {ref_str: ref_str, summary: hotlist.summary};
+  });
+}
+
+
+/**
+ * Initializes hotlists in autocomplete store.
+ * @param {Array<HotlistV0>} hotlists
+ */
+function TKR_populateHotlistAutocomplete(hotlists) {
+  TKR_setUpHotlistsStore(TKR_convertHotlists(hotlists));
+}
+
+
+/**
+ * Add project config data that's already been fetched to the legacy
+ * autocomplete.
+ * @param {Config} projectConfig Returned projectConfig data.
+ * @param {GetVisibleMembersResponse} visibleMembers
+ * @param {Array<string>} customPermissions
+ */
+function TKR_populateAutocomplete(projectConfig, visibleMembers,
+    customPermissions = []) {
+  const {statusDefs, componentDefs, labelDefs, fieldDefs,
+    exclusiveLabelPrefixes, projectName} = projectConfig;
+
+  const {memberEmails, nonGroupEmails} =
+    TKR_convertVisibleMembers(visibleMembers);
+  TKR_setUpMemberStore(memberEmails, nonGroupEmails);
+  TKR_prepOwnerField(memberEmails);
+
+  const {open, closed, strict} = TKR_convertStatuses({statusDefs});
+  TKR_setUpStatusStore(open, closed);
+  TKR_restrict_to_known = strict;
+
+  const {components} = TKR_convertComponents({componentDefs});
+  TKR_setUpComponentStore(components);
+
+  const {excl_prefixes, labels} = TKR_convertLabels(
+      {labelDefs, exclusiveLabelPrefixes}, fieldDefs);
+  TKR_exclPrefixes = excl_prefixes;
+  TKR_setUpLabelStore(labels);
+
+  const {fields} = TKR_convertFields({fieldDefs});
+  TKR_setUpUserAutocompleteStores(fields);
+
+  /* QuickEdit is not yet in Monorail. crbug.com/monorail/1926
+  TKR_setUpQuickEditStore(
+      jsonData.labels, jsonData.memberEmails, jsonData.open, jsonData.closed,
+      jsonData.nonGroupEmails);
+  */
+
+  // We need to wait until both exclusive prefixes (in configPromise) and
+  // labels (in labelsPromise) have been read.
+  TKR_prepLabelAC(TKR_labelFieldIDPrefix);
+
+  TKR_setUpSearchStore(
+      labels, memberEmails, open, closed,
+      components, fields, nonGroupEmails);
+
+  TKR_setUpCustomPermissionsStore(customPermissions);
+}
