diff --git a/businesslogic/work_env.py b/businesslogic/work_env.py
new file mode 100644
index 0000000..c7282c0
--- /dev/null
+++ b/businesslogic/work_env.py
@@ -0,0 +1,3843 @@
+# Copyright 2017 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
+
+"""WorkEnv is a context manager and API for high-level operations.
+
+A work environment is used by request handlers for the legacy UI, v1
+API, and v2 API.  The WorkEnvironment operations are a common code
+path that does permission checking, input validation, coordination of
+service-level calls, follow-up tasks (e.g., triggering
+notifications after certain operations) and other systemic
+functionality so that that code is not duplicated in multiple request
+handlers.
+
+Responsibilities of request handers (legacy UI and external API) and associated
+frameworks:
++ API: check oauth client allowlist or XSRF token
++ Rate-limiting
++ Create a MonorailContext (or MonorailRequest) object:
+  - Parse the request, including syntactic validation, e.g, non-negative ints
+  - Authenticate the requesting user
++ Call the WorkEnvironment to perform the requested action
+  - Catch exceptions and generate error messages
++ UI: Decide screen flow, and on-page online-help
++ Render the result business objects as UI HTML or API response protobufs
+
+Responsibilities of WorkEnv:
++ Most monitoring, profiling, and logging
++ Apply business rules:
+  - Check permissions
+    - Every GetFoo/GetFoosDict method will assert that the user can view Foo(s)
+  - Detailed validation of request parameters
+  - Raise exceptions to indicate problems
++ Make coordinated calls to the services layer to make DB changes
+  - E.g., calls may need to be made in a specific order
++ Enqueue tasks for background follow-up work:
+  - E.g., email notifications
+
+Responsibilities of the Services layer:
++ Individual CRUD operations on objects in the database
+  - Each services class should be independent of others
++ App-specific interface around external services:
+  - E.g., GAE search, GCS, monorail-predict
++ Business object caches
++ Breaking large operations into batches as appropriate for the underlying
+  data storage service, e.g., DB shards and search engine indexing.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import itertools
+import logging
+import time
+
+import settings
+from features import features_constants
+from features import filterrules_helpers
+from features import send_notifications
+from features import features_bizobj
+from features import hotlist_helpers
+from framework import authdata
+from framework import exceptions
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import framework_helpers
+from framework import framework_views
+from framework import permissions
+from search import frontendsearchpipeline
+from services import features_svc
+from services import tracker_fulltext
+from sitewide import sitewide_helpers
+from tracker import field_helpers
+from tracker import rerank_helpers
+from tracker import field_helpers
+from tracker import tracker_bizobj
+from tracker import tracker_constants
+from tracker import tracker_helpers
+from project import project_helpers
+from proto import features_pb2
+from proto import project_pb2
+from proto import tracker_pb2
+from proto import user_pb2
+
+
+# TODO(jrobbins): break this file into one facade plus ~5
+# implementation parts that roughly correspond to services files.
+
+# ListResult is returned in List/Search methods to bundle the requested
+# items and the next start index for a subsequent request. If there are
+# no more items to be fetched, `next_start` should be None.
+ListResult = collections.namedtuple('ListResult', ['items', 'next_start'])
+# type: (Sequence[Object], Optional[int]) -> None
+
+# Comments added to issues impacted by another issue's mergedInto change.
+UNMERGE_COMMENT = 'Issue %s has been un-merged from this issue.\n'
+MERGE_COMMENT = 'Issue %s has been merged into this issue.\n'
+
+
+class WorkEnv(object):
+
+  def __init__(self, mc, services, phase=None):
+    self.mc = mc
+    self.services = services
+    self.phase = phase
+
+  def __enter__(self):
+    if self.mc.profiler and self.phase:
+      self.mc.profiler.StartPhase(name=self.phase)
+    return self  # The instance of this class is the context object.
+
+  def __exit__(self, exception_type, value, traceback):
+    if self.mc.profiler and self.phase:
+      self.mc.profiler.EndPhase()
+    return False  # Re-raise any exception in the with-block.
+
+  def _UserCanViewProject(self, project):
+    """Test if the user may view the given project."""
+    return permissions.UserCanViewProject(
+        self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+
+  def _FilterVisibleProjectsDict(self, projects):
+    """Filter out projects the user doesn't have permission to view."""
+    return {
+        key: proj
+        for key, proj in projects.items()
+        if self._UserCanViewProject(proj)}
+
+  def _AssertPermInProject(self, perm, project):
+    """Make sure the user may use perm in the given project."""
+    project_perms = permissions.GetPermissions(
+        self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+    permitted = project_perms.CanUsePerm(
+        perm, self.mc.auth.effective_ids, project, [])
+    if not permitted:
+      raise permissions.PermissionException(
+        'User lacks permission %r in project %s' % (perm, project.project_name))
+
+  def _UserCanViewIssue(self, issue, allow_viewing_deleted=False):
+    """Test if user may view an issue according to perms in issue's project."""
+    project = self.GetProject(issue.project_id)
+    config = self.GetProjectConfig(issue.project_id)
+    granted_perms = tracker_bizobj.GetGrantedPerms(
+        issue, self.mc.auth.effective_ids, config)
+    project_perms = permissions.GetPermissions(
+        self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+    issue_perms = permissions.UpdateIssuePermissions(
+        project_perms, project, issue, self.mc.auth.effective_ids,
+        granted_perms=granted_perms)
+    permit_view = permissions.CanViewIssue(
+        self.mc.auth.effective_ids, issue_perms, project, issue,
+        allow_viewing_deleted=allow_viewing_deleted,
+        granted_perms=granted_perms)
+    return issue_perms, permit_view
+
+  def _AssertUserCanViewIssue(self, issue, allow_viewing_deleted=False):
+    """Make sure the user may view the issue."""
+    issue_perms, permit_view = self._UserCanViewIssue(
+        issue, allow_viewing_deleted)
+    if not permit_view:
+      raise permissions.PermissionException(
+          'User is not allowed to view issue: %s:%d.' %
+          (issue.project_name, issue.local_id))
+    return issue_perms
+
+  def _UserCanUsePermInIssue(self, issue, perm):
+    """Test if the user may use perm on the given issue."""
+    issue_perms = self._AssertUserCanViewIssue(
+        issue, allow_viewing_deleted=True)
+    return issue_perms.HasPerm(perm, None, None, [])
+
+  def _AssertPermInIssue(self, issue, perm):
+    """Make sure the user may use perm on the given issue."""
+    permitted = self._UserCanUsePermInIssue(issue, perm)
+    if not permitted:
+      raise permissions.PermissionException(
+        'User lacks permission %r in issue' % perm)
+
+  def _AssertUserCanModifyIssues(
+      self, issue_delta_pairs, is_description_change, comment_content=None):
+    # type: (Tuple[Issue, IssueDelta], Boolean, Optional[str]) -> None
+    """Make sure the user may make the delta changes for each paired issue."""
+    # We assume that view permission for each issue, and therefore project,
+    # was checked by the caller.
+    project_ids = list(
+        {issue.project_id for (issue, _delta) in issue_delta_pairs})
+    projects_by_id = self.services.project.GetProjects(
+        self.mc.cnxn, project_ids)
+    configs_by_id = self.services.config.GetProjectConfigs(
+        self.mc.cnxn, project_ids)
+
+    project_perms_by_ids = {}
+    for project_id, project in projects_by_id.items():
+      project_perms_by_ids[project_id] = permissions.GetPermissions(
+          self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+
+    with exceptions.ErrorAggregator(permissions.PermissionException) as err_agg:
+      for issue, delta in issue_delta_pairs:
+        project_perms = project_perms_by_ids.get(issue.project_id)
+        config = configs_by_id.get(issue.project_id)
+        project = projects_by_id.get(issue.project_id)
+        granted_perms = tracker_bizobj.GetGrantedPerms(
+            issue, self.mc.auth.effective_ids, config)
+        issue_perms = permissions.UpdateIssuePermissions(
+            project_perms,
+            project,
+            issue,
+            self.mc.auth.effective_ids,
+            granted_perms=granted_perms)
+
+        # User cannot merge any issue into an issue they cannot edit.
+        if delta.merged_into:
+          merged_into_issue = self.GetIssue(
+              delta.merged_into, use_cache=False, allow_viewing_deleted=True)
+          self._AssertPermInIssue(merged_into_issue, permissions.EDIT_ISSUE)
+
+        # User cannot change values for restricted fields they cannot edit.
+        field_ids = [fv.field_id for fv in delta.field_vals_add]
+        field_ids.extend([fv.field_id for fv in delta.field_vals_remove])
+        field_ids.extend(delta.fields_clear)
+        labels = itertools.chain(delta.labels_add, delta.labels_remove)
+        try:
+          self._AssertUserCanEditFieldsAndEnumMaskedLabels(
+              project, config, field_ids, labels)
+        except permissions.PermissionException as e:
+          err_agg.AddErrorMessage(e.message)
+
+        if issue_perms.HasPerm(permissions.EDIT_ISSUE, self.mc.auth.user_id,
+                               project):
+          continue
+
+        # The user does not have general EDIT_ISSUE permissions, but may
+        # have perms to modify certain issue parts/fields.
+
+        # Description changes can only be made by users with EDIT_ISSUE.
+        if is_description_change:
+          err_agg.AddErrorMessage(
+              'User not allowed to edit description in issue %s:%d' %
+              (issue.project_name, issue.local_id))
+
+        if comment_content and not issue_perms.HasPerm(
+            permissions.ADD_ISSUE_COMMENT, self.mc.auth.user_id, project):
+          err_agg.AddErrorMessage(
+              'User not allowed to add comment in issue %s:%d' %
+              (issue.project_name, issue.local_id))
+
+        if delta == tracker_pb2.IssueDelta():
+          continue
+
+        allowed_delta = tracker_pb2.IssueDelta()
+        if issue_perms.HasPerm(permissions.EDIT_ISSUE_STATUS,
+                               self.mc.auth.user_id, project):
+          allowed_delta.status = delta.status
+        if issue_perms.HasPerm(permissions.EDIT_ISSUE_SUMMARY,
+                               self.mc.auth.user_id, project):
+          allowed_delta.summary = delta.summary
+        if issue_perms.HasPerm(permissions.EDIT_ISSUE_OWNER,
+                               self.mc.auth.user_id, project):
+          allowed_delta.owner_id = delta.owner_id
+        if issue_perms.HasPerm(permissions.EDIT_ISSUE_CC, self.mc.auth.user_id,
+                               project):
+          allowed_delta.cc_ids_add = delta.cc_ids_add
+          allowed_delta.cc_ids_remove = delta.cc_ids_remove
+        # We do not check for or add other fields (e.g. comps, labels, fields)
+        # of `delta` to `allowed_delta` because they are only allowed
+        # with EDIT_ISSUE perms.
+        if delta != allowed_delta:
+          err_agg.AddErrorMessage(
+              'User lack permission to make these changes to issue %s:%d' %
+              (issue.project_name, issue.local_id))
+
+  # end of `with` block.
+
+  def _AssertUserCanDeleteComment(self, issue, comment):
+    issue_perms = self._AssertUserCanViewIssue(
+       issue, allow_viewing_deleted=True)
+    commenter = self.services.user.GetUser(self.mc.cnxn, comment.user_id)
+    permitted = permissions.CanDeleteComment(
+        comment, commenter, self.mc.auth.user_id, issue_perms)
+    if not permitted:
+      raise permissions.PermissionException('Cannot delete comment')
+
+  def _AssertUserCanViewHotlist(self, hotlist):
+    """Make sure the user may view the hotlist."""
+    if not permissions.CanViewHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist):
+      raise permissions.PermissionException(
+          'User is not allowed to view this hotlist')
+
+  def _AssertUserCanEditHotlist(self, hotlist):
+    if not permissions.CanEditHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist):
+      raise permissions.PermissionException(
+          'User is not allowed to edit this hotlist')
+
+  def _AssertUserCanEditValueForFieldDef(self, project, fielddef):
+    if not permissions.CanEditValueForFieldDef(
+        self.mc.auth.effective_ids, self.mc.perms, project, fielddef):
+      raise permissions.PermissionException(
+          'User is not allowed to edit custom field %s' % fielddef.field_name)
+
+  def _AssertUserCanEditFieldsAndEnumMaskedLabels(
+      self, project, config, field_ids, labels):
+    field_ids = set(field_ids)
+
+    enum_fds_by_name = {
+        f.field_name.lower(): f.field_id
+        for f in config.field_defs
+        if f.field_type is tracker_pb2.FieldTypes.ENUM_TYPE and not f.is_deleted
+    }
+    for label in labels:
+      enum_field_name = tracker_bizobj.LabelIsMaskedByField(
+          label, enum_fds_by_name.keys())
+      if enum_field_name:
+        field_ids.add(enum_fds_by_name.get(enum_field_name))
+
+    fds_by_id = {fd.field_id: fd for fd in config.field_defs}
+    with exceptions.ErrorAggregator(permissions.PermissionException) as err_agg:
+      for field_id in field_ids:
+        fd = fds_by_id.get(field_id)
+        if fd:
+          try:
+            self._AssertUserCanEditValueForFieldDef(project, fd)
+          except permissions.PermissionException as e:
+            err_agg.AddErrorMessage(e.message)
+
+  def _AssertUserCanViewFieldDef(self, project, field):
+    """Make sure the user may view the field."""
+    if not permissions.CanViewFieldDef(self.mc.auth.effective_ids,
+                                       self.mc.perms, project, field):
+      raise permissions.PermissionException(
+          'User is not allowed to view this field')
+
+  ### Site methods
+
+  # FUTURE: GetSiteReadOnlyState()
+  # FUTURE: SetSiteReadOnlyState()
+  # FUTURE: GetSiteBannerMessage()
+  # FUTURE: SetSiteBannerMessage()
+
+  ### Project methods
+
+  def CreateProject(
+      self, project_name, owner_ids, committer_ids, contributor_ids,
+      summary, description, state=project_pb2.ProjectState.LIVE,
+      access=None, read_only_reason=None, home_page=None, docs_url=None,
+      source_url=None, logo_gcs_id=None, logo_file_name=None):
+    """Create and store a Project with the given attributes.
+
+    Args:
+      cnxn: connection to SQL database.
+      project_name: a valid project name, all lower case.
+      owner_ids: a list of user IDs for the project owners.
+      committer_ids: a list of user IDs for the project members.
+      contributor_ids: a list of user IDs for the project contributors.
+      summary: one-line explanation of the project.
+      description: one-page explanation of the project.
+      state: a project state enum defined in project_pb2.
+      access: optional project access enum defined in project.proto.
+      read_only_reason: if given, provides a status message and marks
+        the project as read-only.
+      home_page: home page of the project
+      docs_url: url to redirect to for wiki/documentation links
+      source_url: url to redirect to for source browser links
+      logo_gcs_id: google storage object id of the project's logo
+      logo_file_name: uploaded file name of the project's logo
+
+    Returns:
+      The int project_id of the new project.
+
+    Raises:
+      ProjectAlreadyExists: A project with that name already exists.
+    """
+    if not permissions.CanCreateProject(self.mc.perms):
+      raise permissions.PermissionException(
+          'User is not allowed to create a project')
+
+    with self.mc.profiler.Phase('creating project %r' % project_name):
+      project_id = self.services.project.CreateProject(
+          self.mc.cnxn, project_name, owner_ids, committer_ids, contributor_ids,
+          summary, description, state=state, access=access,
+          read_only_reason=read_only_reason, home_page=home_page,
+          docs_url=docs_url, source_url=source_url, logo_gcs_id=logo_gcs_id,
+          logo_file_name=logo_file_name)
+      self.services.template.CreateDefaultProjectTemplates(self.mc.cnxn,
+          project_id)
+    return project_id
+
+  def ListProjects(self, domain=None, use_cache=True):
+    """Return a list of project IDs that the current user may view."""
+    # TODO(crbug.com/monorail/7508): Add permission checking in ListProjects.
+    # Note: No permission checks because anyone can list projects, but
+    # the results are filtered by permission to view each project.
+
+    with self.mc.profiler.Phase('list projects for %r' % self.mc.auth.user_id):
+      project_ids = self.services.project.GetVisibleLiveProjects(
+          self.mc.cnxn, self.mc.auth.user_pb, self.mc.auth.effective_ids,
+          domain=domain, use_cache=use_cache)
+
+    return project_ids
+
+  def CheckProjectName(self, project_name):
+    """Check that a project name is valid and not already in use.
+
+    Args:
+      project_name: str the project name to check.
+
+    Returns:
+      None if the user can create a project with that name, or a string with the
+      reason the name can't be used.
+
+    Raises:
+      PermissionException: The user is not allowed to create a project.
+    """
+    # We check that the user can create a project so we don't leak information
+    # about project names.
+    if not permissions.CanCreateProject(self.mc.perms):
+      raise permissions.PermissionException(
+          'User is not allowed to create a project')
+
+    with self.mc.profiler.Phase('checking project name %s' % project_name):
+      if not project_helpers.IsValidProjectName(project_name):
+        return '"%s" is not a valid project name.' % project_name
+      if self.services.project.LookupProjectIDs(self.mc.cnxn, [project_name]):
+        return 'There is already a project with that name.'
+    return None
+
+  def CheckComponentName(self, project_id, parent_path, component_name):
+    """Check that the component name is valid and not already in use.
+
+    Args:
+      project_id: int with the id of the project where we want to create the
+          component.
+      parent_path: optional str with the path of the parent component.
+      component_name: str with the name of the proposed component.
+
+    Returns:
+      None if the user can create a component with that name, or a string with
+      the reason the name can't be used.
+    """
+    # Check that the project exists and the user can view it.
+    self.GetProject(project_id)
+    # If a parent component is given, make sure it exists.
+    config = self.GetProjectConfig(project_id)
+    if parent_path and not tracker_bizobj.FindComponentDef(parent_path, config):
+      raise exceptions.NoSuchComponentException(
+          'Component %r not found' % parent_path)
+    with self.mc.profiler.Phase(
+        'checking component name %r %r' % (parent_path, component_name)):
+      if not tracker_constants.COMPONENT_NAME_RE.match(component_name):
+        return '"%s" is not a valid component name.' % component_name
+      if parent_path:
+        component_name = '%s>%s' % (parent_path, component_name)
+      if tracker_bizobj.FindComponentDef(component_name, config):
+        return 'There is already a component with that name.'
+    return None
+
+  def CheckFieldName(self, project_id, field_name):
+    """Check that the field name is valid and not already in use.
+
+    Args:
+      project_id: int with the id of the project where we want to create the
+          field.
+      field_name: str with the name of the proposed field.
+
+    Returns:
+      None if the user can create a field with that name, or a string with
+      the reason the name can't be used.
+    """
+    # Check that the project exists and the user can view it.
+    self.GetProject(project_id)
+    config = self.GetProjectConfig(project_id)
+
+    field_name = field_name.lower()
+    with self.mc.profiler.Phase('checking field name %r' % field_name):
+      if not tracker_constants.FIELD_NAME_RE.match(field_name):
+        return '"%s" is not a valid field name.' % field_name
+      if field_name in tracker_constants.RESERVED_PREFIXES:
+        return 'That name is reserved'
+      if field_name.endswith(
+          tuple(tracker_constants.RESERVED_COL_NAME_SUFFIXES)):
+        return 'That suffix is reserved'
+      for fd in config.field_defs:
+        fn = fd.field_name.lower()
+        if field_name == fn:
+          return 'There is already a field with that name.'
+        if field_name.startswith(fn + '-'):
+          return 'An existing field is a prefix of that name.'
+        if fn.startswith(field_name + '-'):
+          return 'That name is a prefix of an existing field name.'
+
+    return None
+
+  def GetProjects(self, project_ids, use_cache=True):
+    """Return the specified projects.
+
+    Args:
+      project_ids: int project_ids of the projects to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified projects.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    with self.mc.profiler.Phase('getting projects %r' % project_ids):
+      projects = self.services.project.GetProjects(
+          self.mc.cnxn, project_ids, use_cache=use_cache)
+
+    projects = self._FilterVisibleProjectsDict(projects)
+    return projects
+
+  def GetProject(self, project_id, use_cache=True):
+    """Return the specified project.
+
+    Args:
+      project_id: int project_id of the project to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified project.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    projects = self.GetProjects([project_id], use_cache=use_cache)
+    if project_id not in projects:
+      raise permissions.PermissionException(
+          'User is not allowed to view this project')
+    return projects[project_id]
+
+  def GetProjectsByName(self, project_names, use_cache=True):
+    """Return the named project.
+
+    Args:
+      project_names: string names of the projects to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified projects.
+    """
+    with self.mc.profiler.Phase('getting projects %r' % project_names):
+      projects = self.services.project.GetProjectsByName(
+          self.mc.cnxn, project_names, use_cache=use_cache)
+
+    for pn in project_names:
+      if pn not in projects:
+        raise exceptions.NoSuchProjectException('Project %r not found.' % pn)
+
+    projects = self._FilterVisibleProjectsDict(projects)
+    return projects
+
+  def GetProjectByName(self, project_name, use_cache=True):
+    """Return the named project.
+
+    Args:
+      project_name: string name of the project to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified project.
+
+    Raises:
+      NoSuchProjectException: There is no project with that name.
+    """
+    projects = self.GetProjectsByName([project_name], use_cache)
+    if not projects:
+      raise permissions.PermissionException(
+          'User is not allowed to view this project')
+
+    return projects[project_name]
+
+  def GatherProjectMembershipsForUser(self, user_id):
+    """Return the projects where the user has a role.
+
+    Args:
+      user_id: ID of the user we are requesting project memberships for.
+
+    Returns:
+      A triple with project IDs where the user is an owner, a committer, or a
+      contributor.
+    """
+    viewed_user_effective_ids = authdata.AuthData.FromUserID(
+        self.mc.cnxn, user_id, self.services).effective_ids
+
+    owner_projects, _archived, committer_projects, contrib_projects = (
+        self.GetUserProjects(viewed_user_effective_ids))
+
+    owner_proj_ids = [proj.project_id for proj in owner_projects]
+    committer_proj_ids = [proj.project_id for proj in committer_projects]
+    contrib_proj_ids = [proj.project_id for proj in contrib_projects]
+    return owner_proj_ids, committer_proj_ids, contrib_proj_ids
+
+  def GetUserRolesInAllProjects(self, viewed_user_effective_ids):
+    """Return the projects where the user has a role.
+
+    Args:
+      viewed_user_effective_ids: list of IDs of the user whose projects we want
+          to see.
+
+    Returns:
+      A triple with projects where the user is an owner, a member or a
+      contributor.
+    """
+    with self.mc.profiler.Phase(
+        'Finding roles in all projects for %r' % viewed_user_effective_ids):
+      project_ids = self.services.project.GetUserRolesInAllProjects(
+          self.mc.cnxn, viewed_user_effective_ids)
+
+    owner_projects = self.GetProjects(project_ids[0])
+    member_projects = self.GetProjects(project_ids[1])
+    contrib_projects = self.GetProjects(project_ids[2])
+
+    return owner_projects, member_projects, contrib_projects
+
+  def GetUserProjects(self, viewed_user_effective_ids):
+    # TODO(crbug.com/monorail/7398): Combine this function with
+    # GatherProjectMembershipsForUser after removing the legacy
+    # project list page and the v0 GetUsersProjects RPC.
+    """Get the projects to display in the user's profile.
+
+    Args:
+      viewed_user_effective_ids: set of int user IDs of the user being viewed.
+
+    Returns:
+      A 4-tuple of lists of PBs:
+        - live projects the viewed user owns
+        - archived projects the viewed user owns
+        - live projects the viewed user is a member of
+        - live projects the viewed user is a contributor to
+
+      Any projects the viewing user should not be able to see are filtered out.
+      Admins can see everything, while other users can see all non-locked
+      projects they own or are a member of, as well as all live projects.
+    """
+    # Permissions are checked in we.GetUserRolesInAllProjects()
+    owner_projects, member_projects, contrib_projects = (
+        self.GetUserRolesInAllProjects(viewed_user_effective_ids))
+
+    # We filter out DELETABLE projects, and keep a project where the user has a
+    # highest role, e.g. if the user is both an owner and a member, the project
+    # is listed under owner projects, not under member_projects.
+    archived_projects = [
+        project
+        for project in owner_projects.values()
+        if project.state == project_pb2.ProjectState.ARCHIVED]
+
+    contrib_projects = [
+        project
+        for pid, project in contrib_projects.items()
+        if pid not in owner_projects
+        and pid not in member_projects
+        and project.state != project_pb2.ProjectState.DELETABLE
+        and project.state != project_pb2.ProjectState.ARCHIVED]
+
+    member_projects = [
+        project
+        for pid, project in member_projects.items()
+        if pid not in owner_projects
+        and project.state != project_pb2.ProjectState.DELETABLE
+        and project.state != project_pb2.ProjectState.ARCHIVED]
+
+    owner_projects = [
+        project
+        for pid, project in owner_projects.items()
+        if project.state != project_pb2.ProjectState.DELETABLE
+        and project.state != project_pb2.ProjectState.ARCHIVED]
+
+    by_name = lambda project: project.project_name
+    owner_projects = sorted(owner_projects, key=by_name)
+    archived_projects = sorted(archived_projects, key=by_name)
+    member_projects = sorted(member_projects, key=by_name)
+    contrib_projects = sorted(contrib_projects, key=by_name)
+
+    return owner_projects, archived_projects, member_projects, contrib_projects
+
+  def UpdateProject(
+      self,
+      project_id,
+      summary=None,
+      description=None,
+      state=None,
+      state_reason=None,
+      access=None,
+      issue_notify_address=None,
+      attachment_bytes_used=None,
+      attachment_quota=None,
+      moved_to=None,
+      process_inbound_email=None,
+      only_owners_remove_restrictions=None,
+      read_only_reason=None,
+      cached_content_timestamp=None,
+      only_owners_see_contributors=None,
+      delete_time=None,
+      recent_activity=None,
+      revision_url_format=None,
+      home_page=None,
+      docs_url=None,
+      source_url=None,
+      logo_gcs_id=None,
+      logo_file_name=None,
+      issue_notify_always_detailed=None):
+    """Update the DB with the given project information."""
+    project = self.GetProject(project_id)
+    self._AssertPermInProject(permissions.EDIT_PROJECT, project)
+
+    with self.mc.profiler.Phase('updating project %r' % project_id):
+      self.services.project.UpdateProject(
+          self.mc.cnxn,
+          project_id,
+          summary=summary,
+          description=description,
+          state=state,
+          state_reason=state_reason,
+          access=access,
+          issue_notify_address=issue_notify_address,
+          attachment_bytes_used=attachment_bytes_used,
+          attachment_quota=attachment_quota,
+          moved_to=moved_to,
+          process_inbound_email=process_inbound_email,
+          only_owners_remove_restrictions=only_owners_remove_restrictions,
+          read_only_reason=read_only_reason,
+          cached_content_timestamp=cached_content_timestamp,
+          only_owners_see_contributors=only_owners_see_contributors,
+          delete_time=delete_time,
+          recent_activity=recent_activity,
+          revision_url_format=revision_url_format,
+          home_page=home_page,
+          docs_url=docs_url,
+          source_url=source_url,
+          logo_gcs_id=logo_gcs_id,
+          logo_file_name=logo_file_name,
+          issue_notify_always_detailed=issue_notify_always_detailed)
+
+  def DeleteProject(self, project_id):
+    """Mark the project as deletable.  It will be reaped by a cron job.
+
+    Args:
+      project_id: int ID of the project to delete.
+
+    Returns:
+      Nothing.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    project = self.GetProject(project_id)
+    self._AssertPermInProject(permissions.EDIT_PROJECT, project)
+
+    with self.mc.profiler.Phase('marking deletable %r' % project_id):
+      _project = self.GetProject(project_id)
+      self.services.project.MarkProjectDeletable(
+          self.mc.cnxn, project_id, self.services.config)
+
+  def StarProject(self, project_id, starred):
+    """Star or unstar the specified project.
+
+    Args:
+      project_id: int ID of the project to star/unstar.
+      starred: true to add a star, false to remove it.
+
+    Returns:
+      Nothing.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    project = self.GetProject(project_id)
+    self._AssertPermInProject(permissions.SET_STAR, project)
+
+    with self.mc.profiler.Phase('(un)starring project %r' % project_id):
+      self.services.project_star.SetStar(
+          self.mc.cnxn, project_id, self.mc.auth.user_id, starred)
+
+  def IsProjectStarred(self, project_id):
+    """Return True if the current user has starred the given project.
+
+    Args:
+      project_id: int ID of the project to check.
+
+    Returns:
+      True if starred.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    if project_id is None:
+      raise exceptions.InputException('No project specified')
+
+    if not self.mc.auth.user_id:
+      return False
+
+    with self.mc.profiler.Phase('checking project star %r' % project_id):
+      # Make sure the project exists and user has permission to see it.
+      _project = self.GetProject(project_id)
+      return self.services.project_star.IsItemStarredBy(
+        self.mc.cnxn, project_id, self.mc.auth.user_id)
+
+  def GetProjectStarCount(self, project_id):
+    """Return the number of times the project has been starred.
+
+    Args:
+      project_id: int ID of the project to check.
+
+    Returns:
+      The number of times the project has been starred.
+
+    Raises:
+      NoSuchProjectException: There is no project with that ID.
+    """
+    if project_id is None:
+      raise exceptions.InputException('No project specified')
+
+    with self.mc.profiler.Phase('counting stars for project %r' % project_id):
+      # Make sure the project exists and user has permission to see it.
+      _project = self.GetProject(project_id)
+      return self.services.project_star.CountItemStars(self.mc.cnxn, project_id)
+
+  def ListStarredProjects(self, viewed_user_id=None):
+    """Return a list of projects starred by the current or viewed user.
+
+    Args:
+      viewed_user_id: optional user ID for another user's profile page, if
+          not supplied, the signed in user is used.
+
+    Returns:
+      A list of projects that were starred by current user and that they
+      are currently allowed to view.
+    """
+    # Note: No permission checks for this call, but the list of starred
+    # projects is filtered based on permission to view.
+
+    if viewed_user_id is None:
+      if self.mc.auth.user_id:
+        viewed_user_id = self.mc.auth.user_id
+      else:
+        return []  # Anon user and no viewed user specified.
+    with self.mc.profiler.Phase('ListStarredProjects for %r' % viewed_user_id):
+      viewable_projects = sitewide_helpers.GetViewableStarredProjects(
+          self.mc.cnxn, self.services, viewed_user_id,
+          self.mc.auth.effective_ids, self.mc.auth.user_pb)
+    return viewable_projects
+
+  def GetProjectConfigs(self, project_ids, use_cache=True):
+    """Return the specifed configs.
+
+    Args:
+      project_ids: int IDs of the projects to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified configs.
+    """
+    with self.mc.profiler.Phase('getting configs for %r' % project_ids):
+      configs = self.services.config.GetProjectConfigs(
+          self.mc.cnxn, project_ids, use_cache=use_cache)
+
+    projects = self._FilterVisibleProjectsDict(
+        self.GetProjects(list(configs.keys())))
+    configs = {project_id: configs[project_id] for project_id in projects}
+
+    return configs
+
+  def GetProjectConfig(self, project_id, use_cache=True):
+    """Return the specifed config.
+
+    Args:
+      project_id: int ID of the project to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified config.
+
+    Raises:
+      NoSuchProjectException: There is no matching config.
+    """
+    configs = self.GetProjectConfigs([project_id], use_cache)
+    if not configs:
+      raise exceptions.NoSuchProjectException()
+    return configs[project_id]
+
+  def ListProjectTemplates(self, project_id):
+    templates = self.services.template.GetProjectTemplates(
+        self.mc.cnxn, project_id)
+    project = self.GetProject(project_id)
+    # Filter non-viewable templates
+    if framework_bizobj.UserIsInProject(project, self.mc.auth.effective_ids):
+      return templates
+    return [template for template in templates if not template.members_only]
+
+  def ListComponentDefs(self, project_id, page_size, start):
+    # type: (int, int, int) -> ListResult
+    """Returns component defs that belong to the project."""
+    if start < 0:
+      raise exceptions.InputException('Invalid `start`: %d' % start)
+    if page_size < 0:
+      raise exceptions.InputException('Invalid `page_size`: %d' % page_size)
+
+    config = self.GetProjectConfig(project_id)
+    end = start + page_size
+    next_start = None
+    if end < len(config.component_defs):
+      next_start = end
+    return ListResult(config.component_defs[start:end], next_start)
+
+  def CreateComponentDef(
+      self, project_id, path, description, admin_ids, cc_ids, labels):
+    # type: (int, str, str, Collection[int], Collection[int], Collection[str])
+    #     -> ComponentDef
+    """Creates a ComponentDef with the given information."""
+    project = self.GetProject(project_id)
+    config = self.GetProjectConfig(project_id)
+
+    # Validate new ComponentDef and check permissions.
+    ancestor_path, leaf_name = None, path
+    if '>' in path:
+      ancestor_path, leaf_name = path.rsplit('>', 1)
+      ancestor_def = tracker_bizobj.FindComponentDef(ancestor_path, config)
+      if not ancestor_def:
+        raise exceptions.InputException(
+            'Ancestor path %s is invalid.' % ancestor_path)
+      project_perms = permissions.GetPermissions(
+          self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+      if not permissions.CanEditComponentDef(
+          self.mc.auth.effective_ids, project_perms, project, ancestor_def,
+          config):
+        raise permissions.PermissionException(
+            'User is not allowed to create a subcomponent under %s.' %
+            ancestor_path)
+    else:
+      # A brand new top level component is being created.
+      self._AssertPermInProject(permissions.EDIT_PROJECT, project)
+
+    if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name):
+      raise exceptions.InputException('Invalid component path: %s.' % leaf_name)
+
+    if tracker_bizobj.FindComponentDef(path, config):
+      raise exceptions.ComponentDefAlreadyExists(
+          'Component path %s already exists.' % path)
+
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      tracker_helpers.AssertUsersExist(
+          self.mc.cnxn, self.services, cc_ids + admin_ids, err_agg)
+
+    label_ids = self.services.config.LookupLabelIDs(
+        self.mc.cnxn, project_id, labels, autocreate=True)
+    self.services.config.CreateComponentDef(
+        self.mc.cnxn, project_id, path, description, False, admin_ids, cc_ids,
+        int(time.time()), self.mc.auth.user_id, label_ids)
+    updated_config = self.GetProjectConfig(project_id, use_cache=False)
+    return tracker_bizobj.FindComponentDef(path, updated_config)
+
+  def DeleteComponentDef(self, project_id, component_id):
+    # type: (MonorailConnection, int, int) -> None
+    """Deletes the given ComponentDef."""
+    project = self.GetProject(project_id)
+    config = self.GetProjectConfig(project_id)
+
+    component_def = tracker_bizobj.FindComponentDefByID(component_id, config)
+    if not component_def:
+      raise exceptions.NoSuchComponentException('The component does not exist.')
+
+    project_perms = permissions.GetPermissions(
+        self.mc.auth.user_pb, self.mc.auth.effective_ids, project)
+    if not permissions.CanEditComponentDef(
+        self.mc.auth.effective_ids, project_perms, project, component_def,
+        config):
+      raise permissions.PermissionException(
+          'User is not allowed to delete this component.')
+
+    if tracker_bizobj.FindDescendantComponents(config, component_def):
+      raise exceptions.InputException(
+          'Components with subcomponents cannot be deleted.')
+
+    self.services.config.DeleteComponentDef(
+        self.mc.cnxn, project_id, component_id)
+
+  # FUTURE: labels, statuses, components, rules, templates, and views.
+  # FUTURE: project saved queries.
+  # FUTURE: GetProjectPermissionsForUser()
+
+  ### Field methods
+
+  # FUTURE: All other field methods.
+
+  def GetFieldDef(self, field_id, project):
+    # type: (int, Project) -> FieldDef
+    """Return the specified hotlist.
+
+    Args:
+      field_id: int field_id of the field to retrieve.
+      project: Project object that the field belongs to.
+
+    Returns:
+      The specified field.
+
+    Raises:
+      InputException: No field was specified.
+      NoSuchFieldDefException: There is no field with that ID.
+      PermissionException: The user is not allowed to view the field.
+    """
+    with self.mc.profiler.Phase('getting fielddef %r' % field_id):
+      config = self.GetProjectConfig(project.project_id)
+      field = tracker_bizobj.FindFieldDefByID(field_id, config)
+      if field is None:
+        raise exceptions.NoSuchFieldDefException('Field not found.')
+    self._AssertUserCanViewFieldDef(project, field)
+    return field
+
+  ### Issue methods
+
+  def CreateIssue(
+      self,
+      project_id,  # type: int
+      summary,  # type: str
+      status,  # type: str
+      owner_id,  # type: int
+      cc_ids,  # type: Sequence[int]
+      labels,  # type: Sequence[str]
+      field_values,  # type: Sequence[proto.tracker_pb2.FieldValue]
+      component_ids,  # type: Sequence[int]
+      marked_description,  # type: str
+      blocked_on=None,  # type: Sequence[int]
+      blocking=None,  # type: Sequence[int]
+      attachments=None,  # type: Sequence[Tuple[str, str, str]]
+      phases=None,  # type: Sequence[proto.tracker_pb2.Phase]
+      approval_values=None,  # type: Sequence[proto.tracker_pb2.ApprovalValue]
+      send_email=True,  # type: bool
+      reporter_id=None,  # type: int
+      timestamp=None,  # type: int
+      dangling_blocked_on=None,  # type: Sequence[DanglingIssueRef]
+      dangling_blocking=None,  # type: Sequence[DanglingIssueRef]
+      raise_filter_errors=True,  # type: bool
+  ):
+    # type: (...) -> (proto.tracker_pb2.Issue, proto.tracker_pb2.IssueComment)
+    """Create and store a new issue with all the given information.
+
+    Args:
+      project_id: int ID for the current project.
+      summary: one-line summary string summarizing this issue.
+      status: string issue status value.  E.g., 'New'.
+      owner_id: user ID of the issue owner.
+      cc_ids: list of user IDs for users to be CC'd on changes.
+      labels: list of label strings.  E.g., 'Priority-High'.
+      field_values: list of FieldValue PBs.
+      component_ids: list of int component IDs.
+      marked_description: issue description with initial HTML markup.
+      blocked_on: list of issue_ids that this issue is blocked on.
+      blocking: list of issue_ids that this issue blocks.
+      attachments: [(filename, contents, mimetype),...] attachments uploaded at
+          the time the comment was made.
+      phases: list of Phase PBs.
+      approval_values: list of ApprovalValue PBs.
+      send_email: set to False to avoid email notifications.
+      reporter_id: optional user ID of a different user to attribute this
+          issue report to.  The requester must have the ImportComment perm.
+      timestamp: optional int timestamp of an imported issue.
+      dangling_blocked_on: a list of DanglingIssueRefs this issue is blocked on.
+      dangling_blocking: a list of DanglingIssueRefs that this issue blocks.
+      raise_filter_errors: whether to raise when filter rules produce errors.
+
+    Returns:
+      A tuple (newly created Issue, Comment PB for the description).
+
+    Raises:
+      FilterRuleException if creation violates any filter rule that shows error.
+      InputException: The issue has invalid input, see validation below.
+      PermissionException if user lacks sufficient permissions.
+    """
+    project = self.GetProject(project_id)
+    self._AssertPermInProject(permissions.CREATE_ISSUE, project)
+
+    # TODO(crbug/monorail/7197): The following are needed for v3 API
+    # Phase 5.2 Validate sufficient attachment quota and update
+
+    if reporter_id and reporter_id != self.mc.auth.user_id:
+      self._AssertPermInProject(permissions.IMPORT_COMMENT, project)
+      importer_id = self.mc.auth.user_id
+    else:
+      reporter_id = self.mc.auth.user_id
+      importer_id = None
+
+    with self.mc.profiler.Phase('creating issue in project %r' % project_id):
+      # TODO(crbug/monorail/8000): Refactor issue proto construction
+      # to the caller.
+      status = framework_bizobj.CanonicalizeLabel(status)
+      labels = [framework_bizobj.CanonicalizeLabel(l) for l in labels]
+      labels = [l for l in labels if l]
+
+      issue = tracker_pb2.Issue()
+      issue.project_id = project_id
+      issue.project_name = self.services.project.LookupProjectNames(
+          self.mc.cnxn, [project_id]).get(project_id)
+      issue.summary = summary
+      issue.status = status
+      issue.owner_id = owner_id
+      issue.cc_ids.extend(cc_ids)
+      issue.labels.extend(labels)
+      issue.field_values.extend(field_values)
+      issue.component_ids.extend(component_ids)
+      issue.reporter_id = reporter_id
+      if blocked_on is not None:
+        issue.blocked_on_iids = blocked_on
+        issue.blocked_on_ranks = [0] * len(blocked_on)
+      if blocking is not None:
+        issue.blocking_iids = blocking
+      if dangling_blocked_on is not None:
+        issue.dangling_blocked_on_refs = dangling_blocked_on
+      if dangling_blocking is not None:
+        issue.dangling_blocking_refs = dangling_blocking
+      if attachments:
+        issue.attachment_count = len(attachments)
+      if phases:
+        issue.phases = phases
+      if approval_values:
+        issue.approval_values = approval_values
+      timestamp = timestamp or int(time.time())
+      issue.opened_timestamp = timestamp
+      issue.modified_timestamp = timestamp
+      issue.owner_modified_timestamp = timestamp
+      issue.status_modified_timestamp = timestamp
+      issue.component_modified_timestamp = timestamp
+
+      # Validate the issue
+      tracker_helpers.AssertValidIssueForCreate(
+          self.mc.cnxn, self.services, issue, marked_description)
+
+      # Apply filter rules.
+      # Set the closed_timestamp both before and after filter rules.
+      config = self.GetProjectConfig(issue.project_id)
+      if not tracker_helpers.MeansOpenInProject(
+          tracker_bizobj.GetStatus(issue), config):
+        issue.closed_timestamp = issue.opened_timestamp
+      filterrules_helpers.ApplyFilterRules(
+          self.mc.cnxn, self.services, issue, config)
+      if issue.derived_errors and raise_filter_errors:
+        raise exceptions.FilterRuleException(issue.derived_errors)
+      if not tracker_helpers.MeansOpenInProject(
+          tracker_bizobj.GetStatus(issue), config):
+        issue.closed_timestamp = issue.opened_timestamp
+
+      new_issue, comment = self.services.issue.CreateIssue(
+          self.mc.cnxn,
+          self.services,
+          issue,
+          marked_description,
+          attachments=attachments,
+          index_now=False,
+          importer_id=importer_id)
+      logging.info(
+          'created issue %r in project %r', new_issue.local_id, project_id)
+
+    with self.mc.profiler.Phase('following up after issue creation'):
+      self.services.project.UpdateRecentActivity(self.mc.cnxn, project_id)
+
+    if send_email:
+      with self.mc.profiler.Phase('queueing notification tasks'):
+        hostport = framework_helpers.GetHostPort(
+            project_name=project.project_name)
+        send_notifications.PrepareAndSendIssueChangeNotification(
+            new_issue.issue_id, hostport, reporter_id, comment_id=comment.id)
+        send_notifications.PrepareAndSendIssueBlockingNotification(
+            new_issue.issue_id, hostport, new_issue.blocked_on_iids,
+            reporter_id)
+
+    return new_issue, comment
+
+  def MakeIssueFromTemplate(self, _template, _description, _issue_delta):
+    # type: (tracker_pb2.TemplateDef, str, tracker_pb2.IssueDelta) ->
+    #     tracker_pb2.Issue
+    """Creates issue from template, issue description, and delta.
+
+    Args:
+      template: Template that issue creation is based on.
+      description: Issue description string.
+      issue_delta: Difference between desired issue and base issue.
+
+    Returns:
+      Newly created issue, as protorpc Issue.
+
+    Raises:
+      TODO(crbug/monorail/7197): Document errors when implemented
+    """
+    # Phase 2: Build Issue from TemplateDef
+    # Use helper method, likely from template_helpers
+
+    # Phase 3: Validate proposed deltas and check permissions
+    # Check summary has been edited if required, else throw
+    # Check description is different from template default, else throw
+    # Check edit permission on field values of issue deltas, else throw
+
+    # Phase 4: Merge template, delta, and defaults
+    # Merge delta into issue
+    # Apply approval def defaults to approval values
+    # Capitalize every line of description
+
+    # Phase 5: Create issue by calling work_env.CreateIssue
+
+    return tracker_pb2.Issue()
+
+  def MakeIssue(self, issue, description, send_email):
+    # type: (tracker_pb2.Issue, str, bool) -> tracker_pb2.Issue
+    """Check restricted field permissions and create issue.
+
+    Args:
+      issue: Data for the created issue in a Protocol Bugger.
+      description: Description for the initial description comment created.
+      send_email: Whether this issue creation should email people.
+
+    Returns:
+      The created Issue PB.
+
+    Raises:
+      FilterRuleException if creation violates any filter rule that shows error.
+      InputException: The issue has invalid input, see validation below.
+      PermissionException if user lacks sufficient permissions.
+    """
+    config = self.GetProjectConfig(issue.project_id)
+    project = self.GetProject(issue.project_id)
+    self._AssertUserCanEditFieldsAndEnumMaskedLabels(
+        project, config, [fv.field_id for fv in issue.field_values],
+        issue.labels)
+    issue, _comment = self.CreateIssue(
+        issue.project_id,
+        issue.summary,
+        issue.status,
+        issue.owner_id,
+        issue.cc_ids,
+        issue.labels,
+        issue.field_values,
+        issue.component_ids,
+        description,
+        blocked_on=issue.blocked_on_iids,
+        blocking=issue.blocking_iids,
+        dangling_blocked_on=issue.dangling_blocked_on_refs,
+        dangling_blocking=issue.dangling_blocking_refs,
+        send_email=send_email)
+    return issue
+
+  def MoveIssue(self, issue, target_project):
+    """Move issue to the target_project.
+
+    The current user needs to have permission to delete the current issue, and
+    to edit issues on the target project.
+
+    Args:
+      issue: the issue PB.
+      target_project: the project PB where the issue should be moved to.
+    Returns:
+      The issue PB of the new issue on the target project.
+    """
+    self._AssertPermInIssue(issue, permissions.DELETE_ISSUE)
+    self._AssertPermInProject(permissions.EDIT_ISSUE, target_project)
+
+    if permissions.GetRestrictions(issue):
+      raise exceptions.InputException(
+          'Issues with Restrict labels are not allowed to be moved')
+
+    with self.mc.profiler.Phase('Moving Issue'):
+      tracker_fulltext.UnindexIssues([issue.issue_id])
+
+      # issue is modified by MoveIssues
+      old_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
+      moved_back_iids = self.services.issue.MoveIssues(
+          self.mc.cnxn, target_project, [issue], self.services.user)
+      new_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
+
+      if issue.issue_id in moved_back_iids:
+        content = 'Moved %s back to %s again.' % (old_text_ref, new_text_ref)
+      else:
+        content = 'Moved %s to now be %s.' % (old_text_ref, new_text_ref)
+      self.services.issue.CreateIssueComment(
+          self.mc.cnxn, issue, self.mc.auth.user_id, content,
+          amendments=[
+              tracker_bizobj.MakeProjectAmendment(target_project.project_name)])
+
+      tracker_fulltext.IndexIssues(
+          self.mc.cnxn, [issue], self.services.user, self.services.issue,
+          self.services.config)
+
+    return issue
+
+  def CopyIssue(self, issue, target_project):
+    """Copy issue to the target_project.
+
+    The current user needs to have permission to delete the current issue, and
+    to edit issues on the target project.
+
+    Args:
+      issue: the issue PB.
+      target_project: the project PB where the issue should be copied to.
+    Returns:
+      The issue PB of the new issue on the target project.
+    """
+    self._AssertPermInIssue(issue, permissions.DELETE_ISSUE)
+    self._AssertPermInProject(permissions.EDIT_ISSUE, target_project)
+
+    if permissions.GetRestrictions(issue):
+      raise exceptions.InputException(
+          'Issues with Restrict labels are not allowed to be copied')
+
+    with self.mc.profiler.Phase('Copying Issue'):
+      copied_issue = self.services.issue.CopyIssues(
+          self.mc.cnxn, target_project, [issue], self.services.user,
+          self.mc.auth.user_id)[0]
+
+      issue_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
+      copied_issue_ref = 'issue %s:%s' % (
+          copied_issue.project_name, copied_issue.local_id)
+
+      # Add comment to the original issue.
+      content = 'Copied %s to %s' % (issue_ref, copied_issue_ref)
+      self.services.issue.CreateIssueComment(
+          self.mc.cnxn, issue, self.mc.auth.user_id, content)
+
+      # Add comment to the newly created issue.
+      # Add project amendment only if the project changed.
+      amendments = []
+      if issue.project_id != copied_issue.project_id:
+        amendments.append(
+            tracker_bizobj.MakeProjectAmendment(target_project.project_name))
+      new_issue_content = 'Copied %s from %s' % (copied_issue_ref, issue_ref)
+      self.services.issue.CreateIssueComment(
+          self.mc.cnxn, copied_issue, self.mc.auth.user_id, new_issue_content,
+          amendments=amendments)
+
+      tracker_fulltext.IndexIssues(
+          self.mc.cnxn, [copied_issue], self.services.user, self.services.issue,
+          self.services.config)
+
+    return copied_issue
+
+  def _MergeLinkedAccounts(self, me_user_id):
+    """Return a list of the given user ID and any linked accounts."""
+    if not me_user_id:
+      return []
+
+    result = [me_user_id]
+    me_user = self.services.user.GetUser(self.mc.cnxn, me_user_id)
+    if me_user:
+      if me_user.linked_parent_id:
+        result.append(me_user.linked_parent_id)
+      result.extend(me_user.linked_child_ids)
+    return result
+
+  def SearchIssues(
+      self, query_string, query_project_names, me_user_id, items_per_page,
+      paginate_start, sort_spec):
+    # type: (str, Sequence[str], int, int, int, str) -> ListResult
+    """Search for issues in the given projects."""
+    # View permissions and project existence check.
+    _projects = self.GetProjectsByName(query_project_names)
+    # TODO(crbug.com/monorail/6988): Delete ListIssues when endpoints and v1
+    # are deprecated. Move pipeline call to SearchIssues.
+    # TODO(crbug.com/monorail/7678): Remove can. Pass project_ids
+    # into pipeline call instead of project_names into SearchIssues call.
+    # project_names with project_ids.
+    use_cached_searches = not settings.local_mode
+    pipeline = self.ListIssues(
+        query_string, query_project_names, me_user_id, items_per_page,
+        paginate_start, 1, '', sort_spec, use_cached_searches)
+
+    end = paginate_start + items_per_page
+    next_start = None
+    if end < pipeline.total_count:
+      next_start = end
+    return ListResult(pipeline.visible_results, next_start)
+
+  def ListIssues(
+      self,
+      query_string,  # type: str
+      query_project_names,  # type: Sequence[str]
+      me_user_id,  # type: int
+      items_per_page,  # type: int
+      paginate_start,  # type: int
+      can,  # type: int
+      group_by_spec,  # type: str
+      sort_spec,  # type: str
+      use_cached_searches,  # type: bool
+      project=None  # type: proto.Project
+  ):
+    # type: (...) -> search.frontendsearchpipeline.FrontendSearchPipeline
+    """Do an issue search w/ mc + passed in args to return a pipeline object.
+
+    Args:
+      query_string: str with the query the user is searching for.
+      query_project_names: List of project names to query for.
+      me_user_id: Relevant user id. Usually the logged in user.
+      items_per_page: Max number of issues to include in the results.
+      paginate_start: Offset of issues to skip for pagination.
+      can: id of canned query to use.
+      group_by_spec: str used to specify how issues should be grouped.
+      sort_spec: str used to specify how issues should be sorted.
+      use_cached_searches: Whether to use the cache or not.
+      project: Project object for the current project the user is viewing.
+
+    Returns:
+      A FrontendSearchPipeline instance with data on issues found.
+    """
+    # Permission to view a project is checked in FrontendSearchPipeline().
+    # Individual results are filtered by permissions in SearchForIIDs().
+
+    with self.mc.profiler.Phase('searching issues'):
+      me_user_ids = self._MergeLinkedAccounts(me_user_id)
+      pipeline = frontendsearchpipeline.FrontendSearchPipeline(
+          self.mc.cnxn,
+          self.services,
+          self.mc.auth,
+          me_user_ids,
+          query_string,
+          query_project_names,
+          items_per_page,
+          paginate_start,
+          can,
+          group_by_spec,
+          sort_spec,
+          self.mc.warnings,
+          self.mc.errors,
+          use_cached_searches,
+          self.mc.profiler,
+          project=project)
+      if not self.mc.errors.AnyErrors():
+        pipeline.SearchForIIDs()
+        pipeline.MergeAndSortIssues()
+        pipeline.Paginate()
+      # TODO(jojwang): raise InvalidQueryException.
+      return pipeline
+
+  # TODO(jrobbins): This method also requires self.mc to be a MonorailRequest.
+  def FindIssuePositionInSearch(self, issue):
+    """Do an issue search and return flipper info for the given issue.
+
+    Args:
+      issue: issue that the user is currently viewing.
+
+    Returns:
+      A 4-tuple of flipper info: (prev_iid, cur_index, next_iid, total_count).
+    """
+    # Permission to view a project is checked in FrontendSearchPipeline().
+    # Individual results are filtered by permissions in SearchForIIDs().
+
+    with self.mc.profiler.Phase('finding issue position in search'):
+      me_user_ids = self._MergeLinkedAccounts(self.mc.me_user_id)
+      pipeline = frontendsearchpipeline.FrontendSearchPipeline(
+          self.mc.cnxn,
+          self.services,
+          self.mc.auth,
+          me_user_ids,
+          self.mc.query,
+          self.mc.query_project_names,
+          self.mc.num,
+          self.mc.start,
+          self.mc.can,
+          self.mc.group_by_spec,
+          self.mc.sort_spec,
+          self.mc.warnings,
+          self.mc.errors,
+          self.mc.use_cached_searches,
+          self.mc.profiler,
+          project=self.mc.project)
+      if not self.mc.errors.AnyErrors():
+        # Only do the search if the user's query parsed OK.
+        pipeline.SearchForIIDs()
+
+      # Note: we never call MergeAndSortIssues() because we don't need a unified
+      # sorted list, we only need to know the position on such a list of the
+      # current issue.
+      prev_iid, cur_index, next_iid = pipeline.DetermineIssuePosition(issue)
+
+      return prev_iid, cur_index, next_iid, pipeline.total_count
+
+  # TODO(crbug/monorail/6988): add boolean to ignore_private_issues
+  def GetIssuesDict(self, issue_ids, use_cache=True,
+                    allow_viewing_deleted=False):
+    # type: (Collection[int], Optional[Boolean], Optional[Boolean]) ->
+    #     Mapping[int, Issue]
+    """Return a dict {iid: issue} with the specified issues, if allowed.
+
+    Args:
+      issue_ids: int global issue IDs.
+      use_cache: set to false to ensure fresh issues.
+      allow_viewing_deleted: set to true to allow user to view deleted issues.
+
+    Returns:
+      A dict {issue_id: issue} for only those issues that the user is allowed
+      to view.
+
+    Raises:
+      NoSuchIssueException if an issue is not found.
+      PermissionException if the user cannot view all issues.
+    """
+    with self.mc.profiler.Phase('getting issues %r' % issue_ids):
+      issues_by_id, missing_ids = self.services.issue.GetIssuesDict(
+          self.mc.cnxn, issue_ids, use_cache=use_cache)
+
+    if missing_ids:
+      with exceptions.ErrorAggregator(
+          exceptions.NoSuchIssueException) as missing_err_agg:
+        for missing_id in missing_ids:
+          missing_err_agg.AddErrorMessage('No such issue: %s' % missing_id)
+
+    with exceptions.ErrorAggregator(
+        permissions.PermissionException) as permission_err_agg:
+      for issue in issues_by_id.values():
+        try:
+          self._AssertUserCanViewIssue(
+              issue, allow_viewing_deleted=allow_viewing_deleted)
+        except permissions.PermissionException as e:
+          permission_err_agg.AddErrorMessage(e.message)
+
+    return issues_by_id
+
+  def GetIssue(self, issue_id, use_cache=True, allow_viewing_deleted=False):
+    """Return the specified issue.
+
+    Args:
+      issue_id: int global issue ID.
+      use_cache: set to false to ensure fresh issue.
+      allow_viewing_deleted: set to true to allow user to view a deleted issue.
+
+    Returns:
+      The requested Issue PB.
+    """
+    if issue_id is None:
+      raise exceptions.InputException('No issue issue_id specified')
+
+    with self.mc.profiler.Phase('getting issue %r' % issue_id):
+      issue = self.services.issue.GetIssue(
+          self.mc.cnxn, issue_id, use_cache=use_cache)
+
+    self._AssertUserCanViewIssue(
+        issue, allow_viewing_deleted=allow_viewing_deleted)
+    return issue
+
+  def ListReferencedIssues(self, ref_tuples, default_project_name):
+    """Return the specified issues."""
+    # Make sure ref_tuples are unique, preserving order.
+    ref_tuples = list(collections.OrderedDict(
+        list(zip(ref_tuples, ref_tuples))))
+    ref_projects = self.services.project.GetProjectsByName(
+        self.mc.cnxn,
+        [(ref_pn or default_project_name) for ref_pn, _ in ref_tuples])
+    issue_ids, _misses = self.services.issue.ResolveIssueRefs(
+        self.mc.cnxn, ref_projects, default_project_name, ref_tuples)
+    open_issues, closed_issues = (
+        tracker_helpers.GetAllowedOpenedAndClosedIssues(
+            self.mc, issue_ids, self.services))
+    return open_issues, closed_issues
+
+  def GetIssueByLocalID(
+      self, project_id, local_id, use_cache=True,
+      allow_viewing_deleted=False):
+    """Return the specified issue, TODO: iff the signed in user may view it.
+
+    Args:
+      project_id: int project ID of the project that contains the issue.
+      local_id: int issue local id number.
+      use_cache: set to False when doing read-modify-write operations.
+      allow_viewing_deleted: set to True to return a deleted issue so that
+          an authorized user may undelete it.
+
+    Returns:
+      The specified Issue PB.
+
+    Raises:
+      exceptions.InputException: Something was not specified properly.
+      exceptions.NoSuchIssueException: The issue does not exist.
+    """
+    if project_id is None:
+      raise exceptions.InputException('No project specified')
+    if local_id is None:
+      raise exceptions.InputException('No issue local_id specified')
+
+    with self.mc.profiler.Phase('getting issue %r:%r' % (project_id, local_id)):
+      issue = self.services.issue.GetIssueByLocalID(
+          self.mc.cnxn, project_id, local_id, use_cache=use_cache)
+
+    self._AssertUserCanViewIssue(
+        issue, allow_viewing_deleted=allow_viewing_deleted)
+    return issue
+
+  def GetRelatedIssueRefs(self, issues):
+    """Return a dict {iid: (project_name, local_id)} for all related issues."""
+    related_iids = set()
+    with self.mc.profiler.Phase('getting related issue refs'):
+      for issue in issues:
+        related_iids.update(issue.blocked_on_iids)
+        related_iids.update(issue.blocking_iids)
+        if issue.merged_into:
+          related_iids.add(issue.merged_into)
+      logging.info('related_iids is %r', related_iids)
+      return self.services.issue.LookupIssueRefs(self.mc.cnxn, related_iids)
+
+  def GetIssueRefs(self, issue_ids):
+    """Return a dict {iid: (project_name, local_id)} for all issue_ids."""
+    return self.services.issue.LookupIssueRefs(self.mc.cnxn, issue_ids)
+
+  def BulkUpdateIssueApprovals(self, issue_ids, approval_id, project,
+                               approval_delta, comment_content,
+                               send_email):
+    """Update all given issues' specified approval."""
+    # Anon users and users with no permission to view the project
+    # will get permission denied. Missing permissions to update
+    # individual issues will not throw exceptions. Issues will just not be
+    # updated.
+    if not self.mc.auth.user_id:
+      raise permissions.PermissionException('Anon cannot make changes')
+    if not self._UserCanViewProject(project):
+      raise permissions.PermissionException('User cannot view project')
+    updated_issue_ids = []
+    for issue_id in issue_ids:
+      try:
+        self.UpdateIssueApproval(
+            issue_id, approval_id, approval_delta, comment_content, False,
+            send_email=False)
+        updated_issue_ids.append(issue_id)
+      except exceptions.NoSuchIssueApprovalException as e:
+        logging.info('Skipping issue %s, no approval: %s', issue_id, e)
+      except permissions.PermissionException as e:
+        logging.info('Skipping issue %s, update not allowed: %s', issue_id, e)
+    # TODO(crbug/monorail/8122): send bulk approval update email if send_email.
+    if send_email:
+      pass
+    return updated_issue_ids
+
+  def BulkUpdateIssueApprovalsV3(
+      self, delta_specifications, comment_content, send_email):
+    # type: (Sequence[Tuple[int, int, tracker_pb2.ApprovalDelta]]], str,
+    #     Boolean -> Sequence[proto.tracker_pb2.ApprovalValue]
+    """Executes the ApprovalDeltas.
+
+    Args:
+      delta_specifications: List of (issue_id, approval_id, ApprovalDelta).
+      comment_content: The content of the comment to be posted with each delta.
+      send_email: Whether to send an email on each change.
+          TODO(crbug/monorail/8122): send bulk approval update email instead.
+
+    Returns:
+      A list of (Issue, ApprovalValue) pairs corresponding to each
+      specification provided in `delta_specifications`.
+
+    Raises:
+      InputException: If a comment is too long.
+      NoSuchIssueApprovalException: If any of the approvals specified
+          does not exist.
+      PermissionException: If the current user lacks permissions to execute
+          any of the deltas provided.
+    """
+    updated_approval_values = []
+    for (issue_id, approval_id, approval_delta) in delta_specifications:
+      updated_av, _comment, issue = self.UpdateIssueApproval(
+          issue_id,
+          approval_id,
+          approval_delta,
+          comment_content,
+          False,
+          send_email=send_email,
+          update_perms=True)
+      updated_approval_values.append((issue, updated_av))
+    return updated_approval_values
+
+  def UpdateIssueApproval(
+      self,
+      issue_id,
+      approval_id,
+      approval_delta,
+      comment_content,
+      is_description,
+      attachments=None,
+      send_email=True,
+      kept_attachments=None,
+      update_perms=False):
+    # type: (int, int, proto.tracker_pb2.ApprovalDelta, str, Boolean,
+    #     Optional[Sequence[proto.tracker_pb2.Attachment]], Optional[Boolean],
+    #     Optional[Sequence[int]], Optional[Boolean]) ->
+    #     (proto.tracker_pb2.ApprovalValue, proto.tracker_pb2.IssueComment)
+    """Update an issue's approval.
+
+    Raises:
+      InputException: The comment content is too long or additional approvers do
+      not exist.
+      PermissionException: The user is lacking one of the permissions needed
+      for the given delta.
+      NoSuchIssueApprovalException: The issue/approval combo does not exist.
+    """
+
+    issue, approval_value = self.services.issue.GetIssueApproval(
+        self.mc.cnxn, issue_id, approval_id, use_cache=False)
+
+    self._AssertPermInIssue(issue, permissions.EDIT_ISSUE)
+
+    if len(comment_content) > tracker_constants.MAX_COMMENT_CHARS:
+      raise exceptions.InputException('Comment is too long')
+
+    project = self.GetProject(issue.project_id)
+    config = self.GetProjectConfig(issue.project_id)
+    # TODO(crbug/monorail/7614): Remove the need for this hack to update perms.
+    if update_perms:
+      self.mc.LookupLoggedInUserPerms(project)
+
+    if attachments:
+      with self.mc.profiler.Phase('Accounting for quota'):
+        new_bytes_used = tracker_helpers.ComputeNewQuotaBytesUsed(
+          project, attachments)
+        self.services.project.UpdateProject(
+          self.mc.cnxn, issue.project_id, attachment_bytes_used=new_bytes_used)
+
+    if kept_attachments:
+      with self.mc.profiler.Phase('Filtering kept attachments'):
+        kept_attachments = tracker_helpers.FilterKeptAttachments(
+            is_description, kept_attachments, self.ListIssueComments(issue),
+            approval_id)
+
+    if approval_delta.status:
+      if not permissions.CanUpdateApprovalStatus(
+          self.mc.auth.effective_ids, self.mc.perms, project,
+          approval_value.approver_ids, approval_delta.status):
+        raise permissions.PermissionException(
+            'User not allowed to make this status update.')
+
+    if approval_delta.approver_ids_remove or approval_delta.approver_ids_add:
+      if not permissions.CanUpdateApprovers(
+          self.mc.auth.effective_ids, self.mc.perms, project,
+          approval_value.approver_ids):
+        raise permissions.PermissionException(
+            'User not allowed to modify approvers of this approval.')
+
+    # Check additional approvers exist.
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      tracker_helpers.AssertUsersExist(
+          self.mc.cnxn, self.services, approval_delta.approver_ids_add, err_agg)
+
+    with self.mc.profiler.Phase(
+        'updating approval for issue %r, aprpoval %r' % (
+            issue_id, approval_id)):
+      comment_pb = self.services.issue.DeltaUpdateIssueApproval(
+          self.mc.cnxn, self.mc.auth.user_id, config, issue, approval_value,
+          approval_delta, comment_content=comment_content,
+          is_description=is_description, attachments=attachments,
+          kept_attachments=kept_attachments)
+      hostport = framework_helpers.GetHostPort(
+          project_name=project.project_name)
+      send_notifications.PrepareAndSendApprovalChangeNotification(
+          issue_id, approval_id, hostport, comment_pb.id,
+          send_email=send_email)
+
+    return approval_value, comment_pb, issue
+
+  def ConvertIssueApprovalsTemplate(
+      self, config, issue, template_name, comment_content, send_email=True):
+    # type: (proto.tracker_pb2.ProjectIssueConfig, proto.tracker_pb2.Issue,
+    #     str, str, Optional[Boolean] )
+    """Convert an issue's existing approvals structure to match the one of
+       the given template.
+
+    Raises:
+      InputException: The comment content is too long.
+    """
+    self._AssertPermInIssue(issue, permissions.EDIT_ISSUE)
+
+    template = self.services.template.GetTemplateByName(
+        self.mc.cnxn, template_name, issue.project_id)
+    if not template:
+      raise exceptions.NoSuchTemplateException(
+          'Template %s is not found' % template_name)
+
+    if len(comment_content) > tracker_constants.MAX_COMMENT_CHARS:
+      raise exceptions.InputException('Comment is too long')
+
+    with self.mc.profiler.Phase('updating issue %r' % issue):
+      comment_pb = self.services.issue.UpdateIssueStructure(
+          self.mc.cnxn, config, issue, template, self.mc.auth.user_id,
+          comment_content)
+      hostport = framework_helpers.GetHostPort(project_name=issue.project_name)
+      send_notifications.PrepareAndSendIssueChangeNotification(
+          issue.issue_id, hostport, self.mc.auth.user_id,
+          send_email=send_email, comment_id=comment_pb.id)
+
+  def UpdateIssue(
+      self, issue, delta, comment_content, attachments=None, send_email=True,
+      is_description=False, kept_attachments=None, inbound_message=None):
+    # type: (...) => None
+    """Update an issue with a set of changes and add a comment.
+
+    Args:
+      issue: Existing Issue PB for the issue to be modified.
+      delta: IssueDelta object containing all the changes to be made.
+      comment_content: string content of the user's comment.
+      attachments: List [(filename, contents, mimetype),...] of attachments.
+      send_email: set to False to suppress email notifications.
+      is_description: True if this adds a new issue description.
+      kept_attachments: This should be a list of int attachment ids for
+          attachments kept from previous descriptions, if the comment is
+          a change to the issue description.
+      inbound_message: optional string full text of an email that caused
+          this comment to be added.
+
+    Returns:
+      Nothing.
+
+    Raises:
+      InputException: The comment content is too long.
+    """
+    if not self._UserCanUsePermInIssue(issue, permissions.EDIT_ISSUE):
+      # We're editing the issue description. Only users with EditIssue
+      # permission can edit the description.
+      if is_description:
+        raise permissions.PermissionException(
+            'Users lack permission EditIssue in issue')
+      # If we're adding a comment, we must have AddIssueComment permission and
+      # verify it's size.
+      if comment_content:
+        self._AssertPermInIssue(issue, permissions.ADD_ISSUE_COMMENT)
+      # If we're modifying the issue, check that we only modify the fields we're
+      # allowed to edit.
+      if delta != tracker_pb2.IssueDelta():
+        allowed_delta = tracker_pb2.IssueDelta()
+        if self._UserCanUsePermInIssue(issue, permissions.EDIT_ISSUE_STATUS):
+          allowed_delta.status = delta.status
+        if self._UserCanUsePermInIssue(issue, permissions.EDIT_ISSUE_SUMMARY):
+          allowed_delta.summary = delta.summary
+        if self._UserCanUsePermInIssue(issue, permissions.EDIT_ISSUE_OWNER):
+          allowed_delta.owner_id = delta.owner_id
+        if self._UserCanUsePermInIssue(issue, permissions.EDIT_ISSUE_CC):
+          allowed_delta.cc_ids_add = delta.cc_ids_add
+          allowed_delta.cc_ids_remove = delta.cc_ids_remove
+        if delta != allowed_delta:
+          raise permissions.PermissionException(
+              'Users lack permission EditIssue in issue')
+
+    if delta.merged_into:
+      # Reject attempts to merge an issue into an issue we cannot view and edit.
+      merged_into_issue = self.GetIssue(
+          delta.merged_into, use_cache=False, allow_viewing_deleted=True)
+      self._AssertPermInIssue(issue, permissions.EDIT_ISSUE)
+      # Reject attempts to merge an issue into itself.
+      if issue.issue_id == delta.merged_into:
+        raise exceptions.InputException(
+          'Cannot merge an issue into itself.')
+
+    # Reject comments that are too long.
+    if comment_content and len(
+        comment_content) > tracker_constants.MAX_COMMENT_CHARS:
+      raise exceptions.InputException('Comment is too long')
+
+    # Reject attempts to block on issue on itself.
+    if (issue.issue_id in delta.blocked_on_add
+        or issue.issue_id in delta.blocking_add):
+      raise exceptions.InputException(
+        'Cannot block an issue on itself.')
+
+    project = self.GetProject(issue.project_id)
+    config = self.GetProjectConfig(issue.project_id)
+
+    # Reject attempts to edit restricted fields that the user cannot change.
+    field_ids = [fv.field_id for fv in delta.field_vals_add]
+    field_ids.extend([fvr.field_id for fvr in delta.field_vals_remove])
+    field_ids.extend(delta.fields_clear)
+    labels = itertools.chain(delta.labels_add, delta.labels_remove)
+    self._AssertUserCanEditFieldsAndEnumMaskedLabels(
+        project, config, field_ids, labels)
+
+    old_owner_id = tracker_bizobj.GetOwnerId(issue)
+
+    if attachments:
+      with self.mc.profiler.Phase('Accounting for quota'):
+        new_bytes_used = tracker_helpers.ComputeNewQuotaBytesUsed(
+            project, attachments)
+        self.services.project.UpdateProject(
+            self.mc.cnxn, issue.project_id,
+            attachment_bytes_used=new_bytes_used)
+
+    with self.mc.profiler.Phase('Validating the issue change'):
+      # If the owner changed, it must be a project member.
+      if (delta.owner_id is not None and delta.owner_id != issue.owner_id):
+        parsed_owner_valid, msg = tracker_helpers.IsValidIssueOwner(
+          self.mc.cnxn, project, delta.owner_id, self.services)
+        if not parsed_owner_valid:
+          raise exceptions.InputException(msg)
+
+    if kept_attachments:
+      with self.mc.profiler.Phase('Filtering kept attachments'):
+        kept_attachments = tracker_helpers.FilterKeptAttachments(
+            is_description, kept_attachments, self.ListIssueComments(issue),
+            None)
+
+    with self.mc.profiler.Phase('Updating issue %r' % (issue.issue_id)):
+      _amendments, comment_pb = self.services.issue.DeltaUpdateIssue(
+          self.mc.cnxn, self.services, self.mc.auth.user_id, issue.project_id,
+          config, issue, delta, comment=comment_content,
+          attachments=attachments, is_description=is_description,
+          kept_attachments=kept_attachments, inbound_message=inbound_message)
+
+    with self.mc.profiler.Phase('Following up after issue update'):
+      if delta.merged_into:
+        new_starrers = tracker_helpers.GetNewIssueStarrers(
+            self.mc.cnxn, self.services, [issue.issue_id],
+            delta.merged_into)
+        merged_into_project = self.GetProject(merged_into_issue.project_id)
+        tracker_helpers.AddIssueStarrers(
+            self.mc.cnxn, self.services, self.mc,
+            delta.merged_into, merged_into_project, new_starrers)
+        # Load target issue again to get the updated star count.
+        merged_into_issue = self.GetIssue(
+            merged_into_issue.issue_id, use_cache=False)
+        merge_comment_pb = tracker_helpers.MergeCCsAndAddComment(
+            self.services, self.mc, issue, merged_into_issue)
+        # Send notification emails.
+        hostport = framework_helpers.GetHostPort(
+            project_name=merged_into_project.project_name)
+        reporter_id = self.mc.auth.user_id
+        send_notifications.PrepareAndSendIssueChangeNotification(
+            merged_into_issue.issue_id,
+            hostport,
+            reporter_id,
+            send_email=send_email,
+            comment_id=merge_comment_pb.id)
+      self.services.project.UpdateRecentActivity(
+          self.mc.cnxn, issue.project_id)
+
+    with self.mc.profiler.Phase('Generating notifications'):
+      if comment_pb:
+        hostport = framework_helpers.GetHostPort(
+            project_name=project.project_name)
+        reporter_id = self.mc.auth.user_id
+        send_notifications.PrepareAndSendIssueChangeNotification(
+            issue.issue_id, hostport, reporter_id,
+            send_email=send_email, old_owner_id=old_owner_id,
+            comment_id=comment_pb.id)
+        delta_blocked_on_iids = delta.blocked_on_add + delta.blocked_on_remove
+        send_notifications.PrepareAndSendIssueBlockingNotification(
+            issue.issue_id, hostport, delta_blocked_on_iids,
+            reporter_id, send_email=send_email)
+
+  def ModifyIssues(
+      self,
+      issue_id_delta_pairs,
+      attachment_uploads=None,
+      comment_content=None,
+      send_email=True):
+    # type: (Sequence[Tuple[int, IssueDelta]], Boolean, Optional[str],
+    #     Optional[bool]) -> Sequence[Issue]
+    """Modify issues by the given deltas and returns all issues post-update.
+
+    Note: Issues with NOOP deltas and no comment_content to add will not be
+        updated and will not be returned.
+
+    Args:
+      issue_id_delta_pairs: List of Tuples containing IDs and IssueDeltas, one
+        for each issue to modify.
+      attachment_uploads: List of AttachmentUpload tuples to be attached to the
+        new comments created for all modified issues in issue_id_delta_pairs.
+      comment_content: The text for the comment this issue change will use.
+      send_email: Whether this change sends an email or not.
+
+    Returns:
+      List of modified issues.
+    """
+
+    main_issue_ids = {issue_id for issue_id, _delta in issue_id_delta_pairs}
+    issues_by_id = self.GetIssuesDict(main_issue_ids, use_cache=False)
+    issue_delta_pairs = [
+        (issues_by_id[issue_id], delta)
+        for (issue_id, delta) in issue_id_delta_pairs
+    ]
+
+    # PHASE 1: Prepare these changes and assert they can be made.
+    self._AssertUserCanModifyIssues(
+        issue_delta_pairs, False, comment_content=comment_content)
+    new_bytes_by_pid = tracker_helpers.PrepareIssueChanges(
+        self.mc.cnxn,
+        issue_delta_pairs,
+        self.services,
+        attachment_uploads=attachment_uploads,
+        comment_content=comment_content)
+    # TODO(crbug.com/monorail/8074): Assert we do not update more than 100
+    # issues at once.
+
+    # PHASE 2: Organize data. tracker_helpers.GroupUniqueDeltaIssues()
+    (_unique_deltas, issues_for_unique_deltas
+    ) = tracker_helpers.GroupUniqueDeltaIssues(issue_delta_pairs)
+
+    # PHASE 3-4: Modify issues in RAM.
+    changes = tracker_helpers.ApplyAllIssueChanges(
+        self.mc.cnxn, issue_delta_pairs, self.services)
+
+    # PHASE 5: Apply filter rules.
+    inflight_issues = changes.issues_to_update_dict.values()
+    project_ids = list(
+        {issue.project_id for issue in inflight_issues})
+    configs_by_id = self.services.config.GetProjectConfigs(
+        self.mc.cnxn, project_ids)
+    with exceptions.ErrorAggregator(exceptions.FilterRuleException) as err_agg:
+      for issue in inflight_issues:
+        config = configs_by_id[issue.project_id]
+
+        # Update closed timestamp before filter rules because filter rules
+        # may affect them.
+        old_effective_status = changes.old_statuses_by_iid.get(issue.issue_id)
+        # The old status might be None because the IssueDeltas did not contain
+        # a status change and MeansOpenInProject treats None as "Open".
+        if old_effective_status:
+          tracker_helpers.UpdateClosedTimestamp(
+              config, issue, old_effective_status)
+
+        filterrules_helpers.ApplyFilterRules(
+              self.mc.cnxn, self.services, issue, config)
+        if issue.derived_errors:
+          err_agg.AddErrorMessage('/n'.join(issue.derived_errors))
+
+        # Update closed timestamp after filter rules because filter rules
+        # could change effective status.
+        # The old status might be None because the IssueDeltas did not contain
+        # a status change and MeansOpenInProject treats None as "Open".
+        if old_effective_status:
+          tracker_helpers.UpdateClosedTimestamp(
+              config, issue, old_effective_status)
+
+    # PHASE 6: Update modified timestamps for issues in RAM.
+    all_involved_iids = main_issue_ids.union(
+        changes.issues_to_update_dict.keys())
+
+    now_timestamp = int(time.time())
+    # Add modified timestamps for issues with amendments.
+    for iid in all_involved_iids:
+      issue = changes.issues_to_update_dict.get(iid, issues_by_id.get(iid))
+      issue_modified = iid in changes.issues_to_update_dict
+
+      if not (issue_modified or comment_content or attachment_uploads):
+        # Skip issues that have neither amendments or comment changes.
+        continue
+
+      old_owner = changes.old_owners_by_iid.get(issue.issue_id)
+      old_status = changes.old_statuses_by_iid.get(issue.issue_id)
+      old_components = changes.old_components_by_iid.get(issue.issue_id)
+
+      # Adding this issue to issues_to_update, so its modified_timestamp gets
+      # updated in PHASE 7's UpdateIssues() call. Issues with NOOP changes
+      # but still need a new comment added for `comment_content` or
+      # `attachments` are added back here.
+      changes.issues_to_update_dict[issue.issue_id] = issue
+
+      issue.modified_timestamp = now_timestamp
+
+      if (iid in changes.old_owners_by_iid and
+          old_owner != tracker_bizobj.GetOwnerId(issue)):
+        issue.owner_modified_timestamp = now_timestamp
+
+      if (iid in changes.old_statuses_by_iid and
+          old_status != tracker_bizobj.GetStatus(issue)):
+        issue.status_modified_timestamp = now_timestamp
+
+      if (iid in changes.old_components_by_iid and
+          set(old_components) != set(issue.component_ids)):
+        issue.component_modified_timestamp = now_timestamp
+
+    # PHASE 7: Apply changes to DB: update issues, combine starrers
+    # for merged issues, create issue comments, enqueue issues for
+    # re-indexing.
+    if changes.issues_to_update_dict:
+      self.services.issue.UpdateIssues(
+          self.mc.cnxn, changes.issues_to_update_dict.values(), commit=False)
+    comments_by_iid = {}
+    impacted_comments_by_iid = {}
+
+    # changes.issues_to_update includes all main issues or impacted
+    # issues with updated fields and main issues that had noop changes
+    # but still need a comment created for `comment_content` or `attachments`.
+    for iid, issue in changes.issues_to_update_dict.items():
+      # Update starrers for merged issues.
+      new_starrers = changes.new_starrers_by_iid.get(iid)
+      if new_starrers:
+        self.services.issue_star.SetStarsBatch_SkipIssueUpdate(
+            self.mc.cnxn, iid, new_starrers, True, commit=False)
+
+      # Create new issue comment for main issue changes.
+      amendments = changes.amendments_by_iid.get(iid)
+      if (amendments or comment_content or
+          attachment_uploads) and iid in main_issue_ids:
+        comments_by_iid[iid] = self.services.issue.CreateIssueComment(
+            self.mc.cnxn,
+            issue,
+            self.mc.auth.user_id,
+            comment_content,
+            amendments=amendments,
+            attachments=attachment_uploads,
+            commit=False)
+
+      # Create new issue comment for impacted issue changes.
+      # ie: when an issue is marked as blockedOn another or similar.
+      imp_amendments = changes.imp_amendments_by_iid.get(iid)
+      if imp_amendments:
+        filtered_imp_amendments = []
+        content = ''
+        # Represent MERGEDINTO Amendments for impacted issues with
+        # comment content instead to be consistent with previous behavior
+        # and so users can tell whether a merged change comment on an issue
+        # is a change in the issue's merged_into or a change in another
+        # issue's merged_into.
+        for am in imp_amendments:
+          if am.field is tracker_pb2.FieldID.MERGEDINTO and am.newvalue:
+            for value in am.newvalue.split():
+              if value.startswith('-'):
+                content += UNMERGE_COMMENT % value.strip('-')
+              else:
+                content += MERGE_COMMENT % value
+          else:
+            filtered_imp_amendments.append(am)
+
+        impacted_comments_by_iid[iid] = self.services.issue.CreateIssueComment(
+            self.mc.cnxn,
+            issue,
+            self.mc.auth.user_id,
+            content,
+            amendments=filtered_imp_amendments,
+            commit=False)
+
+    # Update used bytes for each impacted project.
+    for pid, new_bytes_used in new_bytes_by_pid.items():
+      self.services.project.UpdateProject(
+          self.mc.cnxn, pid, attachment_bytes_used=new_bytes_used, commit=False)
+
+    # Reindex issues and commit all DB changes.
+    issues_to_reindex = set(
+        comments_by_iid.keys() + impacted_comments_by_iid.keys())
+    if issues_to_reindex:
+      self.services.issue.EnqueueIssuesForIndexing(
+          self.mc.cnxn, issues_to_reindex, commit=False)
+      # We only commit if there are issues to reindex. No issues to reindex
+      # means there were no updates that need a commit.
+      self.mc.cnxn.Commit()
+
+    # PHASE 8: Send notifications for each group of issues from Phase 2.
+    # Fetch hostports.
+    hostports_by_pid = {}
+    for iid, issue in changes.issues_to_update_dict.items():
+      # Note: issues_to_update only include issues with changes in metadata.
+      # If iid is not in issues_to_update, the issue may still have a new
+      # comment that we want to send notifications for.
+      issue = changes.issues_to_update_dict.get(iid, issues_by_id.get(iid))
+
+      if issue.project_id not in hostports_by_pid:
+        hostports_by_pid[issue.project_id] = framework_helpers.GetHostPort(
+            project_name=issue.project_name)
+    # Send emails for main changes in issues by unique delta.
+    for issues in issues_for_unique_deltas:
+      # Group issues for each unique delta by project because
+      # SendIssueBulkChangeNotification cannot handle cross-project
+      # notifications and hostports are specific to each project.
+      issues_by_pid = collections.defaultdict(set)
+      for issue in issues:
+        issues_by_pid[issue.project_id].add(issue)
+      for project_issues in issues_by_pid.values():
+        # Send one email to involved users for the issue.
+        if len(project_issues) == 1:
+          (project_issue,) = project_issues
+          self._ModifyIssuesNotifyForDelta(
+              project_issue, changes, comments_by_iid, hostports_by_pid,
+              send_email)
+        # Send one bulk email for users involved in all updated issues.
+        else:
+          self._ModifyIssuesBulkNotifyForDelta(
+              project_issues,
+              changes,
+              hostports_by_pid,
+              send_email,
+              comment_content=comment_content)
+
+    # Send emails for changes to impacted issues.
+    for issue_id, comment_pb in impacted_comments_by_iid.items():
+      issue = changes.issues_to_update_dict[issue_id]
+      hostport = hostports_by_pid[issue.project_id]
+      # We do not need to track old owners because the only owner change
+      # that could have happened for impacted issues' changes is a change from
+      # no owner to a derived owner.
+      send_notifications.PrepareAndSendIssueChangeNotification(
+          issue_id, hostport, self.mc.auth.user_id, comment_id=comment_pb.id,
+          send_email=send_email)
+
+    return [
+        issues_by_id[iid] for iid in main_issue_ids if iid in comments_by_iid
+    ]
+
+  def _ModifyIssuesNotifyForDelta(
+      self, issue, changes, comments_by_iid, hostports_by_pid, send_email):
+    # type: (Issue, tracker_helpers._IssueChangesTuple,
+    #     Mapping[int, IssueComment], Mapping[int, str], bool) -> None
+    comment_pb = comments_by_iid.get(issue.issue_id)
+    # Existence of a comment_pb means there were updates to the issue or
+    # comment_content added to the issue that should trigger
+    # notifications.
+    if comment_pb:
+      hostport = hostports_by_pid[issue.project_id]
+      old_owner_id = changes.old_owners_by_iid.get(issue.issue_id)
+      send_notifications.PrepareAndSendIssueChangeNotification(
+          issue.issue_id,
+          hostport,
+          self.mc.auth.user_id,
+          old_owner_id=old_owner_id,
+          comment_id=comment_pb.id,
+          send_email=send_email)
+
+  def _ModifyIssuesBulkNotifyForDelta(
+      self, issues, changes, hostports_by_pid, send_email,
+      comment_content=None):
+    # type: (Collection[Issue], _IssueChangesTuple, Mapping[int, str], bool,
+    #     Optional[str]) -> None
+    iids = {issue.issue_id for issue in issues}
+    old_owner_ids = [
+        changes.old_owners_by_iid.get(iid)
+        for iid in iids
+        if changes.old_owners_by_iid.get(iid)
+    ]
+    amendments = []
+    for iid in iids:
+      ams = changes.amendments_by_iid.get(iid, [])
+      amendments.extend(ams)
+    # Calling SendBulkChangeNotification does not require the comment_pb
+    # objects only the amendments. Checking for existence of amendments
+    # and comment_content is equivalent to checking for existence of new
+    # comments created for these issues.
+    if amendments or comment_content:
+      # TODO(crbug.com/monorail/8125): Stop using UserViews for bulk
+      # notifications.
+      users_by_id = framework_views.MakeAllUserViews(
+          self.mc.cnxn, self.services.user, old_owner_ids,
+          tracker_bizobj.UsersInvolvedInAmendments(amendments))
+      hostport = hostports_by_pid[issues.pop().project_id]
+      send_notifications.SendIssueBulkChangeNotification(
+          iids, hostport, old_owner_ids, comment_content,
+          self.mc.auth.user_id, amendments, send_email, users_by_id)
+
+  def DeleteIssue(self, issue, delete):
+    """Mark or unmark the given issue as deleted."""
+    self._AssertPermInIssue(issue, permissions.DELETE_ISSUE)
+
+    with self.mc.profiler.Phase('Marking issue %r deleted' % (issue.issue_id)):
+      self.services.issue.SoftDeleteIssue(
+          self.mc.cnxn, issue.project_id, issue.local_id, delete,
+          self.services.user)
+
+  def FlagIssues(self, issues, flag):
+    """Flag or unflag the given issues as spam."""
+    for issue in issues:
+      self._AssertPermInIssue(issue, permissions.FLAG_SPAM)
+
+    issue_ids = [issue.issue_id for issue in issues]
+    with self.mc.profiler.Phase('Marking issues %r as spam' % issue_ids):
+      self.services.spam.FlagIssues(
+          self.mc.cnxn, self.services.issue, issues, self.mc.auth.user_id,
+          flag)
+      if self._UserCanUsePermInIssue(issue, permissions.VERDICT_SPAM):
+        self.services.spam.RecordManualIssueVerdicts(
+            self.mc.cnxn, self.services.issue, issues, self.mc.auth.user_id,
+            flag)
+
+  def LookupIssuesFlaggers(self, issues):
+    """Returns users who've reported the issue or its comments as spam.
+
+    Args:
+      issues: the list of issues to query.
+    Returns:
+      A dictionary
+        {issue_id: ([issue_reporters], {comment_id: [comment_reporters]})}
+      For each issue id, a tuple with the users who have flagged the issue;
+      and a dictionary of users who have flagged a comment for each comment id.
+    """
+    for issue in issues:
+      self._AssertUserCanViewIssue(issue)
+
+    issue_ids = [issue.issue_id for issue in issues]
+    with self.mc.profiler.Phase('Looking up flaggers for %s' % issue_ids):
+      reporters = self.services.spam.LookupIssuesFlaggers(
+          self.mc.cnxn, issue_ids)
+
+    return reporters
+
+  def LookupIssueFlaggers(self, issue):
+    """Returns users who've reported the issue or its comments as spam.
+
+    Args:
+      issue: the issue to query.
+    Returns:
+      A tuple
+        ([issue_reporters], {comment_id: [comment_reporters]})
+      With the users who have flagged the issue; and a dictionary of users who
+      have flagged a comment for each comment id.
+    """
+    return self.LookupIssuesFlaggers([issue])[issue.issue_id]
+
+  def GetIssuePositionInHotlist(
+      self, current_issue, hotlist, can, sort_spec, group_by_spec):
+    # type: (Issue, Hotlist, int, str, str) -> (int, int, int, int)
+    """Get index info of an issue within a hotlist.
+
+    Args:
+      current_issue: the currently viewed issue.
+      hotlist: the hotlist this flipper is flipping through.
+      can: int "canned query" number to scope the visible issues.
+      sort_spec: string that lists the sort order.
+      group_by_spec: string that lists the grouping order.
+    """
+    issues_list = self.services.issue.GetIssues(self.mc.cnxn,
+        [item.issue_id for item in hotlist.items])
+    project_ids = hotlist_helpers.GetAllProjectsOfIssues(issues_list)
+    config_list = hotlist_helpers.GetAllConfigsOfProjects(
+        self.mc.cnxn, project_ids, self.services)
+    harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list)
+    (sorted_issues, _hotlist_issues_context,
+     _users) = hotlist_helpers.GetSortedHotlistIssues(
+         self.mc.cnxn, hotlist.items, issues_list, self.mc.auth,
+         can, sort_spec, group_by_spec, harmonized_config, self.services,
+         self.mc.profiler)
+    (prev_iid, cur_index,
+     next_iid) = features_bizobj.DetermineHotlistIssuePosition(
+         current_issue, [issue.issue_id for issue in sorted_issues])
+    total_count = len(sorted_issues)
+    return prev_iid, cur_index, next_iid, total_count
+
+  def RerankBlockedOnIssues(self, issue, moved_id, target_id, split_above):
+    """Rerank the blocked on issues for issue_id.
+
+    Args:
+      issue: The issue to modify.
+      moved_id: The id of the issue to move.
+      target_id: The id of the issue to move |moved_issue| to.
+      split_above: Whether to move |moved_issue| before or after |target_issue|.
+    """
+    # Make sure the user has permission to edit the issue.
+    self._AssertPermInIssue(issue, permissions.EDIT_ISSUE)
+    # Make sure the moved and target issues are in the blocked-on list.
+    if moved_id not in issue.blocked_on_iids:
+      raise exceptions.InputException(
+          'The issue to move is not in the blocked-on list.')
+    if target_id not in issue.blocked_on_iids:
+      raise exceptions.InputException(
+          'The target issue is not in the blocked-on list.')
+
+    phase_name = 'Moving issue %r %s issue %d.' % (
+        moved_id, 'above' if split_above else 'below', target_id)
+    with self.mc.profiler.Phase(phase_name):
+      lower, higher = tracker_bizobj.SplitBlockedOnRanks(
+          issue, target_id, split_above,
+          [iid for iid in issue.blocked_on_iids if iid != moved_id])
+      rank_changes = rerank_helpers.GetInsertRankings(
+          lower, higher, [moved_id])
+      if rank_changes:
+        self.services.issue.ApplyIssueRerank(
+            self.mc.cnxn, issue.issue_id, rank_changes)
+
+  # FUTURE: GetIssuePermissionsForUser()
+
+  # FUTURE: CreateComment()
+
+
+  # TODO(crbug.com/monorail/7520): Delete when usages removed.
+  def ListIssueComments(self, issue):
+    """Return comments on the specified viewable issue."""
+    self._AssertUserCanViewIssue(issue)
+
+    with self.mc.profiler.Phase('getting comments for %r' % issue.issue_id):
+      comments = self.services.issue.GetCommentsForIssue(
+          self.mc.cnxn, issue.issue_id)
+
+    return comments
+
+
+  def SafeListIssueComments(
+      self, issue_id, max_items, start, approval_id=None):
+    # type: (tracker_pb2.Issue, int, int, Optional[int]) -> ListResult
+    """Return comments on the issue, filtering non-viewable content.
+
+    TODO(crbug.com/monorail/7520): Rename to ListIssueComments.
+
+    Note: This returns `deleted_by`, but it should only be used for the purposes
+    of determining whether the comment is deleted. The viewer may not have
+    access to view who deleted the comment.
+
+    Args:
+      issue_id: The issue for which we're listing comments.
+      max_items: The maximum number of comments to return.
+      start: The index of the start position in the list of comments.
+      approval_id: Whether to only return comments on this approval.
+
+    Returns:
+      A work_env.ListResult namedtuple with the comments for the issue.
+
+    Raises:
+      PermissionException: The logged-in user is not allowed to view the issue.
+    """
+    if start < 0:
+      raise exceptions.InputException('Invalid `start`: %d' % start)
+    if max_items < 0:
+      raise exceptions.InputException('Invalid `max_items`: %d' % max_items)
+
+    with self.mc.profiler.Phase('getting comments for %r' % issue_id):
+      issue = self.GetIssue(issue_id)
+      comments = self.services.issue.GetCommentsForIssue(self.mc.cnxn, issue_id)
+      _, comment_reporters = self.LookupIssueFlaggers(issue)
+      users_involved_in_comments = tracker_bizobj.UsersInvolvedInCommentList(
+          comments)
+      users_by_id = framework_views.MakeAllUserViews(
+          self.mc.cnxn, self.services.user, users_involved_in_comments)
+
+    with self.mc.profiler.Phase('getting perms for comments'):
+      project = self.GetProjectByName(issue.project_name)
+      self.mc.LookupLoggedInUserPerms(project)
+      config = self.GetProjectConfig(project.project_id)
+      perms = permissions.UpdateIssuePermissions(
+          self.mc.perms,
+          project,
+          issue,
+          self.mc.auth.effective_ids,
+          config=config)
+
+    # TODO(crbug.com/monorail/7525): Check values, and return next_start.
+    end = start + max_items
+    filtered_comments = []
+    with self.mc.profiler.Phase('converting comments'):
+      for comment in comments:
+        if approval_id and comment.approval_id != approval_id:
+          continue
+        commenter = users_by_id[comment.user_id]
+
+        _can_flag, is_flagged = permissions.CanFlagComment(
+            comment, commenter, comment_reporters.get(comment.id, []),
+            self.mc.auth.user_id, perms)
+        can_view = permissions.CanViewComment(
+            comment, commenter, self.mc.auth.user_id, perms)
+        can_view_inbound_message = permissions.CanViewInboundMessage(
+            comment, self.mc.auth.user_id, perms)
+
+        # By default, all fields should get filtered out.
+        # i.e. this is an allowlist rather than a denylist to reduce leaking
+        # info.
+        filtered_comment = tracker_pb2.IssueComment(
+            id=comment.id,
+            issue_id=comment.issue_id,
+            project_id=comment.project_id,
+            approval_id=comment.approval_id,
+            timestamp=comment.timestamp,
+            deleted_by=comment.deleted_by,
+            sequence=comment.sequence,
+            is_spam=is_flagged,
+            is_description=comment.is_description,
+            description_num=comment.description_num)
+        if can_view:
+          filtered_comment.content = comment.content
+          filtered_comment.user_id = comment.user_id
+          filtered_comment.amendments.extend(comment.amendments)
+          filtered_comment.attachments.extend(comment.attachments)
+          filtered_comment.importer_id = comment.importer_id
+          if can_view_inbound_message:
+            filtered_comment.inbound_message = comment.inbound_message
+        filtered_comments.append(filtered_comment)
+    next_start = None
+    if end < len(filtered_comments):
+      next_start = end
+    return ListResult(filtered_comments[start:end], next_start)
+
+  # FUTURE: UpdateComment()
+
+  def DeleteComment(self, issue, comment, delete):
+    """Mark or unmark a comment as deleted by the current user."""
+    self._AssertUserCanDeleteComment(issue, comment)
+    if comment.is_spam and self.mc.auth.user_id == comment.user_id:
+      raise permissions.PermissionException('Cannot delete comment.')
+
+    with self.mc.profiler.Phase(
+        'deleting issue %r comment %r' % (issue.issue_id, comment.id)):
+      self.services.issue.SoftDeleteComment(
+          self.mc.cnxn, issue, comment, self.mc.auth.user_id,
+          self.services.user, delete=delete)
+
+  def DeleteAttachment(self, issue, comment, attachment_id, delete):
+    """Mark or unmark a comment attachment as deleted by the current user."""
+    # A user can delete an attachment iff they can delete a comment.
+    self._AssertUserCanDeleteComment(issue, comment)
+
+    phase_message = 'deleting issue %r comment %r attachment %r' % (
+        issue.issue_id, comment.id, attachment_id)
+    with self.mc.profiler.Phase(phase_message):
+      self.services.issue.SoftDeleteAttachment(
+          self.mc.cnxn, issue, comment, attachment_id, self.services.user,
+          delete=delete)
+
+  def FlagComment(self, issue, comment, flag):
+    """Mark or unmark a comment as spam."""
+    self._AssertPermInIssue(issue, permissions.FLAG_SPAM)
+    with self.mc.profiler.Phase(
+        'flagging issue %r comment %r' % (issue.issue_id, comment.id)):
+      self.services.spam.FlagComment(
+          self.mc.cnxn, issue, comment.id, comment.user_id,
+          self.mc.auth.user_id, flag)
+      if self._UserCanUsePermInIssue(issue, permissions.VERDICT_SPAM):
+        self.services.spam.RecordManualCommentVerdict(
+            self.mc.cnxn, self.services.issue, self.services.user, comment.id,
+            self.mc.auth.user_id, flag)
+
+  def StarIssue(self, issue, starred):
+    # type: (Issue, bool) -> Issue
+    """Set or clear a star on the given issue for the signed in user."""
+    if not self.mc.auth.user_id:
+      raise permissions.PermissionException('Anon cannot star issues')
+    self._AssertPermInIssue(issue, permissions.SET_STAR)
+
+    with self.mc.profiler.Phase('starring issue %r' % issue.issue_id):
+      config = self.services.config.GetProjectConfig(
+          self.mc.cnxn, issue.project_id)
+      self.services.issue_star.SetStar(
+          self.mc.cnxn, self.services, config, issue.issue_id,
+          self.mc.auth.user_id, starred)
+    return self.services.issue.GetIssue(self.mc.cnxn, issue.issue_id)
+
+  def IsIssueStarred(self, issue, cnxn=None):
+    """Return True if the given issue is starred by the signed in user."""
+    self._AssertUserCanViewIssue(issue)
+
+    with self.mc.profiler.Phase('checking star %r' % issue.issue_id):
+      return self.services.issue_star.IsItemStarredBy(
+          cnxn or self.mc.cnxn, issue.issue_id, self.mc.auth.user_id)
+
+  def ListStarredIssueIDs(self):
+    """Return a list of the issue IDs that the current issue has starred."""
+    # This returns an unfiltered list of issue_ids.  Permissions will be
+    # applied if and when the caller attempts to load each issue.
+
+    with self.mc.profiler.Phase('getting stars %r' % self.mc.auth.user_id):
+      return self.services.issue_star.LookupStarredItemIDs(
+          self.mc.cnxn, self.mc.auth.user_id)
+
+  def SnapshotCountsQuery(self, project, timestamp, group_by, label_prefix=None,
+                          query=None, canned_query=None, hotlist=None):
+    """Query IssueSnapshots for daily counts.
+
+    See chart_svc.QueryIssueSnapshots for more detail on arguments.
+
+    Args:
+      project (Project): Project to search.
+      timestamp (int): Will query for snapshots at this timestamp.
+      group_by (str): 2nd dimension, see QueryIssueSnapshots for options.
+      label_prefix (str): Required for label queries. Only returns results
+        with the supplied prefix.
+      query (str, optional): If supplied, will parse & apply query conditions.
+      canned_query (str, optional): Parsed canned query.
+      hotlist (Hotlist, optional): Hotlist to search under (in lieu of project).
+
+    Returns:
+      1. A dict of {name: count} for each item in group_by.
+      2. A list of any unsupported query conditions in query.
+    """
+    # This returns counts of viewable issues.
+    with self.mc.profiler.Phase('querying snapshot counts'):
+      return self.services.chart.QueryIssueSnapshots(
+        self.mc.cnxn, self.services, timestamp, self.mc.auth.effective_ids,
+        project, self.mc.perms, group_by=group_by, label_prefix=label_prefix,
+        query=query, canned_query=canned_query, hotlist=hotlist)
+
+  ### User methods
+
+  # TODO(crbug/monorail/7238): rewrite this method to call BatchGetUsers.
+  def GetUser(self, user_id):
+    # type: (int) -> User
+    """Return the user with the given ID."""
+
+    return self.BatchGetUsers([user_id])[0]
+
+  def BatchGetUsers(self, user_ids):
+    # type: (Sequence[int]) -> Sequence[User]
+    """Return all Users for given User IDs.
+
+    Args:
+      user_ids: list of User IDs.
+
+    Returns:
+      A list of User objects in the same order as the given User IDs.
+
+    Raises:
+      NoSuchUserException if a User for a given User ID is not found.
+    """
+    users_by_id = self.services.user.GetUsersByIDs(
+        self.mc.cnxn, user_ids, skip_missed=True)
+    users = []
+    for user_id in user_ids:
+      user = users_by_id.get(user_id)
+      if not user:
+        raise exceptions.NoSuchUserException(
+            'No User with ID %s found' % user_id)
+      users.append(user)
+    return users
+
+  def GetMemberships(self, user_id):
+    """Return the user group ids for the given user visible to the requester."""
+    group_ids = self.services.usergroup.LookupMemberships(self.mc.cnxn, user_id)
+    if user_id == self.mc.auth.user_id:
+      return group_ids
+    (member_ids_by_ids, owner_ids_by_ids
+    ) = self.services.usergroup.LookupAllMembers(
+        self.mc.cnxn, group_ids)
+    settings_by_id = self.services.usergroup.GetAllGroupSettings(
+        self.mc.cnxn, group_ids)
+
+    (owned_project_ids, membered_project_ids,
+     contrib_project_ids) = self.services.project.GetUserRolesInAllProjects(
+         self.mc.cnxn, self.mc.auth.effective_ids)
+    project_ids = owned_project_ids.union(
+        membered_project_ids).union(contrib_project_ids)
+
+    visible_group_ids = []
+    for group_id, group_settings in settings_by_id.items():
+      member_ids = member_ids_by_ids.get(group_id)
+      owner_ids = owner_ids_by_ids.get(group_id)
+      if permissions.CanViewGroupMembers(
+          self.mc.perms, self.mc.auth.effective_ids, group_settings,
+          member_ids, owner_ids, project_ids):
+        visible_group_ids.append(group_id)
+
+    return visible_group_ids
+
+  def ListReferencedUsers(self, emails):
+    """Return a list of the given emails' User PBs, plus linked account ids.
+
+    Args:
+      emails: list of emails of users to look up.
+
+    Returns:
+      A pair (users, linked_users_ids) where users is an unsorted list of
+      User PBs and linked_user_ids is a list of user IDs of any linked accounts.
+    """
+    with self.mc.profiler.Phase('getting existing users'):
+      user_id_dict = self.services.user.LookupExistingUserIDs(
+          self.mc.cnxn, emails)
+      users_by_id = self.services.user.GetUsersByIDs(
+          self.mc.cnxn, list(user_id_dict.values()))
+      user_list = list(users_by_id.values())
+
+      linked_user_ids = []
+      for user in user_list:
+        if user.linked_parent_id:
+          linked_user_ids.append(user.linked_parent_id)
+        linked_user_ids.extend(user.linked_child_ids)
+
+    return user_list, linked_user_ids
+
+  def StarUser(self, user_id, starred):
+    """Star or unstar the specified user.
+
+    Args:
+      user_id: int ID of the user to star/unstar.
+      starred: true to add a star, false to remove it.
+
+    Returns:
+      Nothing.
+
+    Raises:
+      NoSuchUserException: There is no user with that ID.
+    """
+    if not self.mc.auth.user_id:
+      raise exceptions.InputException('No current user specified')
+
+    with self.mc.profiler.Phase('(un)starring user %r' % user_id):
+      # Make sure the user exists and user has permission to see it.
+      self.services.user.LookupUserEmail(self.mc.cnxn, user_id)
+      self.services.user_star.SetStar(
+          self.mc.cnxn, user_id, self.mc.auth.user_id, starred)
+
+  def IsUserStarred(self, user_id):
+    """Return True if the current user has starred the given user.
+
+    Args:
+      user_id: int ID of the user to check.
+
+    Returns:
+      True if starred.
+
+    Raises:
+      NoSuchUserException: There is no user with that ID.
+    """
+    if user_id is None:
+      raise exceptions.InputException('No user specified')
+
+    if not self.mc.auth.user_id:
+      return False
+
+    with self.mc.profiler.Phase('checking user star %r' % user_id):
+      # Make sure the user exists.
+      self.services.user.LookupUserEmail(self.mc.cnxn, user_id)
+      return self.services.user_star.IsItemStarredBy(
+        self.mc.cnxn, user_id, self.mc.auth.user_id)
+
+  def GetUserStarCount(self, user_id):
+    """Return the number of times the user has been starred.
+
+    Args:
+      user_id: int ID of the user to check.
+
+    Returns:
+      The number of times the user has been starred.
+
+    Raises:
+      NoSuchUserException: There is no user with that ID.
+    """
+    if user_id is None:
+      raise exceptions.InputException('No user specified')
+
+    with self.mc.profiler.Phase('counting stars for user %r' % user_id):
+      # Make sure the user exists.
+      self.services.user.LookupUserEmail(self.mc.cnxn, user_id)
+      return self.services.user_star.CountItemStars(self.mc.cnxn, user_id)
+
+  def GetPendingLinkedInvites(self, user_id=None):
+    """Return info about a user's linked account invites."""
+    with self.mc.profiler.Phase('checking linked account invites'):
+      result = self.services.user.GetPendingLinkedInvites(
+          self.mc.cnxn, user_id or self.mc.auth.user_id)
+      return result
+
+  def InviteLinkedParent(self, parent_email):
+    """Invite a matching account to be my parent."""
+    if not parent_email:
+      raise exceptions.InputException('No parent account specified')
+    if not self.mc.auth.user_id:
+      raise permissions.PermissionException('Anon cannot link accounts')
+    with self.mc.profiler.Phase('Validating proposed parent'):
+      # We only offer self-serve account linking to matching usernames.
+      (p_username, p_domain,
+       _obs_username, _obs_email) = framework_bizobj.ParseAndObscureAddress(
+          parent_email)
+      c_view = self.mc.auth.user_view
+      if p_username != c_view.username:
+        logging.info('Username %r != %r', p_username, c_view.username)
+        raise exceptions.InputException('Linked account names must match')
+      allowed_domains = settings.linkable_domains.get(c_view.domain, [])
+      if p_domain not in allowed_domains:
+        logging.info('parent domain %r is not in list for %r: %r',
+                     p_domain, c_view.domain, allowed_domains)
+        raise exceptions.InputException('Linked account unsupported domain')
+      parent_id = self.services.user.LookupUserID(self.mc.cnxn, parent_email)
+    with self.mc.profiler.Phase('Creating linked account invite'):
+      self.services.user.InviteLinkedParent(
+          self.mc.cnxn, parent_id, self.mc.auth.user_id)
+
+  def AcceptLinkedChild(self, child_id):
+    """Accept an invitation from a child account."""
+    with self.mc.profiler.Phase('Accept linked account invite'):
+      self.services.user.AcceptLinkedChild(
+          self.mc.cnxn, self.mc.auth.user_id, child_id)
+
+  def UnlinkAccounts(self, parent_id, child_id):
+    """Delete a linked-account relationship."""
+    if (self.mc.auth.user_id != parent_id and
+        self.mc.auth.user_id != child_id):
+      permitted = self.mc.perms.CanUsePerm(
+        permissions.EDIT_OTHER_USERS, self.mc.auth.effective_ids, None, [])
+      if not permitted:
+        raise permissions.PermissionException(
+          'User lacks permission to unlink accounts')
+
+    with self.mc.profiler.Phase('Unlink accounts'):
+      self.services.user.UnlinkAccounts(self.mc.cnxn, parent_id, child_id)
+
+  def UpdateUserSettings(self, user, **kwargs):
+    """Update the preferences of the specified user.
+
+    Args:
+      user: User PB for the user to update.
+      keyword_args: dictionary of setting names mapped to new values.
+    """
+    if not user or not user.user_id:
+      raise exceptions.InputException('Cannot update user settings for anon.')
+
+    with self.mc.profiler.Phase(
+        'updating settings for %s with %s' % (self.mc.auth.user_id, kwargs)):
+      self.services.user.UpdateUserSettings(
+          self.mc.cnxn, user.user_id, user, **kwargs)
+
+  def GetUserPrefs(self, user_id):
+    """Get the UserPrefs for the specified user."""
+    # Anon user always has default prefs.
+    if not user_id:
+      return user_pb2.UserPrefs(user_id=0)
+    if user_id != self.mc.auth.user_id:
+      if not self.mc.perms.HasPerm(permissions.EDIT_OTHER_USERS, None, None):
+        raise permissions.PermissionException(
+            'Only site admins may see other users\' preferences')
+    with self.mc.profiler.Phase('Getting prefs for %s' % user_id):
+      userprefs = self.services.user.GetUserPrefs(self.mc.cnxn, user_id)
+
+    # Hard-coded user prefs for at-risk users that should use "corp mode".
+    # For some users we mark all of their new issues as Restrict-View-Google.
+    # Others see a "public issue" warning when commenting on public issues.
+    # TODO(crbug.com/monorail/5462):
+    # Remove when user group preferences are implemented.
+    if framework_bizobj.IsRestrictNewIssuesUser(self.mc.cnxn, self.services,
+                                                user_id):
+      # Copy so that cached version is not modified.
+      userprefs = user_pb2.UserPrefs(user_id=user_id, prefs=userprefs.prefs)
+      if 'restrict_new_issues' not in {pref.name for pref in userprefs.prefs}:
+        userprefs.prefs.append(user_pb2.UserPrefValue(
+            name='restrict_new_issues', value='true'))
+    if framework_bizobj.IsPublicIssueNoticeUser(self.mc.cnxn, self.services,
+                                                user_id):
+      # Copy so that cached version is not modified.
+      userprefs = user_pb2.UserPrefs(user_id=user_id, prefs=userprefs.prefs)
+      if 'public_issue_notice' not in {pref.name for pref in userprefs.prefs}:
+        userprefs.prefs.append(user_pb2.UserPrefValue(
+            name='public_issue_notice', value='true'))
+
+    return userprefs
+
+  def SetUserPrefs(self, user_id, prefs):
+    """Set zero or more UserPrefValue for the specified user."""
+    # Anon user always has default prefs.
+    if not user_id:
+      raise exceptions.InputException('Anon cannot have prefs')
+    if user_id != self.mc.auth.user_id:
+      if not self.mc.perms.HasPerm(permissions.EDIT_OTHER_USERS, None, None):
+        raise permissions.PermissionException(
+            'Only site admins may set other users\' preferences')
+    for pref in prefs:
+      error_msg = framework_bizobj.ValidatePref(pref.name, pref.value)
+      if error_msg:
+        raise exceptions.InputException(error_msg)
+    with self.mc.profiler.Phase(
+        'setting prefs for %s' % (self.mc.auth.user_id)):
+      self.services.user.SetUserPrefs(self.mc.cnxn, user_id, prefs)
+
+  # FUTURE: GetUser()
+  # FUTURE: UpdateUser()
+  # FUTURE: DeleteUser()
+  # FUTURE: ListStarredUsers()
+
+  def ExpungeUsers(self, emails, check_perms=True, commit=True):
+    """Permanently deletes user data and removes remaining user references
+       for all listed users.
+
+      To avoid any executions that might take too long and make the site hang,
+      a limit clause will be added to some operations. If any user references
+      are left behind due to the cut-off, the final services.user.ExpungeUsers
+      will fail because we cannot delete User rows that are still referenced
+      in other tables. work_env.ExpungeUsers can be called again until all user
+      references are removed and the final services.user.ExpungeUsers succeeds.
+      The limit clause will not be applied in operations for tables that contain
+      user_id or email columns but do not officially Reference the User table.
+      E.g. SpamVerdict and SpamReport. These user references must all be removed
+      before the attempt to delete rows from User is made. The limit will also
+      not be applied for sets of operations where values removed in earlier
+      operations would have to be known in order for later operations to
+      succeed.  E.g. ExpungeUsersIngroups().
+    """
+    if check_perms:
+      if not permissions.CanExpungeUsers(self.mc):
+        raise permissions.PermissionException(
+            'User is not allowed to delete users.')
+
+    limit = 10000
+    user_ids_by_email = self.services.user.LookupExistingUserIDs(
+        self.mc.cnxn, emails)
+    user_ids = list(set(user_ids_by_email.values()))
+    if framework_constants.DELETED_USER_ID in user_ids:
+      raise exceptions.InputException(
+          'Reserved deleted_user_id found in deletion request and'
+          'should not be deleted')
+    if not user_ids:
+      logging.info('Emails %r not found in DB. No users deleted', emails)
+      return
+
+    # The operations made in the methods below can be limited.
+    # We can adjust 'limit' as necessary to avoid timing out.
+    self.services.issue_star.ExpungeStarsByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+    self.services.project_star.ExpungeStarsByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+    self.services.hotlist_star.ExpungeStarsByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+    self.services.user_star.ExpungeStarsByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+    for user_id in user_ids:
+      self.services.user_star.ExpungeStars(
+          self.mc.cnxn, user_id, commit=False, limit=limit)
+
+    self.services.features.ExpungeQuickEditsByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+    self.services.features.ExpungeSavedQueriesByUsers(
+        self.mc.cnxn, user_ids, limit=limit)
+
+    self.services.template.ExpungeUsersInTemplates(
+        self.mc.cnxn, user_ids, limit=limit)
+    self.services.config.ExpungeUsersInConfigs(
+        self.mc.cnxn, user_ids, limit=limit)
+
+    self.services.project.ExpungeUsersInProjects(
+        self.mc.cnxn, user_ids, limit=limit)
+
+    # The upcoming operations cannot be limited with 'limit'.
+    # So it's possible that these operations below may lead to timing out
+    # and ExpungeUsers will have to run again to fully delete all users.
+    # We commit the above operations here, so if a failure does happen
+    # below, the second run of ExpungeUsers will have less work to do.
+    if commit:
+      self.mc.cnxn.Commit()
+
+    affected_issue_ids = self.services.issue.ExpungeUsersInIssues(
+        self.mc.cnxn, user_ids_by_email, limit=limit)
+    # Commit ExpungeUsersInIssues here, as it has many operations
+    # and at least one operation that cannot be limited.
+    if commit:
+      self.mc.cnxn.Commit()
+      self.services.issue.EnqueueIssuesForIndexing(
+          self.mc.cnxn, affected_issue_ids)
+
+    # Spam verdict and report tables have user_id columns that do not
+    # reference User. No limit will be applied.
+    self.services.spam.ExpungeUsersInSpam(self.mc.cnxn, user_ids)
+    if commit:
+      self.mc.cnxn.Commit()
+
+    # No limit will be applied for expunging in hotlists.
+    self.services.features.ExpungeUsersInHotlists(
+        self.mc.cnxn, user_ids, self.services.hotlist_star, self.services.user,
+        self.services.chart)
+    if commit:
+      self.mc.cnxn.Commit()
+
+    # No limit will be applied for expunging in UserGroups.
+    self.services.usergroup.ExpungeUsersInGroups(
+        self.mc.cnxn, user_ids)
+    if commit:
+      self.mc.cnxn.Commit()
+
+    # No limit will be applied for expunging in FilterRules.
+    deleted_rules_by_project = self.services.features.ExpungeFilterRulesByUser(
+        self.mc.cnxn, user_ids_by_email)
+    rule_strs_by_project = filterrules_helpers.BuildRedactedFilterRuleStrings(
+        self.mc.cnxn, deleted_rules_by_project, self.services.user, emails)
+    if commit:
+      self.mc.cnxn.Commit()
+
+    # We will attempt to expunge all given users here. Limiting the users we
+    # delete should be done before work_env.ExpungeUsers is called.
+    self.services.user.ExpungeUsers(self.mc.cnxn, user_ids)
+    if commit:
+      self.mc.cnxn.Commit()
+      self.services.usergroup.group_dag.MarkObsolete()
+
+    for project_id, filter_rule_strs in rule_strs_by_project.items():
+      project = self.services.project.GetProject(self.mc.cnxn, project_id)
+      hostport = framework_helpers.GetHostPort(
+          project_name=project.project_name)
+      send_notifications.PrepareAndSendDeletedFilterRulesNotification(
+          project_id, hostport, filter_rule_strs)
+
+  def TotalUsersCount(self):
+    """Returns the total number of Users in Monorail."""
+    return self.services.user.TotalUsersCount(self.mc.cnxn)
+
+  def GetAllUserEmailsBatch(self, limit=1000, offset=0):
+    """Returns a list emails that belong to Users in Monorail.
+
+    Returns:
+      A list of emails for Users within Monorail ordered by the user.user_ids.
+      The list will hold at most [limit] emails and will start at the given
+      [offset].
+    """
+    return self.services.user.GetAllUserEmailsBatch(
+        self.mc.cnxn, limit=limit, offset=offset)
+
+  ### Group methods
+
+  # FUTURE: CreateGroup()
+  # FUTURE: ListGroups()
+  # FUTURE: UpdateGroup()
+  # FUTURE: DeleteGroup()
+
+  ### Hotlist methods
+
+  def CreateHotlist(
+      self, name, summary, description, editor_ids, issue_ids, is_private,
+      default_col_spec):
+    # type: (string, string, string, Collection[int], Collection[int], Boolean,
+    #     string)
+    """Create a hotlist.
+
+    Args:
+      name: a valid hotlist name.
+      summary: one-line explanation of the hotlist.
+      description: one-page explanation of the hotlist.
+      editor_ids: a list of user IDs for the hotlist editors.
+      issue_ids: a list of issue IDs for the hotlist issues.
+      is_private: True if the hotlist can only be viewed by owners and editors.
+      default_col_spec: default columns for the hotlist's list view.
+
+
+    Returns:
+      The newly created hotlist.
+
+    Raises:
+      HotlistAlreadyExists: A hotlist with the given name already exists.
+      InputException: No user is signed in or the proposed name is invalid.
+      PermissionException: If the user cannot view all of the issues.
+    """
+    if not self.mc.auth.user_id:
+      raise exceptions.InputException('Anon cannot create hotlists.')
+
+    # GetIssuesDict checks that the user can view all issues.
+    self.GetIssuesDict(issue_ids)
+
+    if not framework_bizobj.IsValidHotlistName(name):
+      raise exceptions.InputException(
+          '%s is not a valid name for a Hotlist' % name)
+    if self.services.features.LookupHotlistIDs(
+        self.mc.cnxn, [name], [self.mc.auth.user_id]):
+      raise features_svc.HotlistAlreadyExists()
+
+    with self.mc.profiler.Phase('creating hotlist %s' % name):
+      hotlist = self.services.features.CreateHotlist(
+          self.mc.cnxn, name, summary, description, [self.mc.auth.user_id],
+          editor_ids, issue_ids=issue_ids, is_private=is_private,
+          default_col_spec=default_col_spec, ts=int(time.time()))
+
+    return hotlist
+
+  def UpdateHotlist(
+      self, hotlist_id, hotlist_name=None, summary=None, description=None,
+      is_private=None, default_col_spec=None, owner_id=None,
+      add_editor_ids=None):
+    # type: (int, str, str, str, bool, str, int, Collection[int]) -> None
+    """Update the given hotlist.
+
+    If a new value is None, the value does not get updated.
+
+    Args:
+      hotlist_id: hotlist_id of the hotlist to update.
+      hotlist_name: proposed new name for the hotlist.
+      summary: new summary for the hotlist.
+      description: new description for the hotlist.
+      is_private: true if hotlist should be updated to private.
+      default_col_spec: new default columns for hotlist list view.
+      owner_id: User id of the new owner.
+      add_editor_ids: User ids to add as editors.
+
+    Raises:
+      InputException: The given hotlist_id is None or proposed new name is not
+        a valid hotlist name.
+      NoSuchHotlistException: There is no hotlist with the given ID.
+      PermissionException: The logged-in user is not allowed to update
+        this hotlist's settings.
+      NoSuchUserException: Some proposed editors or owner were not found.
+      HotlistAlreadyExists: The (proposed new) hotlist owner already owns a
+        hotlist with the same (proposed) name.
+    """
+    hotlist = self.services.features.GetHotlist(
+        self.mc.cnxn, hotlist_id, use_cache=False)
+    if not permissions.CanAdministerHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist):
+      raise permissions.PermissionException(
+          'User is not allowed to update hotlist settings.')
+
+    if hotlist.name == hotlist_name:
+      hotlist_name = None
+    if hotlist.owner_ids[0] == owner_id:
+      owner_id = None
+
+    if hotlist_name and not framework_bizobj.IsValidHotlistName(hotlist_name):
+      raise exceptions.InputException(
+          '"%s" is not a valid hotlist name' % hotlist_name)
+
+    # Check (new) owner does not already own a hotlist with the (new) name.
+    if hotlist_name or owner_id:
+      owner_ids = [owner_id] if owner_id else None
+      if self.services.features.LookupHotlistIDs(
+          self.mc.cnxn, [hotlist_name or hotlist.name],
+          owner_ids or hotlist.owner_ids):
+        raise features_svc.HotlistAlreadyExists(
+            'User already owns a hotlist with name %s' %
+            hotlist_name or hotlist.name)
+
+    # Filter out existing editors and users that will be added as owner
+    # or is the current owner.
+    next_owner_id = owner_id or hotlist.owner_ids[0]
+    if add_editor_ids:
+      new_editor_ids_set = {user_id for user_id in add_editor_ids if
+                            user_id not in hotlist.editor_ids and
+                            user_id != next_owner_id}
+      add_editor_ids = list(new_editor_ids_set)
+
+    # Validate user change requests.
+    user_ids = []
+    if add_editor_ids:
+      user_ids.extend(add_editor_ids)
+    else:
+      add_editor_ids = None
+    if owner_id:
+      user_ids.append(owner_id)
+    if user_ids:
+      self.services.user.LookupUserEmails(self.mc.cnxn, user_ids)
+
+    # Check for other no-op changes.
+    if summary == hotlist.summary:
+      summary = None
+    if description == hotlist.description:
+      description = None
+    if is_private == hotlist.is_private:
+      is_private = None
+    if default_col_spec == hotlist.default_col_spec:
+      default_col_spec = None
+
+    if ([hotlist_name, summary, description, is_private, default_col_spec,
+         owner_id, add_editor_ids] ==
+        [None, None, None, None, None, None, None]):
+      logging.info('No updates given')
+      return
+
+    if (summary is not None) and (not summary):
+      raise exceptions.InputException('Hotlist cannot have an empty summary.')
+    if (description is not None) and (not description):
+      raise exceptions.InputException(
+          'Hotlist cannot have an empty description.')
+    if default_col_spec is not None and not framework_bizobj.IsValidColumnSpec(
+        default_col_spec):
+      raise exceptions.InputException(
+          '"%s" is not a valid column spec' % default_col_spec)
+
+    self.services.features.UpdateHotlist(
+        self.mc.cnxn, hotlist_id, name=hotlist_name, summary=summary,
+        description=description, is_private=is_private,
+        default_col_spec=default_col_spec, owner_id=owner_id,
+        add_editor_ids=add_editor_ids)
+
+  # TODO(crbug/monorail/7104): delete UpdateHotlistRoles.
+
+  def GetHotlist(self, hotlist_id, use_cache=True):
+    # int, Optional[Boolean] -> Hotlist
+    """Return the specified hotlist.
+
+    Args:
+      hotlist_id: int hotlist_id of the hotlist to retrieve.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      The specified hotlist.
+
+    Raises:
+      NoSuchHotlistException: There is no hotlist with that ID.
+      PermissionException: The user is not allowed to view the hotlist.
+    """
+    if hotlist_id is None:
+      raise exceptions.InputException('No hotlist specified')
+
+    with self.mc.profiler.Phase('getting hotlist %r' % hotlist_id):
+      hotlist = self.services.features.GetHotlist(
+          self.mc.cnxn, hotlist_id, use_cache=use_cache)
+    self._AssertUserCanViewHotlist(hotlist)
+    return hotlist
+
+  # TODO(crbug/monorail/7104): Remove group_by_spec argument and pre-pend
+  # values to sort_spec.
+  def ListHotlistItems(self, hotlist_id, max_items, start, can, sort_spec,
+                       group_by_spec, use_cache=True):
+    # type: (int, int, int, int, str, str, bool) -> ListResult
+    """Return a list of HotlistItems for the given hotlist that
+       are visible by the user.
+
+    Args:
+      hotlist_id: int hotlist_id of the hotlist.
+      max_items: int the maximum number of HotlistItems we want to return.
+      start: int start position in the total sorted items.
+      can: int "canned_query" number to scope the visible issues.
+      sort_spec: string that lists the sort order.
+      group_by_spec: string that lists the grouping order.
+      use_cache: set to false when doing read-modify-write.
+
+    Returns:
+      A work_env.ListResult namedtuple.
+
+    Raises:
+      NoSuchHotlistException: There is no hotlist with that ID.
+      InputException: `max_items` or `start` are negative values.
+      PermissionException: The user is not allowed to view the hotlist.
+    """
+    hotlist = self.GetHotlist(hotlist_id, use_cache=use_cache)
+    if start < 0:
+      raise exceptions.InputException('Invalid `start`: %d' % start)
+    if max_items < 0:
+      raise exceptions.InputException('Invalid `max_items`: %d' % max_items)
+
+    hotlist_issues = self.services.issue.GetIssues(
+        self.mc.cnxn, [item.issue_id for item in hotlist.items])
+    project_ids = hotlist_helpers.GetAllProjectsOfIssues(hotlist_issues)
+    config_list = hotlist_helpers.GetAllConfigsOfProjects(
+        self.mc.cnxn, project_ids, self.services)
+    harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list)
+
+    (sorted_issues, _hotlist_items_context,
+     _users_by_id) = hotlist_helpers.GetSortedHotlistIssues(
+        self.mc.cnxn, hotlist.items, hotlist_issues, self.mc.auth, can,
+        sort_spec, group_by_spec, harmonized_config, self.services,
+        self.mc.profiler)
+
+
+    end = start + max_items
+    visible_issues = sorted_issues[start:end]
+    hotlist_items_dict = {item.issue_id: item for item in hotlist.items}
+    visible_hotlist_items = [hotlist_items_dict.get(issue.issue_id) for
+                            issue in visible_issues]
+
+    next_start = None
+    if end < len(sorted_issues):
+      next_start = end
+    return ListResult(visible_hotlist_items, next_start)
+
+  def TransferHotlistOwnership(self, hotlist_id, new_owner_id, remain_editor,
+                               use_cache=True, commit=True):
+    """Transfer ownership of hotlist from current owner to new_owner.
+
+    Args:
+      hotlist_id: int hotlist_id of the hotlist we want to transfer
+      new_owner_id: user_id of the new owner
+      remain_editor: True if the old owner should remain on the hotlist as
+        editor.
+      use_cache: set to false when doing read-modify-write.
+      commit: True, if changes should be committed.
+
+    Raises:
+      NoSuchHotlistException: There is not hotlist with the given ID.
+      PermissionException: The logged-in user is not allowed to change ownership
+        of the hotlist.
+      InputException: The proposed new owner already owns a hotlist with the
+        same name.
+    """
+    hotlist = self.services.features.GetHotlist(
+        self.mc.cnxn, hotlist_id, use_cache=use_cache)
+    edit_permitted = permissions.CanAdministerHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist)
+    if not edit_permitted:
+      raise permissions.PermissionException(
+          'User is not allowed to update hotlist members.')
+
+    if self.services.features.LookupHotlistIDs(
+        self.mc.cnxn, [hotlist.name], [new_owner_id]):
+      raise exceptions.InputException(
+          'Proposed new owner already owns a hotlist with this name.')
+
+    self.services.features.TransferHotlistOwnership(
+        self.mc.cnxn, hotlist, new_owner_id, remain_editor, commit=commit)
+
+  def RemoveHotlistEditors(self, hotlist_id, remove_editor_ids, use_cache=True):
+    """Removes editors in a hotlist.
+
+    Args:
+      hotlist_id: the id of the hotlist we want to update
+      remove_editor_ids: list of user_ids to remove from hotlist editors
+
+    Raises:
+      NoSuchHotlistException: There is not hotlist with the given ID.
+      PermissionException: The logged-in user is not allowed to administer the
+        hotlist.
+      InputException: The users being removed are not editors in the hotlist.
+    """
+    hotlist = self.services.features.GetHotlist(
+        self.mc.cnxn, hotlist_id, use_cache=use_cache)
+    edit_permitted = permissions.CanAdministerHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist)
+
+    # check if user is only removing themselves from the hotlist.
+    # removing linked accounts is allowed but users cannot remove groups
+    # they are part of from hotlists.
+    user_or_linked_ids = (
+        self.mc.auth.user_pb.linked_child_ids + [self.mc.auth.user_id])
+    if self.mc.auth.user_pb.linked_parent_id:
+      user_or_linked_ids.append(self.mc.auth.user_pb.linked_parent_id)
+    removing_self_only = set(remove_editor_ids).issubset(
+        set(user_or_linked_ids))
+
+    if not removing_self_only and not edit_permitted:
+      raise permissions.PermissionException(
+          'User is not allowed to remove editors')
+
+    if not set(remove_editor_ids).issubset(set(hotlist.editor_ids)):
+      raise exceptions.InputException(
+          'Cannot remove users who are not hotlist editors.')
+
+    self.services.features.RemoveHotlistEditors(
+        self.mc.cnxn, hotlist_id, remove_editor_ids)
+
+  def DeleteHotlist(self, hotlist_id):
+    """Delete the given hotlist from the DB.
+
+    Args:
+      hotlist_id (int): The id of the hotlist to delete.
+
+    Raises:
+      NoSuchHotlistException: There is not hotlist with the given ID.
+      PermissionException: The logged-in user is not allowed to
+        delete the hotlist.
+    """
+    hotlist = self.services.features.GetHotlist(
+        self.mc.cnxn, hotlist_id, use_cache=False)
+    edit_permitted = permissions.CanAdministerHotlist(
+        self.mc.auth.effective_ids, self.mc.perms, hotlist)
+    if not edit_permitted:
+      raise permissions.PermissionException(
+          'User is not allowed to delete hotlist')
+
+    self.services.features.ExpungeHotlists(
+        self.mc.cnxn, [hotlist.hotlist_id], self.services.hotlist_star,
+        self.services.user,  self.services.chart)
+
+  def ListHotlistsByUser(self, user_id):
+    """Return the hotlists for the given user.
+
+    Args:
+      user_id (int): The id of the user to query.
+
+    Returns:
+      The hotlists for the given user.
+    """
+    if user_id is None:
+      raise exceptions.InputException('No user specified')
+
+    with self.mc.profiler.Phase('querying hotlists for user %r' % user_id):
+      hotlists = self.services.features.GetHotlistsByUserID(
+          self.mc.cnxn, user_id)
+
+    # Filter the hotlists that the currently authenticated user cannot see.
+    result = [
+        hotlist
+        for hotlist in hotlists
+        if permissions.CanViewHotlist(
+            self.mc.auth.effective_ids, self.mc.perms, hotlist)]
+    return result
+
+  def ListHotlistsByIssue(self, issue_id):
+    """Return the hotlists the given issue is part of.
+
+    Args:
+      issue_id (int): The id of the issue to query.
+
+    Returns:
+      The hotlists the given issue is part of.
+    """
+    # Check that the issue exists and the user has permission to see it.
+    self.GetIssue(issue_id)
+
+    with self.mc.profiler.Phase('querying hotlists for issue %r' % issue_id):
+      hotlists = self.services.features.GetHotlistsByIssueID(
+          self.mc.cnxn, issue_id)
+
+    # Filter the hotlists that the currently authenticated user cannot see.
+    result = [
+        hotlist
+        for hotlist in hotlists
+        if permissions.CanViewHotlist(
+            self.mc.auth.effective_ids, self.mc.perms, hotlist)]
+    return result
+
+  def ListRecentlyVisitedHotlists(self):
+    """Return the recently visited hotlists for the logged in user.
+
+    Returns:
+      The recently visited hotlists for the given user, or an empty list if no
+      user is logged in.
+    """
+    if not self.mc.auth.user_id:
+      return []
+
+    with self.mc.profiler.Phase(
+        'get recently visited hotlists for user %r' % self.mc.auth.user_id):
+      hotlist_ids = self.services.user.GetRecentlyVisitedHotlists(
+          self.mc.cnxn, self.mc.auth.user_id)
+      hotlists_by_id = self.services.features.GetHotlists(
+          self.mc.cnxn, hotlist_ids)
+      hotlists = [hotlists_by_id[hotlist_id] for hotlist_id in hotlist_ids]
+
+    # Filter the hotlists that the currently authenticated user cannot see.
+    # It might be that some of the hotlists have become private since the user
+    # last visited them, or the user has lost access for other reasons.
+    result = [
+        hotlist
+        for hotlist in hotlists
+        if permissions.CanViewHotlist(
+            self.mc.auth.effective_ids, self.mc.perms, hotlist)]
+    return result
+
+  def ListStarredHotlists(self):
+    """Return the starred hotlists for the logged in user.
+
+    Returns:
+      The starred hotlists for the logged in user.
+    """
+    if not self.mc.auth.user_id:
+      return []
+
+    with self.mc.profiler.Phase(
+        'get starred hotlists for user %r' % self.mc.auth.user_id):
+      hotlist_ids = self.services.hotlist_star.LookupStarredItemIDs(
+          self.mc.cnxn, self.mc.auth.user_id)
+      hotlists_by_id, _ = self.services.features.GetHotlistsByID(
+          self.mc.cnxn, hotlist_ids)
+      hotlists = [hotlists_by_id[hotlist_id] for hotlist_id in hotlist_ids]
+
+    # Filter the hotlists that the currently authenticated user cannot see.
+    # It might be that some of the hotlists have become private since the user
+    # starred them, or the user has lost access for other reasons.
+    result = [
+        hotlist
+        for hotlist in hotlists
+        if permissions.CanViewHotlist(
+            self.mc.auth.effective_ids, self.mc.perms, hotlist)]
+    return result
+
+  def StarHotlist(self, hotlist_id, starred):
+    """Star or unstar the specified hotlist.
+
+    Args:
+      hotlist_id: int ID of the hotlist to star/unstar.
+      starred: true to add a star, false to remove it.
+
+    Returns:
+      Nothing.
+
+    Raises:
+      NoSuchHotlistException: There is no hotlist with that ID.
+    """
+    if hotlist_id is None:
+      raise exceptions.InputException('No hotlist specified')
+
+    if not self.mc.auth.user_id:
+      raise exceptions.InputException('No current user specified')
+
+    with self.mc.profiler.Phase('(un)starring hotlist %r' % hotlist_id):
+      # Make sure the hotlist exists and user has permission to see it.
+      self.GetHotlist(hotlist_id)
+      self.services.hotlist_star.SetStar(
+          self.mc.cnxn, hotlist_id, self.mc.auth.user_id, starred)
+
+  def IsHotlistStarred(self, hotlist_id):
+    """Return True if the current hotlist has starred the given hotlist.
+
+    Args:
+      hotlist_id: int ID of the hotlist to check.
+
+    Returns:
+      True if starred.
+
+    Raises:
+      NoSuchHotlistException: There is no hotlist with that ID.
+    """
+    if hotlist_id is None:
+      raise exceptions.InputException('No hotlist specified')
+
+    if not self.mc.auth.user_id:
+      return False
+
+    with self.mc.profiler.Phase('checking hotlist star %r' % hotlist_id):
+      # Make sure the hotlist exists and user has permission to see it.
+      self.GetHotlist(hotlist_id)
+      return self.services.hotlist_star.IsItemStarredBy(
+        self.mc.cnxn, hotlist_id, self.mc.auth.user_id)
+
+  def GetHotlistStarCount(self, hotlist_id):
+    """Return the number of times the hotlist has been starred.
+
+    Args:
+      hotlist_id: int ID of the hotlist to check.
+
+    Returns:
+      The number of times the hotlist has been starred.
+
+    Raises:
+      NoSuchHotlistException: There is no hotlist with that ID.
+    """
+    if hotlist_id is None:
+      raise exceptions.InputException('No hotlist specified')
+
+    with self.mc.profiler.Phase('counting stars for hotlist %r' % hotlist_id):
+      # Make sure the hotlist exists and user has permission to see it.
+      self.GetHotlist(hotlist_id)
+      return self.services.hotlist_star.CountItemStars(self.mc.cnxn, hotlist_id)
+
+  def CheckHotlistName(self, name):
+    """Check that a hotlist name is valid and not already in use.
+
+    Args:
+      name: str the hotlist name to check.
+
+    Returns:
+      None if the user can create a hotlist with that name, or a string with the
+      reason the name can't be used.
+
+    Raises:
+      InputException: The user is not signed in.
+    """
+    if not self.mc.auth.user_id:
+      raise exceptions.InputException('No current user specified')
+
+    with self.mc.profiler.Phase('checking hotlist name: %r' % name):
+      if not framework_bizobj.IsValidHotlistName(name):
+        return '"%s" is not a valid hotlist name.' % name
+      if self.services.features.LookupHotlistIDs(
+          self.mc.cnxn, [name], [self.mc.auth.user_id]):
+        return 'There is already a hotlist with that name.'
+
+    return None
+
+  def RemoveIssuesFromHotlists(self, hotlist_ids, issue_ids):
+    """Remove the issues given in issue_ids from the given hotlists.
+
+    Args:
+      hotlist_ids: a list of hotlist ids to remove the issues from.
+      issue_ids: a list of issue_ids to be removed.
+
+    Raises:
+      PermissionException: The user has no permission to edit the hotlist.
+      NoSuchHotlistException: One of the hotlist ids was not found.
+    """
+    for hotlist_id in hotlist_ids:
+      self._AssertUserCanEditHotlist(self.GetHotlist(hotlist_id))
+
+    with self.mc.profiler.Phase(
+        'Removing issues %r from hotlists %r' % (issue_ids, hotlist_ids)):
+      self.services.features.RemoveIssuesFromHotlists(
+          self.mc.cnxn, hotlist_ids, issue_ids, self.services.issue,
+          self.services.chart)
+
+  def AddIssuesToHotlists(self, hotlist_ids, issue_ids, note):
+    """Add the issues given in issue_ids to the given hotlists.
+
+    Args:
+      hotlist_ids: a list of hotlist ids to add the issues to.
+      issue_ids: a list of issue_ids to be added.
+      note: a string with a message to record along with the issues.
+
+    Raises:
+      PermissionException: The user has no permission to edit the hotlist.
+      NoSuchHotlistException: One of the hotlist ids was not found.
+    """
+    for hotlist_id in hotlist_ids:
+      self._AssertUserCanEditHotlist(self.GetHotlist(hotlist_id))
+
+    # GetIssuesDict checks that the user can view all issues
+    self.GetIssuesDict(issue_ids)
+
+    added_tuples = [
+        (issue_id, self.mc.auth.user_id, int(time.time()), note)
+        for issue_id in issue_ids]
+
+    with self.mc.profiler.Phase(
+        'Removing issues %r from hotlists %r' % (issue_ids, hotlist_ids)):
+      self.services.features.AddIssuesToHotlists(
+          self.mc.cnxn, hotlist_ids, added_tuples, self.services.issue,
+          self.services.chart)
+
+  # TODO(crbug/monorai/7104): RemoveHotlistItems and RerankHotlistItems should
+  # replace RemoveIssuesFromHotlist, AddIssuesToHotlists,
+  # RemoveIssuesFromHotlists.
+  # The latter 3 methods are still used in v0 API paths and should be removed
+  # once those v0 API methods are removed.
+  def RemoveHotlistItems(self, hotlist_id, remove_issue_ids):
+    # type: (int, Collection[int]) -> None
+    """Remove given issues from a hotlist.
+
+    Args:
+      hotlist_id: A hotlist ID of the hotlist to remove issues from.
+      remove_issue_ids: A list of issue IDs that belong to HotlistItems
+        we want to remove from the hotlist.
+
+    Raises:
+      NoSuchHotlistException: If the hotlist is not found.
+      NoSuchIssueException: if an Issue is not found for a given
+        remove_issue_id.
+      PermissionException: If the user lacks permissions to edit the hotlist or
+        view all the given issues.
+      InputException: If there are ids in `remove_issue_ids` that do not exist
+        in the hotlist.
+    """
+    hotlist = self.GetHotlist(hotlist_id)
+    self._AssertUserCanEditHotlist(hotlist)
+    if not remove_issue_ids:
+      raise exceptions.InputException('`remove_issue_ids` empty.')
+
+    item_issue_ids = {item.issue_id for item in hotlist.items}
+    if not (set(remove_issue_ids).issubset(item_issue_ids)):
+      raise exceptions.InputException('item(s) not found in hotlist.')
+
+    # Raise exception for un-viewable or not found item_issue_ids.
+    self.GetIssuesDict(item_issue_ids)
+
+    self.services.features.UpdateHotlistIssues(
+        self.mc.cnxn, hotlist_id, [], remove_issue_ids, self.services.issue,
+        self.services.chart)
+
+  def AddHotlistItems(self, hotlist_id, new_issue_ids, target_position):
+    # type: (int, Sequence[int], int) -> None
+    """Add given issues to a hotlist.
+
+    Args:
+      hotlist_id: A hotlist ID of the hotlist to add issues to.
+      new_issue_ids: A list of issue IDs that should belong to new
+        HotlistItems added to the hotlist. HotlistItems will be added
+        in the same order the IDs are given in. If some HotlistItems already
+        exist in the Hotlist, they will not be moved.
+      target_position: The index, starting at 0, of the new position the
+        first issue in new_issue_ids should have. This value cannot be greater
+        than (# of current hotlist.items).
+
+    Raises:
+      PermissionException: If the user lacks permissions to edit the hotlist or
+        view all the given issues.
+      NoSuchHotlistException: If the hotlist is not found.
+      NoSuchIssueException: If an Issue is not found for a given new_issue_id.
+      InputException: If the target_position or new_issue_ids are not valid.
+    """
+    hotlist = self.GetHotlist(hotlist_id)
+    self._AssertUserCanEditHotlist(hotlist)
+    if not new_issue_ids:
+      raise exceptions.InputException('no new issues given to add.')
+
+    item_issue_ids = {item.issue_id for item in hotlist.items}
+    confirmed_new_issue_ids = set(new_issue_ids).difference(item_issue_ids)
+
+    # Raise exception for un-viewable or not found item_issue_ids.
+    self.GetIssuesDict(item_issue_ids)
+
+    if confirmed_new_issue_ids:
+      changed_items = self._GetChangedHotlistItems(
+          hotlist, list(confirmed_new_issue_ids), target_position)
+      self.services.features.UpdateHotlistIssues(
+          self.mc.cnxn, hotlist_id, changed_items, [], self.services.issue,
+          self.services.chart)
+
+  def RerankHotlistItems(self, hotlist_id, moved_issue_ids, target_position):
+    # type: (int, list(int), int) -> Hotlist
+    """Rerank HotlistItems of a Hotlist.
+
+      This method reranks existing hotlist items to the given target_position.
+        e.g. For a hotlist with items (a, b, c, d, e), if moved_issue_ids were
+        [e.issue_id, c.issue_id] and target_position were 0,
+        the hotlist items would be reranked as (e, c, a, b, d).
+
+    Args:
+      hotlist_id: A hotlist ID of the hotlist to rerank.
+      moved_issue_ids: A list of issue IDs in the hotlist, to be moved
+        together, in the order they should have after the reranking.
+      target_position: The index, starting at 0, of the new position the
+        first issue in moved_issue_ids should have. This value cannot be greater
+        than (# of current hotlist.items not being reranked).
+
+    Returns:
+      The updated hotlist.
+
+    Raises:
+      PermissionException: If the user lacks permissions to rerank the hotlist
+        or view all the given issues.
+      NoSuchHotlistException: If the hotlist is not found.
+      NoSuchIssueException: If an Issue is not found for a given moved_issue_id.
+      InputException: If the target_position or moved_issue_ids are not valid.
+    """
+    hotlist = self.GetHotlist(hotlist_id)
+    self._AssertUserCanEditHotlist(hotlist)
+    if not moved_issue_ids:
+      raise exceptions.InputException('`moved_issue_ids` empty.')
+
+    item_issue_ids = {item.issue_id for item in hotlist.items}
+    if not (set(moved_issue_ids).issubset(item_issue_ids)):
+      raise exceptions.InputException('item(s) not found in hotlist.')
+
+    # Raise exception for un-viewable or not found item_issue_ids.
+    self.GetIssuesDict(item_issue_ids)
+    changed_items = self._GetChangedHotlistItems(
+        hotlist, moved_issue_ids, target_position)
+
+    if changed_items:
+      self.services.features.UpdateHotlistIssues(
+          self.mc.cnxn, hotlist_id, changed_items, [], self.services.issue,
+          self.services.chart)
+
+    return self.GetHotlist(hotlist.hotlist_id)
+
+  def _GetChangedHotlistItems(self, hotlist, moved_issue_ids, target_position):
+    # type: (Hotlist, Sequence(int), int) -> Hotlist
+    """Returns HotlistItems that are changed after moving existing/new issues.
+
+      This returns the list of new HotlistItems and existing HotlistItems
+      with updated ranks as a result of moving the given issues to the given
+      target_position. This list may include HotlistItems whose ranks' must be
+      changed as a result of the `moved_issue_ids`.
+
+    Args:
+      hotlist: The hotlist that owns the HotlistItems.
+      moved_issue_ids: A sequence of issue IDs for new or existing items of the
+        Hotlist, to be moved together, in the order they should have after
+        the change.
+      target_position: The index, starting at 0, of the new position the
+        first issue in moved_issue_ids should have. This value cannot be greater
+        than (# of current hotlist.items not being reranked).
+
+    Returns:
+      The updated hotlist.
+
+    Raises:
+      PermissionException: If the user lacks permissions to rerank the hotlist.
+      NoSuchHotlistException: If the hotlist is not found.
+      InputException: If the target_position or moved_issue_ids are not valid.
+    """
+    # List[Tuple[issue_id, new_rank]]
+    changed_item_ranks = rerank_helpers.GetHotlistRerankChanges(
+        hotlist.items, moved_issue_ids, target_position)
+
+    items_by_id = {item.issue_id: item for item in hotlist.items}
+    changed_items = []
+    current_time = int(time.time())
+    for issue_id, rank in changed_item_ranks:
+      # Get existing item to update or create new item.
+      item = items_by_id.get(
+          issue_id,
+          features_pb2.Hotlist.HotlistItem(
+              issue_id=issue_id,
+              adder_id=self.mc.auth.user_id,
+              date_added=current_time))
+      item.rank = rank
+      changed_items.append(item)
+
+    return changed_items
+
+  # TODO(crbug/monorail/7031): Remove this method
+  # and corresponding v0 prpc method.
+  def RerankHotlistIssues(self, hotlist_id, moved_ids, target_id, split_above):
+    """Rerank the moved issues for the hotlist.
+
+    Args:
+      hotlist_id: an int with the id of the hotlist.
+      moved_ids: The id of the issues to move.
+      target_id: the id of the issue to move the issues to.
+      split_above: True if moved issues should be moved before the target issue.
+    """
+    hotlist = self.GetHotlist(hotlist_id)
+    self._AssertUserCanEditHotlist(hotlist)
+    hotlist_issue_ids = [item.issue_id for item in hotlist.items]
+    if not set(moved_ids).issubset(set(hotlist_issue_ids)):
+      raise exceptions.InputException('The issue to move is not in the hotlist')
+    if target_id not in hotlist_issue_ids:
+      raise exceptions.InputException('The target issue is not in the hotlist.')
+
+    phase_name = 'Moving issues %r %s issue %d.' % (
+        moved_ids, 'above' if split_above else 'below', target_id)
+    with self.mc.profiler.Phase(phase_name):
+      lower, higher = features_bizobj.SplitHotlistIssueRanks(
+          target_id, split_above,
+          [(item.issue_id, item.rank) for item in hotlist.items if
+           item.issue_id not in moved_ids])
+      rank_changes = rerank_helpers.GetInsertRankings(lower, higher, moved_ids)
+      if rank_changes:
+        relations_to_change = {
+            issue_id: rank for issue_id, rank in rank_changes}
+        self.services.features.UpdateHotlistItemsFields(
+            self.mc.cnxn, hotlist_id, new_ranks=relations_to_change)
+
+  def UpdateHotlistIssueNote(self, hotlist_id, issue_id, note):
+    """Update the given issue of the given hotlist with the given note.
+
+    Args:
+      hotlist_id: an int with the id of the hotlist.
+      issue_id: an int with the id of the issue.
+      note: a string with a message to record for the given issue.
+    Raises:
+      PermissionException: The user has no permission to edit the hotlist.
+      NoSuchHotlistException: The hotlist id was not found.
+      InputException: The issue is not part of the hotlist.
+    """
+    # Make sure the hotlist exists and we have permission to see and edit it.
+    hotlist = self.GetHotlist(hotlist_id)
+    self._AssertUserCanEditHotlist(hotlist)
+
+    # Make sure the issue exists and we have permission to see it.
+    self.GetIssue(issue_id)
+
+    # Make sure the issue belongs to the hotlist.
+    if not any(item.issue_id == issue_id for item in hotlist.items):
+      raise exceptions.InputException('The issue is not part of the hotlist.')
+
+    with self.mc.profiler.Phase(
+        'Editing note for issue %s in hotlist %s' % (issue_id, hotlist_id)):
+      new_notes = {issue_id: note}
+      self.services.features.UpdateHotlistItemsFields(
+          self.mc.cnxn, hotlist_id, new_notes=new_notes)
+
+  def expungeUsersFromStars(self, user_ids):
+    """Wipes any starred user or user's stars from all star services.
+
+    This method will not commit the operation. This method will not
+    make changes to in-memory data.
+    """
+
+    self.services.project_star.ExpungeStarsByUsers(self.mc.cnxn, user_ids)
+    self.services.issue_star.ExpungeStarsByUsers(self.mc.cnxn, user_ids)
+    self.services.hotlist_star.ExpungeStarsByUsers(self.mc.cnxn, user_ids)
+    self.services.user_star.ExpungeStarsByUsers(self.mc.cnxn, user_ids)
+    for user_id in user_ids:
+      self.services.user_star.ExpungeStars(self.mc.cnxn, user_id, commit=False)
+
+  # Permissions
+
+  # ListFooPermission methods will return the list of permissions in addition to
+  # the permission to "VIEW",
+  # that the logged in user has for a given resource_id's resource Foo.
+  # If the user cannot view Foo, PermissionException will be raised.
+  # Not all resources will have predefined lists of permissions
+  # (e.g permissions.HOTLIST_OWNER_PERMISSIONS)
+  # For most cases, the list of permissions will be created within the
+  # ListFooPermissions method.
+
+  def ListHotlistPermissions(self, hotlist_id):
+    # type: (int) -> List(str)
+    """Return the list of permissions the current user has for the hotlist."""
+    # Permission to view checked in GetHotlist()
+    hotlist = self.GetHotlist(hotlist_id)
+    if permissions.CanAdministerHotlist(self.mc.auth.effective_ids,
+                                        self.mc.perms, hotlist):
+      return permissions.HOTLIST_OWNER_PERMISSIONS
+    if permissions.CanEditHotlist(self.mc.auth.effective_ids, self.mc.perms,
+                                  hotlist):
+      return permissions.HOTLIST_EDITOR_PERMISSIONS
+    return []
+
+  def ListFieldDefPermissions(self, field_id, project_id):
+    # type:(int, int) -> List[str]
+    """Return the list of permissions the current user has for the fieldDef."""
+    project = self.GetProject(project_id)
+    # TODO(crbug/monorail/7614): The line below was added temporarily while this
+    # bug is fixed.
+    self.mc.LookupLoggedInUserPerms(project)
+    field = self.GetFieldDef(field_id, project)
+    if permissions.CanEditFieldDef(self.mc.auth.effective_ids, self.mc.perms,
+                                   project, field):
+      return [permissions.EDIT_FIELD_DEF, permissions.EDIT_FIELD_DEF_VALUE]
+    if permissions.CanEditValueForFieldDef(self.mc.auth.effective_ids,
+                                           self.mc.perms, project, field):
+      return [permissions.EDIT_FIELD_DEF_VALUE]
+    return []
