diff --git a/services/api_svc_v1.py b/services/api_svc_v1.py
new file mode 100644
index 0000000..20a9c8b
--- /dev/null
+++ b/services/api_svc_v1.py
@@ -0,0 +1,1511 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""API service.
+
+To manually test this API locally, use the following steps:
+1. Start the development server via 'make serve'.
+2. Start a new Chrome session via the command-line:
+  PATH_TO_CHROME --user-data-dir=/tmp/test \
+  --unsafely-treat-insecure-origin-as-secure=http://localhost:8080
+3. Visit http://localhost:8080/_ah/api/explorer
+4. Click shield icon in the omnibar and allow unsafe scripts.
+5. Click on the "Services" menu item in the API Explorer.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import calendar
+import datetime
+import endpoints
+import functools
+import logging
+import re
+import time
+from google.appengine.api import oauth
+from protorpc import message_types
+from protorpc import protojson
+from protorpc import remote
+
+import settings
+from businesslogic import work_env
+from features import filterrules_helpers
+from features import send_notifications
+from framework import authdata
+from framework import exceptions
+from framework import framework_constants
+from framework import framework_helpers
+from framework import framework_views
+from framework import monitoring
+from framework import monorailrequest
+from framework import permissions
+from framework import ratelimiter
+from framework import sql
+from project import project_helpers
+from proto import api_pb2_v1
+from proto import project_pb2
+from proto import tracker_pb2
+from search import frontendsearchpipeline
+from services import api_pb2_v1_helpers
+from services import client_config_svc
+from services import service_manager
+from services import tracker_fulltext
+from sitewide import sitewide_helpers
+from tracker import field_helpers
+from tracker import issuedetailezt
+from tracker import tracker_bizobj
+from tracker import tracker_constants
+from tracker import tracker_helpers
+
+from infra_libs import ts_mon
+
+
+ENDPOINTS_API_NAME = 'monorail'
+DOC_URL = (
+    'https://chromium.googlesource.com/infra/infra/+/main/'
+    'appengine/monorail/doc/api.md')
+
+
+def monorail_api_method(
+    request_message, response_message, **kwargs):
+  """Extends endpoints.method by performing base checks."""
+  time_fn = kwargs.pop('time_fn', time.time)
+  method_name = kwargs.get('name', '')
+  method_path = kwargs.get('path', '')
+  http_method = kwargs.get('http_method', '')
+  def new_decorator(func):
+    @endpoints.method(request_message, response_message, **kwargs)
+    @functools.wraps(func)
+    def wrapper(self, *args, **kwargs):
+      start_time = time_fn()
+      approximate_http_status = 200
+      request = args[0]
+      ret = None
+      c_id = None
+      c_email = None
+      mar = None
+      try:
+        if settings.read_only and http_method.lower() != 'get':
+          raise permissions.PermissionException(
+              'This request is not allowed in read-only mode')
+        requester = endpoints.get_current_user()
+        logging.info('requester is %r', requester)
+        logging.info('args is %r', args)
+        logging.info('kwargs is %r', kwargs)
+        auth_client_ids, auth_emails = (
+            client_config_svc.GetClientConfigSvc().GetClientIDEmails())
+        if settings.local_mode:
+          auth_client_ids.append(endpoints.API_EXPLORER_CLIENT_ID)
+        if self._services is None:
+          self._set_services(service_manager.set_up_services())
+        cnxn = sql.MonorailConnection()
+        c_id, c_email = api_base_checks(
+            request, requester, self._services, cnxn,
+            auth_client_ids, auth_emails)
+        mar = self.mar_factory(request, cnxn)
+        self.ratelimiter.CheckStart(c_id, c_email, start_time)
+        monitoring.IncrementAPIRequestsCount(
+            'endpoints', c_id, client_email=c_email)
+        ret = func(self, mar, *args, **kwargs)
+      except exceptions.NoSuchUserException as e:
+        approximate_http_status = 404
+        raise endpoints.NotFoundException(
+            'The user does not exist: %s' % str(e))
+      except (exceptions.NoSuchProjectException,
+              exceptions.NoSuchIssueException,
+              exceptions.NoSuchComponentException) as e:
+        approximate_http_status = 404
+        raise endpoints.NotFoundException(str(e))
+      except (permissions.BannedUserException,
+              permissions.PermissionException) as e:
+        approximate_http_status = 403
+        logging.info('Allowlist ID %r email %r', auth_client_ids, auth_emails)
+        raise endpoints.ForbiddenException(str(e))
+      except endpoints.BadRequestException:
+        approximate_http_status = 400
+        raise
+      except endpoints.UnauthorizedException:
+        approximate_http_status = 401
+        # Client will refresh token and retry.
+        raise
+      except oauth.InvalidOAuthTokenError:
+        approximate_http_status = 401
+        # Client will refresh token and retry.
+        raise endpoints.UnauthorizedException(
+            'Auth error: InvalidOAuthTokenError')
+      except (exceptions.GroupExistsException,
+              exceptions.InvalidComponentNameException,
+              ratelimiter.ApiRateLimitExceeded) as e:
+        approximate_http_status = 400
+        raise endpoints.BadRequestException(str(e))
+      except Exception as e:
+        approximate_http_status = 500
+        logging.exception('Unexpected error in monorail API')
+        raise
+      finally:
+        if mar:
+          mar.CleanUp()
+        now = time_fn()
+        if c_id and c_email:
+          self.ratelimiter.CheckEnd(c_id, c_email, now, start_time)
+        _RecordMonitoringStats(
+            start_time, request, ret, (method_name or func.__name__),
+            (method_path or func.__name__), approximate_http_status, now)
+
+      return ret
+
+    return wrapper
+  return new_decorator
+
+
+def _RecordMonitoringStats(
+    start_time,
+    request,
+    response,
+    method_name,
+    method_path,
+    approximate_http_status,
+    now=None):
+  now = now or time.time()
+  elapsed_ms = int((now - start_time) * 1000)
+  # Use the api name, not the request path, to prevent an explosion in
+  # possible field values.
+  method_identifier = (
+      ENDPOINTS_API_NAME + '.endpoints.' + method_name + '/' + method_path)
+
+  # Endpoints APIs don't return the full set of http status values.
+  fields = monitoring.GetCommonFields(
+      approximate_http_status, method_identifier)
+
+  monitoring.AddServerDurations(elapsed_ms, fields)
+  monitoring.IncrementServerResponseStatusCount(fields)
+  request_length = len(protojson.encode_message(request))
+  monitoring.AddServerRequesteBytes(request_length, fields)
+  response_length = 0
+  if response:
+    response_length = len(protojson.encode_message(response))
+  monitoring.AddServerResponseBytes(response_length, fields)
+
+
+def _is_requester_in_allowed_domains(requester):
+  if requester.email().endswith(settings.api_allowed_email_domains):
+    if framework_constants.MONORAIL_SCOPE in oauth.get_authorized_scopes(
+        framework_constants.MONORAIL_SCOPE):
+      return True
+    else:
+      logging.info("User is not authenticated with monorail scope")
+  return False
+
+def api_base_checks(request, requester, services, cnxn,
+                    auth_client_ids, auth_emails):
+  """Base checks for API users.
+
+  Args:
+    request: The HTTP request from Cloud Endpoints.
+    requester: The user who sends the request.
+    services: Services object.
+    cnxn: connection to the SQL database.
+    auth_client_ids: authorized client ids.
+    auth_emails: authorized emails when client is anonymous.
+
+  Returns:
+    Client ID and client email.
+
+  Raises:
+    endpoints.UnauthorizedException: If the requester is anonymous.
+    exceptions.NoSuchUserException: If the requester does not exist in Monorail.
+    NoSuchProjectException: If the project does not exist in Monorail.
+    permissions.BannedUserException: If the requester is banned.
+    permissions.PermissionException: If the requester does not have
+        permisssion to view.
+  """
+  valid_user = False
+  auth_err = ''
+  client_id = None
+
+  try:
+    client_id = oauth.get_client_id(framework_constants.OAUTH_SCOPE)
+    logging.info('Oauth client ID %s', client_id)
+  except oauth.Error as ex:
+    auth_err = 'oauth.Error: %s' % ex
+
+  if not requester:
+    try:
+      requester = oauth.get_current_user(framework_constants.OAUTH_SCOPE)
+      logging.info('Oauth requester %s', requester.email())
+    except oauth.Error as ex:
+      logging.info('Got oauth error: %r', ex)
+      auth_err = 'oauth.Error: %s' % ex
+
+  if client_id and requester:
+    if client_id in auth_client_ids:
+      # A allowlisted client app can make requests for any user or anon.
+      logging.info('Client ID %r is allowlisted', client_id)
+      valid_user = True
+    elif requester.email() in auth_emails:
+      # A allowlisted user account can make requests via any client app.
+      logging.info('Client email %r is allowlisted', requester.email())
+      valid_user = True
+    elif _is_requester_in_allowed_domains(requester):
+      # A user with an allowed-domain email and authenticated with the
+      # monorail scope is allowed to make requests via any client app.
+      logging.info(
+          'User email %r is within the allowed domains', requester.email())
+      valid_user = True
+    else:
+      auth_err = (
+          'Neither client ID %r nor email %r is allowlisted' %
+          (client_id, requester.email()))
+
+  if not valid_user:
+    raise endpoints.UnauthorizedException('Auth error: %s' % auth_err)
+  else:
+    logging.info('API request from user %s:%s', client_id, requester.email())
+
+  project_name = None
+  if hasattr(request, 'projectId'):
+    project_name = request.projectId
+  issue_local_id = None
+  if hasattr(request, 'issueId'):
+    issue_local_id = request.issueId
+  # This could raise exceptions.NoSuchUserException
+  requester_id = services.user.LookupUserID(cnxn, requester.email())
+  auth = authdata.AuthData.FromUserID(cnxn, requester_id, services)
+  if permissions.IsBanned(auth.user_pb, auth.user_view):
+    raise permissions.BannedUserException(
+        'The user %s has been banned from using Monorail' %
+        requester.email())
+  if project_name:
+    project = services.project.GetProjectByName(
+        cnxn, project_name)
+    if not project:
+      raise exceptions.NoSuchProjectException(
+          'Project %s does not exist' % project_name)
+    if project.state != project_pb2.ProjectState.LIVE:
+      raise permissions.PermissionException(
+          'API may not access project %s because it is not live'
+          % project_name)
+    if not permissions.UserCanViewProject(
+        auth.user_pb, auth.effective_ids, project):
+      raise permissions.PermissionException(
+          'The user %s has no permission for project %s' %
+          (requester.email(), project_name))
+    if issue_local_id:
+      # This may raise a NoSuchIssueException.
+      issue = services.issue.GetIssueByLocalID(
+          cnxn, project.project_id, issue_local_id)
+      perms = permissions.GetPermissions(
+          auth.user_pb, auth.effective_ids, project)
+      config = services.config.GetProjectConfig(cnxn, project.project_id)
+      granted_perms = tracker_bizobj.GetGrantedPerms(
+          issue, auth.effective_ids, config)
+      if not permissions.CanViewIssue(
+          auth.effective_ids, perms, project, issue,
+          granted_perms=granted_perms):
+        raise permissions.PermissionException(
+            'User is not allowed to view this issue %s:%d' %
+            (project_name, issue_local_id))
+
+  return client_id, requester.email()
+
+
+@endpoints.api(name=ENDPOINTS_API_NAME, version='v1',
+               description='Monorail API to manage issues.',
+               auth_level=endpoints.AUTH_LEVEL.NONE,
+               allowed_client_ids=endpoints.SKIP_CLIENT_ID_CHECK,
+               documentation=DOC_URL)
+class MonorailApi(remote.Service):
+
+  # Class variables. Handy to mock.
+  _services = None
+  _mar = None
+
+  ratelimiter = ratelimiter.ApiRateLimiter()
+
+  @classmethod
+  def _set_services(cls, services):
+    cls._services = services
+
+  def mar_factory(self, request, cnxn):
+    if not self._mar:
+      self._mar = monorailrequest.MonorailApiRequest(
+          request, self._services, cnxn=cnxn)
+    return self._mar
+
+  def aux_delete_comment(self, mar, request, delete=True):
+    action_name = 'delete' if delete else 'undelete'
+
+    with work_env.WorkEnv(mar, self._services) as we:
+      issue = we.GetIssueByLocalID(
+          mar.project_id, request.issueId, use_cache=False)
+      all_comments = we.ListIssueComments(issue)
+      try:
+        issue_comment = all_comments[request.commentId]
+      except IndexError:
+        raise exceptions.NoSuchIssueException(
+              'The issue %s:%d does not have comment %d.' %
+              (mar.project_name, request.issueId, request.commentId))
+
+      issue_perms = permissions.UpdateIssuePermissions(
+          mar.perms, mar.project, issue, mar.auth.effective_ids,
+          granted_perms=mar.granted_perms)
+      commenter = we.GetUser(issue_comment.user_id)
+
+      if not permissions.CanDeleteComment(
+          issue_comment, commenter, mar.auth.user_id, issue_perms):
+        raise permissions.PermissionException(
+              'User is not allowed to %s the comment %d of issue %s:%d' %
+              (action_name, request.commentId, mar.project_name,
+               request.issueId))
+
+      we.DeleteComment(issue, issue_comment, delete=delete)
+    return api_pb2_v1.IssuesCommentsDeleteResponse()
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_COMMENTS_DELETE_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesCommentsDeleteResponse,
+      path='projects/{projectId}/issues/{issueId}/comments/{commentId}',
+      http_method='DELETE',
+      name='issues.comments.delete')
+  def issues_comments_delete(self, mar, request):
+    """Delete a comment."""
+    return self.aux_delete_comment(mar, request, True)
+
+  def parse_imported_reporter(self, mar, request):
+    """Handle the case where an API client is importing issues for users.
+
+    Args:
+      mar: monorail API request object including auth and perms.
+      request: A request PB that defines author and published fields.
+
+    Returns:
+      A pair (reporter_id, timestamp) with the user ID of the user to
+      attribute the comment to and timestamp of the original comment.
+      If the author field is not set, this is not an import request
+      and the comment is attributed to the API client as per normal.
+      An API client that is attempting to post on behalf of other
+      users must have the ImportComment permission in the current
+      project.
+    """
+    reporter_id = mar.auth.user_id
+    timestamp = None
+    if (request.author and request.author.name and
+        request.author.name != mar.auth.email):
+      if not mar.perms.HasPerm(
+          permissions.IMPORT_COMMENT, mar.auth.user_id, mar.project):
+        logging.info('name is %r', request.author.name)
+        raise permissions.PermissionException(
+            'User is not allowed to attribue comments to others')
+      reporter_id = self._services.user.LookupUserID(
+              mar.cnxn, request.author.name, autocreate=True)
+      logging.info('Importing issue or comment.')
+      if request.published:
+        timestamp = calendar.timegm(request.published.utctimetuple())
+
+    return reporter_id, timestamp
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_COMMENTS_INSERT_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesCommentsInsertResponse,
+      path='projects/{projectId}/issues/{issueId}/comments',
+      http_method='POST',
+      name='issues.comments.insert')
+  def issues_comments_insert(self, mar, request):
+    # type (...) -> proto.api_pb2_v1.IssuesCommentsInsertResponse
+    """Add a comment."""
+    # Because we will modify issues, load from DB rather than cache.
+    issue = self._services.issue.GetIssueByLocalID(
+        mar.cnxn, mar.project_id, request.issueId, use_cache=False)
+    old_owner_id = tracker_bizobj.GetOwnerId(issue)
+    if not permissions.CanCommentIssue(
+        mar.auth.effective_ids, mar.perms, mar.project, issue,
+        mar.granted_perms):
+      raise permissions.PermissionException(
+          'User is not allowed to comment this issue (%s, %d)' %
+          (request.projectId, request.issueId))
+
+    # Temporary block on updating approval subfields.
+    if request.updates and request.updates.fieldValues:
+      fds_by_name = {fd.field_name.lower():fd for fd in mar.config.field_defs}
+      for fv in request.updates.fieldValues:
+        # Checking for fv.approvalName is unreliable since it can be removed.
+        fd = fds_by_name.get(fv.fieldName.lower())
+        if fd and fd.approval_id:
+          raise exceptions.ActionNotSupported(
+              'No API support for approval field changes: (approval %s owns %s)'
+              % (fd.approval_id, fd.field_name))
+        # if fd was None, that gets dealt with later.
+
+    if request.content and len(
+        request.content) > tracker_constants.MAX_COMMENT_CHARS:
+      raise endpoints.BadRequestException(
+          'Comment is too long on this issue (%s, %d' %
+          (request.projectId, request.issueId))
+
+    updates_dict = {}
+    move_to_project = None
+    if request.updates:
+      if not permissions.CanEditIssue(
+          mar.auth.effective_ids, mar.perms, mar.project, issue,
+          mar.granted_perms):
+        raise permissions.PermissionException(
+            'User is not allowed to edit this issue (%s, %d)' %
+            (request.projectId, request.issueId))
+      if request.updates.moveToProject:
+        move_to = request.updates.moveToProject.lower()
+        move_to_project = issuedetailezt.CheckMoveIssueRequest(
+            self._services, mar, issue, True, move_to, mar.errors)
+        if mar.errors.AnyErrors():
+          raise endpoints.BadRequestException(mar.errors.move_to)
+
+      updates_dict['summary'] = request.updates.summary
+      updates_dict['status'] = request.updates.status
+      updates_dict['is_description'] = request.updates.is_description
+      if request.updates.owner:
+        # A current issue owner can be removed via the API with a
+        # NO_USER_NAME('----') input.
+        if request.updates.owner == framework_constants.NO_USER_NAME:
+          updates_dict['owner'] = framework_constants.NO_USER_SPECIFIED
+        else:
+          new_owner_id = self._services.user.LookupUserID(
+              mar.cnxn, request.updates.owner)
+          valid, msg = tracker_helpers.IsValidIssueOwner(
+              mar.cnxn, mar.project, new_owner_id, self._services)
+          if not valid:
+            raise endpoints.BadRequestException(msg)
+          updates_dict['owner'] = new_owner_id
+      updates_dict['cc_add'], updates_dict['cc_remove'] = (
+          api_pb2_v1_helpers.split_remove_add(request.updates.cc))
+      updates_dict['cc_add'] = list(self._services.user.LookupUserIDs(
+          mar.cnxn, updates_dict['cc_add'], autocreate=True).values())
+      updates_dict['cc_remove'] = list(self._services.user.LookupUserIDs(
+          mar.cnxn, updates_dict['cc_remove']).values())
+      updates_dict['labels_add'], updates_dict['labels_remove'] = (
+          api_pb2_v1_helpers.split_remove_add(request.updates.labels))
+      blocked_on_add_strs, blocked_on_remove_strs = (
+          api_pb2_v1_helpers.split_remove_add(request.updates.blockedOn))
+      updates_dict['blocked_on_add'] = api_pb2_v1_helpers.issue_global_ids(
+          blocked_on_add_strs, issue.project_id, mar,
+          self._services)
+      updates_dict['blocked_on_remove'] = api_pb2_v1_helpers.issue_global_ids(
+          blocked_on_remove_strs, issue.project_id, mar,
+          self._services)
+      blocking_add_strs, blocking_remove_strs = (
+          api_pb2_v1_helpers.split_remove_add(request.updates.blocking))
+      updates_dict['blocking_add'] = api_pb2_v1_helpers.issue_global_ids(
+          blocking_add_strs, issue.project_id, mar,
+          self._services)
+      updates_dict['blocking_remove'] = api_pb2_v1_helpers.issue_global_ids(
+          blocking_remove_strs, issue.project_id, mar,
+          self._services)
+      components_add_strs, components_remove_strs = (
+          api_pb2_v1_helpers.split_remove_add(request.updates.components))
+      updates_dict['components_add'] = (
+          api_pb2_v1_helpers.convert_component_ids(
+              mar.config, components_add_strs))
+      updates_dict['components_remove'] = (
+          api_pb2_v1_helpers.convert_component_ids(
+              mar.config, components_remove_strs))
+      if request.updates.mergedInto:
+        merge_project_name, merge_local_id = tracker_bizobj.ParseIssueRef(
+            request.updates.mergedInto)
+        merge_into_project = self._services.project.GetProjectByName(
+            mar.cnxn, merge_project_name or issue.project_name)
+        # Because we will modify issues, load from DB rather than cache.
+        merge_into_issue = self._services.issue.GetIssueByLocalID(
+            mar.cnxn, merge_into_project.project_id, merge_local_id,
+            use_cache=False)
+        merge_allowed = tracker_helpers.IsMergeAllowed(
+            merge_into_issue, mar, self._services)
+        if not merge_allowed:
+          raise permissions.PermissionException(
+            'User is not allowed to merge into issue %s:%s' %
+            (merge_into_issue.project_name, merge_into_issue.local_id))
+        updates_dict['merged_into'] = merge_into_issue.issue_id
+      (updates_dict['field_vals_add'], updates_dict['field_vals_remove'],
+       updates_dict['fields_clear'], updates_dict['fields_labels_add'],
+       updates_dict['fields_labels_remove']) = (
+          api_pb2_v1_helpers.convert_field_values(
+              request.updates.fieldValues, mar, self._services))
+
+    field_helpers.ValidateCustomFields(
+        mar.cnxn, self._services,
+        (updates_dict.get('field_vals_add', []) +
+         updates_dict.get('field_vals_remove', [])),
+        mar.config, mar.project, ezt_errors=mar.errors)
+    if mar.errors.AnyErrors():
+      raise endpoints.BadRequestException(
+          'Invalid field values: %s' % mar.errors.custom_fields)
+
+    updates_dict['labels_add'] = (
+        updates_dict.get('labels_add', []) +
+        updates_dict.get('fields_labels_add', []))
+    updates_dict['labels_remove'] = (
+        updates_dict.get('labels_remove', []) +
+        updates_dict.get('fields_labels_remove', []))
+
+    # TODO(jrobbins): Stop using updates_dict in the first place.
+    delta = tracker_bizobj.MakeIssueDelta(
+        updates_dict.get('status'),
+        updates_dict.get('owner'),
+        updates_dict.get('cc_add', []),
+        updates_dict.get('cc_remove', []),
+        updates_dict.get('components_add', []),
+        updates_dict.get('components_remove', []),
+        (updates_dict.get('labels_add', []) +
+         updates_dict.get('fields_labels_add', [])),
+        (updates_dict.get('labels_remove', []) +
+         updates_dict.get('fields_labels_remove', [])),
+        updates_dict.get('field_vals_add', []),
+        updates_dict.get('field_vals_remove', []),
+        updates_dict.get('fields_clear', []),
+        updates_dict.get('blocked_on_add', []),
+        updates_dict.get('blocked_on_remove', []),
+        updates_dict.get('blocking_add', []),
+        updates_dict.get('blocking_remove', []),
+        updates_dict.get('merged_into'),
+        updates_dict.get('summary'))
+
+    importer_id = None
+    reporter_id, timestamp = self.parse_imported_reporter(mar, request)
+    if reporter_id != mar.auth.user_id:
+      importer_id = mar.auth.user_id
+
+    # TODO(jrobbins): Finish refactoring to make everything go through work_env.
+    _, comment = self._services.issue.DeltaUpdateIssue(
+        cnxn=mar.cnxn, services=self._services,
+        reporter_id=reporter_id, project_id=mar.project_id, config=mar.config,
+        issue=issue, delta=delta, index_now=False, comment=request.content,
+        is_description=updates_dict.get('is_description'),
+        timestamp=timestamp, importer_id=importer_id)
+
+    move_comment = None
+    if move_to_project:
+      old_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
+      tracker_fulltext.UnindexIssues([issue.issue_id])
+      moved_back_iids = self._services.issue.MoveIssues(
+          mar.cnxn, move_to_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)
+      move_comment = self._services.issue.CreateIssueComment(
+        mar.cnxn, issue, mar.auth.user_id, content, amendments=[
+            tracker_bizobj.MakeProjectAmendment(move_to_project.project_name)])
+
+    if 'merged_into' in updates_dict:
+      new_starrers = tracker_helpers.GetNewIssueStarrers(
+          mar.cnxn, self._services, [issue.issue_id], merge_into_issue.issue_id)
+      tracker_helpers.AddIssueStarrers(
+          mar.cnxn, self._services, mar,
+          merge_into_issue.issue_id, merge_into_project, new_starrers)
+      # Load target issue again to get the updated star count.
+      merge_into_issue = self._services.issue.GetIssue(
+        mar.cnxn, merge_into_issue.issue_id, use_cache=False)
+      merge_comment_pb = tracker_helpers.MergeCCsAndAddComment(
+        self._services, mar, issue, merge_into_issue)
+      hostport = framework_helpers.GetHostPort(
+          project_name=merge_into_issue.project_name)
+      send_notifications.PrepareAndSendIssueChangeNotification(
+          merge_into_issue.issue_id, hostport,
+          mar.auth.user_id, send_email=True, comment_id=merge_comment_pb.id)
+
+    tracker_fulltext.IndexIssues(
+        mar.cnxn, [issue], self._services.user, self._services.issue,
+        self._services.config)
+
+    comment = comment or move_comment
+    if comment is None:
+      return api_pb2_v1.IssuesCommentsInsertResponse()
+
+    cmnts = self._services.issue.GetCommentsForIssue(mar.cnxn, issue.issue_id)
+    seq = len(cmnts) - 1
+
+    if request.sendEmail:
+      hostport = framework_helpers.GetHostPort(project_name=issue.project_name)
+      send_notifications.PrepareAndSendIssueChangeNotification(
+          issue.issue_id, hostport, comment.user_id, send_email=True,
+          old_owner_id=old_owner_id, comment_id=comment.id)
+
+    issue_perms = permissions.UpdateIssuePermissions(
+        mar.perms, mar.project, issue, mar.auth.effective_ids,
+        granted_perms=mar.granted_perms)
+    commenter = self._services.user.GetUser(mar.cnxn, comment.user_id)
+    can_delete = permissions.CanDeleteComment(
+        comment, commenter, mar.auth.user_id, issue_perms)
+    return api_pb2_v1.IssuesCommentsInsertResponse(
+        id=seq,
+        kind='monorail#issueComment',
+        author=api_pb2_v1_helpers.convert_person(
+            comment.user_id, mar.cnxn, self._services),
+        content=comment.content,
+        published=datetime.datetime.fromtimestamp(comment.timestamp),
+        updates=api_pb2_v1_helpers.convert_amendments(
+            issue, comment.amendments, mar, self._services),
+        canDelete=can_delete)
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_COMMENTS_LIST_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesCommentsListResponse,
+      path='projects/{projectId}/issues/{issueId}/comments',
+      http_method='GET',
+      name='issues.comments.list')
+  def issues_comments_list(self, mar, request):
+    """List all comments for an issue."""
+    issue = self._services.issue.GetIssueByLocalID(
+        mar.cnxn, mar.project_id, request.issueId)
+    comments = self._services.issue.GetCommentsForIssue(
+        mar.cnxn, issue.issue_id)
+    comments = [comment for comment in comments if not comment.approval_id]
+    visible_comments = []
+    for comment in comments[
+        request.startIndex:(request.startIndex + request.maxResults)]:
+      visible_comments.append(
+          api_pb2_v1_helpers.convert_comment(
+              issue, comment, mar, self._services, mar.granted_perms))
+
+    return api_pb2_v1.IssuesCommentsListResponse(
+        kind='monorail#issueCommentList',
+        totalResults=len(comments),
+        items=visible_comments)
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_COMMENTS_DELETE_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesCommentsDeleteResponse,
+      path='projects/{projectId}/issues/{issueId}/comments/{commentId}',
+      http_method='POST',
+      name='issues.comments.undelete')
+  def issues_comments_undelete(self, mar, request):
+    """Restore a deleted comment."""
+    return self.aux_delete_comment(mar, request, False)
+
+  @monorail_api_method(
+      api_pb2_v1.APPROVALS_COMMENTS_LIST_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.ApprovalsCommentsListResponse,
+      path='projects/{projectId}/issues/{issueId}/'
+            'approvals/{approvalName}/comments',
+      http_method='GET',
+      name='approvals.comments.list')
+  def approvals_comments_list(self, mar, request):
+    """List all comments for an issue approval."""
+    issue = self._services.issue.GetIssueByLocalID(
+        mar.cnxn, mar.project_id, request.issueId)
+    if not permissions.CanViewIssue(
+        mar.auth.effective_ids, mar.perms, mar.project, issue,
+        mar.granted_perms):
+      raise permissions.PermissionException(
+          'User is not allowed to view this issue (%s, %d)' %
+          (request.projectId, request.issueId))
+    config = self._services.config.GetProjectConfig(mar.cnxn, issue.project_id)
+    approval_fd = tracker_bizobj.FindFieldDef(request.approvalName, config)
+    if not approval_fd:
+      raise endpoints.BadRequestException(
+          'Field definition for %s not found in project config' %
+          request.approvalName)
+    comments = self._services.issue.GetCommentsForIssue(
+        mar.cnxn, issue.issue_id)
+    comments = [comment for comment in comments
+                if comment.approval_id == approval_fd.field_id]
+    visible_comments = []
+    for comment in comments[
+        request.startIndex:(request.startIndex + request.maxResults)]:
+      visible_comments.append(
+          api_pb2_v1_helpers.convert_approval_comment(
+              issue, comment, mar, self._services, mar.granted_perms))
+
+    return api_pb2_v1.ApprovalsCommentsListResponse(
+        kind='monorail#approvalCommentList',
+        totalResults=len(comments),
+        items=visible_comments)
+
+  @monorail_api_method(
+      api_pb2_v1.APPROVALS_COMMENTS_INSERT_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.ApprovalsCommentsInsertResponse,
+      path=("projects/{projectId}/issues/{issueId}/"
+            "approvals/{approvalName}/comments"),
+      http_method='POST',
+      name='approvals.comments.insert')
+  def approvals_comments_insert(self, mar, request):
+    # type (...) -> proto.api_pb2_v1.ApprovalsCommentsInsertResponse
+    """Add an approval comment."""
+    approval_fd = tracker_bizobj.FindFieldDef(
+        request.approvalName, mar.config)
+    if not approval_fd or (
+        approval_fd.field_type != tracker_pb2.FieldTypes.APPROVAL_TYPE):
+      raise endpoints.BadRequestException(
+          'Field definition for %s not found in project config' %
+          request.approvalName)
+    try:
+      issue = self._services.issue.GetIssueByLocalID(
+          mar.cnxn, mar.project_id, request.issueId)
+    except exceptions.NoSuchIssueException:
+      raise endpoints.BadRequestException(
+          'Issue %s:%s not found' % (request.projectId, request.issueId))
+    approval = tracker_bizobj.FindApprovalValueByID(
+        approval_fd.field_id, issue.approval_values)
+    if not approval:
+      raise endpoints.BadRequestException(
+          'Approval %s not found in issue.' % request.approvalName)
+
+    if not permissions.CanCommentIssue(
+        mar.auth.effective_ids, mar.perms, mar.project, issue,
+        mar.granted_perms):
+      raise permissions.PermissionException(
+          'User is not allowed to comment on this issue (%s, %d)' %
+          (request.projectId, request.issueId))
+
+    if request.content and len(
+        request.content) > tracker_constants.MAX_COMMENT_CHARS:
+      raise endpoints.BadRequestException(
+          'Comment is too long on this issue (%s, %d' %
+          (request.projectId, request.issueId))
+
+    updates_dict = {}
+    if request.approvalUpdates:
+      if request.approvalUpdates.fieldValues:
+        # Block updating field values that don't belong to the approval.
+        approvals_fds_by_name = {
+            fd.field_name.lower():fd for fd in mar.config.field_defs
+            if fd.approval_id == approval_fd.field_id}
+        for fv in request.approvalUpdates.fieldValues:
+          if approvals_fds_by_name.get(fv.fieldName.lower()) is None:
+            raise endpoints.BadRequestException(
+              'Field defition for %s not found in %s subfields.' %
+              (fv.fieldName, request.approvalName))
+        (updates_dict['field_vals_add'], updates_dict['field_vals_remove'],
+         updates_dict['fields_clear'], updates_dict['fields_labels_add'],
+         updates_dict['fields_labels_remove']) = (
+             api_pb2_v1_helpers.convert_field_values(
+                 request.approvalUpdates.fieldValues, mar, self._services))
+      if request.approvalUpdates.approvers:
+        if not permissions.CanUpdateApprovers(
+            mar.auth.effective_ids, mar.perms, mar.project,
+            approval.approver_ids):
+          raise permissions.PermissionException(
+              'User is not allowed to update approvers')
+        approvers_add, approvers_remove = api_pb2_v1_helpers.split_remove_add(
+            request.approvalUpdates.approvers)
+        updates_dict['approver_ids_add'] = list(
+            self._services.user.LookupUserIDs(mar.cnxn, approvers_add,
+              autocreate=True).values())
+        updates_dict['approver_ids_remove'] = list(
+            self._services.user.LookupUserIDs(mar.cnxn, approvers_remove,
+              autocreate=True).values())
+      if request.approvalUpdates.status:
+        status = tracker_pb2.ApprovalStatus(
+            api_pb2_v1.ApprovalStatus(request.approvalUpdates.status).number)
+        if not permissions.CanUpdateApprovalStatus(
+            mar.auth.effective_ids, mar.perms, mar.project,
+            approval.approver_ids, status):
+          raise permissions.PermissionException(
+              'User is not allowed to make this status change')
+        updates_dict['status'] = status
+    logging.info(time.time)
+    approval_delta = tracker_bizobj.MakeApprovalDelta(
+        updates_dict.get('status'), mar.auth.user_id,
+        updates_dict.get('approver_ids_add', []),
+        updates_dict.get('approver_ids_remove', []),
+        updates_dict.get('field_vals_add', []),
+        updates_dict.get('field_vals_remove', []),
+        updates_dict.get('fields_clear', []),
+        updates_dict.get('fields_labels_add', []),
+        updates_dict.get('fields_labels_remove', []))
+    comment = self._services.issue.DeltaUpdateIssueApproval(
+        mar.cnxn, mar.auth.user_id, mar.config, issue, approval, approval_delta,
+        comment_content=request.content,
+        is_description=request.is_description)
+
+    cmnts = self._services.issue.GetCommentsForIssue(mar.cnxn, issue.issue_id)
+    seq = len(cmnts) - 1
+
+    if request.sendEmail:
+      hostport = framework_helpers.GetHostPort(project_name=issue.project_name)
+      send_notifications.PrepareAndSendApprovalChangeNotification(
+          issue.issue_id, approval.approval_id,
+          hostport, comment.id, send_email=True)
+
+    issue_perms = permissions.UpdateIssuePermissions(
+        mar.perms, mar.project, issue, mar.auth.effective_ids,
+        granted_perms=mar.granted_perms)
+    commenter = self._services.user.GetUser(mar.cnxn, comment.user_id)
+    can_delete = permissions.CanDeleteComment(
+        comment, commenter, mar.auth.user_id, issue_perms)
+    return api_pb2_v1.ApprovalsCommentsInsertResponse(
+        id=seq,
+        kind='monorail#approvalComment',
+        author=api_pb2_v1_helpers.convert_person(
+            comment.user_id, mar.cnxn, self._services),
+        content=comment.content,
+        published=datetime.datetime.fromtimestamp(comment.timestamp),
+        approvalUpdates=api_pb2_v1_helpers.convert_approval_amendments(
+            comment.amendments, mar, self._services),
+        canDelete=can_delete)
+
+  @monorail_api_method(
+      api_pb2_v1.USERS_GET_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.UsersGetResponse,
+      path='users/{userId}',
+      http_method='GET',
+      name='users.get')
+  def users_get(self, mar, request):
+    """Get a user."""
+    owner_project_only = request.ownerProjectsOnly
+    with work_env.WorkEnv(mar, self._services) as we:
+      (visible_ownership, visible_deleted, visible_membership,
+       visible_contrib) = we.GetUserProjects(
+           mar.viewed_user_auth.effective_ids)
+
+    project_list = []
+    for proj in (visible_ownership + visible_deleted):
+      config = self._services.config.GetProjectConfig(
+          mar.cnxn, proj.project_id)
+      templates = self._services.template.GetProjectTemplates(
+          mar.cnxn, config.project_id)
+      proj_result = api_pb2_v1_helpers.convert_project(
+          proj, config, api_pb2_v1.Role.owner, templates)
+      project_list.append(proj_result)
+    if not owner_project_only:
+      for proj in visible_membership:
+        config = self._services.config.GetProjectConfig(
+            mar.cnxn, proj.project_id)
+        templates = self._services.template.GetProjectTemplates(
+            mar.cnxn, config.project_id)
+        proj_result = api_pb2_v1_helpers.convert_project(
+            proj, config, api_pb2_v1.Role.member, templates)
+        project_list.append(proj_result)
+      for proj in visible_contrib:
+        config = self._services.config.GetProjectConfig(
+            mar.cnxn, proj.project_id)
+        templates = self._services.template.GetProjectTemplates(
+            mar.cnxn, config.project_id)
+        proj_result = api_pb2_v1_helpers.convert_project(
+            proj, config, api_pb2_v1.Role.contributor, templates)
+        project_list.append(proj_result)
+
+    return api_pb2_v1.UsersGetResponse(
+        id=str(mar.viewed_user_auth.user_id),
+        kind='monorail#user',
+        projects=project_list,
+    )
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_GET_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesGetInsertResponse,
+      path='projects/{projectId}/issues/{issueId}',
+      http_method='GET',
+      name='issues.get')
+  def issues_get(self, mar, request):
+    """Get an issue."""
+    issue = self._services.issue.GetIssueByLocalID(
+        mar.cnxn, mar.project_id, request.issueId)
+
+    return api_pb2_v1_helpers.convert_issue(
+        api_pb2_v1.IssuesGetInsertResponse, issue, mar, self._services)
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_INSERT_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesGetInsertResponse,
+      path='projects/{projectId}/issues',
+      http_method='POST',
+      name='issues.insert')
+  def issues_insert(self, mar, request):
+    """Add a new issue."""
+    if not mar.perms.CanUsePerm(
+        permissions.CREATE_ISSUE, mar.auth.effective_ids, mar.project, []):
+      raise permissions.PermissionException(
+          'The requester %s is not allowed to create issues for project %s.' %
+          (mar.auth.email, mar.project_name))
+
+    with work_env.WorkEnv(mar, self._services) as we:
+      owner_id = framework_constants.NO_USER_SPECIFIED
+      if request.owner and request.owner.name:
+        try:
+          owner_id = self._services.user.LookupUserID(
+              mar.cnxn, request.owner.name)
+        except exceptions.NoSuchUserException:
+          raise endpoints.BadRequestException(
+              'The specified owner %s does not exist.' % request.owner.name)
+
+      cc_ids = []
+      request.cc = [cc for cc in request.cc if cc]
+      if request.cc:
+        cc_ids = list(self._services.user.LookupUserIDs(
+            mar.cnxn, [ap.name for ap in request.cc],
+            autocreate=True).values())
+      comp_ids = api_pb2_v1_helpers.convert_component_ids(
+          mar.config, request.components)
+      fields_add, _, _, fields_labels, _ = (
+          api_pb2_v1_helpers.convert_field_values(
+              request.fieldValues, mar, self._services))
+      field_helpers.ValidateCustomFields(
+          mar.cnxn, self._services, fields_add, mar.config, mar.project,
+          ezt_errors=mar.errors)
+      if mar.errors.AnyErrors():
+        raise endpoints.BadRequestException(
+            'Invalid field values: %s' % mar.errors.custom_fields)
+
+      logging.info('request.author is %r', request.author)
+      reporter_id, timestamp = self.parse_imported_reporter(mar, request)
+      # To preserve previous behavior, do not raise filter rule errors.
+      try:
+        new_issue, _ = we.CreateIssue(
+            mar.project_id,
+            request.summary,
+            request.status,
+            owner_id,
+            cc_ids,
+            request.labels + fields_labels,
+            fields_add,
+            comp_ids,
+            request.description,
+            blocked_on=api_pb2_v1_helpers.convert_issueref_pbs(
+                request.blockedOn, mar, self._services),
+            blocking=api_pb2_v1_helpers.convert_issueref_pbs(
+                request.blocking, mar, self._services),
+            reporter_id=reporter_id,
+            timestamp=timestamp,
+            send_email=request.sendEmail,
+            raise_filter_errors=False)
+        we.StarIssue(new_issue, True)
+      except exceptions.InputException as e:
+        raise endpoints.BadRequestException(str(e))
+
+    return api_pb2_v1_helpers.convert_issue(
+        api_pb2_v1.IssuesGetInsertResponse, new_issue, mar, self._services)
+
+  @monorail_api_method(
+      api_pb2_v1.ISSUES_LIST_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.IssuesListResponse,
+      path='projects/{projectId}/issues',
+      http_method='GET',
+      name='issues.list')
+  def issues_list(self, mar, request):
+    """List issues for projects."""
+    if request.additionalProject:
+      for project_name in request.additionalProject:
+        project = self._services.project.GetProjectByName(
+            mar.cnxn, project_name)
+        if project and not permissions.UserCanViewProject(
+            mar.auth.user_pb, mar.auth.effective_ids, project):
+          raise permissions.PermissionException(
+              'The user %s has no permission for project %s' %
+              (mar.auth.email, project_name))
+    # TODO(jrobbins): This should go through work_env.
+    pipeline = frontendsearchpipeline.FrontendSearchPipeline(
+        mar.cnxn,
+        self._services,
+        mar.auth, [mar.me_user_id],
+        mar.query,
+        mar.query_project_names,
+        mar.num,
+        mar.start,
+        mar.can,
+        mar.group_by_spec,
+        mar.sort_spec,
+        mar.warnings,
+        mar.errors,
+        mar.use_cached_searches,
+        mar.profiler,
+        project=mar.project)
+    if not mar.errors.AnyErrors():
+      pipeline.SearchForIIDs()
+      pipeline.MergeAndSortIssues()
+      pipeline.Paginate()
+    else:
+      raise endpoints.BadRequestException(mar.errors.query)
+
+    issue_list = [
+        api_pb2_v1_helpers.convert_issue(
+            api_pb2_v1.IssueWrapper, r, mar, self._services)
+        for r in pipeline.visible_results]
+    return api_pb2_v1.IssuesListResponse(
+        kind='monorail#issueList',
+        totalResults=pipeline.total_count,
+        items=issue_list)
+
+  @monorail_api_method(
+      api_pb2_v1.GROUPS_SETTINGS_LIST_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.GroupsSettingsListResponse,
+      path='groupsettings',
+      http_method='GET',
+      name='groups.settings.list')
+  def groups_settings_list(self, mar, request):
+    """List all group settings."""
+    all_groups = self._services.usergroup.GetAllUserGroupsInfo(mar.cnxn)
+    group_settings = []
+    for g in all_groups:
+      setting = g[2]
+      wrapper = api_pb2_v1_helpers.convert_group_settings(g[0], setting)
+      if not request.importedGroupsOnly or wrapper.ext_group_type:
+        group_settings.append(wrapper)
+    return api_pb2_v1.GroupsSettingsListResponse(
+        groupSettings=group_settings)
+
+  @monorail_api_method(
+      api_pb2_v1.GROUPS_CREATE_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.GroupsCreateResponse,
+      path='groups',
+      http_method='POST',
+      name='groups.create')
+  def groups_create(self, mar, request):
+    """Create a new user group."""
+    if not permissions.CanCreateGroup(mar.perms):
+      raise permissions.PermissionException(
+          'The user is not allowed to create groups.')
+
+    user_dict = self._services.user.LookupExistingUserIDs(
+        mar.cnxn, [request.groupName])
+    if request.groupName.lower() in user_dict:
+      raise exceptions.GroupExistsException(
+          'group %s already exists' % request.groupName)
+
+    if request.ext_group_type:
+      ext_group_type = str(request.ext_group_type).lower()
+    else:
+      ext_group_type = None
+    group_id = self._services.usergroup.CreateGroup(
+        mar.cnxn, self._services, request.groupName,
+        str(request.who_can_view_members).lower(),
+        ext_group_type)
+
+    return api_pb2_v1.GroupsCreateResponse(
+        groupID=group_id)
+
+  @monorail_api_method(
+      api_pb2_v1.GROUPS_GET_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.GroupsGetResponse,
+      path='groups/{groupName}',
+      http_method='GET',
+      name='groups.get')
+  def groups_get(self, mar, request):
+    """Get a group's settings and users."""
+    if not mar.viewed_user_auth:
+      raise exceptions.NoSuchUserException(request.groupName)
+    group_id = mar.viewed_user_auth.user_id
+    group_settings = self._services.usergroup.GetGroupSettings(
+        mar.cnxn, group_id)
+    member_ids, owner_ids = self._services.usergroup.LookupAllMembers(
+          mar.cnxn, [group_id])
+    (owned_project_ids, membered_project_ids,
+     contrib_project_ids) = self._services.project.GetUserRolesInAllProjects(
+         mar.cnxn, mar.auth.effective_ids)
+    project_ids = owned_project_ids.union(
+        membered_project_ids).union(contrib_project_ids)
+    if not permissions.CanViewGroupMembers(
+        mar.perms, mar.auth.effective_ids, group_settings, member_ids[group_id],
+        owner_ids[group_id], project_ids):
+      raise permissions.PermissionException(
+          'The user is not allowed to view this group.')
+
+    member_ids, owner_ids = self._services.usergroup.LookupMembers(
+        mar.cnxn, [group_id])
+
+    member_emails = list(self._services.user.LookupUserEmails(
+        mar.cnxn, member_ids[group_id]).values())
+    owner_emails = list(self._services.user.LookupUserEmails(
+        mar.cnxn, owner_ids[group_id]).values())
+
+    return api_pb2_v1.GroupsGetResponse(
+      groupID=group_id,
+      groupSettings=api_pb2_v1_helpers.convert_group_settings(
+          request.groupName, group_settings),
+      groupOwners=owner_emails,
+      groupMembers=member_emails)
+
+  @monorail_api_method(
+      api_pb2_v1.GROUPS_UPDATE_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.GroupsUpdateResponse,
+      path='groups/{groupName}',
+      http_method='POST',
+      name='groups.update')
+  def groups_update(self, mar, request):
+    """Update a group's settings and users."""
+    group_id = mar.viewed_user_auth.user_id
+    member_ids_dict, owner_ids_dict = self._services.usergroup.LookupMembers(
+        mar.cnxn, [group_id])
+    owner_ids = owner_ids_dict.get(group_id, [])
+    member_ids = member_ids_dict.get(group_id, [])
+    if not permissions.CanEditGroup(
+        mar.perms, mar.auth.effective_ids, owner_ids):
+      raise permissions.PermissionException(
+          'The user is not allowed to edit this group.')
+
+    group_settings = self._services.usergroup.GetGroupSettings(
+        mar.cnxn, group_id)
+    if (request.who_can_view_members or request.ext_group_type
+        or request.last_sync_time or request.friend_projects):
+      group_settings.who_can_view_members = (
+          request.who_can_view_members or group_settings.who_can_view_members)
+      group_settings.ext_group_type = (
+          request.ext_group_type or group_settings.ext_group_type)
+      group_settings.last_sync_time = (
+          request.last_sync_time or group_settings.last_sync_time)
+      if framework_constants.NO_VALUES in request.friend_projects:
+        group_settings.friend_projects = []
+      else:
+        id_dict = self._services.project.LookupProjectIDs(
+            mar.cnxn, request.friend_projects)
+        group_settings.friend_projects = (
+            list(id_dict.values()) or group_settings.friend_projects)
+      self._services.usergroup.UpdateSettings(
+          mar.cnxn, group_id, group_settings)
+
+    if request.groupOwners or request.groupMembers:
+      self._services.usergroup.RemoveMembers(
+          mar.cnxn, group_id, owner_ids + member_ids)
+      owners_dict = self._services.user.LookupUserIDs(
+          mar.cnxn, request.groupOwners, autocreate=True)
+      self._services.usergroup.UpdateMembers(
+          mar.cnxn, group_id, list(owners_dict.values()), 'owner')
+      members_dict = self._services.user.LookupUserIDs(
+          mar.cnxn, request.groupMembers, autocreate=True)
+      self._services.usergroup.UpdateMembers(
+          mar.cnxn, group_id, list(members_dict.values()), 'member')
+
+    return api_pb2_v1.GroupsUpdateResponse()
+
+  @monorail_api_method(
+      api_pb2_v1.COMPONENTS_LIST_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.ComponentsListResponse,
+      path='projects/{projectId}/components',
+      http_method='GET',
+      name='components.list')
+  def components_list(self, mar, _request):
+    """List all components of a given project."""
+    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
+    components = [api_pb2_v1_helpers.convert_component_def(
+        cd, mar, self._services) for cd in config.component_defs]
+    return api_pb2_v1.ComponentsListResponse(
+        components=components)
+
+  @monorail_api_method(
+      api_pb2_v1.COMPONENTS_CREATE_REQUEST_RESOURCE_CONTAINER,
+      api_pb2_v1.Component,
+      path='projects/{projectId}/components',
+      http_method='POST',
+      name='components.create')
+  def components_create(self, mar, request):
+    """Create a component."""
+    if not mar.perms.CanUsePerm(
+        permissions.EDIT_PROJECT, mar.auth.effective_ids, mar.project, []):
+      raise permissions.PermissionException(
+          'User is not allowed to create components for this project')
+
+    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
+    leaf_name = request.componentName
+    if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name):
+      raise exceptions.InvalidComponentNameException(
+          'The component name %s is invalid.' % leaf_name)
+
+    parent_path = request.parentPath
+    if parent_path:
+      parent_def = tracker_bizobj.FindComponentDef(parent_path, config)
+      if not parent_def:
+        raise exceptions.NoSuchComponentException(
+            'Parent component %s does not exist.' % parent_path)
+      if not permissions.CanEditComponentDef(
+          mar.auth.effective_ids, mar.perms, mar.project, parent_def, config):
+        raise permissions.PermissionException(
+            'User is not allowed to add a subcomponent to component %s' %
+            parent_path)
+
+      path = '%s>%s' % (parent_path, leaf_name)
+    else:
+      path = leaf_name
+
+    if tracker_bizobj.FindComponentDef(path, config):
+      raise exceptions.InvalidComponentNameException(
+          'The name %s is already in use.' % path)
+
+    created = int(time.time())
+    user_emails = set()
+    user_emails.update([mar.auth.email] + request.admin + request.cc)
+    user_ids_dict = self._services.user.LookupUserIDs(
+        mar.cnxn, list(user_emails), autocreate=False)
+    request.admin = [admin for admin in request.admin if admin]
+    admin_ids = [user_ids_dict[uname] for uname in request.admin]
+    request.cc = [cc for cc in request.cc if cc]
+    cc_ids = [user_ids_dict[uname] for uname in request.cc]
+    label_ids = []  # TODO(jrobbins): allow API clients to specify this too.
+
+    component_id = self._services.config.CreateComponentDef(
+        mar.cnxn, mar.project_id, path, request.description, request.deprecated,
+        admin_ids, cc_ids, created, user_ids_dict[mar.auth.email], label_ids)
+
+    return api_pb2_v1.Component(
+        componentId=component_id,
+        projectName=request.projectId,
+        componentPath=path,
+        description=request.description,
+        admin=request.admin,
+        cc=request.cc,
+        deprecated=request.deprecated,
+        created=datetime.datetime.fromtimestamp(created),
+        creator=mar.auth.email)
+
+  @monorail_api_method(
+      api_pb2_v1.COMPONENTS_DELETE_REQUEST_RESOURCE_CONTAINER,
+      message_types.VoidMessage,
+      path='projects/{projectId}/components/{componentPath}',
+      http_method='DELETE',
+      name='components.delete')
+  def components_delete(self, mar, request):
+    """Delete a component."""
+    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
+    component_path = request.componentPath
+    component_def = tracker_bizobj.FindComponentDef(
+        component_path, config)
+    if not component_def:
+      raise exceptions.NoSuchComponentException(
+          'The component %s does not exist.' % component_path)
+    if not permissions.CanViewComponentDef(
+        mar.auth.effective_ids, mar.perms, mar.project, component_def):
+      raise permissions.PermissionException(
+          'User is not allowed to view this component %s' % component_path)
+    if not permissions.CanEditComponentDef(
+        mar.auth.effective_ids, mar.perms, mar.project, component_def, config):
+      raise permissions.PermissionException(
+          'User is not allowed to delete this component %s' % component_path)
+
+    allow_delete = not tracker_bizobj.FindDescendantComponents(
+        config, component_def)
+    if not allow_delete:
+      raise permissions.PermissionException(
+          'User tried to delete component that had subcomponents')
+
+    self._services.issue.DeleteComponentReferences(
+        mar.cnxn, component_def.component_id)
+    self._services.config.DeleteComponentDef(
+        mar.cnxn, mar.project_id, component_def.component_id)
+    return message_types.VoidMessage()
+
+  @monorail_api_method(
+      api_pb2_v1.COMPONENTS_UPDATE_REQUEST_RESOURCE_CONTAINER,
+      message_types.VoidMessage,
+      path='projects/{projectId}/components/{componentPath}',
+      http_method='POST',
+      name='components.update')
+  def components_update(self, mar, request):
+    """Update a component."""
+    config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id)
+    component_path = request.componentPath
+    component_def = tracker_bizobj.FindComponentDef(
+        component_path, config)
+    if not component_def:
+      raise exceptions.NoSuchComponentException(
+          'The component %s does not exist.' % component_path)
+    if not permissions.CanViewComponentDef(
+        mar.auth.effective_ids, mar.perms, mar.project, component_def):
+      raise permissions.PermissionException(
+          'User is not allowed to view this component %s' % component_path)
+    if not permissions.CanEditComponentDef(
+        mar.auth.effective_ids, mar.perms, mar.project, component_def, config):
+      raise permissions.PermissionException(
+          'User is not allowed to edit this component %s' % component_path)
+
+    original_path = component_def.path
+    new_path = component_def.path
+    new_docstring = component_def.docstring
+    new_deprecated = component_def.deprecated
+    new_admin_ids = component_def.admin_ids
+    new_cc_ids = component_def.cc_ids
+    update_filterrule = False
+    for update in request.updates:
+      if update.field == api_pb2_v1.ComponentUpdateFieldID.LEAF_NAME:
+        leaf_name = update.leafName
+        if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name):
+          raise exceptions.InvalidComponentNameException(
+              'The component name %s is invalid.' % leaf_name)
+
+        if '>' in original_path:
+          parent_path = original_path[:original_path.rindex('>')]
+          new_path = '%s>%s' % (parent_path, leaf_name)
+        else:
+          new_path = leaf_name
+
+        conflict = tracker_bizobj.FindComponentDef(new_path, config)
+        if conflict and conflict.component_id != component_def.component_id:
+          raise exceptions.InvalidComponentNameException(
+              'The name %s is already in use.' % new_path)
+        update_filterrule = True
+      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DESCRIPTION:
+        new_docstring = update.description
+      elif update.field == api_pb2_v1.ComponentUpdateFieldID.ADMIN:
+        user_ids_dict = self._services.user.LookupUserIDs(
+            mar.cnxn, list(update.admin), autocreate=True)
+        new_admin_ids = list(set(user_ids_dict.values()))
+      elif update.field == api_pb2_v1.ComponentUpdateFieldID.CC:
+        user_ids_dict = self._services.user.LookupUserIDs(
+            mar.cnxn, list(update.cc), autocreate=True)
+        new_cc_ids = list(set(user_ids_dict.values()))
+        update_filterrule = True
+      elif update.field == api_pb2_v1.ComponentUpdateFieldID.DEPRECATED:
+        new_deprecated = update.deprecated
+      else:
+        logging.error('Unknown component field %r', update.field)
+
+    new_modified = int(time.time())
+    new_modifier_id = self._services.user.LookupUserID(
+        mar.cnxn, mar.auth.email, autocreate=False)
+    logging.info(
+        'Updating component id %d: path-%s, docstring-%s, deprecated-%s,'
+        ' admin_ids-%s, cc_ids-%s modified by %s', component_def.component_id,
+        new_path, new_docstring, new_deprecated, new_admin_ids, new_cc_ids,
+        new_modifier_id)
+    self._services.config.UpdateComponentDef(
+        mar.cnxn, mar.project_id, component_def.component_id,
+        path=new_path, docstring=new_docstring, deprecated=new_deprecated,
+        admin_ids=new_admin_ids, cc_ids=new_cc_ids, modified=new_modified,
+        modifier_id=new_modifier_id)
+
+    # TODO(sheyang): reuse the code in componentdetails
+    if original_path != new_path:
+      # If the name changed then update all of its subcomponents as well.
+      subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs(
+          original_path, config, exact=False)
+      for subcomponent_id in subcomponent_ids:
+        if subcomponent_id == component_def.component_id:
+          continue
+        subcomponent_def = tracker_bizobj.FindComponentDefByID(
+            subcomponent_id, config)
+        subcomponent_new_path = subcomponent_def.path.replace(
+            original_path, new_path, 1)
+        self._services.config.UpdateComponentDef(
+            mar.cnxn, mar.project_id, subcomponent_def.component_id,
+            path=subcomponent_new_path)
+
+    if update_filterrule:
+      filterrules_helpers.RecomputeAllDerivedFields(
+          mar.cnxn, self._services, mar.project, config)
+
+    return message_types.VoidMessage()
+
+
+@endpoints.api(name='monorail_client_configs', version='v1',
+               description='Monorail API client configs.')
+class ClientConfigApi(remote.Service):
+
+  # Class variables. Handy to mock.
+  _services = None
+  _mar = None
+
+  @classmethod
+  def _set_services(cls, services):
+    cls._services = services
+
+  def mar_factory(self, request, cnxn):
+    if not self._mar:
+      self._mar = monorailrequest.MonorailApiRequest(
+          request, self._services, cnxn=cnxn)
+    return self._mar
+
+  @endpoints.method(
+      message_types.VoidMessage,
+      message_types.VoidMessage,
+      path='client_configs',
+      http_method='POST',
+      name='client_configs.update')
+  def client_configs_update(self, request):
+    if self._services is None:
+      self._set_services(service_manager.set_up_services())
+    mar = self.mar_factory(request, sql.MonorailConnection())
+    if not mar.perms.HasPerm(permissions.ADMINISTER_SITE, None, None):
+      raise permissions.PermissionException(
+          'The requester %s is not allowed to update client configs.' %
+           mar.auth.email)
+
+    ROLE_DICT = {
+        1: permissions.COMMITTER_ROLE,
+        2: permissions.CONTRIBUTOR_ROLE,
+    }
+
+    client_config = client_config_svc.GetClientConfigSvc()
+
+    cfg = client_config.GetConfigs()
+    if not cfg:
+      msg = 'Failed to fetch client configs.'
+      logging.error(msg)
+      raise endpoints.InternalServerErrorException(msg)
+
+    for client in cfg.clients:
+      if not client.client_email:
+        continue
+      # 1: create the user if non-existent
+      user_id = self._services.user.LookupUserID(
+          mar.cnxn, client.client_email, autocreate=True)
+      user_pb = self._services.user.GetUser(mar.cnxn, user_id)
+
+      logging.info('User ID %d for email %s', user_id, client.client_email)
+
+      # 2: set period and lifetime limit
+      # new_soft_limit, new_hard_limit, new_lifetime_limit
+      new_limit_tuple = (
+          client.period_limit, client.period_limit, client.lifetime_limit)
+      action_limit_updates = {'api_request': new_limit_tuple}
+      self._services.user.UpdateUserSettings(
+          mar.cnxn, user_id, user_pb, action_limit_updates=action_limit_updates)
+
+      logging.info('Updated api request limit %r', new_limit_tuple)
+
+      # 3: Update project role and extra perms
+      projects_dict = self._services.project.GetAllProjects(mar.cnxn)
+      project_name_to_ids = {
+          p.project_name: p.project_id for p in projects_dict.values()}
+
+      # Set project role and extra perms
+      for perm in client.project_permissions:
+        project_ids = self._GetProjectIDs(perm.project, project_name_to_ids)
+        logging.info('Matching projects %r for name %s',
+                     project_ids, perm.project)
+
+        role = ROLE_DICT[perm.role]
+        for p_id in project_ids:
+          project = projects_dict[p_id]
+          people_list = []
+          if role == 'owner':
+            people_list = project.owner_ids
+          elif role == 'committer':
+            people_list = project.committer_ids
+          elif role == 'contributor':
+            people_list = project.contributor_ids
+          # Onlu update role/extra perms iff changed
+          if not user_id in people_list:
+            logging.info('Update project %s role %s for user %s',
+                         project.project_name, role, client.client_email)
+            owner_ids, committer_ids, contributor_ids = (
+                project_helpers.MembersWithGivenIDs(project, {user_id}, role))
+            self._services.project.UpdateProjectRoles(
+                mar.cnxn, p_id, owner_ids, committer_ids,
+                contributor_ids)
+          if perm.extra_permissions:
+            logging.info('Update project %s extra perm %s for user %s',
+                         project.project_name, perm.extra_permissions,
+                         client.client_email)
+            self._services.project.UpdateExtraPerms(
+                mar.cnxn, p_id, user_id, list(perm.extra_permissions))
+
+    mar.CleanUp()
+    return message_types.VoidMessage()
+
+  def _GetProjectIDs(self, project_str, project_name_to_ids):
+    result = []
+    if any(ch in project_str for ch in ['*', '+', '?', '.']):
+      pattern = re.compile(project_str)
+      for p_name in project_name_to_ids.keys():
+        if pattern.match(p_name):
+          project_id = project_name_to_ids.get(p_name)
+          if project_id:
+            result.append(project_id)
+    else:
+      project_id = project_name_to_ids.get(project_str)
+      if project_id:
+        result.append(project_id)
+
+    if not result:
+      logging.warning('Cannot find projects for specified name %s',
+                      project_str)
+    return result
