diff --git a/tracker/issuebulkedit.py b/tracker/issuebulkedit.py
new file mode 100644
index 0000000..c1f5229
--- /dev/null
+++ b/tracker/issuebulkedit.py
@@ -0,0 +1,473 @@
+# 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
+
+"""Classes that implement the issue bulk edit page and related forms.
+
+Summary of classes:
+  IssueBulkEdit: Show a form for editing multiple issues and allow the
+     user to update them all at once.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import httplib
+import itertools
+import logging
+import time
+
+import ezt
+
+from features import filterrules_helpers
+from features import send_notifications
+from framework import exceptions
+from framework import framework_constants
+from framework import framework_views
+from framework import permissions
+from framework import servlet
+from framework import template_helpers
+from services import tracker_fulltext
+from tracker import field_helpers
+from tracker import tracker_bizobj
+from tracker import tracker_constants
+from tracker import tracker_helpers
+from tracker import tracker_views
+
+
+class IssueBulkEdit(servlet.Servlet):
+  """IssueBulkEdit lists multiple issues and allows an edit to all of them."""
+
+  _PAGE_TEMPLATE = 'tracker/issue-bulk-edit-page.ezt'
+  _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+  _SECONDS_OVERHEAD = 4
+  _SECONDS_PER_UPDATE = 0.12
+  _SLOWNESS_THRESHOLD = 10
+
+  def AssertBasePermission(self, mr):
+    """Check whether the user has any permission to visit this page.
+
+    Args:
+      mr: commonly used info parsed from the request.
+
+    Raises:
+      PermissionException: if the user is not allowed to enter an issue.
+    """
+    super(IssueBulkEdit, self).AssertBasePermission(mr)
+    can_edit = self.CheckPerm(mr, permissions.EDIT_ISSUE)
+    can_comment = self.CheckPerm(mr, permissions.ADD_ISSUE_COMMENT)
+    if not (can_edit and can_comment):
+      raise permissions.PermissionException('bulk edit forbidden')
+
+  def GatherPageData(self, mr):
+    """Build up a dictionary of data values to use when rendering the page.
+
+    Args:
+      mr: commonly used info parsed from the request.
+
+    Returns:
+      Dict of values used by EZT for rendering the page.
+    """
+    with mr.profiler.Phase('getting issues'):
+      if not mr.local_id_list:
+        raise exceptions.InputException()
+      requested_issues = self.services.issue.GetIssuesByLocalIDs(
+          mr.cnxn, mr.project_id, sorted(mr.local_id_list))
+
+    with mr.profiler.Phase('filtering issues'):
+      # TODO(jrobbins): filter out issues that the user cannot edit and
+      # provide that as feedback rather than just siliently ignoring them.
+      open_issues, closed_issues = (
+          tracker_helpers.GetAllowedOpenedAndClosedIssues(
+              mr, [issue.issue_id for issue in requested_issues],
+              self.services))
+      issues = open_issues + closed_issues
+
+    if not issues:
+      self.abort(404, 'no issues found')
+
+    config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
+    type_label_set = {
+        lab.lower() for lab in issues[0].labels
+        if lab.lower().startswith('type-')}
+    for issue in issues[1:]:
+      new_type_set = {
+          lab.lower() for lab in issue.labels
+          if lab.lower().startswith('type-')}
+      type_label_set &= new_type_set
+
+    issue_phases = list(
+        itertools.chain.from_iterable(issue.phases for issue in issues))
+
+    field_views = tracker_views.MakeAllFieldValueViews(
+        config, type_label_set, [], [], {}, phases=issue_phases)
+    for fv in field_views:
+      # Explicitly set all field views to not required. We do not want to force
+      # users to have to set it for issues missing required fields.
+      # See https://bugs.chromium.org/p/monorail/issues/detail?id=500 for more
+      # details.
+      fv.field_def.is_required_bool = None
+
+      if permissions.CanEditValueForFieldDef(
+          mr.auth.effective_ids, mr.perms, mr.project, fv.field_def.field_def):
+        fv.is_editable = ezt.boolean(True)
+      else:
+        fv.is_editable = ezt.boolean(False)
+
+    with mr.profiler.Phase('making issue proxies'):
+      issue_views = [
+          template_helpers.EZTItem(
+              local_id=issue.local_id, summary=issue.summary,
+              closed=ezt.boolean(issue in closed_issues))
+          for issue in issues]
+
+    num_seconds = (int(len(issue_views) * self._SECONDS_PER_UPDATE) +
+                   self._SECONDS_OVERHEAD)
+
+    page_perms = self.MakePagePerms(
+        mr, None,
+        permissions.CREATE_ISSUE,
+        permissions.DELETE_ISSUE)
+
+    return {
+        'issue_tab_mode': 'issueBulkEdit',
+        'issues': issue_views,
+        'local_ids_str': ','.join([str(issue.local_id) for issue in issues]),
+        'num_issues': len(issue_views),
+        'show_progress': ezt.boolean(num_seconds > self._SLOWNESS_THRESHOLD),
+        'num_seconds': num_seconds,
+
+        'initial_blocked_on': '',
+        'initial_blocking': '',
+        'initial_comment': '',
+        'initial_status': '',
+        'initial_owner': '',
+        'initial_merge_into': '',
+        'initial_cc': '',
+        'initial_components': '',
+        'labels': [],
+        'fields': field_views,
+
+        'restrict_to_known': ezt.boolean(config.restrict_to_known),
+        'page_perms': page_perms,
+        'statuses_offer_merge': config.statuses_offer_merge,
+        'issue_phase_names': list(
+            {phase.name.lower() for phase in issue_phases}),
+        }
+
+  def ProcessFormData(self, mr, post_data):
+    # (...) -> str
+    """Process the posted issue update form.
+
+    Args:
+      mr: commonly used info parsed from the request.
+      post_data: HTML form data from the request.
+
+    Returns:
+      String URL to redirect the user to after processing.
+    """
+    if not mr.local_id_list:
+      logging.info('missing issue local IDs, probably tampered')
+      self.response.status = httplib.BAD_REQUEST
+      return
+
+    # Check that the user is logged in; anon users cannot update issues.
+    if not mr.auth.user_id:
+      logging.info('user was not logged in, cannot update issue')
+      self.response.status = httplib.BAD_REQUEST  # xxx should raise except
+      return
+
+    # Check that the user has permission to add a comment, and to enter
+    # metadata if they are trying to do that.
+    if not self.CheckPerm(mr, permissions.ADD_ISSUE_COMMENT):
+      logging.info('user has no permission to add issue comment')
+      self.response.status = httplib.BAD_REQUEST
+      return
+
+    if not self.CheckPerm(mr, permissions.EDIT_ISSUE):
+      logging.info('user has no permission to edit issue metadata')
+      self.response.status = httplib.BAD_REQUEST
+      return
+
+    move_to = post_data.get('move_to', '').lower()
+    if move_to and not self.CheckPerm(mr, permissions.DELETE_ISSUE):
+      logging.info('user has no permission to move issue')
+      self.response.status = httplib.BAD_REQUEST
+      return
+
+    config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
+
+    parsed = tracker_helpers.ParseIssueRequest(
+        mr.cnxn, post_data, self.services, mr.errors, mr.project_name)
+    bounce_labels = (
+        parsed.labels[:] +
+        ['-%s' % lr for lr in parsed.labels_remove])
+    bounce_fields = tracker_views.MakeBounceFieldValueViews(
+        parsed.fields.vals, parsed.fields.phase_vals, config)
+    field_helpers.ShiftEnumFieldsIntoLabels(
+        parsed.labels, parsed.labels_remove,
+        parsed.fields.vals, parsed.fields.vals_remove,
+        config)
+    issue_list = self.services.issue.GetIssuesByLocalIDs(
+        mr.cnxn, mr.project_id, mr.local_id_list)
+    issue_phases = list(
+        itertools.chain.from_iterable(issue.phases for issue in issue_list))
+    phase_ids_by_name = collections.defaultdict(set)
+    for phase in issue_phases:
+      phase_ids_by_name[phase.name.lower()].add(phase.phase_id)
+    # Note: Not all parsed phase field values will be applicable to every issue.
+    # tracker_bizobj.ApplyFieldValueChanges will take care of not adding
+    # phase field values to issues that don't contain the correct phase.
+    field_vals = field_helpers.ParseFieldValues(
+        mr.cnxn, self.services.user, parsed.fields.vals,
+        parsed.fields.phase_vals, config,
+        phase_ids_by_name=phase_ids_by_name)
+    field_vals_remove = field_helpers.ParseFieldValues(
+        mr.cnxn, self.services.user, parsed.fields.vals_remove,
+        parsed.fields.phase_vals_remove, config,
+        phase_ids_by_name=phase_ids_by_name)
+
+    field_helpers.AssertCustomFieldsEditPerms(
+        mr, config, field_vals, field_vals_remove, parsed.fields.fields_clear,
+        parsed.labels, parsed.labels_remove)
+    field_helpers.ValidateCustomFields(
+        mr.cnxn, self.services, field_vals, config, mr.project,
+        ezt_errors=mr.errors)
+
+    # Treat status '' as no change and explicit 'clear' as clearing the status.
+    status = parsed.status
+    if status == '':
+      status = None
+    if post_data.get('op_statusenter') == 'clear':
+      status = ''
+
+    reporter_id = mr.auth.user_id
+    logging.info('bulk edit request by %s', reporter_id)
+
+    if parsed.users.owner_id is None:
+      mr.errors.owner = 'Invalid owner username'
+    else:
+      valid, msg = tracker_helpers.IsValidIssueOwner(
+          mr.cnxn, mr.project, parsed.users.owner_id, self.services)
+      if not valid:
+        mr.errors.owner = msg
+
+    if (status in config.statuses_offer_merge and
+        not post_data.get('merge_into')):
+      mr.errors.merge_into_id = 'Please enter a valid issue ID'
+
+    move_to_project = None
+    if move_to:
+      if mr.project_name == move_to:
+        mr.errors.move_to = 'The issues are already in project ' + move_to
+      else:
+        move_to_project = self.services.project.GetProjectByName(
+            mr.cnxn, move_to)
+        if not move_to_project:
+          mr.errors.move_to = 'No such project: ' + move_to
+
+    # Treat owner '' as no change, and explicit 'clear' as NO_USER_SPECIFIED
+    owner_id = parsed.users.owner_id
+    if parsed.users.owner_username == '':
+      owner_id = None
+    if post_data.get('op_ownerenter') == 'clear':
+      owner_id = framework_constants.NO_USER_SPECIFIED
+
+    comp_ids = tracker_helpers.LookupComponentIDs(
+        parsed.components.paths, config, mr.errors)
+    comp_ids_remove = tracker_helpers.LookupComponentIDs(
+        parsed.components.paths_remove, config, mr.errors)
+    if post_data.get('op_componententer') == 'remove':
+      comp_ids, comp_ids_remove = comp_ids_remove, comp_ids
+
+    cc_ids, cc_ids_remove = parsed.users.cc_ids, parsed.users.cc_ids_remove
+    if post_data.get('op_memberenter') == 'remove':
+      cc_ids, cc_ids_remove = parsed.users.cc_ids_remove, parsed.users.cc_ids
+
+    issue_list_iids = {issue.issue_id for issue in issue_list}
+    if post_data.get('op_blockedonenter') == 'append':
+      if issue_list_iids.intersection(parsed.blocked_on.iids):
+        mr.errors.blocked_on = 'Cannot block an issue on itself.'
+      blocked_on_add = parsed.blocked_on.iids
+      blocked_on_remove = []
+    else:
+      blocked_on_add = []
+      blocked_on_remove = parsed.blocked_on.iids
+    if post_data.get('op_blockingenter') == 'append':
+      if issue_list_iids.intersection(parsed.blocking.iids):
+        mr.errors.blocking = 'Cannot block an issue on itself.'
+      blocking_add = parsed.blocking.iids
+      blocking_remove = []
+    else:
+      blocking_add = []
+      blocking_remove = parsed.blocking.iids
+
+    if len(parsed.comment) > tracker_constants.MAX_COMMENT_CHARS:
+      mr.errors.comment = 'Comment is too long.'
+
+    iids_actually_changed = []
+    old_owner_ids = []
+    combined_amendments = []
+    merge_into_issue = None
+    new_starrers = set()
+
+    if not mr.errors.AnyErrors():
+      # Because we will modify issues, load from DB rather than cache.
+      issue_list = self.services.issue.GetIssuesByLocalIDs(
+          mr.cnxn, mr.project_id, mr.local_id_list, use_cache=False)
+
+      # Skip any individual issues that the user is not allowed to edit.
+      editable_issues = [
+          issue for issue in issue_list
+          if permissions.CanEditIssue(
+              mr.auth.effective_ids, mr.perms, mr.project, issue)]
+
+      # Skip any restrict issues that cannot be moved
+      if move_to:
+        editable_issues = [
+            issue for issue in editable_issues
+            if not permissions.GetRestrictions(issue)]
+
+      # If 'Duplicate' status is specified ensure there are no permission issues
+      # with the issue we want to merge with.
+      if post_data.get('merge_into'):
+        for issue in editable_issues:
+          _, merge_into_issue = tracker_helpers.ParseMergeFields(
+              mr.cnxn, self.services, mr.project_name, post_data, parsed.status,
+              config, issue, mr.errors)
+          if merge_into_issue:
+            merge_allowed = tracker_helpers.IsMergeAllowed(
+                merge_into_issue, mr, self.services)
+            if not merge_allowed:
+              mr.errors.merge_into_id = 'Target issue %s cannot be modified' % (
+                                            merge_into_issue.local_id)
+              break
+
+            # Update the new_starrers set.
+            new_starrers.update(tracker_helpers.GetNewIssueStarrers(
+                mr.cnxn, self.services, [issue.issue_id],
+                merge_into_issue.issue_id))
+
+      # Proceed with amendments only if there are no reported errors.
+      if not mr.errors.AnyErrors():
+        # Sort the issues: we want them in this order so that the
+        # corresponding old_owner_id are found in the same order.
+        editable_issues.sort(key=lambda issue: issue.local_id)
+
+        iids_to_invalidate = set()
+        rules = self.services.features.GetFilterRules(
+            mr.cnxn, config.project_id)
+        predicate_asts = filterrules_helpers.ParsePredicateASTs(
+            rules, config, [])
+        for issue in editable_issues:
+          old_owner_id = tracker_bizobj.GetOwnerId(issue)
+          merge_into_iid = (
+              merge_into_issue.issue_id if merge_into_issue else None)
+
+          delta = tracker_bizobj.MakeIssueDelta(
+            status, owner_id, cc_ids, cc_ids_remove, comp_ids, comp_ids_remove,
+            parsed.labels, parsed.labels_remove, field_vals, field_vals_remove,
+            parsed.fields.fields_clear, blocked_on_add, blocked_on_remove,
+            blocking_add, blocking_remove, merge_into_iid, None)
+          amendments, _ = self.services.issue.DeltaUpdateIssue(
+              mr.cnxn, self.services, mr.auth.user_id, mr.project_id, config,
+              issue, delta, comment=parsed.comment,
+              iids_to_invalidate=iids_to_invalidate, rules=rules,
+              predicate_asts=predicate_asts)
+
+          if amendments or parsed.comment:  # Avoid empty comments.
+            iids_actually_changed.append(issue.issue_id)
+            old_owner_ids.append(old_owner_id)
+            combined_amendments.extend(amendments)
+
+        self.services.issue.InvalidateIIDs(mr.cnxn, iids_to_invalidate)
+        self.services.project.UpdateRecentActivity(
+            mr.cnxn, mr.project.project_id)
+
+        # Add new_starrers and new CCs to merge_into_issue.
+        if merge_into_issue:
+          merge_into_project = self.services.project.GetProjectByName(
+              mr.cnxn, merge_into_issue.project_name)
+          tracker_helpers.AddIssueStarrers(
+              mr.cnxn, self.services, mr, 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(
+              mr.cnxn, merge_into_issue.issue_id, use_cache=False)
+          tracker_helpers.MergeCCsAndAddCommentMultipleIssues(
+              self.services, mr, editable_issues, merge_into_issue)
+
+        if move_to and editable_issues:
+          tracker_fulltext.UnindexIssues(
+              [issue.issue_id for issue in editable_issues])
+          for issue in editable_issues:
+            old_text_ref = 'issue %s:%s' % (issue.project_name, issue.local_id)
+            moved_back_iids = self.services.issue.MoveIssues(
+                mr.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)
+            self.services.issue.CreateIssueComment(
+                mr.cnxn, issue, mr.auth.user_id, content, amendments=[
+                   tracker_bizobj.MakeProjectAmendment(
+                       move_to_project.project_name)])
+
+        send_email = 'send_email' in post_data
+
+        users_by_id = framework_views.MakeAllUserViews(
+            mr.cnxn, self.services.user,
+            [owner_id], cc_ids, cc_ids_remove, old_owner_ids,
+            tracker_bizobj.UsersInvolvedInAmendments(combined_amendments))
+        if move_to and editable_issues:
+          iids_actually_changed = [
+              issue.issue_id for issue in editable_issues]
+
+        send_notifications.SendIssueBulkChangeNotification(
+            iids_actually_changed, mr.request.host,
+            old_owner_ids, parsed.comment,
+            reporter_id, combined_amendments, send_email, users_by_id)
+
+    if mr.errors.AnyErrors():
+      bounce_cc_parts = (
+          parsed.users.cc_usernames +
+          ['-%s' % ccur for ccur in parsed.users.cc_usernames_remove])
+      self.PleaseCorrect(
+          mr, initial_status=parsed.status,
+          initial_owner=parsed.users.owner_username,
+          initial_merge_into=post_data.get('merge_into', 0),
+          initial_cc=', '.join(bounce_cc_parts),
+          initial_comment=parsed.comment,
+          initial_components=parsed.components.entered_str,
+          labels=bounce_labels,
+          fields=bounce_fields)
+      return
+
+    with mr.profiler.Phase('reindexing issues'):
+      logging.info('starting reindexing')
+      start = time.time()
+      # Get the updated issues and index them
+      issue_list = self.services.issue.GetIssuesByLocalIDs(
+          mr.cnxn, mr.project_id, mr.local_id_list)
+      tracker_fulltext.IndexIssues(
+          mr.cnxn, issue_list, self.services.user, self.services.issue,
+          self.services.config)
+      logging.info('reindexing %d issues took %s sec',
+                   len(issue_list), time.time() - start)
+
+    # TODO(jrobbins): These could be put into the form action attribute.
+    mr.can = int(post_data['can'])
+    mr.query = post_data['q']
+    mr.col_spec = post_data['colspec']
+    mr.sort_spec = post_data['sort']
+    mr.group_by_spec = post_data['groupby']
+    mr.start = int(post_data['start'])
+    mr.num = int(post_data['num'])
+
+    # TODO(jrobbins): implement bulk=N param for a better confirmation alert.
+    return tracker_helpers.FormatIssueListURL(
+        mr, config, saved=len(mr.local_id_list), ts=int(time.time()))
