diff --git a/features/notify.py b/features/notify.py
new file mode 100644
index 0000000..c285c76
--- /dev/null
+++ b/features/notify.py
@@ -0,0 +1,1055 @@
+# 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
+
+"""Task handlers for email notifications of issue changes.
+
+Email notificatons are sent when an issue changes, an issue that is blocking
+another issue changes, or a bulk edit is done.  The users notified include
+the project-wide mailing list, issue owners, cc'd users, starrers,
+also-notify addresses, and users who have saved queries with email notification
+set.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import json
+import logging
+import os
+
+import ezt
+
+from google.appengine.api import mail
+from google.appengine.runtime import apiproxy_errors
+
+import settings
+from features import autolink
+from features import notify_helpers
+from features import notify_reasons
+from framework import authdata
+from framework import emailfmt
+from framework import exceptions
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import framework_helpers
+from framework import framework_views
+from framework import jsonfeed
+from framework import monorailrequest
+from framework import permissions
+from framework import template_helpers
+from framework import urls
+from tracker import tracker_bizobj
+from tracker import tracker_helpers
+from tracker import tracker_views
+from proto import tracker_pb2
+
+
+class NotifyIssueChangeTask(notify_helpers.NotifyTaskBase):
+  """JSON servlet that notifies appropriate users after an issue change."""
+
+  _EMAIL_TEMPLATE = 'tracker/issue-change-notification-email.ezt'
+  _LINK_ONLY_EMAIL_TEMPLATE = (
+      'tracker/issue-change-notification-email-link-only.ezt')
+
+  def HandleRequest(self, mr):
+    """Process the task to notify users after an issue change.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful just for debugging.
+      The main goal is the side-effect of sending emails.
+    """
+    issue_id = mr.GetPositiveIntParam('issue_id')
+    if not issue_id:
+      return {
+          'params': {},
+          'notified': [],
+          'message': 'Cannot proceed without a valid issue ID.',
+      }
+    commenter_id = mr.GetPositiveIntParam('commenter_id')
+    seq_num = mr.seq
+    omit_ids = [commenter_id]
+    hostport = mr.GetParam('hostport')
+    try:
+      old_owner_id = mr.GetPositiveIntParam('old_owner_id')
+    except Exception:
+      old_owner_id = framework_constants.NO_USER_SPECIFIED
+    send_email = bool(mr.GetIntParam('send_email'))
+    comment_id = mr.GetPositiveIntParam('comment_id')
+    params = dict(
+        issue_id=issue_id, commenter_id=commenter_id,
+        seq_num=seq_num, hostport=hostport, old_owner_id=old_owner_id,
+        omit_ids=omit_ids, send_email=send_email, comment_id=comment_id)
+
+    logging.info('issue change params are %r', params)
+    # TODO(jrobbins): Re-enable the issue cache for notifications after
+    # the stale issue defect (monorail:2514) is 100% resolved.
+    issue = self.services.issue.GetIssue(mr.cnxn, issue_id, use_cache=False)
+    project = self.services.project.GetProject(mr.cnxn, issue.project_id)
+    config = self.services.config.GetProjectConfig(mr.cnxn, issue.project_id)
+
+    if issue.is_spam:
+      # Don't send email for spam issues.
+      return {
+          'params': params,
+          'notified': [],
+      }
+
+    all_comments = self.services.issue.GetCommentsForIssue(
+        mr.cnxn, issue.issue_id)
+    if comment_id:
+      logging.info('Looking up comment by comment_id')
+      for c in all_comments:
+        if c.id == comment_id:
+          comment = c
+          logging.info('Comment was found by comment_id')
+          break
+      else:
+        raise ValueError('Comment %r was not found' % comment_id)
+    else:
+      logging.info('Looking up comment by seq_num')
+      comment = all_comments[seq_num]
+
+    # Only issues that any contributor could view sent to mailing lists.
+    contributor_could_view = permissions.CanViewIssue(
+        set(), permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET,
+        project, issue)
+    starrer_ids = self.services.issue_star.LookupItemStarrers(
+        mr.cnxn, issue.issue_id)
+    users_by_id = framework_views.MakeAllUserViews(
+        mr.cnxn, self.services.user,
+        tracker_bizobj.UsersInvolvedInIssues([issue]), [old_owner_id],
+        tracker_bizobj.UsersInvolvedInComment(comment),
+        issue.cc_ids, issue.derived_cc_ids, starrer_ids, omit_ids)
+
+    # Make followup tasks to send emails
+    tasks = []
+    if send_email:
+      tasks = self._MakeEmailTasks(
+          mr.cnxn, project, issue, config, old_owner_id, users_by_id,
+          all_comments, comment, starrer_ids, contributor_could_view,
+          hostport, omit_ids, mr.perms)
+
+    notified = notify_helpers.AddAllEmailTasks(tasks)
+
+    return {
+        'params': params,
+        'notified': notified,
+        }
+
+  def _MakeEmailTasks(
+      self, cnxn, project, issue, config, old_owner_id,
+      users_by_id, all_comments, comment, starrer_ids,
+      contributor_could_view, hostport, omit_ids, perms):
+    """Formulate emails to be sent."""
+    detail_url = framework_helpers.IssueCommentURL(
+        hostport, project, issue.local_id, seq_num=comment.sequence)
+
+    # TODO(jrobbins): avoid the need to make a MonorailRequest object.
+    mr = monorailrequest.MonorailRequest(self.services)
+    mr.project_name = project.project_name
+    mr.project = project
+    mr.perms = perms
+
+    # We do not autolink in the emails, so just use an empty
+    # registry of autolink rules.
+    # TODO(jrobbins): offer users an HTML email option w/ autolinks.
+    autolinker = autolink.Autolink()
+    was_created = ezt.boolean(comment.sequence == 0)
+
+    email_data = {
+        # Pass open_related and closed_related into this method and to
+        # the issue view so that we can show it on new issue email.
+        'issue': tracker_views.IssueView(issue, users_by_id, config),
+        'summary': issue.summary,
+        'comment': tracker_views.IssueCommentView(
+            project.project_name, comment, users_by_id,
+            autolinker, {}, mr, issue),
+        'comment_text': comment.content,
+        'detail_url': detail_url,
+        'was_created': was_created,
+        }
+
+    # Generate three versions of email body: link-only is just the link,
+    # non-members see some obscured email addresses, and members version has
+    # all full email addresses exposed.
+    body_link_only = self.link_only_email_template.GetResponse(
+      {'detail_url': detail_url, 'was_created': was_created})
+    body_for_non_members = self.email_template.GetResponse(email_data)
+    framework_views.RevealAllEmails(users_by_id)
+    email_data['comment'] = tracker_views.IssueCommentView(
+        project.project_name, comment, users_by_id,
+        autolinker, {}, mr, issue)
+    body_for_members = self.email_template.GetResponse(email_data)
+
+    logging.info('link-only body is:\n%r' % body_link_only)
+    logging.info('body for non-members is:\n%r' % body_for_non_members)
+    logging.info('body for members is:\n%r' % body_for_members)
+
+    commenter_email = users_by_id[comment.user_id].email
+    omit_addrs = set([commenter_email] +
+                     [users_by_id[omit_id].email for omit_id in omit_ids])
+
+    auth = authdata.AuthData.FromUserID(
+        cnxn, comment.user_id, self.services)
+    commenter_in_project = framework_bizobj.UserIsInProject(
+        project, auth.effective_ids)
+    noisy = tracker_helpers.IsNoisy(len(all_comments) - 1, len(starrer_ids))
+
+    # Give each user a bullet-list of all the reasons that apply for that user.
+    group_reason_list = notify_reasons.ComputeGroupReasonList(
+        cnxn, self.services, project, issue, config, users_by_id,
+        omit_addrs, contributor_could_view, noisy=noisy,
+        starrer_ids=starrer_ids, old_owner_id=old_owner_id,
+        commenter_in_project=commenter_in_project)
+
+    commenter_view = users_by_id[comment.user_id]
+    detail_url = framework_helpers.FormatAbsoluteURLForDomain(
+        hostport, issue.project_name, urls.ISSUE_DETAIL,
+        id=issue.local_id)
+    email_tasks = notify_helpers.MakeBulletedEmailWorkItems(
+        group_reason_list, issue, body_link_only, body_for_non_members,
+        body_for_members, project, hostport, commenter_view, detail_url,
+        seq_num=comment.sequence)
+
+    return email_tasks
+
+
+class NotifyBlockingChangeTask(notify_helpers.NotifyTaskBase):
+  """JSON servlet that notifies appropriate users after a blocking change."""
+
+  _EMAIL_TEMPLATE = 'tracker/issue-blocking-change-notification-email.ezt'
+  _LINK_ONLY_EMAIL_TEMPLATE = (
+      'tracker/issue-change-notification-email-link-only.ezt')
+
+  def HandleRequest(self, mr):
+    """Process the task to notify users after an issue blocking change.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful just for debugging.
+      The main goal is the side-effect of sending emails.
+    """
+    issue_id = mr.GetPositiveIntParam('issue_id')
+    if not issue_id:
+      return {
+          'params': {},
+          'notified': [],
+          'message': 'Cannot proceed without a valid issue ID.',
+      }
+    commenter_id = mr.GetPositiveIntParam('commenter_id')
+    omit_ids = [commenter_id]
+    hostport = mr.GetParam('hostport')
+    delta_blocker_iids = mr.GetIntListParam('delta_blocker_iids')
+    send_email = bool(mr.GetIntParam('send_email'))
+    params = dict(
+        issue_id=issue_id, commenter_id=commenter_id,
+        hostport=hostport, delta_blocker_iids=delta_blocker_iids,
+        omit_ids=omit_ids, send_email=send_email)
+
+    logging.info('blocking change params are %r', params)
+    issue = self.services.issue.GetIssue(mr.cnxn, issue_id)
+    if issue.is_spam:
+      return {
+        'params': params,
+        'notified': [],
+        }
+
+    upstream_issues = self.services.issue.GetIssues(
+        mr.cnxn, delta_blocker_iids)
+    logging.info('updating ids %r', [up.local_id for up in upstream_issues])
+    upstream_projects = tracker_helpers.GetAllIssueProjects(
+        mr.cnxn, upstream_issues, self.services.project)
+    upstream_configs = self.services.config.GetProjectConfigs(
+        mr.cnxn, list(upstream_projects.keys()))
+
+    users_by_id = framework_views.MakeAllUserViews(
+        mr.cnxn, self.services.user, [commenter_id])
+    commenter_view = users_by_id[commenter_id]
+
+    tasks = []
+    if send_email:
+      for upstream_issue in upstream_issues:
+        one_issue_email_tasks = self._ProcessUpstreamIssue(
+            mr.cnxn, upstream_issue,
+            upstream_projects[upstream_issue.project_id],
+            upstream_configs[upstream_issue.project_id],
+            issue, omit_ids, hostport, commenter_view)
+        tasks.extend(one_issue_email_tasks)
+
+    notified = notify_helpers.AddAllEmailTasks(tasks)
+
+    return {
+        'params': params,
+        'notified': notified,
+        }
+
+  def _ProcessUpstreamIssue(
+      self, cnxn, upstream_issue, upstream_project, upstream_config,
+      issue, omit_ids, hostport, commenter_view):
+    """Compute notifications for one upstream issue that is now blocking."""
+    upstream_detail_url = framework_helpers.FormatAbsoluteURLForDomain(
+        hostport, upstream_issue.project_name, urls.ISSUE_DETAIL,
+        id=upstream_issue.local_id)
+    logging.info('upstream_detail_url = %r', upstream_detail_url)
+    detail_url = framework_helpers.FormatAbsoluteURLForDomain(
+        hostport, issue.project_name, urls.ISSUE_DETAIL,
+        id=issue.local_id)
+
+    # Only issues that any contributor could view are sent to mailing lists.
+    contributor_could_view = permissions.CanViewIssue(
+        set(), permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET,
+        upstream_project, upstream_issue)
+
+    # Now construct the e-mail to send
+
+    # Note: we purposely do not notify users who starred an issue
+    # about changes in blocking.
+    users_by_id = framework_views.MakeAllUserViews(
+        cnxn, self.services.user,
+        tracker_bizobj.UsersInvolvedInIssues([upstream_issue]), omit_ids)
+
+    is_blocking = upstream_issue.issue_id in issue.blocked_on_iids
+
+    email_data = {
+        'issue': tracker_views.IssueView(
+            upstream_issue, users_by_id, upstream_config),
+        'summary': upstream_issue.summary,
+        'detail_url': upstream_detail_url,
+        'is_blocking': ezt.boolean(is_blocking),
+        'downstream_issue_ref': tracker_bizobj.FormatIssueRef(
+            (None, issue.local_id)),
+        'downstream_issue_url': detail_url,
+        }
+
+    # TODO(jrobbins): Generate two versions of email body: members
+    # vesion has other member full email addresses exposed.  But, don't
+    # expose too many as we iterate through upstream projects.
+    body_link_only = self.link_only_email_template.GetResponse(
+        {'detail_url': upstream_detail_url, 'was_created': ezt.boolean(False)})
+    body = self.email_template.GetResponse(email_data)
+
+    omit_addrs = {users_by_id[omit_id].email for omit_id in omit_ids}
+
+    # Get the transitive set of owners and Cc'd users, and their UserView's.
+    # Give each user a bullet-list of all the reasons that apply for that user.
+    # Starrers are not notified of blocking changes to reduce noise.
+    group_reason_list = notify_reasons.ComputeGroupReasonList(
+        cnxn, self.services, upstream_project, upstream_issue,
+        upstream_config, users_by_id, omit_addrs, contributor_could_view)
+    one_issue_email_tasks = notify_helpers.MakeBulletedEmailWorkItems(
+        group_reason_list, upstream_issue, body_link_only, body, body,
+        upstream_project, hostport, commenter_view, detail_url)
+
+    return one_issue_email_tasks
+
+
+class NotifyBulkChangeTask(notify_helpers.NotifyTaskBase):
+  """JSON servlet that notifies appropriate users after a bulk edit."""
+
+  _EMAIL_TEMPLATE = 'tracker/issue-bulk-change-notification-email.ezt'
+
+  def HandleRequest(self, mr):
+    """Process the task to notify users after an issue blocking change.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful just for debugging.
+      The main goal is the side-effect of sending emails.
+    """
+    issue_ids = mr.GetIntListParam('issue_ids')
+    hostport = mr.GetParam('hostport')
+    if not issue_ids:
+      return {
+          'params': {},
+          'notified': [],
+          'message': 'Cannot proceed without a valid issue IDs.',
+      }
+
+    old_owner_ids = mr.GetIntListParam('old_owner_ids')
+    comment_text = mr.GetParam('comment_text')
+    commenter_id = mr.GetPositiveIntParam('commenter_id')
+    amendments = mr.GetParam('amendments')
+    send_email = bool(mr.GetIntParam('send_email'))
+    params = dict(
+        issue_ids=issue_ids, commenter_id=commenter_id, hostport=hostport,
+        old_owner_ids=old_owner_ids, comment_text=comment_text,
+        send_email=send_email, amendments=amendments)
+
+    logging.info('bulk edit params are %r', params)
+    issues = self.services.issue.GetIssues(mr.cnxn, issue_ids)
+    # TODO(jrobbins): For cross-project bulk edits, prefetch all relevant
+    # projects and configs and pass a dict of them to subroutines.  For
+    # now, all issue must be in the same project.
+    project_id = issues[0].project_id
+    project = self.services.project.GetProject(mr.cnxn, project_id)
+    config = self.services.config.GetProjectConfig(mr.cnxn, project_id)
+    issues = [issue for issue in issues if not issue.is_spam]
+    anon_perms = permissions.GetPermissions(None, set(), project)
+
+    users_by_id = framework_views.MakeAllUserViews(
+        mr.cnxn, self.services.user, [commenter_id])
+    ids_in_issues = {}
+    starrers = {}
+
+    non_private_issues = []
+    for issue, old_owner_id in zip(issues, old_owner_ids):
+      # TODO(jrobbins): use issue_id consistently rather than local_id.
+      starrers[issue.local_id] = self.services.issue_star.LookupItemStarrers(
+          mr.cnxn, issue.issue_id)
+      named_ids = set()  # users named in user-value fields that notify.
+      for fd in config.field_defs:
+        named_ids.update(notify_reasons.ComputeNamedUserIDsToNotify(
+            issue.field_values, fd))
+      direct, indirect = self.services.usergroup.ExpandAnyGroupEmailRecipients(
+          mr.cnxn,
+          list(issue.cc_ids) + list(issue.derived_cc_ids) +
+          [issue.owner_id, old_owner_id, issue.derived_owner_id] +
+          list(named_ids))
+      ids_in_issues[issue.local_id] = set(starrers[issue.local_id])
+      ids_in_issues[issue.local_id].update(direct)
+      ids_in_issues[issue.local_id].update(indirect)
+      ids_in_issue_needing_views = (
+          ids_in_issues[issue.local_id] |
+          tracker_bizobj.UsersInvolvedInIssues([issue]))
+      new_ids_in_issue = [user_id for user_id in ids_in_issue_needing_views
+                          if user_id not in users_by_id]
+      users_by_id.update(
+          framework_views.MakeAllUserViews(
+              mr.cnxn, self.services.user, new_ids_in_issue))
+
+      anon_can_view = permissions.CanViewIssue(
+          set(), anon_perms, project, issue)
+      if anon_can_view:
+        non_private_issues.append(issue)
+
+    commenter_view = users_by_id[commenter_id]
+    omit_addrs = {commenter_view.email}
+
+    tasks = []
+    if send_email:
+      email_tasks = self._BulkEditEmailTasks(
+          mr.cnxn, issues, old_owner_ids, omit_addrs, project,
+          non_private_issues, users_by_id, ids_in_issues, starrers,
+          commenter_view, hostport, comment_text, amendments, config)
+      tasks = email_tasks
+
+    notified = notify_helpers.AddAllEmailTasks(tasks)
+    return {
+        'params': params,
+        'notified': notified,
+        }
+
+  def _BulkEditEmailTasks(
+      self, cnxn, issues, old_owner_ids, omit_addrs, project,
+      non_private_issues, users_by_id, ids_in_issues, starrers,
+      commenter_view, hostport, comment_text, amendments, config):
+    """Generate Email PBs to notify interested users after a bulk edit."""
+    # 1. Get the user IDs of everyone who could be notified,
+    # and make all their user proxies. Also, build a dictionary
+    # of all the users to notify and the issues that they are
+    # interested in.  Also, build a dictionary of additional email
+    # addresses to notify and the issues to notify them of.
+    users_by_id = {}
+    ids_to_notify_of_issue = {}
+    additional_addrs_to_notify_of_issue = collections.defaultdict(list)
+
+    users_to_queries = notify_reasons.GetNonOmittedSubscriptions(
+        cnxn, self.services, [project.project_id], {})
+    config = self.services.config.GetProjectConfig(
+        cnxn, project.project_id)
+    for issue, old_owner_id in zip(issues, old_owner_ids):
+      issue_participants = set(
+          [tracker_bizobj.GetOwnerId(issue), old_owner_id] +
+          tracker_bizobj.GetCcIds(issue))
+      # users named in user-value fields that notify.
+      for fd in config.field_defs:
+        issue_participants.update(
+            notify_reasons.ComputeNamedUserIDsToNotify(issue.field_values, fd))
+      for user_id in ids_in_issues[issue.local_id]:
+        # TODO(jrobbins): implement batch GetUser() for speed.
+        if not user_id:
+          continue
+        auth = authdata.AuthData.FromUserID(
+            cnxn, user_id, self.services)
+        if (auth.user_pb.notify_issue_change and
+            not auth.effective_ids.isdisjoint(issue_participants)):
+          ids_to_notify_of_issue.setdefault(user_id, []).append(issue)
+        elif (auth.user_pb.notify_starred_issue_change and
+              user_id in starrers[issue.local_id]):
+          # Skip users who have starred issues that they can no longer view.
+          starrer_perms = permissions.GetPermissions(
+              auth.user_pb, auth.effective_ids, project)
+          granted_perms = tracker_bizobj.GetGrantedPerms(
+              issue, auth.effective_ids, config)
+          starrer_can_view = permissions.CanViewIssue(
+              auth.effective_ids, starrer_perms, project, issue,
+              granted_perms=granted_perms)
+          if starrer_can_view:
+            ids_to_notify_of_issue.setdefault(user_id, []).append(issue)
+        logging.info(
+            'ids_to_notify_of_issue[%s] = %s',
+            user_id,
+            [i.local_id for i in ids_to_notify_of_issue.get(user_id, [])])
+
+      # Find all subscribers that should be notified.
+      subscribers_to_consider = notify_reasons.EvaluateSubscriptions(
+          cnxn, issue, users_to_queries, self.services, config)
+      for sub_id in subscribers_to_consider:
+        auth = authdata.AuthData.FromUserID(cnxn, sub_id, self.services)
+        sub_perms = permissions.GetPermissions(
+            auth.user_pb, auth.effective_ids, project)
+        granted_perms = tracker_bizobj.GetGrantedPerms(
+            issue, auth.effective_ids, config)
+        sub_can_view = permissions.CanViewIssue(
+            auth.effective_ids, sub_perms, project, issue,
+            granted_perms=granted_perms)
+        if sub_can_view:
+          ids_to_notify_of_issue.setdefault(sub_id, [])
+          if issue not in ids_to_notify_of_issue[sub_id]:
+            ids_to_notify_of_issue[sub_id].append(issue)
+
+      if issue in non_private_issues:
+        for notify_addr in issue.derived_notify_addrs:
+          additional_addrs_to_notify_of_issue[notify_addr].append(issue)
+
+    # 2. Compose an email specifically for each user, and one email to each
+    # notify_addr with all the issues that it.
+    # Start from non-members first, then members to reveal email addresses.
+    email_tasks = []
+    needed_user_view_ids = [uid for uid in ids_to_notify_of_issue
+                            if uid not in users_by_id]
+    users_by_id.update(framework_views.MakeAllUserViews(
+        cnxn, self.services.user, needed_user_view_ids))
+    member_ids_to_notify_of_issue = {}
+    non_member_ids_to_notify_of_issue = {}
+    member_additional_addrs = {}
+    non_member_additional_addrs = {}
+    addr_to_addrperm = {}  # {email_address: AddrPerm object}
+    all_user_prefs = self.services.user.GetUsersPrefs(
+        cnxn, ids_to_notify_of_issue)
+
+    # TODO(jrobbins): Merge ids_to_notify_of_issue entries for linked accounts.
+
+    for user_id in ids_to_notify_of_issue:
+      if not user_id:
+        continue  # Don't try to notify NO_USER_SPECIFIED
+      if users_by_id[user_id].email in omit_addrs:
+        logging.info('Omitting %s', user_id)
+        continue
+      user_issues = ids_to_notify_of_issue[user_id]
+      if not user_issues:
+        continue  # user's prefs indicate they don't want these notifications
+      auth = authdata.AuthData.FromUserID(
+          cnxn, user_id, self.services)
+      is_member = bool(framework_bizobj.UserIsInProject(
+          project, auth.effective_ids))
+      if is_member:
+        member_ids_to_notify_of_issue[user_id] = user_issues
+      else:
+        non_member_ids_to_notify_of_issue[user_id] = user_issues
+      addr = users_by_id[user_id].email
+      omit_addrs.add(addr)
+      addr_to_addrperm[addr] = notify_reasons.AddrPerm(
+          is_member, addr, users_by_id[user_id].user,
+          notify_reasons.REPLY_NOT_ALLOWED, all_user_prefs[user_id])
+
+    for addr, addr_issues in additional_addrs_to_notify_of_issue.items():
+      auth = None
+      try:
+        auth = authdata.AuthData.FromEmail(cnxn, addr, self.services)
+      except:  # pylint: disable=bare-except
+        logging.warning('Cannot find user of email %s ', addr)
+      if auth:
+        is_member = bool(framework_bizobj.UserIsInProject(
+            project, auth.effective_ids))
+      else:
+        is_member = False
+      if is_member:
+        member_additional_addrs[addr] = addr_issues
+      else:
+        non_member_additional_addrs[addr] = addr_issues
+      omit_addrs.add(addr)
+      addr_to_addrperm[addr] = notify_reasons.AddrPerm(
+          is_member, addr, None, notify_reasons.REPLY_NOT_ALLOWED, None)
+
+    for user_id, user_issues in non_member_ids_to_notify_of_issue.items():
+      addr = users_by_id[user_id].email
+      email = self._FormatBulkIssuesEmail(
+          addr_to_addrperm[addr], user_issues, users_by_id,
+          commenter_view, hostport, comment_text, amendments, config, project)
+      email_tasks.append(email)
+      logging.info('about to bulk notify non-member %s (%s) of %s',
+                   users_by_id[user_id].email, user_id,
+                   [issue.local_id for issue in user_issues])
+
+    for addr, addr_issues in non_member_additional_addrs.items():
+      email = self._FormatBulkIssuesEmail(
+          addr_to_addrperm[addr], addr_issues, users_by_id, commenter_view,
+          hostport, comment_text, amendments, config, project)
+      email_tasks.append(email)
+      logging.info('about to bulk notify non-member additional addr %s of %s',
+                   addr, [addr_issue.local_id for addr_issue in addr_issues])
+
+    framework_views.RevealAllEmails(users_by_id)
+    commenter_view.RevealEmail()
+
+    for user_id, user_issues in member_ids_to_notify_of_issue.items():
+      addr = users_by_id[user_id].email
+      email = self._FormatBulkIssuesEmail(
+          addr_to_addrperm[addr], user_issues, users_by_id,
+          commenter_view, hostport, comment_text, amendments, config, project)
+      email_tasks.append(email)
+      logging.info('about to bulk notify member %s (%s) of %s',
+                   addr, user_id, [issue.local_id for issue in user_issues])
+
+    for addr, addr_issues in member_additional_addrs.items():
+      email = self._FormatBulkIssuesEmail(
+          addr_to_addrperm[addr], addr_issues, users_by_id, commenter_view,
+          hostport, comment_text, amendments, config, project)
+      email_tasks.append(email)
+      logging.info('about to bulk notify member additional addr %s of %s',
+                   addr, [addr_issue.local_id for addr_issue in addr_issues])
+
+    # 4. Add in the project's issue_notify_address.  This happens even if it
+    # is the same as the commenter's email address (which would be an unusual
+    # but valid project configuration).  Only issues that any contributor could
+    # view are included in emails to the all-issue-activity mailing lists.
+    if (project.issue_notify_address
+        and project.issue_notify_address not in omit_addrs):
+      non_private_issues_live = []
+      for issue in issues:
+        contributor_could_view = permissions.CanViewIssue(
+            set(), permissions.CONTRIBUTOR_ACTIVE_PERMISSIONSET,
+            project, issue)
+        if contributor_could_view:
+          non_private_issues_live.append(issue)
+
+      if non_private_issues_live:
+        project_notify_addrperm = notify_reasons.AddrPerm(
+            True, project.issue_notify_address, None,
+            notify_reasons.REPLY_NOT_ALLOWED, None)
+        email = self._FormatBulkIssuesEmail(
+            project_notify_addrperm, non_private_issues_live,
+            users_by_id, commenter_view, hostport, comment_text, amendments,
+            config, project)
+        email_tasks.append(email)
+        omit_addrs.add(project.issue_notify_address)
+        logging.info('about to bulk notify all-issues %s of %s',
+                     project.issue_notify_address,
+                     [issue.local_id for issue in non_private_issues])
+
+    return email_tasks
+
+  def _FormatBulkIssuesEmail(
+      self, addr_perm, issues, users_by_id, commenter_view,
+      hostport, comment_text, amendments, config, project):
+    """Format an email to one user listing many issues."""
+
+    from_addr = emailfmt.FormatFromAddr(
+        project, commenter_view=commenter_view, reveal_addr=addr_perm.is_member,
+        can_reply_to=False)
+
+    subject, body = self._FormatBulkIssues(
+        issues, users_by_id, commenter_view, hostport, comment_text,
+        amendments, config, addr_perm)
+    body = notify_helpers._TruncateBody(body)
+
+    return dict(from_addr=from_addr, to=addr_perm.address, subject=subject,
+                body=body)
+
+  def _FormatBulkIssues(
+      self, issues, users_by_id, commenter_view, hostport, comment_text,
+      amendments, config, addr_perm):
+    """Format a subject and body for a bulk issue edit."""
+    project_name = issues[0].project_name
+
+    any_link_only = False
+    issue_views = []
+    for issue in issues:
+      # TODO(jrobbins): choose config from dict of prefetched configs.
+      issue_view = tracker_views.IssueView(issue, users_by_id, config)
+      issue_view.link_only = ezt.boolean(False)
+      if addr_perm and notify_helpers.ShouldUseLinkOnly(addr_perm, issue):
+        issue_view.link_only = ezt.boolean(True)
+        any_link_only = True
+      issue_views.append(issue_view)
+
+    email_data = {
+        'any_link_only': ezt.boolean(any_link_only),
+        'hostport': hostport,
+        'num_issues': len(issues),
+        'issues': issue_views,
+        'comment_text': comment_text,
+        'commenter': commenter_view,
+        'amendments': amendments,
+    }
+
+    if len(issues) == 1:
+      # TODO(jrobbins): use compact email subject lines based on user pref.
+      if addr_perm and notify_helpers.ShouldUseLinkOnly(addr_perm, issues[0]):
+        subject = 'issue %s in %s' % (issues[0].local_id, project_name)
+      else:
+        subject = 'issue %s in %s: %s' % (
+            issues[0].local_id, project_name, issues[0].summary)
+      # TODO(jrobbins): Look up the sequence number instead and treat this
+      # more like an individual change for email threading.  For now, just
+      # add "Re:" because bulk edits are always replies.
+      subject = 'Re: ' + subject
+    else:
+      subject = '%d issues changed in %s' % (len(issues), project_name)
+
+    body = self.email_template.GetResponse(email_data)
+
+    return subject, body
+
+
+# For now, this class will not be used to send approval comment notifications
+# TODO(jojwang): monorail:3588, it might make sense for this class to handle
+# sending comment notifications for approval custom_subfield changes.
+class NotifyApprovalChangeTask(notify_helpers.NotifyTaskBase):
+  """JSON servlet that notifies appropriate users after an approval change."""
+
+  _EMAIL_TEMPLATE = 'tracker/approval-change-notification-email.ezt'
+
+  def HandleRequest(self, mr):
+    """Process the task to notify users after an approval change.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful just for debugging.
+      The main goal is the side-effect of sending emails.
+    """
+
+    send_email = bool(mr.GetIntParam('send_email'))
+    issue_id = mr.GetPositiveIntParam('issue_id')
+    approval_id = mr.GetPositiveIntParam('approval_id')
+    comment_id = mr.GetPositiveIntParam('comment_id')
+    hostport = mr.GetParam('hostport')
+
+    params = dict(
+        temporary='',
+        hostport=hostport,
+        issue_id=issue_id
+        )
+    logging.info('approval change params are %r', params)
+
+    issue, approval_value = self.services.issue.GetIssueApproval(
+        mr.cnxn, issue_id, approval_id, use_cache=False)
+    project = self.services.project.GetProject(mr.cnxn, issue.project_id)
+    config = self.services.config.GetProjectConfig(mr.cnxn, issue.project_id)
+
+    approval_fd = tracker_bizobj.FindFieldDefByID(approval_id, config)
+    if approval_fd is None:
+      raise exceptions.NoSuchFieldDefException()
+
+    # GetCommentsForIssue will fill the sequence for all comments, while
+    # other method for getting a single comment will not.
+    # The comment sequence is especially useful for Approval issues with
+    # many comment sections.
+    comment = None
+    all_comments = self.services.issue.GetCommentsForIssue(mr.cnxn, issue_id)
+    for c in all_comments:
+      if c.id == comment_id:
+        comment = c
+        break
+    if not comment:
+      raise exceptions.NoSuchCommentException()
+
+    field_user_ids = set()
+    relevant_fds = [fd for fd in config.field_defs if
+                    not fd.approval_id or
+                    fd.approval_id is approval_value.approval_id]
+    for fd in relevant_fds:
+      field_user_ids.update(
+          notify_reasons.ComputeNamedUserIDsToNotify(issue.field_values, fd))
+    users_by_id = framework_views.MakeAllUserViews(
+        mr.cnxn, self.services.user, [issue.owner_id],
+        approval_value.approver_ids,
+        tracker_bizobj.UsersInvolvedInComment(comment),
+        list(field_user_ids))
+
+    tasks = []
+    if send_email:
+      tasks = self._MakeApprovalEmailTasks(
+          hostport, issue, project, approval_value, approval_fd.field_name,
+          comment, users_by_id, list(field_user_ids), mr.perms)
+
+    notified = notify_helpers.AddAllEmailTasks(tasks)
+
+    return {
+        'params': params,
+        'notified': notified,
+        'tasks': tasks,
+        }
+
+  def _MakeApprovalEmailTasks(
+      self, hostport, issue, project, approval_value, approval_name,
+      comment, users_by_id, user_ids_from_fields, perms):
+    """Formulate emails to be sent."""
+
+    # TODO(jojwang): avoid need to make MonorailRequest and autolinker
+    # for comment_view OR make make tracker_views._ParseTextRuns public
+    # and only pass text_runs to email_data.
+    mr = monorailrequest.MonorailRequest(self.services)
+    mr.project_name = project.project_name
+    mr.project = project
+    mr.perms = perms
+    autolinker = autolink.Autolink()
+
+    approval_url = framework_helpers.IssueCommentURL(
+        hostport, project, issue.local_id, seq_num=comment.sequence)
+
+    comment_view = tracker_views.IssueCommentView(
+        project.project_name, comment, users_by_id, autolinker, {}, mr, issue)
+    domain_url = framework_helpers.FormatAbsoluteURLForDomain(
+        hostport, project.project_name, '/issues/')
+
+    commenter_view = users_by_id[comment.user_id]
+    email_data = {
+        'domain_url': domain_url,
+        'approval_url': approval_url,
+        'comment': comment_view,
+        'issue_local_id': issue.local_id,
+        'summary': issue.summary,
+        }
+    subject = '%s Approval: %s (Issue %s)' % (
+        approval_name, issue.summary, issue.local_id)
+    email_body = self.email_template.GetResponse(email_data)
+    body = notify_helpers._TruncateBody(email_body)
+
+    recipient_ids = self._GetApprovalEmailRecipients(
+        approval_value, comment, issue, user_ids_from_fields,
+        omit_ids=[comment.user_id])
+    direct, indirect = self.services.usergroup.ExpandAnyGroupEmailRecipients(
+        mr.cnxn, recipient_ids)
+    # group ids were found in recipient_ids.
+    # Re-set recipient_ids to remove group_ids
+    if indirect:
+      recipient_ids = set(direct + indirect)
+      users_by_id.update(framework_views.MakeAllUserViews(
+          mr.cnxn, self.services.user, indirect))  # already contains direct
+
+    # TODO(crbug.com/monorail/9104): Compute notify_reasons.AddrPerms based on
+    # project settings and recipient permissions so `reply_to` can be accurately
+    # set.
+
+    email_tasks = []
+    for rid in recipient_ids:
+      from_addr = emailfmt.FormatFromAddr(
+          project, commenter_view=commenter_view, can_reply_to=False)
+      dest_email = users_by_id[rid].email
+
+      refs = emailfmt.GetReferences(
+          dest_email, subject, comment.sequence,
+          '%s@%s' % (project.project_name, emailfmt.MailDomain()))
+      reply_to = emailfmt.NoReplyAddress()
+      email_tasks.append(
+          dict(
+              from_addr=from_addr,
+              to=dest_email,
+              subject=subject,
+              body=body,
+              reply_to=reply_to,
+              references=refs))
+
+    return email_tasks
+
+  def _GetApprovalEmailRecipients(
+      self, approval_value, comment, issue, user_ids_from_fields,
+      omit_ids=None):
+    # TODO(jojwang): monorail:3588, reorganize this, since now, comment_content
+    # and approval amendments happen in the same comment.
+    # NOTE: user_ids_from_fields are all the notify_on=ANY_COMMENT users.
+    # However, these users will still be excluded from notifications
+    # meant for approvers only eg. (status changed to REVIEW_REQUESTED).
+    recipient_ids = []
+    if comment.amendments:
+      for amendment in comment.amendments:
+        if amendment.custom_field_name == 'Status':
+          if (approval_value.status is
+              tracker_pb2.ApprovalStatus.REVIEW_REQUESTED):
+            recipient_ids = approval_value.approver_ids
+          else:
+            recipient_ids.extend([issue.owner_id])
+            recipient_ids.extend(user_ids_from_fields)
+
+        elif amendment.custom_field_name == 'Approvers':
+          recipient_ids.extend(approval_value.approver_ids)
+          recipient_ids.append(issue.owner_id)
+          recipient_ids.extend(user_ids_from_fields)
+          recipient_ids.extend(amendment.removed_user_ids)
+    else:
+      # No amendments, just a comment.
+      recipient_ids.extend(approval_value.approver_ids)
+      recipient_ids.append(issue.owner_id)
+      recipient_ids.extend(user_ids_from_fields)
+
+    if omit_ids:
+      recipient_ids = [rid for rid in recipient_ids if rid not in omit_ids]
+
+    return list(set(recipient_ids))
+
+
+class NotifyRulesDeletedTask(notify_helpers.NotifyTaskBase):
+  """JSON servlet that sends one email."""
+
+  _EMAIL_TEMPLATE = 'project/rules-deleted-notification-email.ezt'
+
+  def HandleRequest(self, mr):
+    """Process the task to notify project owners after a filter rule
+      has been deleted.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful for debugging.
+    """
+    project_id = mr.GetPositiveIntParam('project_id')
+    rules = mr.GetListParam('filter_rules')
+    hostport = mr.GetParam('hostport')
+
+    params = dict(
+        project_id=project_id,
+        rules=rules,
+        hostport=hostport,
+        )
+    logging.info('deleted filter rules params are %r', params)
+
+    project = self.services.project.GetProject(mr.cnxn, project_id)
+    emails_by_id = self.services.user.LookupUserEmails(
+        mr.cnxn, project.owner_ids, ignore_missed=True)
+
+    tasks = self._MakeRulesDeletedEmailTasks(
+        hostport, project, emails_by_id, rules)
+    notified = notify_helpers.AddAllEmailTasks(tasks)
+
+    return {
+        'params': params,
+        'notified': notified,
+        'tasks': tasks,
+        }
+
+  def _MakeRulesDeletedEmailTasks(self, hostport, project, emails_by_id, rules):
+
+    rules_url = framework_helpers.FormatAbsoluteURLForDomain(
+        hostport, project.project_name, urls.ADMIN_RULES)
+
+    email_data = {
+        'project_name': project.project_name,
+        'rules': rules,
+        'rules_url': rules_url,
+    }
+    logging.info(email_data)
+    subject = '%s Project: Deleted Filter Rules' % project.project_name
+    email_body = self.email_template.GetResponse(email_data)
+    body = notify_helpers._TruncateBody(email_body)
+
+    email_tasks = []
+    for rid in project.owner_ids:
+      from_addr = emailfmt.FormatFromAddr(
+          project, reveal_addr=True, can_reply_to=False)
+      dest_email = emails_by_id.get(rid)
+      email_tasks.append(
+          dict(from_addr=from_addr, to=dest_email, subject=subject, body=body))
+
+    return email_tasks
+
+
+class OutboundEmailTask(jsonfeed.InternalTask):
+  """JSON servlet that sends one email.
+
+  Handles tasks enqueued from notify_helpers._EnqueueOutboundEmail.
+  """
+
+  def HandleRequest(self, mr):
+    """Process the task to send one email message.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+
+    Returns:
+      Results dictionary in JSON format which is useful just for debugging.
+      The main goal is the side-effect of sending emails.
+    """
+    # To avoid urlencoding the email body, the most salient parameters to this
+    # method are passed as a json-encoded POST body.
+    try:
+      email_params = json.loads(self.request.body)
+    except ValueError:
+      logging.error(self.request.body)
+      raise
+    # If running on a GAFYD domain, you must define an app alias on the
+    # Application Settings admin web page.
+    sender = email_params.get('from_addr')
+    reply_to = email_params.get('reply_to')
+    to = email_params.get('to')
+    if not to:
+      # Cannot proceed if we cannot create a valid EmailMessage.
+      return {'note': 'Skipping because no "to" address found.'}
+
+    # Don't send emails to any banned users.
+    try:
+      user_id = self.services.user.LookupUserID(mr.cnxn, to)
+      user = self.services.user.GetUser(mr.cnxn, user_id)
+      if user.banned:
+        logging.info('Not notifying banned user %r', user.email)
+        return {'note': 'Skipping because user is banned.'}
+    except exceptions.NoSuchUserException:
+      pass
+
+    references = email_params.get('references')
+    subject = email_params.get('subject')
+    body = email_params.get('body')
+    html_body = email_params.get('html_body')
+
+    if settings.local_mode:
+      to_format = settings.send_local_email_to
+    else:
+      to_format = settings.send_all_email_to
+
+    if to_format:
+      to_user, to_domain = to.split('@')
+      to = to_format % {'user': to_user, 'domain': to_domain}
+
+    logging.info(
+        'Email:\n sender: %s\n reply_to: %s\n to: %s\n references: %s\n '
+        'subject: %s\n body: %s\n html body: %s',
+        sender, reply_to, to, references, subject, body, html_body)
+    if html_body:
+      logging.info('Readable HTML:\n%s', html_body.replace('<br/>', '<br/>\n'))
+    message = mail.EmailMessage(
+        sender=sender, to=to, subject=subject, body=body)
+    if html_body:
+      message.html = html_body
+    if reply_to:
+      message.reply_to = reply_to
+    if references:
+      message.headers = {'References': references}
+    if settings.unit_test_mode:
+      logging.info('Sending message "%s" in test mode.', message.subject)
+    else:
+      retry_count = 3
+      for i in range(retry_count):
+        try:
+          message.send()
+          break
+        except apiproxy_errors.DeadlineExceededError as ex:
+          logging.warning('Sending email timed out on try: %d', i)
+          logging.warning(str(ex))
+
+    return dict(
+        sender=sender, to=to, subject=subject, body=body, html_body=html_body,
+        reply_to=reply_to, references=references)
