diff --git a/api/v3/converters.py b/api/v3/converters.py
new file mode 100644
index 0000000..60aebd7
--- /dev/null
+++ b/api/v3/converters.py
@@ -0,0 +1,1979 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import itertools
+import logging
+import time
+
+from google.protobuf import timestamp_pb2
+
+from api import resource_name_converters as rnc
+from api.v3.api_proto import feature_objects_pb2
+from api.v3.api_proto import issues_pb2
+from api.v3.api_proto import issue_objects_pb2
+from api.v3.api_proto import project_objects_pb2
+from api.v3.api_proto import user_objects_pb2
+
+from framework import exceptions
+from framework import filecontent
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import framework_helpers
+from proto import tracker_pb2
+from project import project_helpers
+from tracker import attachment_helpers
+from tracker import field_helpers
+from tracker import tracker_bizobj as tbo
+from tracker import tracker_helpers
+
+Choice = project_objects_pb2.FieldDef.EnumTypeSettings.Choice
+
+# Ingest/convert dicts for ApprovalStatus.
+_V3_APPROVAL_STATUS = issue_objects_pb2.ApprovalValue.ApprovalStatus.Value
+_APPROVAL_STATUS_INGEST = {
+  _V3_APPROVAL_STATUS('APPROVAL_STATUS_UNSPECIFIED'): None,
+  _V3_APPROVAL_STATUS('NOT_SET'): tracker_pb2.ApprovalStatus.NOT_SET,
+  _V3_APPROVAL_STATUS('NEEDS_REVIEW'): tracker_pb2.ApprovalStatus.NEEDS_REVIEW,
+  _V3_APPROVAL_STATUS('NA'): tracker_pb2.ApprovalStatus.NA,
+  _V3_APPROVAL_STATUS('REVIEW_REQUESTED'):
+      tracker_pb2.ApprovalStatus.REVIEW_REQUESTED,
+  _V3_APPROVAL_STATUS('REVIEW_STARTED'):
+      tracker_pb2.ApprovalStatus.REVIEW_STARTED,
+  _V3_APPROVAL_STATUS('NEED_INFO'): tracker_pb2.ApprovalStatus.NEED_INFO,
+  _V3_APPROVAL_STATUS('APPROVED'): tracker_pb2.ApprovalStatus.APPROVED,
+  _V3_APPROVAL_STATUS('NOT_APPROVED'): tracker_pb2.ApprovalStatus.NOT_APPROVED,
+}
+_APPROVAL_STATUS_CONVERT = {
+  val: key for key, val in _APPROVAL_STATUS_INGEST.items()}
+
+
+class Converter(object):
+  """Class to manage converting objects between the API and backend layer."""
+
+  def __init__(self, mc, services):
+    # type: (MonorailContext, Services) -> Converter
+    """Create a Converter with the given MonorailContext and Services.
+
+    Args:
+      mc: MonorailContext object containing the MonorailConnection to the DB
+            and the requester's AuthData object.
+      services: Services object for connections to backend services.
+    """
+    self.cnxn = mc.cnxn
+    self.user_auth = mc.auth
+    self.services = services
+
+  # Hotlists
+
+  def ConvertHotlist(self, hotlist):
+    # type: (proto.feature_objects_pb2.Hotlist)
+    #    -> api_proto.feature_objects_pb2.Hotlist
+    """Convert a protorpc Hotlist into a protoc Hotlist."""
+
+    hotlist_resource_name = rnc.ConvertHotlistName(hotlist.hotlist_id)
+    members_by_id = rnc.ConvertUserNames(
+        hotlist.owner_ids + hotlist.editor_ids)
+    default_columns = self._ComputeIssuesListColumns(hotlist.default_col_spec)
+    if hotlist.is_private:
+      hotlist_privacy = feature_objects_pb2.Hotlist.HotlistPrivacy.Value(
+          'PRIVATE')
+    else:
+      hotlist_privacy = feature_objects_pb2.Hotlist.HotlistPrivacy.Value(
+          'PUBLIC')
+
+    return feature_objects_pb2.Hotlist(
+        name=hotlist_resource_name,
+        display_name=hotlist.name,
+        owner=members_by_id.get(hotlist.owner_ids[0]),
+        editors=[
+            members_by_id.get(editor_id) for editor_id in hotlist.editor_ids
+        ],
+        summary=hotlist.summary,
+        description=hotlist.description,
+        default_columns=default_columns,
+        hotlist_privacy=hotlist_privacy)
+
+  def ConvertHotlists(self, hotlists):
+    # type: (Sequence[proto.feature_objects_pb2.Hotlist])
+    #    -> Sequence[api_proto.feature_objects_pb2.Hotlist]
+    """Convert protorpc Hotlists into protoc Hotlists."""
+    return [self.ConvertHotlist(hotlist) for hotlist in hotlists]
+
+  def ConvertHotlistItems(self, hotlist_id, items):
+    # type: (int, Sequence[proto.features_pb2.HotlistItem]) ->
+    #     Sequence[api_proto.feature_objects_pb2.Hotlist]
+    """Convert a Sequence of protorpc HotlistItems into a Sequence of protoc
+       HotlistItems.
+
+    Args:
+      hotlist_id: ID of the Hotlist the items belong to.
+      items: Sequence of HotlistItem protorpc objects.
+
+    Returns:
+      Sequence of protoc HotlistItems in the same order they are given in
+        `items`.
+      In the rare event that any issues in `items` are not found, they will be
+        omitted from the result.
+    """
+    issue_ids = [item.issue_id for item in items]
+    # Converting HotlistItemNames and IssueNames both require looking up the
+    # issues in the hotlist. However, we want to keep the code clean and
+    # readable so we keep the two processes separate.
+    resource_names_dict = rnc.ConvertHotlistItemNames(
+        self.cnxn, hotlist_id, issue_ids, self.services)
+    issue_names_dict = rnc.ConvertIssueNames(
+        self.cnxn, issue_ids, self.services)
+    adders_by_id = rnc.ConvertUserNames([item.adder_id for item in items])
+
+    # Filter out items whose issues were not found.
+    found_items = [
+        item for item in items if resource_names_dict.get(item.issue_id) and
+        issue_names_dict.get(item.issue_id)
+    ]
+    if len(items) != len(found_items):
+      found_ids = [item.issue_id for item in found_items]
+      missing_ids = [iid for iid in issue_ids if iid not in found_ids]
+      logging.info('HotlistItem issues %r not found' % missing_ids)
+
+    # Generate user friendly ranks (0, 1, 2, 3,...) that are exposed to API
+    # clients, instead of using padded ranks (1, 11, 21, 31,...).
+    sorted_ranks = sorted(item.rank for item in found_items)
+    friendly_ranks_dict = {
+        rank: friendly_rank for friendly_rank, rank in enumerate(sorted_ranks)
+    }
+
+    api_items = []
+    for item in found_items:
+      api_item = feature_objects_pb2.HotlistItem(
+          name=resource_names_dict.get(item.issue_id),
+          issue=issue_names_dict.get(item.issue_id),
+          rank=friendly_ranks_dict[item.rank],
+          adder=adders_by_id.get(item.adder_id),
+          note=item.note)
+      if item.date_added:
+        api_item.create_time.FromSeconds(item.date_added)
+      api_items.append(api_item)
+
+    return api_items
+
+  # Issues
+
+  def _ConvertComponentValues(self, issue):
+    # proto.tracker_pb2.Issue ->
+    #     Sequence[api_proto.issue_objects_pb2.Issue.ComponentValue]
+    """Convert the status string on issue into a ComponentValue."""
+    component_values = []
+    component_ids = itertools.chain(
+        issue.component_ids, issue.derived_component_ids)
+    ids_to_names = rnc.ConvertComponentDefNames(
+        self.cnxn, component_ids, issue.project_id, self.services)
+
+    for component_id in issue.component_ids:
+      if component_id in ids_to_names:
+        component_values.append(
+            issue_objects_pb2.Issue.ComponentValue(
+                component=ids_to_names[component_id],
+                derivation=issue_objects_pb2.Derivation.Value(
+                    'EXPLICIT')))
+    for derived_component_id in issue.derived_component_ids:
+      if derived_component_id in ids_to_names:
+        component_values.append(
+            issue_objects_pb2.Issue.ComponentValue(
+                component=ids_to_names[derived_component_id],
+                derivation=issue_objects_pb2.Derivation.Value('RULE')))
+
+    return component_values
+
+  def _ConvertStatusValue(self, issue):
+    # proto.tracker_pb2.Issue -> api_proto.issue_objects_pb2.Issue.StatusValue
+    """Convert the status string on issue into a StatusValue."""
+    derivation = issue_objects_pb2.Derivation.Value(
+        'DERIVATION_UNSPECIFIED')
+    if issue.status:
+      derivation = issue_objects_pb2.Derivation.Value('EXPLICIT')
+    else:
+      derivation = issue_objects_pb2.Derivation.Value('RULE')
+    return issue_objects_pb2.Issue.StatusValue(
+        status=issue.status or issue.derived_status, derivation=derivation)
+
+  def _ConvertAmendments(self, amendments, user_display_names):
+    # type: (Sequence[proto.tracker_pb2.Amendment], Mapping[int, str]) ->
+    #     Sequence[api_proto.issue_objects_pb2.Comment.Amendment]
+    """Convert protorpc Amendments to protoc Amendments.
+
+    Args:
+      amendments: the amendments to convert
+      user_display_names: map from user_id to display name for all users
+          involved in the amendments.
+
+    Returns:
+      The converted amendments.
+    """
+    results = []
+    for amendment in amendments:
+      field_name = tbo.GetAmendmentFieldName(amendment)
+      new_value = tbo.AmendmentString_New(amendment, user_display_names)
+      results.append(
+          issue_objects_pb2.Comment.Amendment(
+              field_name=field_name,
+              new_or_delta_value=new_value,
+              old_value=amendment.oldvalue))
+    return results
+
+  def _ConvertAttachments(self, attachments, project_name):
+    # type: (Sequence[proto.tracker_pb2.Attachment], str) ->
+    #     Sequence[api_proto.issue_objects_pb2.Comment.Attachment]
+    """Convert protorpc Attachments to protoc Attachments."""
+    results = []
+    for attach in attachments:
+      if attach.deleted:
+        state = issue_objects_pb2.IssueContentState.Value('DELETED')
+        size, thumbnail_uri, view_uri, download_uri = None, None, None, None
+      else:
+        state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
+        size = attach.filesize
+        download_uri = attachment_helpers.GetDownloadURL(attach.attachment_id)
+        view_uri = attachment_helpers.GetViewURL(
+            attach, download_uri, project_name)
+        thumbnail_uri = attachment_helpers.GetThumbnailURL(attach, download_uri)
+      results.append(
+          issue_objects_pb2.Comment.Attachment(
+              filename=attach.filename,
+              state=state,
+              size=size,
+              media_type=attach.mimetype,
+              thumbnail_uri=thumbnail_uri,
+              view_uri=view_uri,
+              download_uri=download_uri))
+    return results
+
+  def ConvertComments(self, issue_id, comments):
+    # type: (int, Sequence[proto.tracker_pb2.IssueComment])
+    #     -> Sequence[api_proto.issue_objects_pb2.Comment]
+    """Convert protorpc IssueComments from issue into protoc Comments."""
+    issue = self.services.issue.GetIssue(self.cnxn, issue_id)
+    users_by_id = self.services.user.GetUsersByIDs(
+        self.cnxn, tbo.UsersInvolvedInCommentList(comments))
+    (user_display_names,
+     _user_display_emails) = framework_bizobj.CreateUserDisplayNamesAndEmails(
+         self.cnxn, self.services, self.user_auth, users_by_id.values())
+    comment_names_dict = rnc.CreateCommentNames(
+        issue.local_id, issue.project_name,
+        [comment.sequence for comment in comments])
+    approval_ids = [
+        comment.approval_id
+        for comment in comments
+        if comment.approval_id is not None  # In case of a 0 approval_id.
+    ]
+    approval_ids_to_names = rnc.ConvertApprovalDefNames(
+        self.cnxn, approval_ids, issue.project_id, self.services)
+
+    converted_comments = []
+    for comment in comments:
+      if comment.is_spam:
+        state = issue_objects_pb2.IssueContentState.Value('SPAM')
+      elif comment.deleted_by:
+        state = issue_objects_pb2.IssueContentState.Value('DELETED')
+      else:
+        state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
+      comment_type = issue_objects_pb2.Comment.Type.Value('COMMENT')
+      if comment.is_description:
+        comment_type = issue_objects_pb2.Comment.Type.Value('DESCRIPTION')
+      converted_attachments = self._ConvertAttachments(
+          comment.attachments, issue.project_name)
+      converted_amendments = self._ConvertAmendments(
+          comment.amendments, user_display_names)
+      converted_comment = issue_objects_pb2.Comment(
+          name=comment_names_dict[comment.sequence],
+          state=state,
+          type=comment_type,
+          create_time=timestamp_pb2.Timestamp(seconds=comment.timestamp),
+          attachments=converted_attachments,
+          amendments=converted_amendments)
+      if comment.content:
+        converted_comment.content = comment.content
+      if comment.user_id:
+        converted_comment.commenter = rnc.ConvertUserName(comment.user_id)
+      if comment.inbound_message:
+        converted_comment.inbound_message = comment.inbound_message
+      if comment.approval_id and comment.approval_id in approval_ids_to_names:
+        converted_comment.approval = approval_ids_to_names[comment.approval_id]
+      converted_comments.append(converted_comment)
+    return converted_comments
+
+  def ConvertIssue(self, issue):
+    # type: (proto.tracker_pb2.Issue) -> api_proto.issue_objects_pb2.Issue
+    """Convert a protorpc Issue into a protoc Issue."""
+    issues = self.ConvertIssues([issue])
+    if len(issues) < 1:
+      raise exceptions.NoSuchIssueException()
+    if len(issues) > 1:
+      logging.warning('More than one converted issue returned: %s', issues)
+    return issues[0]
+
+  def ConvertIssues(self, issues):
+    # type: (Sequence[proto.tracker_pb2.Issue]) ->
+    #     Sequence[api_proto.issue_objects_pb2.Issue]
+    """Convert protorpc Issues into protoc Issues."""
+    issue_ids = [issue.issue_id for issue in issues]
+    issue_names_dict = rnc.ConvertIssueNames(
+        self.cnxn, issue_ids, self.services)
+    found_issues = [
+        issue for issue in issues if issue.issue_id in issue_names_dict
+    ]
+    converted_issues = []
+    for issue in found_issues:
+      status = self._ConvertStatusValue(issue)
+      content_state = issue_objects_pb2.IssueContentState.Value(
+          'STATE_UNSPECIFIED')
+      if issue.is_spam:
+        content_state = issue_objects_pb2.IssueContentState.Value('SPAM')
+      elif issue.deleted:
+        content_state = issue_objects_pb2.IssueContentState.Value('DELETED')
+      else:
+        content_state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
+
+      owner = None
+      # Explicit values override values derived from rules.
+      if issue.owner_id:
+        owner = issue_objects_pb2.Issue.UserValue(
+            derivation=issue_objects_pb2.Derivation.Value('EXPLICIT'),
+            user=rnc.ConvertUserName(issue.owner_id))
+      elif issue.derived_owner_id:
+        owner = issue_objects_pb2.Issue.UserValue(
+            derivation=issue_objects_pb2.Derivation.Value('RULE'),
+            user=rnc.ConvertUserName(issue.derived_owner_id))
+
+      cc_users = []
+      for cc_user_id in issue.cc_ids:
+        cc_users.append(
+            issue_objects_pb2.Issue.UserValue(
+                derivation=issue_objects_pb2.Derivation.Value('EXPLICIT'),
+                user=rnc.ConvertUserName(cc_user_id)))
+      for derived_cc_user_id in issue.derived_cc_ids:
+        cc_users.append(
+            issue_objects_pb2.Issue.UserValue(
+                derivation=issue_objects_pb2.Derivation.Value('RULE'),
+                user=rnc.ConvertUserName(derived_cc_user_id)))
+
+      labels = self.ConvertLabels(
+          issue.labels, issue.derived_labels, issue.project_id)
+      components = self._ConvertComponentValues(issue)
+      non_approval_fvs = self._GetNonApprovalFieldValues(
+          issue.field_values, issue.project_id)
+      field_values = self.ConvertFieldValues(
+          non_approval_fvs, issue.project_id, issue.phases)
+      field_values.extend(
+          self.ConvertEnumFieldValues(
+              issue.labels, issue.derived_labels, issue.project_id))
+      related_issue_ids = (
+          [issue.merged_into] + issue.blocked_on_iids + issue.blocking_iids)
+      issue_names_by_ids = rnc.ConvertIssueNames(
+          self.cnxn, related_issue_ids, self.services)
+      merged_into_issue_ref = None
+      if issue.merged_into and issue.merged_into in issue_names_by_ids:
+        merged_into_issue_ref = issue_objects_pb2.IssueRef(
+            issue=issue_names_by_ids[issue.merged_into])
+      if issue.merged_into_external:
+        merged_into_issue_ref = issue_objects_pb2.IssueRef(
+            ext_identifier=issue.merged_into_external)
+
+      blocked_on_issue_refs = [
+          issue_objects_pb2.IssueRef(issue=issue_names_by_ids[iid])
+          for iid in issue.blocked_on_iids
+          if iid in issue_names_by_ids
+      ]
+      blocked_on_issue_refs.extend(
+          issue_objects_pb2.IssueRef(
+              ext_identifier=blocked_on.ext_issue_identifier)
+          for blocked_on in issue.dangling_blocked_on_refs)
+
+      blocking_issue_refs = [
+          issue_objects_pb2.IssueRef(issue=issue_names_by_ids[iid])
+          for iid in issue.blocking_iids
+          if iid in issue_names_by_ids
+      ]
+      blocking_issue_refs.extend(
+          issue_objects_pb2.IssueRef(
+              ext_identifier=blocking.ext_issue_identifier)
+          for blocking in issue.dangling_blocking_refs)
+      # All other timestamps were set when the issue was created.
+      close_time = None
+      if issue.closed_timestamp:
+        close_time = timestamp_pb2.Timestamp(seconds=issue.closed_timestamp)
+
+      phases = self._ComputePhases(issue.phases)
+
+      result = issue_objects_pb2.Issue(
+          name=issue_names_dict[issue.issue_id],
+          summary=issue.summary,
+          state=content_state,
+          status=status,
+          reporter=rnc.ConvertUserName(issue.reporter_id),
+          owner=owner,
+          cc_users=cc_users,
+          labels=labels,
+          components=components,
+          field_values=field_values,
+          merged_into_issue_ref=merged_into_issue_ref,
+          blocked_on_issue_refs=blocked_on_issue_refs,
+          blocking_issue_refs=blocking_issue_refs,
+          create_time=timestamp_pb2.Timestamp(seconds=issue.opened_timestamp),
+          close_time=close_time,
+          modify_time=timestamp_pb2.Timestamp(seconds=issue.modified_timestamp),
+          component_modify_time=timestamp_pb2.Timestamp(
+              seconds=issue.component_modified_timestamp),
+          status_modify_time=timestamp_pb2.Timestamp(
+              seconds=issue.status_modified_timestamp),
+          owner_modify_time=timestamp_pb2.Timestamp(
+              seconds=issue.owner_modified_timestamp),
+          star_count=issue.star_count,
+          phases=phases)
+      # TODO(crbug.com/monorail/5857): Set attachment_count unconditionally
+      # after the underlying source of negative attachment counts has been
+      # resolved and database has been repaired.
+      if issue.attachment_count >= 0:
+        result.attachment_count = issue.attachment_count
+      converted_issues.append(result)
+    return converted_issues
+
+  def IngestAttachmentUploads(self, attachment_uploads):
+    # type: (Sequence[api_proto.issues_pb2.AttachmentUpload] ->
+    #     Sequence[framework_helpers.AttachmentUpload])
+    """Ingests protoc AttachmentUploads into framework_helpers.AttachUploads."""
+    ingested_uploads = []
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      for up in attachment_uploads:
+        if not up.filename or not up.content:
+          err_agg.AddErrorMessage(
+              'Uploaded atachment missing filename or content')
+        mimetype = filecontent.GuessContentTypeFromFilename(up.filename)
+        ingested_uploads.append(
+            framework_helpers.AttachmentUpload(
+                up.filename, up.content, mimetype))
+
+    return ingested_uploads
+
+  def IngestIssueDeltas(self, issue_deltas):
+    # type: (Sequence[api_proto.issues_pb2.IssueDelta]) ->
+    #     Sequence[Tuple[int, proto.tracker_pb2.IssueDelta]]
+    """Ingests protoc IssueDeltas, into protorpc IssueDeltas.
+
+    Args:
+      issue_deltas: the protoc IssueDeltas to ingest.
+
+    Returns:
+      A list of (issue_id, tracker_pb2.IssueDelta) tuples that contain
+      values found in issue_deltas, ignoring all OUTPUT_ONLY and masked
+      fields.
+
+    Raises:
+      InputException: if any fields in the approval_deltas were invalid.
+      NoSuchProjectException: if any parent projects are not found.
+      NoSuchIssueException: if any issues are not found.
+      NoSuchComponentException: if any components are not found.
+    """
+    issue_names = [delta.issue.name for delta in issue_deltas]
+    issue_ids = rnc.IngestIssueNames(self.cnxn, issue_names, self.services)
+    issues_dict, misses = self.services.issue.GetIssuesDict(
+        self.cnxn, issue_ids)
+    if misses:
+      logging.info(
+          'Issues not found for supposedly valid issue_ids: %r' % misses)
+      raise ValueError('Could not fetch some issues.')
+    configs_by_pid = self.services.config.GetProjectConfigs(
+        self.cnxn, {issue.project_id for issue in issues_dict.values()})
+
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      for api_delta in issue_deltas:
+        if not api_delta.HasField('update_mask'):
+          err_agg.AddErrorMessage(
+              '`update_mask` must be set for {} delta.', api_delta.issue.name)
+        elif not api_delta.update_mask.IsValidForDescriptor(
+            issue_objects_pb2.Issue.DESCRIPTOR):
+          err_agg.AddErrorMessage(
+              'Invalid `update_mask` for {} delta.', api_delta.issue.name)
+
+    ingested = []
+    for iid, api_delta in zip(issue_ids, issue_deltas):
+      delta = tracker_pb2.IssueDelta()
+
+      # Check non-repeated fields before MergeMessage because in an object
+      # where fields are not set and with a FieldMask applied, there is no
+      # way to tell if empty fields were explicitly listed or not listed
+      # in the FieldMask.
+      paths_set = set(api_delta.update_mask.paths)
+      if (not paths_set.isdisjoint({'status', 'status.status'}) and
+          api_delta.issue.status.status):
+        delta.status = api_delta.issue.status.status
+      elif 'status.status' in paths_set and not api_delta.issue.status.status:
+        delta.status = ''
+
+      if (not paths_set.isdisjoint({'owner', 'owner.user'}) and
+          api_delta.issue.owner.user):
+        delta.owner_id = rnc.IngestUserName(
+              self.cnxn, api_delta.issue.owner.user, self.services)
+      elif 'owner.user' in paths_set and not api_delta.issue.owner.user:
+        delta.owner_id = framework_constants.NO_USER_SPECIFIED
+
+      if 'summary' in paths_set:
+        if api_delta.issue.summary:
+          delta.summary = api_delta.issue.summary
+        else:
+          delta.summary = ''
+
+      merge_ref = api_delta.issue.merged_into_issue_ref
+      if 'merged_into_issue_ref' in paths_set:
+        if (api_delta.issue.merged_into_issue_ref.issue or
+            api_delta.issue.merged_into_issue_ref.ext_identifier):
+          ingested_ref = self._IngestIssueRef(merge_ref)
+          if isinstance(ingested_ref, tracker_pb2.DanglingIssueRef):
+            delta.merged_into_external = ingested_ref.ext_issue_identifier
+          else:
+            delta.merged_into = ingested_ref
+      elif 'merged_into_issue_ref.issue' in paths_set:
+        if api_delta.issue.merged_into_issue_ref.issue:
+          delta.merged_into = self._IngestIssueRef(merge_ref)
+        else:
+          delta.merged_into = 0
+      elif 'merged_into_issue_ref.ext_identifier' in paths_set:
+        if api_delta.issue.merged_into_issue_ref.ext_identifier:
+          ingested_ref = self._IngestIssueRef(merge_ref)
+          delta.merged_into_external = ingested_ref.ext_issue_identifier
+        else:
+          delta.merged_into_external = ''
+
+      filtered_api_issue = issue_objects_pb2.Issue()
+      api_delta.update_mask.MergeMessage(
+          api_delta.issue,
+          filtered_api_issue,
+          replace_message_field=True,
+          replace_repeated_field=True)
+
+      cc_names = [name for name in api_delta.ccs_remove] + [
+          user_value.user for user_value in filtered_api_issue.cc_users
+      ]
+      cc_ids = rnc.IngestUserNames(self.cnxn, cc_names, self.services)
+      delta.cc_ids_remove = cc_ids[:len(api_delta.ccs_remove)]
+      delta.cc_ids_add = cc_ids[len(api_delta.ccs_remove):]
+
+      comp_names = [component for component in api_delta.components_remove] + [
+          c_value.component for c_value in filtered_api_issue.components
+      ]
+      project_comp_ids = rnc.IngestComponentDefNames(
+          self.cnxn, comp_names, self.services)
+      comp_ids = [comp_id for (_pid, comp_id) in project_comp_ids]
+      delta.comp_ids_remove = comp_ids[:len(api_delta.components_remove)]
+      delta.comp_ids_add = comp_ids[len(api_delta.components_remove):]
+
+      # Added to delta below, after ShiftEnumFieldsIntoLabels.
+      labels_add = [value.label for value in filtered_api_issue.labels]
+      labels_remove = [label for label in api_delta.labels_remove]
+
+      config = configs_by_pid[issues_dict[iid].project_id]
+      fvs_add, add_enums = self._IngestFieldValues(
+          filtered_api_issue.field_values, config)
+      fvs_remove, remove_enums = self._IngestFieldValues(
+          api_delta.field_vals_remove, config)
+      field_helpers.ShiftEnumFieldsIntoLabels(
+          labels_add, labels_remove, add_enums, remove_enums, config)
+      delta.field_vals_add = fvs_add
+      delta.field_vals_remove = fvs_remove
+      delta.labels_add = labels_add
+      delta.labels_remove = labels_remove
+      assert len(add_enums) == 0  # ShiftEnumFieldsIntoLabels clears all enums.
+      assert len(remove_enums) == 0
+
+      blocked_on_iids_rm, blocked_on_dangling_rm = self._IngestIssueRefs(
+          api_delta.blocked_on_issues_remove)
+      delta.blocked_on_remove = blocked_on_iids_rm
+      delta.ext_blocked_on_remove = [
+          ref.ext_issue_identifier for ref in blocked_on_dangling_rm
+      ]
+
+      blocked_on_iids_add, blocked_on_dangling_add = self._IngestIssueRefs(
+          filtered_api_issue.blocked_on_issue_refs)
+      delta.blocked_on_add = blocked_on_iids_add
+      delta.ext_blocked_on_add = [
+          ref.ext_issue_identifier for ref in blocked_on_dangling_add
+      ]
+
+      blocking_iids_rm, blocking_dangling_rm = self._IngestIssueRefs(
+          api_delta.blocking_issues_remove)
+      delta.blocking_remove = blocking_iids_rm
+      delta.ext_blocking_remove = [
+          ref.ext_issue_identifier for ref in blocking_dangling_rm
+      ]
+
+      blocking_iids_add, blocking_dangling_add = self._IngestIssueRefs(
+          filtered_api_issue.blocking_issue_refs)
+      delta.blocking_add = blocking_iids_add
+      delta.ext_blocking_add = [
+          ref.ext_issue_identifier for ref in blocking_dangling_add
+      ]
+
+      ingested.append((iid, delta))
+
+    return ingested
+
+  def IngestApprovalDeltas(self, approval_deltas, setter_id):
+    # type: (Sequence[api_proto.issues_pb2.ApprovalDelta], int) ->
+    #     Sequence[Tuple[int, int, proto.tracker_pb2.ApprovalDelta]]
+    """Ingests protoc ApprovalDeltas into protorpc ApprovalDeltas.
+
+    Args:
+      approval_deltas: the protoc ApprovalDeltas to ingest.
+      setter_id: The ID for the user setting the deltas.
+
+    Returns:
+      Sequence of (issue_id, approval_id, ApprovalDelta) tuples in the order
+      provided. The ApprovalDeltas ignore all OUTPUT_ONLY and masked fields.
+      The tuples are "delta_specifications;" they identify one requested change.
+
+    Raises:
+      InputException: if any fields in the approval_delta protos were invalid.
+      NoSuchProjectException: if the parent project of any ApprovalValue isn't
+          found.
+      NoSuchIssueException: if the issue of any ApprovalValue isn't found.
+      NoSuchUserException: if any user value was provided with an invalid email.
+          Note that users specified by ID are not checked for existence.
+    """
+    delta_specifications = []
+    set_on = int(time.time())  # Use the same timestamp for all deltas.
+    for approval_delta in approval_deltas:
+      approval_name = approval_delta.approval_value.name
+      # TODO(crbug/monorail/8173): Aggregate errors.
+      project_id, issue_id, approval_id = rnc.IngestApprovalValueName(
+          self.cnxn, approval_name, self.services)
+
+      if not approval_delta.HasField('update_mask'):
+        raise exceptions.InputException(
+            '`update_mask` must be set for %s delta.' % approval_name)
+      elif not approval_delta.update_mask.IsValidForDescriptor(
+          issue_objects_pb2.ApprovalValue.DESCRIPTOR):
+        raise exceptions.InputException(
+            'Invalid `update_mask` for %s delta.' % approval_name)
+      filtered_value = issue_objects_pb2.ApprovalValue()
+      approval_delta.update_mask.MergeMessage(
+          approval_delta.approval_value,
+          filtered_value,
+          replace_message_field=True,
+          replace_repeated_field=True)
+      status = _APPROVAL_STATUS_INGEST[filtered_value.status]
+      # Approvers
+      # No autocreate.
+      # A user may try to remove all existing approvers [a, b] and add another
+      # approver [c]. If they mis-type `c` and we auto-create `c` instead of
+      # raising error, this would cause the ApprovalValue to be editable by no
+      # one but site admins.
+      approver_ids_add = rnc.IngestUserNames(
+          self.cnxn, filtered_value.approvers, self.services, autocreate=False)
+      approver_ids_remove = rnc.IngestUserNames(
+          self.cnxn,
+          approval_delta.approvers_remove,
+          self.services,
+          autocreate=False)
+
+      # Field Values.
+      config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+      approval_fds_by_id = {
+          fd.field_id: fd
+          for fd in config.field_defs
+          if fd.field_type is tracker_pb2.FieldTypes.APPROVAL_TYPE
+      }
+      if approval_id not in approval_fds_by_id:
+        raise exceptions.InputException(
+            'Approval not found in project for %s' % approval_name)
+
+      sub_fvs_add, add_enums = self._IngestFieldValues(
+          filtered_value.field_values, config, approval_id_filter=approval_id)
+      sub_fvs_remove, remove_enums = self._IngestFieldValues(
+          approval_delta.field_vals_remove,
+          config,
+          approval_id_filter=approval_id)
+      labels_add = []
+      labels_remove = []
+      field_helpers.ShiftEnumFieldsIntoLabels(
+          labels_add, labels_remove, add_enums, remove_enums, config)
+      assert len(add_enums) == 0  # ShiftEnumFieldsIntoLabels clears all enums.
+      assert len(remove_enums) == 0
+      delta = tbo.MakeApprovalDelta(
+          status,
+          setter_id,
+          approver_ids_add,
+          approver_ids_remove,
+          sub_fvs_add,
+          sub_fvs_remove, [],
+          labels_add,
+          labels_remove,
+          set_on=set_on)
+      delta_specifications.append((issue_id, approval_id, delta))
+    return delta_specifications
+
+  def IngestIssue(self, issue, project_id):
+    # type: (api_proto.issue_objects_pb2.Issue, int) -> proto.tracker_pb2.Issue
+    """Ingest a protoc Issue into a protorpc Issue.
+
+    Args:
+      issue: the protoc issue to ingest.
+      project_id: The project into which we're ingesting `issue`.
+
+    Returns:
+      protorpc version of issue, ignoring all OUTPUT_ONLY fields.
+
+    Raises:
+      InputException: if any fields in the 'issue' proto were invalid.
+      NoSuchProjectException: if 'project_id' is not found.
+    """
+    # Get config first. We can't ingest the issue if the project isn't found.
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    ingestedDict = {
+      'project_id': project_id,
+      'summary': issue.summary
+    }
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      self._ExtractOwner(issue, ingestedDict, err_agg)
+
+      # Extract ccs.
+      try:
+        ingestedDict['cc_ids'] = rnc.IngestUserNames(
+            self.cnxn, [cc.user for cc in issue.cc_users], self.services,
+            autocreate=True)
+      except exceptions.InputException as e:
+        err_agg.AddErrorMessage('Error ingesting cc_users: {}', e)
+
+      # Extract status.
+      if issue.HasField('status') and issue.status.status:
+        ingestedDict['status'] = issue.status.status
+      else:
+        err_agg.AddErrorMessage('Status is required when creating an issue')
+
+      # Extract components.
+      try:
+        project_comp_ids = rnc.IngestComponentDefNames(
+            self.cnxn, [cv.component for cv in issue.components], self.services)
+        ingestedDict['component_ids'] = [
+            comp_id for (_pid, comp_id) in project_comp_ids]
+      except (exceptions.InputException, exceptions.NoSuchProjectException,
+              exceptions.NoSuchComponentException) as e:
+        err_agg.AddErrorMessage('Error ingesting components: {}', e)
+
+      # Extract labels and field values.
+      ingestedDict['labels'] = [lv.label for lv in issue.labels]
+      try:
+        ingestedDict['field_values'], enums = self._IngestFieldValues(
+            issue.field_values, config)
+        field_helpers.ShiftEnumFieldsIntoLabels(
+            ingestedDict['labels'], [], enums, [], config)
+        assert len(
+            enums) == 0  # ShiftEnumFieldsIntoLabels must clear all enums.
+      except exceptions.InputException as e:
+        err_agg.AddErrorMessage(e.message)
+
+      # Ingest merged, blocking/blocked_on.
+      self._ExtractIssueRefs(issue, ingestedDict, err_agg)
+    return tracker_pb2.Issue(**ingestedDict)
+
+  def _IngestFieldValues(self, field_values, config, approval_id_filter=None):
+    # type: (Sequence[api_proto.issue_objects.FieldValue],
+    #     proto.tracker_pb2.ProjectIssueConfig, Optional[int]) ->
+    #     Tuple[Sequence[proto.tracker_pb2.FieldValue],
+    #         Mapping[int, Sequence[str]]]
+    """Returns protorpc FieldValues for the given protoc FieldValues.
+
+    Raises exceptions if any field could not be parsed for any reasons such as
+        unsupported field type, non-existent field, field from different
+        projects, or fields with mismatched parent approvals.
+
+    Args:
+      field_values: protoc FieldValues to ingest.
+      config: ProjectIssueConfig for the FieldValues we're ingesting.
+      approval_id_filter: an approval_id, including any FieldValues that does
+          not have this approval as a parent will trigger InputException.
+
+    Returns:
+      A pair 1) Ingested FieldValues. 2) A mapping of field ids to values
+      for ENUM_TYPE fields in 'field_values.'
+
+    Raises:
+      InputException: if any fields_values could not be parsed for any reasons
+          such as unsupported field type, non-existent field, or field from
+          different projects.
+    """
+    fds_by_id = {fd.field_id: fd for fd in config.field_defs}
+    enums = {}
+    ingestedFieldValues = []
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      for fv in field_values:
+        try:
+          project_id, fd_id = rnc.IngestFieldDefName(
+              self.cnxn, fv.field, self.services)
+          fd = fds_by_id[fd_id]
+          # Raise if field does not belong to approval_id_filter (if provided).
+          if (approval_id_filter is not None and
+              fd.approval_id != approval_id_filter):
+            approval_name = rnc.ConvertApprovalDefNames(
+                self.cnxn, [approval_id_filter], project_id,
+                self.services)[approval_id_filter]
+            err_agg.AddErrorMessage(
+                'Field {} does not belong to approval {}', fv.field,
+                approval_name)
+            continue
+          if fd.field_type == tracker_pb2.FieldTypes.ENUM_TYPE:
+            enums.setdefault(fd_id, []).append(fv.value)
+          else:
+            ingestedFieldValues.append(self._IngestFieldValue(fv, fd))
+        except (exceptions.InputException, exceptions.NoSuchProjectException,
+                exceptions.NoSuchFieldDefException, ValueError) as e:
+          err_agg.AddErrorMessage(
+              'Could not ingest value ({}) for FieldDef ({}): {}', fv.value,
+              fv.field, e)
+        except exceptions.NoSuchUserException as e:
+          err_agg.AddErrorMessage(
+              'User ({}) not found when ingesting user field: {}', fv.value,
+              fv.field)
+        except KeyError as e:
+          err_agg.AddErrorMessage('Field {} is not in this project', fv.field)
+    return ingestedFieldValues, enums
+
+  def _IngestFieldValue(self, field_value, field_def):
+    # type: (api_proto.issue_objects.FieldValue, proto.tracker_pb2.FieldDef) ->
+    #     proto.tracker_pb2.FieldValue
+    """Ingest a protoc FieldValue into a protorpc FieldValue.
+
+    Args:
+      field_value: protoc FieldValue to ingest.
+      field_def: protorpc FieldDef associated with 'field_value'.
+          BOOL_TYPE and APPROVAL_TYPE are ignored.
+          Enum values are not allowed. They must be ingested as labels.
+
+    Returns:
+      Ingested protorpc FieldValue.
+
+    Raises:
+      InputException if 'field_def' is USER_TYPE and 'field_value' does not
+          have a valid formatted resource name.
+      NoSuchUserException if specified user in field does not exist.
+      ValueError if 'field_value' could not be parsed for 'field_def'.
+    """
+    assert field_def.field_type != tracker_pb2.FieldTypes.ENUM_TYPE
+    if field_def.field_type == tracker_pb2.FieldTypes.USER_TYPE:
+      return self._ParseOneUserFieldValue(field_value.value, field_def.field_id)
+    fv = field_helpers.ParseOneFieldValue(
+        self.cnxn, self.services.user, field_def, field_value.value)
+    # ParseOneFieldValue currently ignores parsing errors, although it has TODOs
+    # to raise them.
+    if not fv:
+      raise ValueError('Could not parse %s' % field_value.value)
+    return fv
+
+  def _ParseOneUserFieldValue(self, value, field_id):
+    # type: (str, int) -> proto.tracker_pb2.FieldValue
+    """Replacement for the obsolete user parsing in ParseOneFieldValue."""
+    user_id = rnc.IngestUserName(self.cnxn, value, self.services)
+    return tbo.MakeFieldValue(field_id, None, None, user_id, None, None, False)
+
+  def _ExtractOwner(self, issue, ingestedDict, err_agg):
+    # type: (api_proto.issue_objects_pb2.Issue, Dict[str, Any], ErrorAggregator)
+    #     -> None
+    """Fills 'owner' into `ingestedDict`, if it can be extracted."""
+    if issue.HasField('owner'):
+      try:
+        # Unlike for cc's, we require owner be an existing user, thus call we
+        # do not autocreate.
+        ingestedDict['owner_id'] = rnc.IngestUserName(
+            self.cnxn, issue.owner.user, self.services, autocreate=False)
+      except exceptions.InputException as e:
+        err_agg.AddErrorMessage(
+            'Error ingesting owner ({}): {}', issue.owner.user, e)
+      except exceptions.NoSuchUserException as e:
+        err_agg.AddErrorMessage(
+            'User ({}) not found when ingesting owner', e)
+    else:
+      ingestedDict['owner_id'] = framework_constants.NO_USER_SPECIFIED
+
+  def _ExtractIssueRefs(self, issue, ingestedDict, err_agg):
+    # type: (api_proto.issue_objects_pb2.Issue, Dict[str, Any], ErrorAggregator)
+    #     -> None
+    """Fills issue relationships into `ingestedDict` from `issue`."""
+    if issue.HasField('merged_into_issue_ref'):
+      try:
+        merged_into_ref = self._IngestIssueRef(issue.merged_into_issue_ref)
+        if isinstance(merged_into_ref, tracker_pb2.DanglingIssueRef):
+          ingestedDict['merged_into_external'] = (
+              merged_into_ref.ext_issue_identifier)
+        else:
+          ingestedDict['merged_into'] = merged_into_ref
+      except exceptions.InputException as e:
+        err_agg.AddErrorMessage(
+            'Error ingesting ref {}: {}', issue.merged_into_issue_ref, e)
+    try:
+      iids, dangling_refs = self._IngestIssueRefs(issue.blocked_on_issue_refs)
+      ingestedDict['blocked_on_iids'] = iids
+      ingestedDict['dangling_blocked_on_refs'] = dangling_refs
+    except exceptions.InputException as e:
+      err_agg.AddErrorMessage(e.message)
+    try:
+      iids, dangling_refs = self._IngestIssueRefs(issue.blocking_issue_refs)
+      ingestedDict['blocking_iids'] = iids
+      ingestedDict['dangling_blocking_refs'] = dangling_refs
+    except exceptions.InputException as e:
+      err_agg.AddErrorMessage(e.message)
+
+  def _IngestIssueRefs(self, issue_refs):
+    # type: (api_proto.issue_objects.IssueRf) ->
+    #     Tuple[Sequence[int], Sequence[tracker_pb2.DanglingIssueRef]]
+    """Given protoc IssueRefs, returns issue_ids and DanglingIssueRefs."""
+    issue_ids = []
+    external_refs = []
+    with exceptions.ErrorAggregator(exceptions.InputException) as err_agg:
+      for ref in issue_refs:
+        try:
+          ingested_ref = self._IngestIssueRef(ref)
+          if isinstance(ingested_ref, tracker_pb2.DanglingIssueRef):
+            external_refs.append(ingested_ref)
+          else:
+            issue_ids.append(ingested_ref)
+        except (exceptions.InputException, exceptions.NoSuchIssueException,
+                exceptions.NoSuchProjectException) as e:
+          err_agg.AddErrorMessage('Error ingesting ref {}: {}', ref, e)
+
+    return issue_ids, external_refs
+
+  def _IngestIssueRef(self, issue_ref):
+    # type: (api_proto.issue_objects.IssueRef) ->
+    #     Union[int, tracker_pb2.DanglingIssueRef]
+    """Given a protoc IssueRef, returns an issue id or DanglingIssueRef."""
+    if issue_ref.issue and issue_ref.ext_identifier:
+      raise exceptions.InputException(
+        'IssueRefs MUST NOT have both `issue` and `ext_identifier`')
+    if issue_ref.issue:
+      return rnc.IngestIssueName(self.cnxn, issue_ref.issue, self.services)
+    if issue_ref.ext_identifier:
+      # TODO(crbug.com/monorail/7208): Handle ingestion/conversion of CodeSite
+      # refs. We may be able to avoid ever needing to ingest them.
+      return tracker_pb2.DanglingIssueRef(
+          ext_issue_identifier=issue_ref.ext_identifier
+        )
+    raise exceptions.InputException(
+        'IssueRefs MUST have one of `issue` and `ext_identifier`')
+
+  def IngestIssuesListColumns(self, issues_list_columns):
+    # type: (Sequence[proto.issue_objects_pb2.IssuesListColumn] -> str
+    """Ingest a list of protoc IssueListColumns and returns a string."""
+    return ' '.join([col.column for col in issues_list_columns])
+
+  def _ComputeIssuesListColumns(self, columns):
+    # type: (string) -> Sequence[api_proto.issue_objects_pb2.IssuesListColumn]
+    """Convert string representation of columns to protoc IssuesListColumns"""
+    return [
+        issue_objects_pb2.IssuesListColumn(column=col)
+        for col in columns.split()
+    ]
+
+  def IngestNotifyType(self, notify):
+    # type: (issue_pb.NotifyType) -> bool
+    """Ingest a NotifyType to boolean."""
+    if (notify == issues_pb2.NotifyType.Value('NOTIFY_TYPE_UNSPECIFIED') or
+        notify == issues_pb2.NotifyType.Value('EMAIL')):
+      return True
+    elif notify == issues_pb2.NotifyType.Value('NO_NOTIFICATION'):
+      return False
+
+  # Users
+
+  def ConvertUser(self, user):
+    # type: (protorpc.User) -> api_proto.user_objects_pb2.User
+    """Convert a protorpc User into a protoc User.
+
+    Args:
+      user: protorpc User object.
+
+    Returns:
+      The protoc User object.
+    """
+    return self.ConvertUsers([user.user_id])[user.user_id]
+
+
+  # TODO(crbug/monorail/7238): Make this take in a full User object and
+  # return a Sequence, rather than a map, after hotlist users are converted.
+  def ConvertUsers(self, user_ids):
+    # type: (Sequence[int]) -> Map(int, api_proto.user_objects_pb2.User)
+    """Convert list of protorpc Users into list of protoc Users.
+
+    Args:
+      user_ids: List of User IDs.
+
+    Returns:
+      Dict of User IDs to User protos for given user_ids that could be found.
+    """
+    user_ids_to_names = {}
+
+    # Get display names
+    users_by_id = self.services.user.GetUsersByIDs(self.cnxn, user_ids)
+    (display_names_by_id,
+     display_emails_by_id) = framework_bizobj.CreateUserDisplayNamesAndEmails(
+         self.cnxn, self.services, self.user_auth, users_by_id.values())
+
+    for user_id, user in users_by_id.items():
+      name = rnc.ConvertUserNames([user_id]).get(user_id)
+
+      display_name = display_names_by_id.get(user_id)
+      display_email = display_emails_by_id.get(user_id)
+      availability = framework_helpers.GetUserAvailability(user)
+      availability_message, _availability_status = availability
+
+      user_ids_to_names[user_id] = user_objects_pb2.User(
+          name=name,
+          display_name=display_name,
+          email=display_email,
+          availability_message=availability_message)
+
+    return user_ids_to_names
+
+  def ConvertProjectStars(self, user_id, projects):
+    # type: (int, Collection[protorpc.Project]) ->
+    #     Collection[api_proto.user_objects_pb2.ProjectStar]
+    """Convert list of protorpc Projects into protoc ProjectStars.
+
+    Args:
+      user_id: The user the ProjectStar is associated with.
+      projects: All starred projects.
+
+    Returns:
+      List of ProjectStar messages.
+    """
+    api_project_stars = []
+    for proj in projects:
+      name = rnc.ConvertProjectStarName(
+          self.cnxn, user_id, proj.project_id, self.services)
+      star = user_objects_pb2.ProjectStar(name=name)
+      api_project_stars.append(star)
+    return api_project_stars
+
+  # Field Defs
+
+  def ConvertFieldDefs(self, field_defs, project_id):
+    # type: (Sequence[proto.tracker_pb2.FieldDef], int) ->
+    #     Sequence[api_proto.project_objects_pb2.FieldDef]
+    """Convert sequence of protorpc FieldDefs to protoc FieldDefs.
+
+    Args:
+      field_defs: List of protorpc FieldDefs
+      project_id: ID of the Project that is ancestor to all given
+        `field_defs`.
+
+    Returns:
+      Sequence of protoc FieldDef in the same order they are given in
+      `field_defs`. In the event any field_def or the referenced approval_id
+      in `field_defs` is not found, they will be omitted from the result.
+    """
+    field_ids = [fd.field_id for fd in field_defs]
+    resource_names_dict = rnc.ConvertFieldDefNames(
+        self.cnxn, field_ids, project_id, self.services)
+    parent_approval_ids = [
+        fd.approval_id for fd in field_defs if fd.approval_id is not None
+    ]
+    approval_names_dict = rnc.ConvertApprovalDefNames(
+        self.cnxn, parent_approval_ids, project_id, self.services)
+
+    api_fds = []
+    for fd in field_defs:
+      # Skip over approval fields, they have their separate ApprovalDef
+      if fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE:
+        continue
+      if fd.field_id not in resource_names_dict:
+        continue
+
+      name = resource_names_dict.get(fd.field_id)
+      display_name = fd.field_name
+      docstring = fd.docstring
+      field_type = self._ConvertFieldDefType(fd.field_type)
+      applicable_issue_type = fd.applicable_type
+      admins = rnc.ConvertUserNames(fd.admin_ids).values()
+      editors = rnc.ConvertUserNames(fd.editor_ids).values()
+      traits = self._ComputeFieldDefTraits(fd)
+      approval_parent = approval_names_dict.get(fd.approval_id)
+
+      enum_settings = None
+      if field_type == project_objects_pb2.FieldDef.Type.Value('ENUM'):
+        enum_settings = project_objects_pb2.FieldDef.EnumTypeSettings(
+            choices=self._GetEnumFieldChoices(fd))
+
+      int_settings = None
+      if field_type == project_objects_pb2.FieldDef.Type.Value('INT'):
+        int_settings = project_objects_pb2.FieldDef.IntTypeSettings(
+            min_value=fd.min_value, max_value=fd.max_value)
+
+      str_settings = None
+      if field_type == project_objects_pb2.FieldDef.Type.Value('STR'):
+        str_settings = project_objects_pb2.FieldDef.StrTypeSettings(
+            regex=fd.regex)
+
+      user_settings = None
+      if field_type == project_objects_pb2.FieldDef.Type.Value('USER'):
+        user_settings = project_objects_pb2.FieldDef.UserTypeSettings(
+            role_requirements=self._ConvertRoleRequirements(fd.needs_member),
+            notify_triggers=self._ConvertNotifyTriggers(fd.notify_on),
+            grants_perm=fd.grants_perm,
+            needs_perm=fd.needs_perm)
+
+      date_settings = None
+      if field_type == project_objects_pb2.FieldDef.Type.Value('DATE'):
+        date_settings = project_objects_pb2.FieldDef.DateTypeSettings(
+            date_action=self._ConvertDateAction(fd.date_action))
+
+      api_fd = project_objects_pb2.FieldDef(
+          name=name,
+          display_name=display_name,
+          docstring=docstring,
+          type=field_type,
+          applicable_issue_type=applicable_issue_type,
+          admins=admins,
+          traits=traits,
+          approval_parent=approval_parent,
+          enum_settings=enum_settings,
+          int_settings=int_settings,
+          str_settings=str_settings,
+          user_settings=user_settings,
+          date_settings=date_settings,
+          editors=editors)
+      api_fds.append(api_fd)
+    return api_fds
+
+  def _ConvertDateAction(self, date_action):
+    # type: (proto.tracker_pb2.DateAction) ->
+    #     api_proto.project_objects_pb2.FieldDef.DateTypeSettings.DateAction
+    """Convert protorpc DateAction to protoc
+       FieldDef.DateTypeSettings.DateAction"""
+    if date_action == tracker_pb2.DateAction.NO_ACTION:
+      return project_objects_pb2.FieldDef.DateTypeSettings.DateAction.Value(
+          'NO_ACTION')
+    elif date_action == tracker_pb2.DateAction.PING_OWNER_ONLY:
+      return project_objects_pb2.FieldDef.DateTypeSettings.DateAction.Value(
+          'NOTIFY_OWNER')
+    elif date_action == tracker_pb2.DateAction.PING_PARTICIPANTS:
+      return project_objects_pb2.FieldDef.DateTypeSettings.DateAction.Value(
+          'NOTIFY_PARTICIPANTS')
+    else:
+      raise ValueError('Unsupported DateAction Value')
+
+  def _ConvertRoleRequirements(self, needs_member):
+    # type: (bool) ->
+    #     api_proto.project_objects_pb2.FieldDef.
+    #     UserTypeSettings.RoleRequirements
+    """Convert protorpc RoleRequirements to protoc
+       FieldDef.UserTypeSettings.RoleRequirements"""
+
+    proto_user_settings = project_objects_pb2.FieldDef.UserTypeSettings
+    if needs_member:
+      return proto_user_settings.RoleRequirements.Value('PROJECT_MEMBER')
+    else:
+      return proto_user_settings.RoleRequirements.Value('NO_ROLE_REQUIREMENT')
+
+  def _ConvertNotifyTriggers(self, notify_trigger):
+    # type: (proto.tracker_pb2.NotifyTriggers) ->
+    #     api_proto.project_objects_pb2.FieldDef.UserTypeSettings.NotifyTriggers
+    """Convert protorpc NotifyTriggers to protoc
+       FieldDef.UserTypeSettings.NotifyTriggers"""
+    if notify_trigger == tracker_pb2.NotifyTriggers.NEVER:
+      return project_objects_pb2.FieldDef.UserTypeSettings.NotifyTriggers.Value(
+          'NEVER')
+    elif notify_trigger == tracker_pb2.NotifyTriggers.ANY_COMMENT:
+      return project_objects_pb2.FieldDef.UserTypeSettings.NotifyTriggers.Value(
+          'ANY_COMMENT')
+    else:
+      raise ValueError('Unsupported NotifyTriggers Value')
+
+  def _ConvertFieldDefType(self, field_type):
+    # type: (proto.tracker_pb2.FieldTypes) ->
+    #     api_proto.project_objects_pb2.FieldDef.Type
+    """Convert protorpc FieldType to protoc FieldDef.Type
+
+    Args:
+      field_type: protorpc FieldType
+
+    Returns:
+      Corresponding protoc FieldDef.Type
+
+    Raises:
+      ValueError if input `field_type` has no suitable supported FieldDef.Type,
+      or input `field_type` is not a recognized enum option.
+    """
+    if field_type == tracker_pb2.FieldTypes.ENUM_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('ENUM')
+    elif field_type == tracker_pb2.FieldTypes.INT_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('INT')
+    elif field_type == tracker_pb2.FieldTypes.STR_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('STR')
+    elif field_type == tracker_pb2.FieldTypes.USER_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('USER')
+    elif field_type == tracker_pb2.FieldTypes.DATE_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('DATE')
+    elif field_type == tracker_pb2.FieldTypes.URL_TYPE:
+      return project_objects_pb2.FieldDef.Type.Value('URL')
+    else:
+      raise ValueError(
+          'Unsupported tracker_pb2.FieldType enum. Boolean types '
+          'are unsupported and approval types are found in ApprovalDefs')
+
+  def _ComputeFieldDefTraits(self, field_def):
+    # type: (proto.tracker_pb2.FieldDef) ->
+    #     Sequence[api_proto.project_objects_pb2.FieldDef.Traits]
+    """Compute sequence of FieldDef.Traits for a given protorpc FieldDef."""
+    trait_protos = []
+    if field_def.is_required:
+      trait_protos.append(project_objects_pb2.FieldDef.Traits.Value('REQUIRED'))
+    if field_def.is_niche:
+      trait_protos.append(
+          project_objects_pb2.FieldDef.Traits.Value('DEFAULT_HIDDEN'))
+    if field_def.is_multivalued:
+      trait_protos.append(
+          project_objects_pb2.FieldDef.Traits.Value('MULTIVALUED'))
+    if field_def.is_phase_field:
+      trait_protos.append(project_objects_pb2.FieldDef.Traits.Value('PHASE'))
+    if field_def.is_restricted_field:
+      trait_protos.append(
+          project_objects_pb2.FieldDef.Traits.Value('RESTRICTED'))
+    return trait_protos
+
+  def _GetEnumFieldChoices(self, field_def):
+    # type: (proto.tracker_pb2.FieldDef) ->
+    #     Sequence[Choice]
+    """Get sequence of choices for an enum field
+
+    Args:
+      field_def: protorpc FieldDef
+
+    Returns:
+      Sequence of valid Choices for enum field `field_def`.
+
+    Raises:
+      ValueError if input `field_def` is not an enum type field.
+    """
+    if field_def.field_type != tracker_pb2.FieldTypes.ENUM_TYPE:
+      raise ValueError('Cannot get value from label for non-enum-type field')
+
+    config = self.services.config.GetProjectConfig(
+        self.cnxn, field_def.project_id)
+    value_docstr_tuples = tracker_helpers._GetEnumFieldValuesAndDocstrings(
+        field_def, config)
+
+    return [
+        Choice(value=value, docstring=docstring)
+        for value, docstring in value_docstr_tuples
+    ]
+
+  # Field Values
+
+  def _GetNonApprovalFieldValues(self, field_values, project_id):
+    # type: (Sequence[proto.tracker_pb2.FieldValue], int) ->
+    #     Sequence[proto.tracker_pb2.FieldValue]
+    """Filter out field values that belong to an approval field."""
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    approval_fd_ids = set(
+        [fd.field_id for fd in config.field_defs if fd.approval_id])
+
+    return [fv for fv in field_values if fv.field_id not in approval_fd_ids]
+
+  def ConvertFieldValues(self, field_values, project_id, phases):
+    # type: (Sequence[proto.tracker_pb2.FieldValue], int,
+    #     Sequence[proto.tracker_pb2.Phase]) ->
+    #     Sequence[api_proto.issue_objects_pb2.FieldValue]
+    """Convert sequence of field_values to protoc FieldValues.
+
+    This method does not handle enum_type fields.
+
+    Args:
+      field_values: List of FieldValues
+      project_id: ID of the Project that is ancestor to all given
+        `field_values`.
+      phases: List of Phases
+
+    Returns:
+      Sequence of protoc FieldValues in the same order they are given in
+      `field_values`. In the event any field_values in `field_values` are not
+      found, they will be omitted from the result.
+    """
+    phase_names_by_id = {phase.phase_id: phase.name for phase in phases}
+    field_ids = [fv.field_id for fv in field_values]
+    resource_names_dict = rnc.ConvertFieldDefNames(
+        self.cnxn, field_ids, project_id, self.services)
+
+    api_fvs = []
+    for fv in field_values:
+      if fv.field_id not in resource_names_dict:
+        continue
+
+      name = resource_names_dict.get(fv.field_id)
+      value = self._ComputeFieldValueString(fv)
+      derivation = self._ComputeFieldValueDerivation(fv)
+      phase = phase_names_by_id.get(fv.phase_id)
+      api_item = issue_objects_pb2.FieldValue(
+          field=name, value=value, derivation=derivation, phase=phase)
+      api_fvs.append(api_item)
+
+    return api_fvs
+
+  def _ComputeFieldValueString(self, field_value):
+    # type: (proto.tracker_pb2.FieldValue) -> str
+    """Convert a FieldValue's value to a string."""
+    if field_value is None:
+      raise exceptions.InputException('No FieldValue specified')
+    elif field_value.int_value is not None:
+      return str(field_value.int_value)
+    elif field_value.str_value is not None:
+      return field_value.str_value
+    elif field_value.user_id is not None:
+      return rnc.ConvertUserNames([field_value.user_id
+                                  ]).get(field_value.user_id)
+    elif field_value.date_value is not None:
+      return str(field_value.date_value)
+    elif field_value.url_value is not None:
+      return field_value.url_value
+    else:
+      raise exceptions.InputException('FieldValue must have at least one value')
+
+  def _ComputeFieldValueDerivation(self, field_value):
+    # type: (proto.tracker_pb2.FieldValue) ->
+    #     api_proto.issue_objects_pb2.Issue.Derivation
+    """Convert a FieldValue's 'derived' to a protoc Issue.Derivation.
+
+    Args:
+      field_value: protorpc FieldValue
+
+    Returns:
+      Issue.Derivation of given `field_value`
+    """
+    if field_value.derived:
+      return issue_objects_pb2.Derivation.Value('RULE')
+    else:
+      return issue_objects_pb2.Derivation.Value('EXPLICIT')
+
+  # Approval Def
+
+  def ConvertApprovalDefs(self, approval_defs, project_id):
+    # type: (Sequence[proto.tracker_pb2.ApprovalDef], int) ->
+    #     Sequence[api_proto.project_objects_pb2.ApprovalDef]
+    """Convert sequence of protorpc ApprovalDefs to protoc ApprovalDefs.
+
+    Args:
+      approval_defs: List of protorpc ApprovalDefs
+      project_id: ID of the Project the approval_defs belong to.
+
+    Returns:
+      Sequence of protoc ApprovalDefs in the same order they are given in
+      in `approval_defs`. In the event any approval_def in `approval_defs`
+      are not found, they will be omitted from the result.
+    """
+    approval_ids = set([ad.approval_id for ad in approval_defs])
+    resource_names_dict = rnc.ConvertApprovalDefNames(
+        self.cnxn, approval_ids, project_id, self.services)
+
+    # Get matching field defs, needed to fill out protoc ApprovalDefs
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    fd_by_id = {}
+    for fd in config.field_defs:
+      if (fd.field_type == tracker_pb2.FieldTypes.APPROVAL_TYPE and
+          fd.field_id in approval_ids):
+        fd_by_id[fd.field_id] = fd
+
+    all_users = tbo.UsersInvolvedInApprovalDefs(
+        approval_defs, fd_by_id.values())
+    user_resource_names_dict = rnc.ConvertUserNames(all_users)
+
+    api_ads = []
+    for ad in approval_defs:
+      if (ad.approval_id not in resource_names_dict or
+          ad.approval_id not in fd_by_id):
+        continue
+      matching_fd = fd_by_id.get(ad.approval_id)
+      name = resource_names_dict.get(ad.approval_id)
+      display_name = matching_fd.field_name
+      docstring = matching_fd.docstring
+      survey = ad.survey
+      approvers = [
+          user_resource_names_dict.get(approver_id)
+          for approver_id in ad.approver_ids
+      ]
+      admins = [
+          user_resource_names_dict.get(admin_id)
+          for admin_id in matching_fd.admin_ids
+      ]
+
+      api_ad = project_objects_pb2.ApprovalDef(
+          name=name,
+          display_name=display_name,
+          docstring=docstring,
+          survey=survey,
+          approvers=approvers,
+          admins=admins)
+      api_ads.append(api_ad)
+    return api_ads
+
+  def ConvertApprovalValues(self, approval_values, field_values, phases,
+                            issue_id=None, project_id=None):
+    # type: (Sequence[proto.tracker_pb2.ApprovalValue],
+    #     Sequence[proto.tracker_pb2.FieldValue],
+    #     Sequence[proto.tracker_pb2.Phase], Optional[int], Optional[int]) ->
+    #     Sequence[api_proto.issue_objects_pb2.ApprovalValue]
+    """Convert sequence of approval_values to protoc ApprovalValues.
+
+    `approval_values` may belong to a template or an issue. If they belong to a
+    template, `project_id` should be given for the project the template is in.
+    If these are issue `approval_values` `issue_id` should be given`.
+    So, one of `issue_id` or `project_id` must be provided.
+    If both are given, we ignore `project_id` and assume the `approval_values`
+    belong to an issue.
+
+    Args:
+      approval_values: List of ApprovalValues.
+      field_values: List of FieldValues that may belong to the approval_values.
+      phases: List of Phases that may be associated with the approval_values.
+      issue_id: ID of the Issue that the `approval_values` belong to.
+      project_id: ID of the Project that the `approval_values`
+        template belongs to.
+
+    Returns:
+      Sequence of protoc ApprovalValues in the same order they are given in
+      in `approval_values`. In the event any approval definitions in
+      `approval_values` are not found, they will be omitted from the result.
+
+    Raises:
+      InputException if neither `issue_id` nor `project_id` is given.
+    """
+
+    approval_ids = [av.approval_id for av in approval_values]
+    resource_names_dict = {}
+    if issue_id is not None:
+      # Only issue approval_values have resource names.
+      resource_names_dict = rnc.ConvertApprovalValueNames(
+          self.cnxn, issue_id, self.services)
+      project_id = self.services.issue.GetIssue(self.cnxn, issue_id).project_id
+    elif project_id is None:
+      raise exceptions.InputException(
+          'One  `issue_id` or `project_id` must be given.')
+
+    phase_names_by_id = {phase.phase_id: phase.name for phase in phases}
+    ad_names_dict = rnc.ConvertApprovalDefNames(
+        self.cnxn, approval_ids, project_id, self.services)
+
+    # Organize the field values by the approval values they are
+    # associated with.
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    fds_by_id = {fd.field_id: fd for fd in config.field_defs}
+    fvs_by_parent_approvals = collections.defaultdict(list)
+    for fv in field_values:
+      fd = fds_by_id.get(fv.field_id)
+      if fd and fd.approval_id:
+        fvs_by_parent_approvals[fd.approval_id].append(fv)
+
+    api_avs = []
+    for av in approval_values:
+      # We only skip missing approval names if we are converting issue approval
+      # values.
+      if issue_id is not None and av.approval_id not in resource_names_dict:
+        continue
+
+      name = resource_names_dict.get(av.approval_id)
+      approval_def = ad_names_dict.get(av.approval_id)
+      approvers = rnc.ConvertUserNames(av.approver_ids).values()
+      status = self._ComputeApprovalValueStatus(av.status)
+      setter = rnc.ConvertUserName(av.setter_id)
+      phase = phase_names_by_id.get(av.phase_id)
+
+      field_values = self.ConvertFieldValues(
+          fvs_by_parent_approvals[av.approval_id], project_id, phases)
+
+      api_item = issue_objects_pb2.ApprovalValue(
+          name=name,
+          approval_def=approval_def,
+          approvers=approvers,
+          status=status,
+          setter=setter,
+          field_values=field_values,
+          phase=phase)
+      if av.set_on:
+        api_item.set_time.FromSeconds(av.set_on)
+      api_avs.append(api_item)
+
+    return api_avs
+
+  def _ComputeApprovalValueStatus(self, status):
+    # type: (proto.tracker_pb2.ApprovalStatus) ->
+    #     api_proto.issue_objects_pb2.Issue.ApprovalStatus
+    """Convert a protorpc ApprovalStatus to a protoc Issue.ApprovalStatus."""
+    try:
+      return _APPROVAL_STATUS_CONVERT[status]
+    except KeyError:
+      raise ValueError('Unrecognized tracker_pb2.ApprovalStatus enum')
+
+  # Projects
+
+  def ConvertIssueTemplates(self, project_id, templates):
+    # type: (int, Sequence[proto.tracker_pb2.TemplateDef]) ->
+    #     Sequence[api_proto.project_objects_pb2.IssueTemplate]
+    """Convert a Sequence of TemplateDefs to protoc IssueTemplates.
+
+    Args:
+      project_id: ID of the Project the templates belong to.
+      templates: Sequence of TemplateDef protorpc objects.
+
+    Returns:
+      Sequence of protoc IssueTemplate in the same order they are given in
+      `templates`. In the rare event that any templates are not found,
+      they will be omitted from the result.
+    """
+    api_templates = []
+
+    resource_names_dict = rnc.ConvertTemplateNames(
+        self.cnxn, project_id, [template.template_id for template in templates],
+        self.services)
+
+    for template in templates:
+      if template.template_id not in resource_names_dict:
+        continue
+      name = resource_names_dict.get(template.template_id)
+      summary_must_be_edited = template.summary_must_be_edited
+      template_privacy = self._ComputeTemplatePrivacy(template)
+      default_owner = self._ComputeTemplateDefaultOwner(template)
+      component_required = template.component_required
+      admins = rnc.ConvertUserNames(template.admin_ids).values()
+      issue = self._FillIssueFromTemplate(template, project_id)
+      approval_values = self.ConvertApprovalValues(
+          template.approval_values, template.field_values, template.phases,
+          project_id=project_id)
+      api_templates.append(
+          project_objects_pb2.IssueTemplate(
+              name=name,
+              display_name=template.name,
+              issue=issue,
+              approval_values=approval_values,
+              summary_must_be_edited=summary_must_be_edited,
+              template_privacy=template_privacy,
+              default_owner=default_owner,
+              component_required=component_required,
+              admins=admins))
+
+    return api_templates
+
+  def _FillIssueFromTemplate(self, template, project_id):
+    # type: (proto.tracker_pb2.TemplateDef, int) ->
+    #     api_proto.issue_objects_pb2.Issue
+    """Convert a TemplateDef to its embedded protoc Issue.
+
+    IssueTemplate does not set the following fields:
+      name
+      reporter
+      cc_users
+      blocked_on_issue_refs
+      blocking_issue_refs
+      create_time
+      close_time
+      modify_time
+      component_modify_time
+      status_modify_time
+      owner_modify_time
+      attachment_count
+      star_count
+
+    Args:
+      template: TemplateDef protorpc objects.
+      project_id: ID of the Project the template belongs to.
+
+    Returns:
+      protoc Issue filled with data from given `template`.
+    """
+    summary = template.summary
+    state = issue_objects_pb2.IssueContentState.Value('ACTIVE')
+    status = issue_objects_pb2.Issue.StatusValue(
+        status=template.status,
+        derivation=issue_objects_pb2.Derivation.Value('EXPLICIT'))
+    owner = None
+    if template.owner_id is not None:
+      owner = issue_objects_pb2.Issue.UserValue(
+          user=rnc.ConvertUserNames([template.owner_id]).get(template.owner_id))
+    labels = self.ConvertLabels(template.labels, [], project_id)
+    components_dict = rnc.ConvertComponentDefNames(
+        self.cnxn, template.component_ids, project_id, self.services)
+    components = []
+    for component_resource_name in components_dict.values():
+      components.append(
+          issue_objects_pb2.Issue.ComponentValue(
+              component=component_resource_name,
+              derivation=issue_objects_pb2.Derivation.Value('EXPLICIT')))
+    non_approval_fvs = self._GetNonApprovalFieldValues(
+        template.field_values, project_id)
+    field_values = self.ConvertFieldValues(
+        non_approval_fvs, project_id, template.phases)
+    field_values.extend(
+        self.ConvertEnumFieldValues(template.labels, [], project_id))
+    phases = self._ComputePhases(template.phases)
+
+    filled_issue = issue_objects_pb2.Issue(
+        summary=summary,
+        state=state,
+        status=status,
+        owner=owner,
+        labels=labels,
+        components=components,
+        field_values=field_values,
+        phases=phases)
+    return filled_issue
+
+  def _ComputeTemplatePrivacy(self, template):
+    # type: (proto.tracker_pb2.TemplateDef) ->
+    #     api_proto.project_objects_pb2.IssueTemplate.TemplatePrivacy
+    """Convert a protorpc TemplateDef to its protoc TemplatePrivacy."""
+    if template.members_only:
+      return project_objects_pb2.IssueTemplate.TemplatePrivacy.Value(
+          'MEMBERS_ONLY')
+    else:
+      return project_objects_pb2.IssueTemplate.TemplatePrivacy.Value('PUBLIC')
+
+  def _ComputeTemplateDefaultOwner(self, template):
+    # type: (proto.tracker_pb2.TemplateDef) ->
+    #     api_proto.project_objects_pb2.IssueTemplate.DefaultOwner
+    """Convert a protorpc TemplateDef to its protoc DefaultOwner."""
+    if template.owner_defaults_to_member:
+      return project_objects_pb2.IssueTemplate.DefaultOwner.Value(
+          'PROJECT_MEMBER_REPORTER')
+    else:
+      return project_objects_pb2.IssueTemplate.DefaultOwner.Value(
+          'DEFAULT_OWNER_UNSPECIFIED')
+
+  def _ComputePhases(self, phases):
+    # type: (proto.tracker_pb2.TemplateDef) -> Sequence[str]
+    """Convert a protorpc TemplateDef to its sorted string phases."""
+    sorted_phases = sorted(phases, key=lambda phase: phase.rank)
+    return [phase.name for phase in sorted_phases]
+
+  def ConvertLabels(self, labels, derived_labels, project_id):
+    # type: (Sequence[str], Sequence[str], int) ->
+    #     Sequence[api_proto.issue_objects_pb2.Issue.LabelValue]
+    """Convert string labels to LabelValues for non-enum-field labels
+
+    Args:
+      labels: Sequence of string labels
+      project_id: ID of the Project these labels belong to.
+
+    Return:
+      Sequence of protoc IssueValues for given `labels` that
+      do not represent enum field values.
+    """
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    non_fd_labels, non_fd_der_labels = tbo.ExplicitAndDerivedNonMaskedLabels(
+        labels, derived_labels, config)
+    api_labels = []
+    for label in non_fd_labels:
+      api_labels.append(
+          issue_objects_pb2.Issue.LabelValue(
+              label=label,
+              derivation=issue_objects_pb2.Derivation.Value('EXPLICIT')))
+    for label in non_fd_der_labels:
+      api_labels.append(
+          issue_objects_pb2.Issue.LabelValue(
+              label=label,
+              derivation=issue_objects_pb2.Derivation.Value('RULE')))
+    return api_labels
+
+  def ConvertEnumFieldValues(self, labels, derived_labels, project_id):
+    # type: (Sequence[str], Sequence[str], int) ->
+    #     Sequence[api_proto.issue_objects_pb2.FieldValue]
+    """Convert string labels to FieldValues for enum-field labels
+
+    Args:
+      labels: Sequence of string labels
+      project_id: ID of the Project these labels belong to.
+
+    Return:
+      Sequence of protoc FieldValues only for given `labels` that
+      represent enum field values.
+    """
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    enum_ids_by_name = {
+        fd.field_name.lower(): fd.field_id
+        for fd in config.field_defs
+        if fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE
+        and not fd.is_deleted
+    }
+    resource_names_dict = rnc.ConvertFieldDefNames(
+        self.cnxn, enum_ids_by_name.values(), project_id, self.services)
+
+    api_fvs = []
+
+    labels_by_prefix = tbo.LabelsByPrefix(labels, enum_ids_by_name.keys())
+    for lower_field_name, values in labels_by_prefix.items():
+      field_id = enum_ids_by_name.get(lower_field_name)
+      resource_name = resource_names_dict.get(field_id)
+      if not resource_name:
+        continue
+      api_fvs.extend(
+          [
+              issue_objects_pb2.FieldValue(
+                  field=resource_name,
+                  value=value,
+                  derivation=issue_objects_pb2.Derivation.Value(
+                      'EXPLICIT')) for value in values
+          ])
+
+    der_labels_by_prefix = tbo.LabelsByPrefix(
+        derived_labels, enum_ids_by_name.keys())
+    for lower_field_name, values in der_labels_by_prefix.items():
+      field_id = enum_ids_by_name.get(lower_field_name)
+      resource_name = resource_names_dict.get(field_id)
+      if not resource_name:
+        continue
+      api_fvs.extend(
+          [
+              issue_objects_pb2.FieldValue(
+                  field=resource_name,
+                  value=value,
+                  derivation=issue_objects_pb2.Derivation.Value('RULE'))
+              for value in values
+          ])
+
+    return api_fvs
+
+  def ConvertProject(self, project):
+    # type: (proto.project_pb2.Project) ->
+    #     api_proto.project_objects_pb2.Project
+    """Convert a protorpc Project to its protoc Project."""
+
+    return project_objects_pb2.Project(
+        name=rnc.ConvertProjectName(
+            self.cnxn, project.project_id, self.services),
+        display_name=project.project_name,
+        summary=project.summary,
+        thumbnail_url=project_helpers.GetThumbnailUrl(project.logo_gcs_id))
+
+  def ConvertProjects(self, projects):
+    # type: (Sequence[proto.project_pb2.Project]) ->
+    #     Sequence[api_proto.project_objects_pb2.Project]
+    """Convert a Sequence of protorpc Projects to protoc Projects."""
+    return [self.ConvertProject(proj) for proj in projects]
+
+  def ConvertProjectConfig(self, project_config):
+    # type: (proto.tracker_pb2.ProjectIssueConfig) ->
+    #     api_proto.project_objects_pb2.ProjectConfig
+    """Convert protorpc ProjectIssueConfig to protoc ProjectConfig."""
+    project = self.services.project.GetProject(
+        self.cnxn, project_config.project_id)
+    project_grid_config = project_objects_pb2.ProjectConfig.GridViewConfig(
+        default_x_attr=project_config.default_x_attr,
+        default_y_attr=project_config.default_y_attr)
+    template_names = rnc.ConvertTemplateNames(
+        self.cnxn, project_config.project_id, [
+            project_config.default_template_for_developers,
+            project_config.default_template_for_users
+        ], self.services)
+    return project_objects_pb2.ProjectConfig(
+        name=rnc.ConvertProjectConfigName(
+            self.cnxn, project_config.project_id, self.services),
+        exclusive_label_prefixes=project_config.exclusive_label_prefixes,
+        member_default_query=project_config.member_default_query,
+        default_sort=project_config.default_sort_spec,
+        default_columns=self._ComputeIssuesListColumns(
+            project_config.default_col_spec),
+        project_grid_config=project_grid_config,
+        member_default_template=template_names.get(
+            project_config.default_template_for_developers),
+        non_members_default_template=template_names.get(
+            project_config.default_template_for_users),
+        revision_url_format=project.revision_url_format,
+        custom_issue_entry_url=project_config.custom_issue_entry_url)
+
+  def CreateProjectMember(self, cnxn, project_id, user_id, role):
+    # type: (MonorailContext, int, int, str) ->
+    #     api_proto.project_objects_pb2.ProjectMember
+    """Creates a ProjectMember object from specified parameters.
+
+    Args:
+      cnxn: MonorailConnection object.
+      project_id: ID of the Project the User is a member of.
+      user_id: ID of the user who is a member.
+      role: str specifying the user's role based on a ProjectRole value.
+
+    Return:
+      A protoc ProjectMember object.
+    """
+    name = rnc.ConvertProjectMemberName(
+        cnxn, project_id, user_id, self.services)
+    return project_objects_pb2.ProjectMember(
+        name=name,
+        role=project_objects_pb2.ProjectMember.ProjectRole.Value(role))
+
+  def ConvertLabelDefs(self, label_defs, project_id):
+    # type: (Sequence[proto.tracker_pb2.LabelDef], int) ->
+    #     Sequence[api_proto.project_objects_pb2.LabelDef]
+    """Convert protorpc LabelDefs to protoc LabelDefs"""
+    resource_names_dict = rnc.ConvertLabelDefNames(
+        self.cnxn, [ld.label for ld in label_defs], project_id, self.services)
+
+    api_lds = []
+    for ld in label_defs:
+      state = project_objects_pb2.LabelDef.LabelDefState.Value('ACTIVE')
+      if ld.deprecated:
+        state = project_objects_pb2.LabelDef.LabelDefState.Value('DEPRECATED')
+      api_lds.append(
+          project_objects_pb2.LabelDef(
+              name=resource_names_dict.get(ld.label),
+              value=ld.label,
+              docstring=ld.label_docstring,
+              state=state))
+    return api_lds
+
+  def ConvertStatusDefs(self, status_defs, project_id):
+    # type: (Sequence[proto.tracker_pb2.StatusDef], int) ->
+    #     Sequence[api_proto.project_objects_pb2.StatusDef]
+    """Convert protorpc StatusDefs to protoc StatusDefs
+
+    Args:
+      status_defs: Sequence of StatusDefs.
+      project_id: ID of the Project these belong to.
+
+    Returns:
+      Sequence of protoc StatusDefs in the same order they are given in
+      `status_defs`.
+    """
+    resource_names_dict = rnc.ConvertStatusDefNames(
+        self.cnxn, [sd.status for sd in status_defs], project_id, self.services)
+    config = self.services.config.GetProjectConfig(self.cnxn, project_id)
+    mergeable_statuses = set(config.statuses_offer_merge)
+
+    # Rank is only surfaced as positional value in well_known_statuses
+    rank_by_status = {}
+    for rank, sd in enumerate(config.well_known_statuses):
+      rank_by_status[sd.status] = rank
+
+    api_sds = []
+    for sd in status_defs:
+      state = project_objects_pb2.StatusDef.StatusDefState.Value('ACTIVE')
+      if sd.deprecated:
+        state = project_objects_pb2.StatusDef.StatusDefState.Value('DEPRECATED')
+
+      if sd.means_open:
+        status_type = project_objects_pb2.StatusDef.StatusDefType.Value('OPEN')
+      else:
+        if sd.status in mergeable_statuses:
+          status_type = project_objects_pb2.StatusDef.StatusDefType.Value(
+              'MERGED')
+        else:
+          status_type = project_objects_pb2.StatusDef.StatusDefType.Value(
+              'CLOSED')
+
+      api_sd = project_objects_pb2.StatusDef(
+          name=resource_names_dict.get(sd.status),
+          value=sd.status,
+          type=status_type,
+          rank=rank_by_status[sd.status],
+          docstring=sd.status_docstring,
+          state=state,
+      )
+      api_sds.append(api_sd)
+    return api_sds
+
+  def ConvertComponentDef(self, component_def):
+    # type: (proto.tracker_pb2.ComponentDef) ->
+    #     api_proto.project_objects.ComponentDef
+    """Convert a protorpc ComponentDef to a protoc ComponentDef."""
+    return self.ConvertComponentDefs([component_def],
+                                     component_def.project_id)[0]
+
+  def ConvertComponentDefs(self, component_defs, project_id):
+    # type: (Sequence[proto.tracker_pb2.ComponentDef], int) ->
+    #     Sequence[api_proto.project_objects.ComponentDef]
+    """Convert sequence of protorpc ComponentDefs to protoc ComponentDefs
+
+    Args:
+      component_defs: Sequence of protoc ComponentDefs.
+      project_id: ID of the Project these belong to.
+
+    Returns:
+      Sequence of protoc ComponentDefs in the same order they are given in
+      `component_defs`.
+    """
+    resource_names_dict = rnc.ConvertComponentDefNames(
+        self.cnxn, [cd.component_id for cd in component_defs], project_id,
+        self.services)
+    involved_user_ids = tbo.UsersInvolvedInComponents(component_defs)
+    user_resource_names_dict = rnc.ConvertUserNames(involved_user_ids)
+
+    all_label_ids = set()
+    for cd in component_defs:
+      all_label_ids.update(cd.label_ids)
+
+    # If this becomes a performance issue, we should add bulk look up.
+    labels_by_id = {
+        label_id: self.services.config.LookupLabel(
+            self.cnxn, project_id, label_id) for label_id in all_label_ids
+    }
+
+    api_cds = []
+    for cd in component_defs:
+      state = project_objects_pb2.ComponentDef.ComponentDefState.Value('ACTIVE')
+      if cd.deprecated:
+        state = project_objects_pb2.ComponentDef.ComponentDefState.Value(
+            'DEPRECATED')
+
+      api_cd = project_objects_pb2.ComponentDef(
+          name=resource_names_dict.get(cd.component_id),
+          value=cd.path,
+          docstring=cd.docstring,
+          state=state,
+          admins=[
+              user_resource_names_dict.get(admin_id)
+              for admin_id in cd.admin_ids
+          ],
+          ccs=[user_resource_names_dict.get(cc_id) for cc_id in cd.cc_ids],
+          creator=user_resource_names_dict.get(cd.creator_id),
+          modifier=user_resource_names_dict.get(cd.modifier_id),
+          create_time=timestamp_pb2.Timestamp(seconds=cd.created),
+          modify_time=timestamp_pb2.Timestamp(seconds=cd.modified),
+          labels=[labels_by_id[label_id] for label_id in cd.label_ids],
+      )
+      api_cds.append(api_cd)
+    return api_cds
+
+  def ConvertProjectSavedQueries(self, saved_queries, project_id):
+    # type: (Sequence[proto.tracker_pb2.SavedQuery], int) ->
+    #     Sequence(api_proto.project_objects.ProjectSavedQuery)
+    """Convert sequence of protorpc SavedQueries to protoc ProjectSavedQueries
+
+    Args:
+      saved_queries: Sequence of SavedQueries.
+      project_id: ID of the Project these belong to.
+
+    Returns:
+      Sequence of protoc ProjectSavedQueries in the same order they are given in
+      `saved_queries`. In the event any items in `saved_queries` are not found
+      or don't belong to the project, they will be omitted from the result.
+    """
+    resource_names_dict = rnc.ConvertProjectSavedQueryNames(
+        self.cnxn, [sq.query_id for sq in saved_queries], project_id,
+        self.services)
+    api_psqs = []
+    for sq in saved_queries:
+      if sq.query_id not in resource_names_dict:
+        continue
+
+      # TODO(crbug/monorail/7756): Remove base_query_id, avoid confusions.
+      # Until then we have to expand the query by including base_query_id.
+      # base_query_id can only be in the set of DEFAULT_CANNED_QUERIES.
+      if sq.base_query_id:
+        query = '{} {}'.format(tbo.GetBuiltInQuery(sq.base_query_id), sq.query)
+      else:
+        query = sq.query
+
+      api_psqs.append(
+          project_objects_pb2.ProjectSavedQuery(
+              name=resource_names_dict.get(sq.query_id),
+              display_name=sq.name,
+              query=query))
+    return api_psqs
