diff --git a/static_src/reducers/issueV0.js b/static_src/reducers/issueV0.js
new file mode 100644
index 0000000..36c446d
--- /dev/null
+++ b/static_src/reducers/issueV0.js
@@ -0,0 +1,1411 @@
+// 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.
+
+/**
+ * @fileoverview Issue actions, selectors, and reducers organized into
+ * a single Redux "Duck" that manages updating and retrieving issue state
+ * on the frontend.
+ *
+ * Reference: https://github.com/erikras/ducks-modular-redux
+ */
+
+import {combineReducers} from 'redux';
+import {createSelector} from 'reselect';
+import {autolink} from 'autolink.js';
+import {fieldTypes, extractTypeForIssue,
+  fieldValuesToMap} from 'shared/issue-fields.js';
+import {removePrefix, objectToMap} from 'shared/helpers.js';
+import {issueRefToString, issueToIssueRefString,
+  issueStringToRef, issueNameToRefString} from 'shared/convertersV0.js';
+import {fromShortlink} from 'shared/federated.js';
+import {createReducer, createRequestReducer,
+  createKeyedRequestReducer} from './redux-helpers.js';
+import * as projectV0 from './projectV0.js';
+import * as userV0 from './userV0.js';
+import {fieldValueMapKey} from 'shared/metadata-helpers.js';
+import {prpcClient} from 'prpc-client-instance.js';
+import loadGapi, {fetchGapiEmail} from 'shared/gapi-loader.js';
+import 'shared/typedef.js';
+
+/** @typedef {import('redux').AnyAction} AnyAction */
+
+// Actions
+export const VIEW_ISSUE = 'VIEW_ISSUE';
+
+export const FETCH_START = 'issueV0/FETCH_START';
+export const FETCH_SUCCESS = 'issueV0/FETCH_SUCCESS';
+export const FETCH_FAILURE = 'issueV0/FETCH_FAILURE';
+
+export const FETCH_ISSUES_START = 'issueV0/FETCH_ISSUES_START';
+export const FETCH_ISSUES_SUCCESS = 'issueV0/FETCH_ISSUES_SUCCESS';
+export const FETCH_ISSUES_FAILURE = 'issueV0/FETCH_ISSUES_FAILURE';
+
+const FETCH_HOTLISTS_START = 'FETCH_HOTLISTS_START';
+export const FETCH_HOTLISTS_SUCCESS = 'FETCH_HOTLISTS_SUCCESS';
+const FETCH_HOTLISTS_FAILURE = 'FETCH_HOTLISTS_FAILURE';
+
+const FETCH_ISSUE_LIST_START = 'FETCH_ISSUE_LIST_START';
+export const FETCH_ISSUE_LIST_UPDATE = 'FETCH_ISSUE_LIST_UPDATE';
+const FETCH_ISSUE_LIST_SUCCESS = 'FETCH_ISSUE_LIST_SUCCESS';
+const FETCH_ISSUE_LIST_FAILURE = 'FETCH_ISSUE_LIST_FAILURE';
+
+const FETCH_PERMISSIONS_START = 'FETCH_PERMISSIONS_START';
+const FETCH_PERMISSIONS_SUCCESS = 'FETCH_PERMISSIONS_SUCCESS';
+const FETCH_PERMISSIONS_FAILURE = 'FETCH_PERMISSIONS_FAILURE';
+
+export const STAR_START = 'STAR_START';
+export const STAR_SUCCESS = 'STAR_SUCCESS';
+const STAR_FAILURE = 'STAR_FAILURE';
+
+const PRESUBMIT_START = 'PRESUBMIT_START';
+const PRESUBMIT_SUCCESS = 'PRESUBMIT_SUCCESS';
+const PRESUBMIT_FAILURE = 'PRESUBMIT_FAILURE';
+
+export const FETCH_IS_STARRED_START = 'FETCH_IS_STARRED_START';
+export const FETCH_IS_STARRED_SUCCESS = 'FETCH_IS_STARRED_SUCCESS';
+const FETCH_IS_STARRED_FAILURE = 'FETCH_IS_STARRED_FAILURE';
+
+const FETCH_ISSUES_STARRED_START = 'FETCH_ISSUES_STARRED_START';
+export const FETCH_ISSUES_STARRED_SUCCESS = 'FETCH_ISSUES_STARRED_SUCCESS';
+const FETCH_ISSUES_STARRED_FAILURE = 'FETCH_ISSUES_STARRED_FAILURE';
+
+const FETCH_COMMENTS_START = 'FETCH_COMMENTS_START';
+export const FETCH_COMMENTS_SUCCESS = 'FETCH_COMMENTS_SUCCESS';
+const FETCH_COMMENTS_FAILURE = 'FETCH_COMMENTS_FAILURE';
+
+const FETCH_COMMENT_REFERENCES_START = 'FETCH_COMMENT_REFERENCES_START';
+const FETCH_COMMENT_REFERENCES_SUCCESS = 'FETCH_COMMENT_REFERENCES_SUCCESS';
+const FETCH_COMMENT_REFERENCES_FAILURE = 'FETCH_COMMENT_REFERENCES_FAILURE';
+
+const FETCH_REFERENCED_USERS_START = 'FETCH_REFERENCED_USERS_START';
+const FETCH_REFERENCED_USERS_SUCCESS = 'FETCH_REFERENCED_USERS_SUCCESS';
+const FETCH_REFERENCED_USERS_FAILURE = 'FETCH_REFERENCED_USERS_FAILURE';
+
+const FETCH_RELATED_ISSUES_START = 'FETCH_RELATED_ISSUES_START';
+const FETCH_RELATED_ISSUES_SUCCESS = 'FETCH_RELATED_ISSUES_SUCCESS';
+const FETCH_RELATED_ISSUES_FAILURE = 'FETCH_RELATED_ISSUES_FAILURE';
+
+const FETCH_FEDERATED_REFERENCES_START = 'FETCH_FEDERATED_REFERENCES_START';
+const FETCH_FEDERATED_REFERENCES_SUCCESS = 'FETCH_FEDERATED_REFERENCES_SUCCESS';
+const FETCH_FEDERATED_REFERENCES_FAILURE = 'FETCH_FEDERATED_REFERENCES_FAILURE';
+
+const CONVERT_START = 'CONVERT_START';
+const CONVERT_SUCCESS = 'CONVERT_SUCCESS';
+const CONVERT_FAILURE = 'CONVERT_FAILURE';
+
+const UPDATE_START = 'UPDATE_START';
+const UPDATE_SUCCESS = 'UPDATE_SUCCESS';
+const UPDATE_FAILURE = 'UPDATE_FAILURE';
+
+const UPDATE_APPROVAL_START = 'UPDATE_APPROVAL_START';
+const UPDATE_APPROVAL_SUCCESS = 'UPDATE_APPROVAL_SUCCESS';
+const UPDATE_APPROVAL_FAILURE = 'UPDATE_APPROVAL_FAILURE';
+
+/* State Shape
+{
+  issuesByRefString: Object<IssueRefString, Issue>,
+
+  viewedIssueRef: IssueRefString,
+
+  hotlists: Array<HotlistV0>,
+  issueList: {
+    issueRefs: Array<IssueRefString>,
+    progress: number,
+    totalResults: number,
+  }
+  comments: Array<IssueComment>,
+  commentReferences: Object,
+  relatedIssues: Object,
+  referencedUsers: Array<UserV0>,
+  starredIssues: Object<IssueRefString, Boolean>,
+  permissions: Array<string>,
+  presubmitResponse: Object,
+
+  requests: {
+    fetch: ReduxRequestState,
+    fetchHotlists: ReduxRequestState,
+    fetchIssueList: ReduxRequestState,
+    fetchPermissions: ReduxRequestState,
+    starringIssues: Object<string, ReduxRequestState>,
+    presubmit: ReduxRequestState,
+    fetchComments: ReduxRequestState,
+    fetchCommentReferences: ReduxRequestState,
+    fetchFederatedReferences: ReduxRequestState,
+    fetchRelatedIssues: ReduxRequestState,
+    fetchStarredIssues: ReduxRequestState,
+    fetchStarredIssues: ReduxRequestState,
+    convert: ReduxRequestState,
+    update: ReduxRequestState,
+    updateApproval: ReduxRequestState,
+  },
+}
+*/
+
+// Helpers for the reducers.
+
+/**
+ * Overrides local data for single approval on an Issue object with fresh data.
+ * Note that while an Issue can have multiple approvals, this function only
+ * refreshes data for a single approval.
+ * @param {Issue} issue Issue Object being updated.
+ * @param {ApprovalDef} approval A single approval to override in the issue.
+ * @return {Issue} Issue with updated approval data.
+ */
+const updateApprovalValues = (issue, approval) => {
+  if (!issue.approvalValues) return issue;
+  const newApprovals = issue.approvalValues.map((item) => {
+    if (item.fieldRef.fieldName === approval.fieldRef.fieldName) {
+      // PhaseRef isn't populated on the response so we want to make sure
+      // it doesn't overwrite the original phaseRef with {}.
+      return {...approval, phaseRef: item.phaseRef};
+    }
+    return item;
+  });
+  return {...issue, approvalValues: newApprovals};
+};
+
+// Reducers
+
+/**
+ * Creates a new issuesByRefString Object with a single issue's data
+ * edited.
+ * @param {Object<IssueRefString, Issue>} issuesByRefString
+ * @param {Issue} issue The new issue data to add to the state.
+ * @return {Object<IssueRefString, Issue>}
+ */
+const updateSingleIssueInState = (issuesByRefString, issue) => {
+  return {
+    ...issuesByRefString,
+    [issueToIssueRefString(issue)]: issue,
+  };
+};
+
+// TODO(crbug.com/monorail/6882): Finish converting all other issue
+//   actions to use this format.
+/**
+ * Adds issues fetched by a ListIssues request to the Redux store in a
+ * normalized format.
+ * @param {Object<IssueRefString, Issue>} state Redux state.
+ * @param {AnyAction} action
+ * @param {Array<Issue>} action.issues The list of issues that was fetched.
+ * @param {Issue=} action.issue The issue being updated.
+ * @param {number=} action.starCount Number of stars the issue has. This changes
+ *   when a user stars an issue and needs to be updated.
+ * @param {ApprovalDef=} action.approval A new approval to update the issue
+ *   with.
+ * @param {IssueRef=} action.issueRef A specific IssueRef to update.
+ */
+export const issuesByRefStringReducer = createReducer({}, {
+  [FETCH_ISSUE_LIST_UPDATE]: (state, {issues}) => {
+    const newState = {...state};
+
+    issues.forEach((issue) => {
+      const refString = issueToIssueRefString(issue);
+      newState[refString] = {...newState[refString], ...issue};
+    });
+
+    return newState;
+  },
+  [FETCH_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
+  [FETCH_ISSUES_SUCCESS]: (state, {issues}) => {
+    const newState = {...state};
+
+    issues.forEach((issue) => {
+      const refString = issueToIssueRefString(issue);
+      newState[refString] = {...newState[refString], ...issue};
+    });
+
+    return newState;
+  },
+  [CONVERT_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
+  [UPDATE_SUCCESS]: (state, {issue}) => updateSingleIssueInState(state, issue),
+  [UPDATE_APPROVAL_SUCCESS]: (state, {issueRef, approval}) => {
+    const issueRefString = issueToIssueRefString(issueRef);
+    const originalIssue = state[issueRefString] || {};
+    const newIssue = updateApprovalValues(originalIssue, approval);
+    return {
+      ...state,
+      [issueRefString]: {
+        ...newIssue,
+      },
+    };
+  },
+  [STAR_SUCCESS]: (state, {issueRef, starCount}) => {
+    const issueRefString = issueToIssueRefString(issueRef);
+    const originalIssue = state[issueRefString] || {};
+    return {
+      ...state,
+      [issueRefString]: {
+        ...originalIssue,
+        starCount,
+      },
+    };
+  },
+});
+
+/**
+ * Sets a reference for the issue that the user is currently viewing.
+ * @param {IssueRefString} state Currently viewed issue.
+ * @param {AnyAction} action
+ * @param {IssueRef} action.issueRef The updated localId to view.
+ * @return {IssueRefString}
+ */
+const viewedIssueRefReducer = createReducer('', {
+  [VIEW_ISSUE]: (state, {issueRef}) => issueRefToString(issueRef) || state,
+});
+
+/**
+ * Reducer to manage updating the list of hotlists attached to an Issue.
+ * @param {Array<HotlistV0>} state List of issue hotlists.
+ * @param {AnyAction} action
+ * @param {Array<HotlistV0>} action.hotlists New list of hotlists.
+ * @return {Array<HotlistV0>}
+ */
+const hotlistsReducer = createReducer([], {
+  [FETCH_HOTLISTS_SUCCESS]: (_, {hotlists}) => hotlists,
+});
+
+/**
+ * @typedef {Object} IssueListState
+ * @property {Array<IssueRefString>} issues The list of issues being viewed,
+ *   in a normalized form.
+ * @property {number} progress The percentage of issues loaded. Used for
+ *   incremental loading of issues in the grid view.
+ * @property {number} totalResults The total number of issues matching the
+ *   query.
+ */
+
+/**
+ * Handles the state of the currently viewed issue list. This reducer
+ * stores this data in normalized form.
+ * @param {IssueListState} state
+ * @param {AnyAction} action
+ * @param {Array<Issue>} action.issues Issues that were fetched.
+ * @param {number} state.progress New percentage of issues have been loaded.
+ * @param {number} state.totalResults The total number of issues matching the
+ *   query.
+ * @return {IssueListState}
+ */
+export const issueListReducer = createReducer({}, {
+  [FETCH_ISSUE_LIST_UPDATE]: (_state, {issues, progress, totalResults}) => ({
+    issueRefs: issues.map(issueToIssueRefString), progress, totalResults,
+  }),
+});
+
+/**
+ * Updates the comments attached to the currently viewed issue.
+ * @param {Array<IssueComment>} state The list of comments in an issue.
+ * @param {AnyAction} action
+ * @param {Array<IssueComment>} action.comments Fetched comments.
+ * @return {Array<IssueComment>}
+ */
+const commentsReducer = createReducer([], {
+  [FETCH_COMMENTS_SUCCESS]: (_state, {comments}) => comments,
+});
+
+// TODO(crbug.com/monorail/5953): Come up with some way to refactor
+// autolink.js's reference code to allow avoiding duplicate lookups
+// with data already in Redux state.
+/**
+ * For autolinking, this reducer stores the dereferenced data for bits
+ * of data that were referenced in comments. For example, comments might
+ * include user emails or IDs for other issues, and this state slice would
+ * store the full Objects for that data.
+ * @param {Array<CommentReference>} state
+ * @param {AnyAction} action
+ * @param {Array<CommentReference>} action.commentReferences New references
+ *   to store.
+ * @return {Array<CommentReference>}
+ */
+const commentReferencesReducer = createReducer({}, {
+  [FETCH_COMMENTS_START]: (_state, _action) => ({}),
+  [FETCH_COMMENT_REFERENCES_SUCCESS]: (_state, {commentReferences}) => {
+    return commentReferences;
+  },
+});
+
+/**
+ * Handles state for related issues such as blocking and blocked on issues,
+ * including federated references that could reference external issues outside
+ * Monorail.
+ * @param {Object<IssueRefString, Issue>} state
+ * @param {AnyAction} action
+ * @param {Object<IssueRefString, Issue>=} action.relatedIssues New related
+ *   issues.
+ * @param {Array<IssueRef>=} action.fedRefIssueRefs List of fetched federated
+ *   issue references.
+ * @return {Object<IssueRefString, Issue>}
+ */
+export const relatedIssuesReducer = createReducer({}, {
+  [FETCH_RELATED_ISSUES_SUCCESS]: (_state, {relatedIssues}) => relatedIssues,
+  [FETCH_FEDERATED_REFERENCES_SUCCESS]: (state, {fedRefIssueRefs}) => {
+    if (!fedRefIssueRefs) {
+      return state;
+    }
+
+    const fedRefStates = {};
+    fedRefIssueRefs.forEach((ref) => {
+      fedRefStates[ref.extIdentifier] = ref;
+    });
+
+    // Return a new object, in Redux fashion.
+    return Object.assign(fedRefStates, state);
+  },
+});
+
+/**
+ * Stores data for users referenced by issue. ie: Owner, CC, etc.
+ * @param {Object<string, UserV0>} state
+ * @param {AnyAction} action
+ * @param {Object<string, UserV0>} action.referencedUsers
+ * @return {Object<string, UserV0>}
+ */
+const referencedUsersReducer = createReducer({}, {
+  [FETCH_REFERENCED_USERS_SUCCESS]: (_state, {referencedUsers}) =>
+    referencedUsers,
+});
+
+/**
+ * Handles updating state of all starred issues.
+ * @param {Object<IssueRefString, boolean>} state Set of starred issues,
+ *   stored in a serializeable Object form.
+ * @param {AnyAction} action
+ * @param {IssueRef=} action.issueRef An issue with a star state being updated.
+ * @param {boolean=} action.starred Whether the issue is starred or unstarred.
+ * @param {Array<IssueRef>=} action.starredIssueRefs A list of starred issues.
+ * @return {Object<IssueRefString, boolean>}
+ */
+export const starredIssuesReducer = createReducer({}, {
+  [STAR_SUCCESS]: (state, {issueRef, starred}) => {
+    return {...state, [issueRefToString(issueRef)]: starred};
+  },
+  [FETCH_ISSUES_STARRED_SUCCESS]: (_state, {starredIssueRefs}) => {
+    const normalizedStars = {};
+    starredIssueRefs.forEach((issueRef) => {
+      normalizedStars[issueRefToString(issueRef)] = true;
+    });
+    return normalizedStars;
+  },
+  [FETCH_IS_STARRED_SUCCESS]: (state, {issueRef, starred}) => {
+    const refString = issueRefToString(issueRef);
+    return {...state, [refString]: starred};
+  },
+});
+
+/**
+ * Adds the result of an IssuePresubmit response to the Redux store.
+ * @param {Object} state Initial Redux state.
+ * @param {AnyAction} action
+ * @param {Object} action.presubmitResponse The issue
+ *   presubmit response Object.
+ * @return {Object}
+ */
+const presubmitResponseReducer = createReducer({}, {
+  [PRESUBMIT_SUCCESS]: (_state, {presubmitResponse}) => presubmitResponse,
+});
+
+/**
+ * Stores the user's permissions for a given issue.
+ * @param {Array<string>} state Permission list. Each permission is a string
+ *   with the name of the permission.
+ * @param {AnyAction} action
+ * @param {Array<string>} action.permissions The fetched permission data.
+ * @return {Array<string>}
+ */
+const permissionsReducer = createReducer([], {
+  [FETCH_PERMISSIONS_SUCCESS]: (_state, {permissions}) => permissions,
+});
+
+const requestsReducer = combineReducers({
+  fetch: createRequestReducer(
+      FETCH_START, FETCH_SUCCESS, FETCH_FAILURE),
+  fetchIssues: createRequestReducer(
+      FETCH_ISSUES_START, FETCH_ISSUES_SUCCESS, FETCH_ISSUES_FAILURE),
+  fetchHotlists: createRequestReducer(
+      FETCH_HOTLISTS_START, FETCH_HOTLISTS_SUCCESS, FETCH_HOTLISTS_FAILURE),
+  fetchIssueList: createRequestReducer(
+      FETCH_ISSUE_LIST_START,
+      FETCH_ISSUE_LIST_SUCCESS,
+      FETCH_ISSUE_LIST_FAILURE),
+  fetchPermissions: createRequestReducer(
+      FETCH_PERMISSIONS_START,
+      FETCH_PERMISSIONS_SUCCESS,
+      FETCH_PERMISSIONS_FAILURE),
+  starringIssues: createKeyedRequestReducer(
+      STAR_START, STAR_SUCCESS, STAR_FAILURE),
+  presubmit: createRequestReducer(
+      PRESUBMIT_START, PRESUBMIT_SUCCESS, PRESUBMIT_FAILURE),
+  fetchComments: createRequestReducer(
+      FETCH_COMMENTS_START, FETCH_COMMENTS_SUCCESS, FETCH_COMMENTS_FAILURE),
+  fetchCommentReferences: createRequestReducer(
+      FETCH_COMMENT_REFERENCES_START,
+      FETCH_COMMENT_REFERENCES_SUCCESS,
+      FETCH_COMMENT_REFERENCES_FAILURE),
+  fetchFederatedReferences: createRequestReducer(
+      FETCH_FEDERATED_REFERENCES_START,
+      FETCH_FEDERATED_REFERENCES_SUCCESS,
+      FETCH_FEDERATED_REFERENCES_FAILURE),
+  fetchRelatedIssues: createRequestReducer(
+      FETCH_RELATED_ISSUES_START,
+      FETCH_RELATED_ISSUES_SUCCESS,
+      FETCH_RELATED_ISSUES_FAILURE),
+  fetchReferencedUsers: createRequestReducer(
+      FETCH_REFERENCED_USERS_START,
+      FETCH_REFERENCED_USERS_SUCCESS,
+      FETCH_REFERENCED_USERS_FAILURE),
+  fetchIsStarred: createRequestReducer(
+      FETCH_IS_STARRED_START, FETCH_IS_STARRED_SUCCESS,
+      FETCH_IS_STARRED_FAILURE),
+  fetchStarredIssues: createRequestReducer(
+      FETCH_ISSUES_STARRED_START, FETCH_ISSUES_STARRED_SUCCESS,
+      FETCH_ISSUES_STARRED_FAILURE,
+  ),
+  convert: createRequestReducer(
+      CONVERT_START, CONVERT_SUCCESS, CONVERT_FAILURE),
+  update: createRequestReducer(
+      UPDATE_START, UPDATE_SUCCESS, UPDATE_FAILURE),
+  // TODO(zhangtiff): Update this to use createKeyedRequestReducer() instead, so
+  // users can update multiple approvals at once.
+  updateApproval: createRequestReducer(
+      UPDATE_APPROVAL_START, UPDATE_APPROVAL_SUCCESS, UPDATE_APPROVAL_FAILURE),
+});
+
+export const reducer = combineReducers({
+  viewedIssueRef: viewedIssueRefReducer,
+
+  issuesByRefString: issuesByRefStringReducer,
+
+  hotlists: hotlistsReducer,
+  issueList: issueListReducer,
+  comments: commentsReducer,
+  commentReferences: commentReferencesReducer,
+  relatedIssues: relatedIssuesReducer,
+  referencedUsers: referencedUsersReducer,
+  starredIssues: starredIssuesReducer,
+  permissions: permissionsReducer,
+  presubmitResponse: presubmitResponseReducer,
+
+  requests: requestsReducer,
+});
+
+// Selectors
+const RESTRICT_VIEW_PREFIX = 'restrict-view-';
+const RESTRICT_EDIT_PREFIX = 'restrict-editissue-';
+const RESTRICT_COMMENT_PREFIX = 'restrict-addissuecomment-';
+
+/**
+ * Selector to retrieve all normalized Issue data in the Redux store,
+ * keyed by IssueRefString.
+ * @param {any} state
+ * @return {Object<IssueRefString, Issue>}
+ */
+const issuesByRefString = (state) => state.issue.issuesByRefString;
+
+/**
+ * Selector to return a function to retrieve an Issue from the Redux store.
+ * @param {any} state
+ * @return {function(string): ?Issue}
+ */
+export const issue = createSelector(issuesByRefString, (issuesByRefString) =>
+  (name) => issuesByRefString[issueNameToRefString(name)]);
+
+/**
+ * Selector to return a function to retrieve a given Issue Object from
+ * the Redux store.
+ * @param {any} state
+ * @return {function(IssueRefString, string): Issue}
+ */
+export const issueForRefString = createSelector(issuesByRefString,
+    (issuesByRefString) => (issueRefString, projectName = undefined) => {
+      // In some contexts, an issue ref string will omit a project name,
+      // assuming the default project to be the project name. We never
+      // omit the project name in strings used as keys, so we have to
+      // make sure issue ref strings contain the project name.
+      const ref = issueStringToRef(issueRefString, projectName);
+      const refString = issueRefToString(ref);
+      if (issuesByRefString.hasOwnProperty(refString)) {
+        return issuesByRefString[refString];
+      }
+      return issueStringToRef(refString, projectName);
+    });
+
+/**
+ * Selector to get a reference to the currently viewed issue, in string form.
+ * @param {any} state
+ * @return {IssueRefString}
+ */
+const viewedIssueRefString = (state) => state.issue.viewedIssueRef;
+
+/**
+ * Selector to get a reference to the currently viewed issue.
+ * @param {any} state
+ * @return {IssueRef}
+ */
+export const viewedIssueRef = createSelector(viewedIssueRefString,
+    (viewedIssueRefString) => issueStringToRef(viewedIssueRefString));
+
+/**
+ * Selector to get the full Issue data for the currently viewed issue.
+ * @param {any} state
+ * @return {Issue}
+ */
+export const viewedIssue = createSelector(issuesByRefString,
+    viewedIssueRefString,
+    (issuesByRefString, viewedIssueRefString) =>
+      issuesByRefString[viewedIssueRefString] || {});
+
+export const comments = (state) => state.issue.comments;
+export const commentsLoaded = (state) => state.issue.commentsLoaded;
+
+const _commentReferences = (state) => state.issue.commentReferences;
+export const commentReferences = createSelector(_commentReferences,
+    (commentReferences) => objectToMap(commentReferences));
+
+export const hotlists = (state) => state.issue.hotlists;
+
+const stateIssueList = (state) => state.issue.issueList;
+export const issueList = createSelector(
+    issuesByRefString,
+    stateIssueList,
+    (issuesByRefString, stateIssueList) => {
+      return (stateIssueList.issueRefs || []).map((issueRef) => {
+        return issuesByRefString[issueRef];
+      });
+    },
+);
+export const totalIssues = (state) => state.issue.issueList.totalResults;
+export const issueListProgress = (state) => state.issue.issueList.progress;
+export const issueListPhaseNames = createSelector(issueList, (issueList) => {
+  const phaseNamesSet = new Set();
+  if (issueList) {
+    issueList.forEach(({phases}) => {
+      if (phases) {
+        phases.forEach(({phaseRef: {phaseName}}) => {
+          phaseNamesSet.add(phaseName.toLowerCase());
+        });
+      }
+    });
+  }
+  return Array.from(phaseNamesSet);
+});
+
+/**
+ * @param {any} state
+ * @return {boolean} Whether the currently viewed issue list
+ *   has loaded.
+ */
+export const issueListLoaded = createSelector(
+    stateIssueList,
+    (stateIssueList) => stateIssueList.issueRefs !== undefined);
+
+export const permissions = (state) => state.issue.permissions;
+export const presubmitResponse = (state) => state.issue.presubmitResponse;
+
+const _relatedIssues = (state) => state.issue.relatedIssues || {};
+export const relatedIssues = createSelector(_relatedIssues,
+    (relatedIssues) => objectToMap(relatedIssues));
+
+const _referencedUsers = (state) => state.issue.referencedUsers || {};
+export const referencedUsers = createSelector(_referencedUsers,
+    (referencedUsers) => objectToMap(referencedUsers));
+
+export const isStarred = (state) => state.issue.isStarred;
+export const _starredIssues = (state) => state.issue.starredIssues;
+
+export const requests = (state) => state.issue.requests;
+
+// Returns a Map of in flight StarIssues requests, keyed by issueRef.
+export const starringIssues = createSelector(requests, (requests) =>
+  objectToMap(requests.starringIssues));
+
+export const starredIssues = createSelector(
+    _starredIssues,
+    (starredIssues) => {
+      const stars = new Set();
+      for (const [ref, starred] of Object.entries(starredIssues)) {
+        if (starred) stars.add(ref);
+      }
+      return stars;
+    },
+);
+
+// TODO(zhangtiff): Split up either comments or approvals into their own "duck".
+export const commentsByApprovalName = createSelector(
+    comments,
+    (comments) => {
+      const map = new Map();
+      comments.forEach((comment) => {
+        const key = (comment.approvalRef && comment.approvalRef.fieldName) ||
+          '';
+        if (map.has(key)) {
+          map.get(key).push(comment);
+        } else {
+          map.set(key, [comment]);
+        }
+      });
+      return map;
+    },
+);
+
+export const fieldValues = createSelector(
+    viewedIssue,
+    (issue) => issue && issue.fieldValues,
+);
+
+export const labelRefs = createSelector(
+    viewedIssue,
+    (issue) => issue && issue.labelRefs,
+);
+
+export const type = createSelector(
+    fieldValues,
+    labelRefs,
+    (fieldValues, labelRefs) => extractTypeForIssue(fieldValues, labelRefs),
+);
+
+export const restrictions = createSelector(
+    labelRefs,
+    (labelRefs) => {
+      if (!labelRefs) return {};
+
+      const restrictions = {};
+
+      labelRefs.forEach((labelRef) => {
+        const label = labelRef.label;
+        const lowerCaseLabel = label.toLowerCase();
+
+        if (lowerCaseLabel.startsWith(RESTRICT_VIEW_PREFIX)) {
+          const permissionType = removePrefix(label, RESTRICT_VIEW_PREFIX);
+          if (!('view' in restrictions)) {
+            restrictions['view'] = [permissionType];
+          } else {
+            restrictions['view'].push(permissionType);
+          }
+        } else if (lowerCaseLabel.startsWith(RESTRICT_EDIT_PREFIX)) {
+          const permissionType = removePrefix(label, RESTRICT_EDIT_PREFIX);
+          if (!('edit' in restrictions)) {
+            restrictions['edit'] = [permissionType];
+          } else {
+            restrictions['edit'].push(permissionType);
+          }
+        } else if (lowerCaseLabel.startsWith(RESTRICT_COMMENT_PREFIX)) {
+          const permissionType = removePrefix(label, RESTRICT_COMMENT_PREFIX);
+          if (!('comment' in restrictions)) {
+            restrictions['comment'] = [permissionType];
+          } else {
+            restrictions['comment'].push(permissionType);
+          }
+        }
+      });
+
+      return restrictions;
+    },
+);
+
+export const isOpen = createSelector(
+    viewedIssue,
+    (issue) => issue && issue.statusRef && issue.statusRef.meansOpen || false);
+
+// Returns a function that, given an issue and its related issues,
+// returns a combined list of issue ref strings including related issues,
+// blocking or blocked on issues, and federated references.
+const mapRefsWithRelated = (blocking) => {
+  return (issue, relatedIssues) => {
+    let refs = [];
+    if (blocking) {
+      if (issue.blockingIssueRefs) {
+        refs = refs.concat(issue.blockingIssueRefs);
+      }
+      if (issue.danglingBlockingRefs) {
+        refs = refs.concat(issue.danglingBlockingRefs);
+      }
+    } else {
+      if (issue.blockedOnIssueRefs) {
+        refs = refs.concat(issue.blockedOnIssueRefs);
+      }
+      if (issue.danglingBlockedOnRefs) {
+        refs = refs.concat(issue.danglingBlockedOnRefs);
+      }
+    }
+
+    // Note: relatedIssues is a Redux generated key for issues, not part of the
+    // pRPC Issue object.
+    if (issue.relatedIssues) {
+      refs = refs.concat(issue.relatedIssues);
+    }
+    return refs.map((ref) => {
+      const key = issueRefToString(ref);
+      if (relatedIssues.has(key)) {
+        return relatedIssues.get(key);
+      }
+      return ref;
+    });
+  };
+};
+
+export const blockingIssues = createSelector(
+    viewedIssue, relatedIssues,
+    mapRefsWithRelated(true),
+);
+
+export const blockedOnIssues = createSelector(
+    viewedIssue, relatedIssues,
+    mapRefsWithRelated(false),
+);
+
+export const mergedInto = createSelector(
+    viewedIssue, relatedIssues,
+    (issue, relatedIssues) => {
+      if (!issue || !issue.mergedIntoIssueRef) return {};
+      const key = issueRefToString(issue.mergedIntoIssueRef);
+      if (relatedIssues && relatedIssues.has(key)) {
+        return relatedIssues.get(key);
+      }
+      return issue.mergedIntoIssueRef;
+    },
+);
+
+export const sortedBlockedOn = createSelector(
+    blockedOnIssues,
+    (blockedOn) => blockedOn.sort((a, b) => {
+      const aIsOpen = a.statusRef && a.statusRef.meansOpen ? 1 : 0;
+      const bIsOpen = b.statusRef && b.statusRef.meansOpen ? 1 : 0;
+      return bIsOpen - aIsOpen;
+    }),
+);
+
+// values (from issue.fieldValues) is an array with one entry per value.
+// We want to turn this into a map of fieldNames -> values.
+export const fieldValueMap = createSelector(
+    fieldValues,
+    (fieldValues) => fieldValuesToMap(fieldValues),
+);
+
+// Get the list of full componentDefs for the viewed issue.
+export const components = createSelector(
+    viewedIssue,
+    projectV0.componentsMap,
+    (issue, components) => {
+      if (!issue || !issue.componentRefs) return [];
+      return issue.componentRefs.map(
+          (comp) => components.get(comp.path) || comp);
+    },
+);
+
+// Get custom fields that apply to a specific issue.
+export const fieldDefs = createSelector(
+    projectV0.fieldDefs,
+    type,
+    fieldValueMap,
+    (fieldDefs, type, fieldValues) => {
+      if (!fieldDefs) return [];
+      type = type || '';
+      return fieldDefs.filter((f) => {
+        const fieldValueKey = fieldValueMapKey(f.fieldRef.fieldName,
+            f.phaseRef && f.phaseRef.phaseName);
+        if (fieldValues && fieldValues.has(fieldValueKey)) {
+        // Regardless of other checks, include a particular field def if the
+        // issue has a value defined.
+          return true;
+        }
+        // Skip approval type and phase fields here.
+        if (f.fieldRef.approvalName ||
+            f.fieldRef.type === fieldTypes.APPROVAL_TYPE ||
+            f.isPhaseField) {
+          return false;
+        }
+
+        // If this fieldDef belongs to only one type, filter out the field if
+        // that type isn't the specified type.
+        if (f.applicableType && type.toLowerCase() !==
+            f.applicableType.toLowerCase()) {
+          return false;
+        }
+
+        return true;
+      });
+    },
+);
+
+// Action Creators
+/**
+ * Tells Redux that the user has navigated to an issue page and is now
+ * viewing a new issue.
+ * @param {IssueRef} issueRef The issue that the user is viewing.
+ * @return {AnyAction}
+ */
+export const viewIssue = (issueRef) => ({type: VIEW_ISSUE, issueRef});
+
+export const fetchCommentReferences = (comments, projectName) => {
+  return async (dispatch) => {
+    dispatch({type: FETCH_COMMENT_REFERENCES_START});
+
+    try {
+      const refs = await autolink.getReferencedArtifacts(comments, projectName);
+      const commentRefs = {};
+      refs.forEach(({componentName, existingRefs}) => {
+        commentRefs[componentName] = existingRefs;
+      });
+      dispatch({
+        type: FETCH_COMMENT_REFERENCES_SUCCESS,
+        commentReferences: commentRefs,
+      });
+    } catch (error) {
+      dispatch({type: FETCH_COMMENT_REFERENCES_FAILURE, error});
+    }
+  };
+};
+
+export const fetchReferencedUsers = (issue) => async (dispatch) => {
+  if (!issue) return;
+  dispatch({type: FETCH_REFERENCED_USERS_START});
+
+  // TODO(zhangtiff): Make this function account for custom fields
+  // of type user.
+  const userRefs = [...(issue.ccRefs || [])];
+  if (issue.ownerRef) {
+    userRefs.push(issue.ownerRef);
+  }
+  (issue.approvalValues || []).forEach((approval) => {
+    userRefs.push(...(approval.approverRefs || []));
+    if (approval.setterRef) {
+      userRefs.push(approval.setterRef);
+    }
+  });
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Users', 'ListReferencedUsers', {userRefs});
+
+    const referencedUsers = {};
+    (resp.users || []).forEach((user) => {
+      referencedUsers[user.displayName] = user;
+    });
+    dispatch({type: FETCH_REFERENCED_USERS_SUCCESS, referencedUsers});
+  } catch (error) {
+    dispatch({type: FETCH_REFERENCED_USERS_FAILURE, error});
+  }
+};
+
+export const fetchFederatedReferences = (issue) => async (dispatch) => {
+  dispatch({type: FETCH_FEDERATED_REFERENCES_START});
+
+  // Concat all potential fedrefs together, convert from shortlink to classes,
+  // then fire off a request to fetch the status of each.
+  const fedRefs = []
+      .concat(issue.danglingBlockingRefs || [])
+      .concat(issue.danglingBlockedOnRefs || [])
+      .concat(issue.mergedIntoIssueRef ? [issue.mergedIntoIssueRef] : [])
+      .filter((ref) => ref && ref.extIdentifier)
+      .map((ref) => fromShortlink(ref.extIdentifier))
+      .filter((fedRef) => fedRef);
+
+  // If no FedRefs, return empty Map.
+  if (fedRefs.length === 0) {
+    return;
+  }
+
+  try {
+    // Load email separately since it might have changed.
+    await loadGapi();
+    const email = await fetchGapiEmail();
+
+    // If already logged in, dispatch login success event.
+    dispatch({
+      type: userV0.GAPI_LOGIN_SUCCESS,
+      email: email,
+    });
+
+    await Promise.all(fedRefs.map((fedRef) => fedRef.getFederatedDetails()));
+    const fedRefIssueRefs = fedRefs.map((fedRef) => fedRef.toIssueRef());
+
+    dispatch({
+      type: FETCH_FEDERATED_REFERENCES_SUCCESS,
+      fedRefIssueRefs: fedRefIssueRefs,
+    });
+  } catch (error) {
+    dispatch({type: FETCH_FEDERATED_REFERENCES_FAILURE, error});
+  }
+};
+
+// TODO(zhangtiff): Figure out if we can reduce request/response sizes by
+// diffing issues to fetch against issues we already know about to avoid
+// fetching duplicate info.
+export const fetchRelatedIssues = (issue) => async (dispatch) => {
+  if (!issue) return;
+  dispatch({type: FETCH_RELATED_ISSUES_START});
+
+  const refsToFetch = (issue.blockedOnIssueRefs || []).concat(
+      issue.blockingIssueRefs || []);
+  // Add mergedinto ref, exclude FedRefs which are fetched separately.
+  if (issue.mergedIntoIssueRef && !issue.mergedIntoIssueRef.extIdentifier) {
+    refsToFetch.push(issue.mergedIntoIssueRef);
+  }
+
+  const message = {
+    issueRefs: refsToFetch,
+  };
+  try {
+    // Fire off call to fetch FedRefs. Since it might take longer it is
+    // handled by a separate reducer.
+    dispatch(fetchFederatedReferences(issue));
+
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'ListReferencedIssues', message);
+
+    const relatedIssues = {};
+
+    const openIssues = resp.openRefs || [];
+    const closedIssues = resp.closedRefs || [];
+    openIssues.forEach((issue) => {
+      issue.statusRef.meansOpen = true;
+      relatedIssues[issueRefToString(issue)] = issue;
+    });
+    closedIssues.forEach((issue) => {
+      issue.statusRef.meansOpen = false;
+      relatedIssues[issueRefToString(issue)] = issue;
+    });
+    dispatch({
+      type: FETCH_RELATED_ISSUES_SUCCESS,
+      relatedIssues: relatedIssues,
+    });
+  } catch (error) {
+    dispatch({type: FETCH_RELATED_ISSUES_FAILURE, error});
+  };
+};
+
+/**
+ * Fetches issue data needed to display a detailed view of a single
+ * issue. This function dispatches many actions to handle the fetching
+ * of issue comments, permissions, star state, and more.
+ * @param {IssueRef} issueRef The issue that the user is viewing.
+ * @return {function(function): Promise<void>}
+ */
+export const fetchIssuePageData = (issueRef) => async (dispatch) => {
+  dispatch(fetchComments(issueRef));
+  dispatch(fetch(issueRef));
+  dispatch(fetchPermissions(issueRef));
+  dispatch(fetchIsStarred(issueRef));
+};
+
+/**
+ * @param {IssueRef} issueRef Which issue to fetch.
+ * @return {function(function): Promise<void>}
+ */
+export const fetch = (issueRef) => async (dispatch) => {
+  dispatch({type: FETCH_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'GetIssue', {issueRef},
+    );
+
+    const movedToRef = resp.movedToRef;
+
+    // The API can return deleted issue objects that don't have issueRef data
+    // specified. For this case, we want to make sure a projectName and localId
+    // are still provided to the frontend to ensure that keying issues still
+    // works.
+    const issue = {...issueRef, ...resp.issue};
+    if (movedToRef) {
+      issue.movedToRef = movedToRef;
+    }
+
+    dispatch({type: FETCH_SUCCESS, issue});
+
+    if (!issue.isDeleted && !movedToRef) {
+      dispatch(fetchRelatedIssues(issue));
+      dispatch(fetchHotlists(issueRef));
+      dispatch(fetchReferencedUsers(issue));
+      dispatch(userV0.fetchProjects([issue.reporterRef]));
+    }
+  } catch (error) {
+    dispatch({type: FETCH_FAILURE, error});
+  }
+};
+
+/**
+ * Action creator to fetch multiple Issues.
+ * @param {Array<IssueRef>} issueRefs An Array of Issue references to fetch.
+ * @return {function(function): Promise<void>}
+ */
+export const fetchIssues = (issueRefs) => async (dispatch) => {
+  dispatch({type: FETCH_ISSUES_START});
+
+  try {
+    const {openRefs, closedRefs} = await prpcClient.call(
+        'monorail.Issues', 'ListReferencedIssues', {issueRefs});
+    const issues = [...openRefs || [], ...closedRefs || []];
+
+    dispatch({type: FETCH_ISSUES_SUCCESS, issues});
+  } catch (error) {
+    dispatch({type: FETCH_ISSUES_FAILURE, error});
+  }
+};
+
+/**
+ * Gets the hotlists that a given issue is in.
+ * @param {IssueRef} issueRef
+ * @return {function(function): Promise<void>}
+ */
+export const fetchHotlists = (issueRef) => async (dispatch) => {
+  dispatch({type: FETCH_HOTLISTS_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Features', 'ListHotlistsByIssue', {issue: issueRef});
+
+    const hotlists = (resp.hotlists || []);
+    hotlists.sort((hotlistA, hotlistB) => {
+      return hotlistA.name.localeCompare(hotlistB.name);
+    });
+    dispatch({type: FETCH_HOTLISTS_SUCCESS, hotlists});
+  } catch (error) {
+    dispatch({type: FETCH_HOTLISTS_FAILURE, error});
+  };
+};
+
+/**
+ * Async action creator to fetch issues in the issue list and grid pages. This
+ * action creator supports batching multiple async requests to support the grid
+ * view's ability to load up to 6,000 issues in one page load.
+ *
+ * @param {string} projectName The project to fetch issues from.
+ * @param {Object} params Options for which issues to fetch.
+ * @param {string=} params.q The query string for the search.
+ * @param {string=} params.can The ID of the canned query for the search.
+ * @param {string=} params.groupby The spec of which fields to group by.
+ * @param {string=} params.sort The spec of which fields to sort by.
+ * @param {number=} params.start What cursor index to start at.
+ * @param {number=} params.maxItems How many items to fetch per page.
+ * @param {number=} params.maxCalls The maximum number of API calls to make.
+ *   Combined with pagination.maxItems, this defines the maximum number of
+ *   issues this method can fetch.
+ * @return {function(function): Promise<void>}
+ */
+export const fetchIssueList =
+  (projectName, {q = undefined, can = undefined, groupby = undefined,
+    sort = undefined, start = undefined, maxItems = undefined,
+    maxCalls = 1,
+  }) => async (dispatch) => {
+    let updateData = {};
+    const promises = [];
+    const issuesByRequest = [];
+    let issueLimit;
+    let totalIssues;
+    let totalCalls;
+    const itemsPerCall = maxItems || 1000;
+
+    const cannedQuery = Number.parseInt(can) || undefined;
+
+    const pagination = {
+      ...(start && {start}),
+      ...(maxItems && {maxItems}),
+    };
+
+    const message = {
+      projectNames: [projectName],
+      query: q,
+      cannedQuery,
+      groupBySpec: groupby,
+      sortSpec: sort,
+      pagination,
+    };
+
+    dispatch({type: FETCH_ISSUE_LIST_START});
+
+    // initial api call made to determine total number of issues matching
+    // the query.
+    try {
+      // TODO(zhangtiff): Refactor this action creator when adding issue
+      // list pagination.
+      const resp = await prpcClient.call(
+          'monorail.Issues', 'ListIssues', message);
+
+      // prpcClient is not actually a protobuf client and therefore not
+      // hydrating default values. See crbug.com/monorail/6641
+      // Until that is fixed, we have to explicitly define it.
+      const defaultFetchListResponse = {totalResults: 0, issues: []};
+
+      updateData =
+        Object.entries(resp).length === 0 ?
+          defaultFetchListResponse :
+          resp;
+      issuesByRequest[0] = updateData.issues;
+      issueLimit = updateData.totalResults;
+
+      // determine correct issues to load and number of calls to be made.
+      if (issueLimit > (itemsPerCall * maxCalls)) {
+        totalIssues = itemsPerCall * maxCalls;
+        totalCalls = maxCalls - 1;
+      } else {
+        totalIssues = issueLimit;
+        totalCalls = Math.ceil(issueLimit / itemsPerCall) - 1;
+      }
+
+      if (totalIssues) {
+        updateData.progress = updateData.issues.length / totalIssues;
+      } else {
+        updateData.progress = 1;
+      }
+
+      dispatch({type: FETCH_ISSUE_LIST_UPDATE, ...updateData});
+
+      // remaining api calls are made.
+      for (let i = 1; i <= totalCalls; i++) {
+        promises[i - 1] = (async () => {
+          const resp = await prpcClient.call(
+              'monorail.Issues', 'ListIssues', {
+                ...message,
+                pagination: {start: i * itemsPerCall, maxItems: itemsPerCall},
+              });
+          issuesByRequest[i] = (resp.issues || []);
+          // sort the issues in the correct order.
+          updateData.issues = [];
+          issuesByRequest.forEach((issue) => {
+            updateData.issues = updateData.issues.concat(issue);
+          });
+          updateData.progress = updateData.issues.length / totalIssues;
+          dispatch({type: FETCH_ISSUE_LIST_UPDATE, ...updateData});
+        })();
+      }
+
+      await Promise.all(promises);
+
+      // TODO(zhangtiff): Try to delete FETCH_ISSUE_LIST_SUCCESS in favor of
+      // just FETCH_ISSUE_LIST_UPDATE.
+      dispatch({type: FETCH_ISSUE_LIST_SUCCESS});
+    } catch (error) {
+      dispatch({type: FETCH_ISSUE_LIST_FAILURE, error});
+    };
+  };
+
+/**
+ * Fetches the currently logged in user's permissions for a given issue.
+ * @param {Issue} issueRef
+ * @return {function(function): Promise<void>}
+ */
+export const fetchPermissions = (issueRef) => async (dispatch) => {
+  dispatch({type: FETCH_PERMISSIONS_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'ListIssuePermissions', {issueRef},
+    );
+
+    dispatch({type: FETCH_PERMISSIONS_SUCCESS, permissions: resp.permissions});
+  } catch (error) {
+    dispatch({type: FETCH_PERMISSIONS_FAILURE, error});
+  };
+};
+
+/**
+ * Fetches comments for an issue. Note that issue descriptions are also
+ * comments.
+ * @param {IssueRef} issueRef
+ * @return {function(function): Promise<void>}
+ */
+export const fetchComments = (issueRef) => async (dispatch) => {
+  dispatch({type: FETCH_COMMENTS_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'ListComments', {issueRef});
+
+    dispatch({type: FETCH_COMMENTS_SUCCESS, comments: resp.comments});
+    dispatch(fetchCommentReferences(
+        resp.comments, issueRef.projectName));
+
+    const commenterRefs = (resp.comments || []).map(
+        (comment) => comment.commenter);
+    dispatch(userV0.fetchProjects(commenterRefs));
+  } catch (error) {
+    dispatch({type: FETCH_COMMENTS_FAILURE, error});
+  };
+};
+
+/**
+ * Gets whether the logged in user has starred a given issue.
+ * @param {IssueRef} issueRef
+ * @return {function(function): Promise<void>}
+ */
+export const fetchIsStarred = (issueRef) => async (dispatch) => {
+  dispatch({type: FETCH_IS_STARRED_START});
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'IsIssueStarred', {issueRef},
+    );
+
+    dispatch({
+      type: FETCH_IS_STARRED_SUCCESS,
+      starred: resp.isStarred,
+      issueRef: issueRef,
+    });
+  } catch (error) {
+    dispatch({type: FETCH_IS_STARRED_FAILURE, error});
+  };
+};
+
+/**
+ * Fetch all of a logged in user's starred issues.
+ * @return {function(function): Promise<void>}
+ */
+export const fetchStarredIssues = () => async (dispatch) => {
+  dispatch({type: FETCH_ISSUES_STARRED_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'ListStarredIssues', {},
+    );
+    dispatch({type: FETCH_ISSUES_STARRED_SUCCESS,
+      starredIssueRefs: resp.starredIssueRefs});
+  } catch (error) {
+    dispatch({type: FETCH_ISSUES_STARRED_FAILURE, error});
+  };
+};
+
+/**
+ * Stars or unstars an issue.
+ * @param {IssueRef} issueRef The issue to star.
+ * @param {boolean} starred Whether to star or unstar.
+ * @return {function(function): Promise<void>}
+ */
+export const star = (issueRef, starred) => async (dispatch) => {
+  const requestKey = issueRefToString(issueRef);
+
+  dispatch({type: STAR_START, requestKey});
+  const message = {issueRef, starred};
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'StarIssue', message,
+    );
+
+    dispatch({
+      type: STAR_SUCCESS,
+      starCount: resp.starCount,
+      issueRef,
+      starred,
+      requestKey,
+    });
+  } catch (error) {
+    dispatch({type: STAR_FAILURE, error, requestKey});
+  }
+};
+
+/**
+ * Runs a presubmit request to find warnings to show the user before an issue
+ * edit is saved.
+ * @param {IssueRef} issueRef The issue being edited.
+ * @param {IssueDelta} issueDelta The user's in flight changes to the issue.
+ * @return {function(function): Promise<void>}
+ */
+export const presubmit = (issueRef, issueDelta) => async (dispatch) => {
+  dispatch({type: PRESUBMIT_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'PresubmitIssue', {issueRef, issueDelta});
+
+    dispatch({type: PRESUBMIT_SUCCESS, presubmitResponse: resp});
+  } catch (error) {
+    dispatch({type: PRESUBMIT_FAILURE, error: error});
+  }
+};
+
+/**
+ * Async action creator to update an issue's approval.
+ *
+ * @param {Object} params Options for the approval update.
+ * @param {IssueRef} params.issueRef
+ * @param {FieldRef} params.fieldRef
+ * @param {ApprovalDelta=} params.approvalDelta
+ * @param {string=} params.commentContent
+ * @param {boolean=} params.sendEmail
+ * @param {boolean=} params.isDescription
+ * @param {AttachmentUpload=} params.uploads
+ * @return {function(function): Promise<void>}
+ */
+export const updateApproval = ({issueRef, fieldRef, approvalDelta,
+  commentContent, sendEmail, isDescription, uploads}) => async (dispatch) => {
+  dispatch({type: UPDATE_APPROVAL_START});
+  try {
+    const {approval} = await prpcClient.call(
+        'monorail.Issues', 'UpdateApproval', {
+          ...(issueRef && {issueRef}),
+          ...(fieldRef && {fieldRef}),
+          ...(approvalDelta && {approvalDelta}),
+          ...(commentContent && {commentContent}),
+          ...(sendEmail && {sendEmail}),
+          ...(isDescription && {isDescription}),
+          ...(uploads && {uploads}),
+        });
+
+    dispatch({type: UPDATE_APPROVAL_SUCCESS, approval, issueRef});
+    dispatch(fetch(issueRef));
+    dispatch(fetchComments(issueRef));
+  } catch (error) {
+    dispatch({type: UPDATE_APPROVAL_FAILURE, error: error});
+  };
+};
+
+/**
+ * Async action creator to update an issue.
+ *
+ * @param {Object} params Options for the issue update.
+ * @param {IssueRef} params.issueRef
+ * @param {IssueDelta=} params.delta
+ * @param {string=} params.commentContent
+ * @param {boolean=} params.sendEmail
+ * @param {boolean=} params.isDescription
+ * @param {AttachmentUpload=} params.uploads
+ * @param {Array<number>=} params.keptAttachments
+ * @return {function(function): Promise<void>}
+ */
+export const update = ({issueRef, delta, commentContent, sendEmail,
+  isDescription, uploads, keptAttachments}) => async (dispatch) => {
+  dispatch({type: UPDATE_START});
+
+  try {
+    const {issue} = await prpcClient.call(
+        'monorail.Issues', 'UpdateIssue', {issueRef, delta,
+          commentContent, sendEmail, isDescription, uploads,
+          keptAttachments});
+
+    dispatch({type: UPDATE_SUCCESS, issue});
+    dispatch(fetchComments(issueRef));
+    dispatch(fetchRelatedIssues(issue));
+    dispatch(fetchReferencedUsers(issue));
+  } catch (error) {
+    dispatch({type: UPDATE_FAILURE, error: error});
+  };
+};
+
+/**
+ * Converts an issue from one template to another. This is used for changing
+ * launch issues.
+ * @param {IssueRef} issueRef
+ * @param {Object} options
+ * @param {string=} options.templateName
+ * @param {string=} options.commentContent
+ * @param {boolean=} options.sendEmail
+ * @return {function(function): Promise<void>}
+ */
+export const convert = (issueRef, {templateName = '',
+  commentContent = '', sendEmail = true},
+) => async (dispatch) => {
+  dispatch({type: CONVERT_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Issues', 'ConvertIssueApprovalsTemplate',
+        {issueRef, templateName, commentContent, sendEmail});
+
+    dispatch({type: CONVERT_SUCCESS, issue: resp.issue});
+    const fetchCommentsMessage = {issueRef};
+    dispatch(fetchComments(fetchCommentsMessage));
+  } catch (error) {
+    dispatch({type: CONVERT_FAILURE, error: error});
+  };
+};
