diff --git a/api/v3/apps-script-client/IssueService.js b/api/v3/apps-script-client/IssueService.js
new file mode 100644
index 0000000..d1c6c9d
--- /dev/null
+++ b/api/v3/apps-script-client/IssueService.js
@@ -0,0 +1,908 @@
+// Copyright 2020 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.
+
+/* eslint-disable no-unused-vars */
+
+const COMMENT_TYPE_DESCRIPTION = 'DESCRIPTION';
+
+/**
+ * Fetches the issue from Monorail.
+ * @param {string} issueName The resource name of the issue.
+ * @return {Issue}
+ */
+function getIssue(issueName) {
+  const message = {'name': issueName};
+  const url = URL + 'monorail.v3.Issues/GetIssue';
+  return run_(url, message);
+}
+
+/**
+ * Fetches all the given issues from Monorail.
+ * @param {Array<string>} issueNames The resource names of the issues.
+ * @return {Array<Issue>}
+ */
+function batchGetIssues(issueNames) {
+  const message = {'names': issueNames};
+  const url = URL + 'monorail.v3.Issues/BatchGetIssues';
+  return run_(url, message);
+}
+
+/**
+ * Fetches all the ApprovalValues that belong to the given issue.
+ * @param {string} issueName The resource name of the issue.
+ * @return {Array<ApprovalValue>}
+ */
+function listApprovalValues(issueName) {
+  const message = {'parent': issueName};
+  const url = URL + 'monorail.v3.Issues/ListApprovalValues';
+  return run_(url, message);
+}
+
+/**
+ * Calls SearchIssues with the given parameters.
+ * @param {Array<string>} projectNames resource names of the projects to search.
+ * @param {string} query The query to use to search.
+ * @param {string} orderBy The issue fields to order issues by.
+ * @param {Number} pageSize The maximum issues to return.
+ * @param {string} pageToken The page token from the previous call.
+ * @return {Array<SearchIssuesResponse>}
+ */
+function searchIssuesPagination_(
+    projectNames, query, orderBy, pageSize, pageToken) {
+  const message = {
+    'projects': projectNames,
+    'query': query,
+    'orderBy': orderBy,
+    'pageToken': pageToken};
+  if (pageSize) {
+    message['pageSize'] = pageSize;
+  }
+  const url = URL + 'monorail.v3.Issues/SearchIssues';
+  return run_(url, message);
+}
+
+// TODO(crbug.com/monorail/7143): SearchIssues only accepts one project.
+/**
+ * Searches Monorail for issues using the given query.
+ * NOTE: We currently only accept `projectNames` with one and only one project.
+ * @param {Array<string>} projects Resource names of the projects to search
+ *     within.
+ * @param {string=} query The query to use to search.
+ * @param {string=} orderBy The issue fields to order issues by,
+ *    e.g. 'EstDays,Opened,-stars'
+ * @return {Array<Issue>}
+ */
+function searchIssues(projects, query, orderBy) {
+  const pageSize = 100;
+  let pageToken;
+
+  issues = [];
+
+  do {
+    const resp = searchIssuesPagination_(
+        projects, query, orderBy, pageSize, pageToken);
+    issues = issues.concat(resp.issues);
+    pageToken = resp.nextPageToken;
+  }
+  while (pageToken);
+
+  return issues;
+}
+
+/**
+ * Calls ListComments with the given parameters.
+ * @param {string} issueName Resource name of the issue.
+ * @param {string} filter The approval filter query.
+ * @param {Number} pageSize The maximum number of comments to return.
+ * @param {string} pageToken The page token from the previous request.
+ * @return {ListCommentsResponse}
+ */
+function listCommentsPagination_(issueName, filter, pageSize, pageToken) {
+  const message = {
+    'parent': issueName,
+    'pageToken': pageToken,
+    'filter': filter,
+  };
+  if (pageSize) {
+    message['pageSize'] = pageSize;
+  }
+  const url = URL + 'monorail.v3.Issues/ListComments';
+  return run_(url, message);
+}
+
+/**
+ * Returns all comments and previous/current descriptions of an issue.
+ * @param {string} issueName Resource name of the Issue.
+ * @param {string=} filter The filter query filtering out comments.
+ *     We only accept `approval = "<approvalDef resource name>""`.
+ *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
+ * @return {Array<Comment>}
+ */
+function listComments(issueName, filter) {
+  let pageToken;
+
+  let comments = [];
+  do {
+    const resp = listCommentsPagination_(issueName, filter, '', pageToken);
+    comments = comments.concat(resp.comments);
+    pageToken = resp.nextPageToken;
+  }
+  while (pageToken);
+
+  return comments;
+}
+
+/**
+ * Gets the current description of an issue.
+ * @param {string} issueName Resource name of the Issue.
+ * @param {string=} filter The filter query filtering out comments.
+ *     We only accept `approval = "<approvalDef resource name>""`.
+ *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
+ * @return {Comment}
+ */
+function getCurrentDescription(issueName, filter) {
+  const allComments = listComments(issueName, filter);
+  for (let i = (allComments.length - 1); i > -1; i--) {
+    if (allComments[i].type === COMMENT_TYPE_DESCRIPTION) {
+      return allComments[i];
+    }
+  }
+}
+
+/**
+ * Gets the first (non-description) comment of an issue.
+ * @param {string} issueName Resource name of the Issue.
+ * @param {string=} filter The filter query filtering out comments.
+ *     We only accept `approval = "<approvalDef resource name>""`.
+ *      e.g. 'approval = "projects/chromium/approvalDefs/34"'
+ * @return {Comment}
+ */
+function getFirstComment(issueName, filter) {
+  const allComments = listComments(issueName, filter);
+  for (let i = 0; i < allComments.length; i++) {
+    if (allComments[i].type !== COMMENT_TYPE_DESCRIPTION) {
+      return allComments[i];
+    }
+  }
+  return null;
+}
+
+/**
+ * Gets the last (non-description) comment of an issue.
+ * @param {string} issueName The resource name of the issue.
+ * @param {string=} filter The filter query filtering out comments.
+ *     We only accept `approval = "<approvalDef resource name>""`.
+ *     e.g. 'approval = "projects/chromium/approvalDefs/34"'
+ * @return {Issue}
+ */
+function getLastComment(issueName, filter) {
+  const allComments = listComments(issueName, filter);
+  for (let i = (allComments.length - 1); i > -1; i--) {
+    if (allComments[i].type != COMMENT_TYPE_DESCRIPTION) {
+      return allComments[i];
+    }
+  }
+  return null;
+}
+
+/**
+ * Checks if the given label exists in the issue.
+ * @param {Issue} issue The issue to search within for the label.
+ * @param {string} label The label to search for.
+ * @return {boolean}
+ */
+function hasLabel(issue, label) {
+  if (issue.labels) {
+    const testLabel = label.toLowerCase();
+    return issue.labels.some(({label}) => testLabel === label.toLowerCase());
+  }
+  return false;
+}
+
+/**
+ * Checks if the issue has any labels matching the given regex.
+ * @param {Issue} issue The issue to search within for matching labels.
+ * @param {string} regex The regex pattern to use to search for labels.
+ * @return {boolean}
+ */
+function hasLabelMatching(issue, regex) {
+  if (issue.labels) {
+    const re = new RegExp(regex, 'i');
+    return issue.labels.some(({label}) => re.test(label));
+  }
+  return false;
+}
+
+/**
+ * Returns all labels in the issue that match the given regex.
+ * @param {Issue} issue The issue to search within for matching labels.
+ * @param {string} regex The regex pattern to use to search for labels.
+ * @return {Array<string>}
+ */
+function getLabelsMatching(issue, regex) {
+  const labels = [];
+  if (issue.labels) {
+    const re = new RegExp(regex, 'i');
+    for (let i = 0; i < issue.labels.length; i++) {
+      if (re.test(issue.labels[i].label)) {
+        labels.push(issue.labels[i].label);
+      }
+    }
+  }
+  return labels;
+}
+
+/**
+ * Get the comment where the given label was added, if any.
+ * @param {string} issueName The resource name of the issue.
+ * @param {string} label The label that was remove.
+ * @return {Comment}
+ */
+function getLabelSetComment(issueName, label) {
+  const comments = listComments(issueName);
+  for (let i = 0; i < comments.length; i++) {
+    const comment = comments[i];
+    if (comment.amendments) {
+      for (let j = 0; j < comment.amendments.length; j++) {
+        const amendment = comment.amendments[j];
+        if (amendment['fieldName'] === 'Labels' &&
+            amendment['newOrDeltaValue'].toLowerCase() === (
+              label.toLocaleLowerCase())) {
+          return comment;
+        }
+      }
+    }
+  }
+  return null;
+}
+
+/**
+ * Get the comment where the given label was removed, if any.
+ * @param {string} issueName The resource name of the issue.
+ * @param {string} label The label that was remove.
+ * @return {Comment}
+ */
+function getLabelRemoveComment(issueName, label) {
+  const comments = listComments(issueName);
+  for (let i = 0; i < comments.length; i++) {
+    const comment = comments[i];
+    if (comment.amendments) {
+      for (let j = 0; j < comment.amendments.length; j++) {
+        const amendment = comment.amendments[j];
+        if (amendment['fieldName'] === 'Labels' &&
+            amendment[
+                'newOrDeltaValue'].toLowerCase() === (
+              '-' + label.toLocaleLowerCase())) {
+          return comment;
+        }
+      }
+    }
+  }
+  return null;
+}
+
+/**
+ * Updates the issue to have the given label added.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue The issue to update.
+ * @param {string} label The label to add.
+ */
+function addLabel(issue, label) {
+  if (hasLabel(issue, label)) return;
+  maybeCreateDelta_(issue);
+  // Add the label to the issue's delta.labelsAdd.
+  issue.delta.labelsAdd.push(label);
+  // Add the label to the issue.
+  issue.labels.push({label: label});
+  // 'labels' added to updateMask in saveChanges().
+}
+
+/**
+ * Updates the issue to have the given label removed from the issue.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue The issue to update.
+ * @param {string} label The label to remove.
+ */
+function removeLabel(issue, label) {
+  if (!hasLabel(issue, label)) return;
+  maybeCreateDelta_(issue);
+  // Add the label to the issue's delta.labelsRemove.
+  issue.delta.labelsRemove.push(label);
+  // Remove label from issue.
+  for (let i = 0; i < issue.labels.length; i++) {
+    if (issue.labels[i].label.toLowerCase() === label.toLowerCase()) {
+      issue.labels.splice(i, 1);
+      break;
+    }
+  }
+}
+
+/**
+ * Sets the owner of the given issue.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {string} ownerName The resource name of the new owner,
+ *     e.g. 'users/chicken@email.com'
+*/
+function setOwner(issue, ownerName) {
+  maybeCreateDelta_(issue);
+  issue.owner = {'user': ownerName};
+  if (issue.delta.updateMask.indexOf('owner.user') === -1) {
+    issue.delta.updateMask.push('owner.user');
+  }
+}
+
+/**
+ * Sets the summary of the given issue.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {string} summary The new summary of the issue.
+*/
+function setSummary(issue, summary) {
+  maybeCreateDelta_(issue);
+  issue.summary = summary;
+  if (issue.delta.updateMask.indexOf('summary') === -1) {
+    issue.delta.updateMask.push('summary');
+  }
+}
+
+/**
+ *Sets the status of the given issue.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {string} status The new status of the issue e.g. 'Available'.
+*/
+function setStatus(issue, status) {
+  maybeCreateDelta_(issue);
+  issue.status.status = status;
+  if (issue.delta.updateMask.indexOf('status.status') === -1) {
+    issue.delta.updateMask.push('status.status');
+  }
+}
+
+/**
+ * Sets the merged into issue for the given issue.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {IssueRef} mergedIntoRef IssueRef of the issue to merge into.
+ */
+function setMergedInto(issue, mergedIntoRef) {
+  maybeCreateDelta_(issue);
+  issue.mergedIntoIssueRef = mergedIntoRef;
+  if (issue.delta.updateMask.indexOf('mergedIntoIssueRef') === -1) {
+    issue.delta.updateMask.push('mergedIntoIssueRef');
+  }
+}
+
+/**
+ * Checks if target is found in source.
+ * @param {IssueRef} target The IssueRef to look for.
+ * @param {Array<IssueRef>} source the IssueRefs to look in.
+ * @return {number} index of target in source, -1 if not found.
+ */
+function issueRefExists_(target, source) {
+  for (let i = 0; i < source.length; i++) {
+    if ((source[i].issue === target.issue || (!source[i].issue && !target.issue)
+    ) && (source[i].extIdentifier === target.extIdentifier || (
+      !source[i].extIdentifier && !target.extIdentifier))) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Makes blocking issue ref changes.
+ * blockingIssuesAdd are added before blockingIssuesRemove are removed.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {Array<IssueRef>} blockingIssuesAdd issues to add as blocking issues.
+ * @param {Array<IssueRef>} blockingIssuesRemove issues to remove from blocking
+ *     issues.
+ */
+function addBlockingIssueChanges(
+    issue, blockingIssuesAdd, blockingIssuesRemove) {
+  maybeCreateDelta_(issue);
+  blockingIssuesAdd.forEach((addRef) => {
+    const iInIssue = issueRefExists_(addRef, issue.blockingIssueRefs);
+    if (iInIssue === -1) { // addRef not found in issue
+      issue.blockingIssueRefs.push(addRef);
+      issue.delta.blockingAdd.push(addRef);
+      const iInDeltaRemove = issueRefExists_(
+          addRef, issue.delta.blockingRemove);
+      if (iInDeltaRemove != -1) {
+        // Remove addRef from blckingRemove that may have been added earlier.
+        issue.delta.blockingRemove.splice(iInDeltaRemove, 1);
+      }
+      // issue.delta.updateMask is updated in saveChanges()
+    }
+  });
+  // Add blockingIssuesAdd to issue and issue.delta.blockingAdd if not in
+  // issue.blockingIssues
+  blockingIssuesRemove.forEach((removeRef) => {
+    const iInIssue = issueRefExists_(removeRef, issue.blockingIssueRefs);
+    if (iInIssue > -1) {
+      issue.blockingIssueRefs.splice(iInIssue, 1);
+      issue.delta.blockingRemove.push(removeRef);
+      const iInDeltaAdd = issueRefExists_(removeRef, issue.delta.blockingAdd);
+      if (iInDeltaAdd != -1) {
+        issue.delta.blockingAdd.splice(iInDeltaAdd, 1);
+      }
+    }
+  });
+}
+
+/**
+ * Makes blocked-on issue ref changes.
+ * blockedOnIssuesAdd are added before blockedOnIssuesRemove are removed.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {Array<IssueRef>} blockedOnIssuesAdd issues to add as blockedon
+ *     issues.
+ * @param {Array<IssueRef>} blockedOnIssuesRemove issues to remove from
+ *     blockedon issues.
+ */
+function addBlockedOnIssueChanges(
+    issue, blockedOnIssuesAdd, blockedOnIssuesRemove) {
+  maybeCreateDelta_(issue);
+  blockedOnIssuesAdd.forEach((addRef) => {
+    const iInIssue = issueRefExists_(addRef, issue.blockedOnIssueRefs);
+    if (iInIssue === -1) { // addRef not found in issue
+      issue.blockedOnIssueRefs.push(addRef);
+      issue.delta.blockedOnAdd.push(addRef);
+      const iInDeltaRemove = issueRefExists_(
+          addRef, issue.delta.blockedOnRemove);
+      if (iInDeltaRemove != -1) {
+        // Remove addRef from blckingRemove that may have been added earlier.
+        issue.delta.blockedOnRemove.splice(iInDeltaRemove, 1);
+      }
+      // issue.delta.updateMask is updated in saveChanges()
+    }
+  });
+  // Add blockedOnIssuesAdd to issue and issue.delta.blockedOnAdd if not in
+  // issue.blockedOnIssues.
+  blockedOnIssuesRemove.forEach((removeRef) => {
+    const iInIssue = issueRefExists_(removeRef, issue.blockedOnIssueRefs);
+    if (iInIssue > -1) {
+      issue.blockedOnIssueRefs.splice(iInIssue, 1);
+      issue.delta.blockedOnRemove.push(removeRef);
+      const iInDeltaAdd = issueRefExists_(removeRef, issue.delta.blockedOnAdd);
+      if (iInDeltaAdd != -1) {
+        issue.delta.blockedOnAdd.splice(iInDeltaAdd, 1);
+      }
+    }
+  });
+}
+
+
+/**
+ * Looks for a component name in an Array of ComponentValues.
+ * @param {string} compName Resource name of the Component to look for.
+ * @param {Array<ComponentValue>} compArray List of ComponentValues.
+ * @return {number} Index of compName in compArray, -1 if not found.
+ */
+function componentExists_(compName, compArray) {
+  for (let i = 0; i < compArray.length; i++) {
+    if (compArray[i].component === compName) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Adds the component changes to the issue.
+ * componentNamesAdd are added before componentNamesremove are removed.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {Array<string>} componentNamesAdd Array of component resource names.
+ * @param {Array<string>} componentNamesRemove Array or component resource
+ *     names.
+
+*/
+function addComponentChanges(issue, componentNamesAdd, componentNamesRemove) {
+  maybeCreateDelta_(issue);
+  componentNamesAdd.forEach((compName) => {
+    const iInIssue = componentExists_(compName, issue.components);
+    if (iInIssue === -1) { // compName is not in issue.
+      issue.components.push({'component': compName});
+      issue.delta.componentsAdd.push(compName);
+      const iInDeltaRemove = issue.delta.componentsRemove.indexOf(compName);
+      if (iInDeltaRemove != -1) {
+        // Remove compName from issue.delta.componentsRemove that may have been
+        // added before.
+        issue.delta.componentsRemove.splice(iInDeltaRemove, 1);
+      }
+      // issue.delta.updateMask is updated in saveChanges()
+    }
+  });
+
+  componentNamesRemove.forEach((compName) => {
+    const iInIssue = componentExists_(compName, issue.components);
+    if (iInIssue != -1) { // compName was found in issue.
+      issue.components.splice(iInIssue, 1);
+      issue.delta.componentsRemove.push(compName);
+      const iInDeltaAdd = issue.delta.componentsAdd.indexOf(compName);
+      if (iInDeltaAdd != -1) {
+        // Remove compName from issue.delta.componentsAdd that may have been
+        // added before.
+        issue.delta.componentsAdd.splice(iInDeltaAdd, 1);
+      }
+    }
+  });
+}
+
+/**
+ * Checks if the fieldVal is found in fieldValsArray
+ * @param {FieldValue} fieldVal the field to look for.
+ * @param {Array<FieldValue>} fieldValsArray the Array to look within.
+ * @return {number} the index of fieldVal in fieldValsArray, or -1 if not found.
+ */
+function fieldValueExists_(fieldVal, fieldValsArray) {
+  for (let i = 0; i < fieldValsArray.length; i++) {
+    const currFv = fieldValsArray[i];
+    if (currFv.field === fieldVal.field && currFv.value === fieldVal.value && (
+      currFv.phase === fieldVal.phase || (
+        !currFv.phase && !fieldVal.phase))) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Adds the FieldValue changes to the issue.
+ * fieldValuesAdd are added before fieldValuesRemove are removed.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {Array<FieldValue>} fieldValuesAdd Array of FieldValues to add.
+ * @param {Array<FieldValue>} fieldValuesRemove Array of FieldValues to remove.
+*/
+function addFieldValueChanges(issue, fieldValuesAdd, fieldValuesRemove) {
+  maybeCreateDelta_(issue);
+  fieldValuesAdd.forEach((fvAdd) => {
+    const iInIssue = fieldValueExists_(fvAdd, issue.fieldValues);
+    if (iInIssue === -1) { // fvAdd is not already in issue, so we can add it.
+      issue.fieldValues.push(fvAdd);
+      issue.delta.fieldValuesAdd.push(fvAdd);
+      const iInDeltaRemove = fieldValueExists_(
+          fvAdd, issue.delta.fieldValuesRemove);
+      if (iInDeltaRemove != -1) {
+        // fvAdd was added to fieldValuesRemove in a previous call.
+        issue.delta.fieldValuesRemove.splice(iInDeltaRemove, 1);
+      }
+      // issue.delta.updateMask is updated in saveChanges()
+    }
+  });
+  // issue.delta.updateMask is updated in saveChanges()
+  fieldValuesRemove.forEach((fvRemove) => {
+    const iInIssue = fieldValueExists_(fvRemove, issue.fieldValues);
+    if (iInIssue != -1) { // fvRemove is in issue, so we can remove it.
+      issue.fieldValues.splice(iInIssue, 1);
+      issue.delta.fieldValuesRemove.push(fvRemove);
+      const iInDeltaAdd = fieldValueExists_(
+          fvRemove, issue.delta.fieldValuesAdd);
+      if (iInDeltaAdd != -1) {
+        // fvRemove was added to fieldValuesAdd in a previous call.
+        issue.delta.fieldValuesAdd.splice(iInDeltaAdd, 1);
+      }
+    }
+  });
+}
+
+/**
+ * Checks for the existence of userName in userValues
+ * @param {string} userName A user resource name to look for.
+ * @param {Array<UserValue>} userValues UserValues to search through.
+ * @return {number} Index of userName's UserValue in userValues or -1 if not
+ *     found.
+ */
+function userValueExists_(userName, userValues) {
+  for (let i = 0; i< userValues.length; i++) {
+    if (userValues[i].user === userName) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+/**
+ * Adds the CC changes to the issue.
+ * ccNamesAdd are added before ccNamesRemove are removed.
+ * This method does not call Monorail's API to save this change.
+ * Call saveChanges() to send all updates to Monorail.
+ * @param {Issue} issue Issue to change.
+ * @param {Array<string>} ccNamesAdd Array if user resource names.
+ * @param {Array<string>} ccNamesRemove Array if user resource names.
+*/
+function addCcChanges(issue, ccNamesAdd, ccNamesRemove) {
+  maybeCreateDelta_(issue);
+  ccNamesAdd.forEach((ccName) => {
+    const iInIssue = userValueExists_(ccName, issue.ccUsers);
+    if (iInIssue === -1) { // User is not in issue, so we can add them.
+      issue.ccUsers.push({'user': ccName});
+      issue.delta.ccsAdd.push(ccName);
+      const iInDeltaRemove = issue.delta.ccsRemove.indexOf(ccName);
+      if (iInDeltaRemove != -1) {
+        // ccName was added to ccsRemove in a previous call.
+        issue.delta.ccsRemove.splice(iInDeltaRemove, 1);
+      }
+    }
+  });
+  ccNamesRemove.forEach((ccName) => {
+    const iInIssue = userValueExists_(ccName, issue.ccUsers);
+    if (iInIssue != -1) { // User is in issue, so we can remove it.
+      issue.ccUsers.splice(iInIssue, 1);
+      issue.delta.ccsRemove.push(ccName);
+      const iInDeltaAdd = issue.delta.ccsAdd.indexOf(ccName);
+      if (iInDeltaAdd != -1) {
+        // ccName was added to delta.ccsAdd in a previous all.
+        issue.delta.ccsAdd.splice(iInDeltaAdd, 1);
+      }
+    }
+  });
+}
+
+/**
+ * Set the pending comment of the issue.
+ * @param {Issue} issue Issue whose comment we want to set.
+ * @param {string} comment Comment that we want for the issue.
+ */
+function setComment(issue, comment) {
+  maybeCreateDelta_(issue);
+  issue.delta.comment = comment;
+}
+
+/**
+ * Get the pending comment for the issue.
+ * @param {Issue} issue Issue whose comment we want.
+ * @return {string}
+ */
+function getPendingComment(issue) {
+  if (issue.delta) {
+    return issue.delta.comment;
+  }
+  return '';
+}
+
+/**
+ * Adds to the existing pending comment
+ * @param {Issue} issue Issue to update.
+ * @param {string} comment The comment string to add to the existing one.
+ */
+function appendComment(issue, comment) {
+  maybeCreateDelta_(issue);
+  issue.delta.comment = issue.delta.comment.concat(comment);
+}
+
+/**
+ * Sets up an issue for pending changes.
+ * @param {Issue} issue The issue that needs to be updated.
+ */
+function maybeCreateDelta_(issue) {
+  if (!issue.delta) {
+    issue.delta = newIssueDelta_();
+    if (!issue.components) {
+      issue.components = [];
+    };
+    if (!issue.blockingIssueRefs) {
+      issue.blockingIssueRefs = [];
+    }
+    if (!issue.blockedOnIssueRefs) {
+      issue.blockedOnIssueRefs = [];
+    }
+    if (!issue.ccUsers) {
+      issue.ccUsers = [];
+    }
+    if (!issue.labels) {
+      issue.labels = [];
+    }
+    if (!issue.fieldValues) {
+      issue.fieldValues = [];
+    }
+  }
+}
+
+/**
+ * Creates an IssueDelta
+ * @return {IssueDelta_}
+ */
+function newIssueDelta_() {
+  return new IssueDelta_();
+}
+
+/** Used to track pending changes to an issue.*/
+function IssueDelta_() {
+  /** Array<string> */ this.updateMask = [];
+
+  // User resource names.
+  /** Array<string> */ this.ccsRemove = [];
+  /** Array<string> */ this.ccsAdd = [];
+
+  /** Array<IssueRef> */ this.blockedOnRemove = [];
+  /** Array<IssueRef> */ this.blockedOnAdd = [];
+  /** Array<IssueRef> */ this.blockingRemove = [];
+  /** Array<IssueRef> */ this.blockingAdd = [];
+
+  // Component resource names.
+  /** Array<string> */ this.componentsRemove = [];
+  /** Array<string> */ this.componentsAdd = [];
+
+  // Label values, e.g. 'Security-Notify'.
+  /** Array<string> */ this.labelsRemove = [];
+  /** Array<string> */ this.labelsAdd = [];
+
+  /** Array<FieldValue> */ this.fieldValuesRemove = [];
+  /** Array<FieldValue> */ this.fieldValuesAdd = [];
+
+  this.comment = '';
+}
+
+/**
+ * Calls Monorail's API to update the issue.
+ * @param {Issue} issue The issue to update where issue['delta'] is expected
+ *     to exist.
+ * @param {boolean} sendEmail True if the update should trigger email
+ *     notifications.
+ * @return {Issue}
+ */
+function saveChanges(issue, sendEmail) {
+  if (!issue.delta) {
+    throw new Error('No pending changes for issue.');
+  }
+
+  const modifyDelta = {
+    'ccsRemove': issue.delta.ccsRemove,
+    'blockedOnIssuesRemove': issue.delta.blockedOnRemove,
+    'blockingIssuesRemove': issue.delta.blockingRemove,
+    'componentsRemove': issue.delta.componentsRemove,
+    'labelsRemove': issue.delta.labelsRemove,
+    'fieldValsRemove': issue.delta.fieldValuesRemove,
+    'issue': {
+      'name': issue.name,
+      'fieldValues': issue.delta.fieldValuesAdd,
+      'blockedOnIssueRefs': issue.delta.blockedOnAdd,
+      'blockingIssueRefs': issue.delta.blockingAdd,
+      'mergedIntoIssueRef': issue.mergedIntoIssueRef,
+      'summary': issue.summary,
+      'status': issue.status,
+      'owner': issue.owner,
+      'labels': [],
+      'ccUsers': [],
+      'components': [],
+    },
+  };
+
+  if (issue.delta.fieldValuesAdd.length > 0) {
+    issue.delta.updateMask.push('fieldValues');
+  }
+
+  if (issue.delta.blockedOnAdd.length > 0) {
+    issue.delta.updateMask.push('blockedOnIssueRefs');
+  }
+
+  if (issue.delta.blockingAdd.length > 0) {
+    issue.delta.updateMask.push('blockingIssueRefs');
+  }
+
+  if (issue.delta.ccsAdd.length > 0) {
+    issue.delta.updateMask.push('ccUsers');
+  }
+  issue.delta.ccsAdd.forEach((userResourceName) => {
+    modifyDelta.issue['ccUsers'].push({'user': userResourceName});
+  });
+
+  if (issue.delta.labelsAdd.length > 0) {
+    issue.delta.updateMask.push('labels');
+  }
+  issue.delta.labelsAdd.forEach((label) => {
+    modifyDelta.issue['labels'].push({'label': label});
+  });
+
+  if (issue.delta.componentsAdd.length > 0) {
+    issue.delta.updateMask.push('components');
+  }
+  issue.delta.componentsAdd.forEach((compResourceName) => {
+    modifyDelta.issue['components'].push({'component': compResourceName});
+  });
+
+  modifyDelta['updateMask'] = issue.delta.updateMask.join();
+
+  const message = {
+    'deltas': [modifyDelta],
+    'notifyType': sendEmail ? 'EMAIL' : 'NO_NOTIFICATION',
+    'commentContent': issue.delta.comment,
+  };
+
+  const url = URL + 'monorail.v3.Issues/ModifyIssues';
+  response = run_(url, message);
+  if (!response.issues) {
+    Logger.log('All changes Noop');
+    return null;
+  }
+  issue = response.issues[0];
+  return issue;
+}
+
+/**
+ * Creates an Issue.
+ * @param {string} projectName: Resource name of the parent project.
+ * @param {string} summary: Summary of the issue.
+ * @param {string} description: Description of the issue.
+ * @param {string} status: Status of the issue, e.g. "Untriaged".
+ * @param {boolean} sendEmail: True if this should trigger email notifications.
+ * @param {string=} ownerName: Resource name of the issue owner.
+ * @param {Array<string>=} ccNames: Resource names of the users to cc.
+ * @param {Array<string>=} labels: Labels to add to the issue,
+ *     e.g. "Restict-View-Google".
+ * @param {Array<string>=} componentNames: Resource names of components to add.
+ * @param {Array<FieldValue>=} fieldValues: FieldValues to add to the issue.
+ * @param {Array<IssueRef>=} blockedOnRefs: IssueRefs for blocked on issues.
+ * @param {Array<IssueRef>=} blockingRefs: IssueRefs for blocking issues.
+ * @return {Issue}
+ */
+function makeIssue(
+    projectName, summary, description, status, sendEmail, ownerName, ccNames,
+    labels, componentNames, fieldValues, blockedOnRefs, blockingRefs) {
+  const issue = {
+    'summary': summary,
+    'status': {'status': status},
+    'ccUsers': [],
+    'components': [],
+    'labels': [],
+  };
+
+  if (ownerName) {
+    issue['owner'] = {'user': ownerName};
+  }
+
+  if (ccNames) {
+    ccNames.forEach((ccName) => {
+      issue['ccUsers'].push({'user': ccName});
+    });
+  };
+
+  if (labels) {
+    labels.forEach((label) => {
+      issue['labels'].push({'label': label});
+    });
+  };
+
+  if (componentNames) {
+    componentNames.forEach((componentName) => {
+      issue['components'].push({'component': componentName});
+    });
+  };
+
+  if (fieldValues) {
+    issue['fieldValues'] = fieldValues;
+  };
+
+  if (blockedOnRefs) {
+    issue['blockedOnIssueRefs'] = blockedOnRefs;
+  };
+
+  if (blockingRefs) {
+    issue['blockingIssueRefs'] = blockingRefs;
+  };
+
+  const message = {
+    'parent': projectName,
+    'issue': issue,
+    'description': description,
+    'notifyType': sendEmail ? 'EMAIL': 'NO_NOTIFICATION',
+  };
+  const url = URL + 'monorail.v3.Issues/MakeIssue';
+  return run_(url, message);
+}
