diff --git a/features/notify_reasons.py b/features/notify_reasons.py
new file mode 100644
index 0000000..436f975
--- /dev/null
+++ b/features/notify_reasons.py
@@ -0,0 +1,438 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Helper functions for deciding who to notify and why.."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import logging
+
+import settings
+from features import filterrules_helpers
+from features import savedqueries_helpers
+from framework import authdata
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import framework_helpers
+from framework import framework_views
+from framework import permissions
+from proto import tracker_pb2
+from search import query2ast
+from search import searchpipeline
+from tracker import component_helpers
+from tracker import tracker_bizobj
+
+# When sending change notification emails, choose the reply-to header and
+# footer message based on three levels of the recipient's permissions
+# for that issue.
+REPLY_NOT_ALLOWED = 'REPLY_NOT_ALLOWED'
+REPLY_MAY_COMMENT = 'REPLY_MAY_COMMENT'
+REPLY_MAY_UPDATE = 'REPLY_MAY_UPDATE'
+
+# These are strings describing the various reasons that we send notifications.
+REASON_REPORTER = 'You reported this issue'
+REASON_OWNER = 'You are the owner of the issue'
+REASON_OLD_OWNER = 'You were the issue owner before this change'
+REASON_DEFAULT_OWNER = 'A rule made you owner of the issue'
+REASON_CCD = 'You were specifically CC\'d on the issue'
+REASON_DEFAULT_CCD = 'A rule CC\'d you on the issue'
+# TODO(crbug.com/monorail/2857): separate reasons for notification to group
+# members resulting from component and rules derived ccs.
+REASON_GROUP_CCD = (
+    'A group you\'re a member of was specifically CC\'d on the issue')
+REASON_STARRER = 'You starred the issue'
+REASON_SUBSCRIBER = 'Your saved query matched the issue'
+REASON_ALSO_NOTIFY = 'A rule was set up to notify you'
+REASON_ALL_NOTIFICATIONS = (
+    'The project was configured to send all issue notifications '
+    'to this address')
+REASON_LINKED_ACCOUNT = 'Your linked account would have been notified'
+
+# An AddrPerm is how we represent our decision to notify a given
+# email address, which version of the email body to send to them, and
+# whether to offer them the option to reply to the notification.  Many
+# of the functions in this file pass around AddrPerm lists (an "APL").
+# is_member is a boolean
+# address is a string email address
+# user is a User PB, including built-in user preference fields.
+# reply_perm is one of REPLY_NOT_ALLOWED, REPLY_MAY_COMMENT,
+# REPLY_MAY_UPDATE.
+# user_prefs is a UserPrefs object with string->string user prefs.
+AddrPerm = collections.namedtuple(
+    'AddrPerm', 'is_member, address, user, reply_perm, user_prefs')
+
+
+
+def ComputeIssueChangeAddressPermList(
+    cnxn, ids_to_consider, project, issue, services, omit_addrs,
+    users_by_id, pref_check_function=lambda u: u.notify_issue_change):
+  """Return a list of user email addresses to notify of an issue change.
+
+  User email addresses are determined by looking up the given user IDs
+  in the given users_by_id dict.
+
+  Args:
+    cnxn: connection to SQL database.
+    ids_to_consider: list of user IDs for users interested in this issue.
+    project: Project PB for the project containing this issue.
+    issue: Issue PB for the issue that was updated.
+    services: Services.
+    omit_addrs: set of strings for email addresses to not notify because
+        they already know.
+    users_by_id: dict {user_id: user_view} user info.
+    pref_check_function: optional function to use to check if a certain
+        User PB has a preference set to receive the email being sent.  It
+        defaults to "If I am in the issue's owner or cc field", but it
+        can be set to check "If I starred the issue."
+
+  Returns:
+    A list of AddrPerm objects.
+  """
+  memb_addr_perm_list = []
+  logging.info('Considering %r ', ids_to_consider)
+  all_user_prefs = services.user.GetUsersPrefs(cnxn, ids_to_consider)
+  for user_id in ids_to_consider:
+    if user_id == framework_constants.NO_USER_SPECIFIED:
+      continue
+    user = services.user.GetUser(cnxn, user_id)
+    # Notify people who have a pref set, or if they have no User PB
+    # because the pref defaults to True.
+    if user and not pref_check_function(user):
+      logging.info('Not notifying %r: user preference', user.email)
+      continue
+    # TODO(jrobbins): doing a bulk operation would reduce DB load.
+    auth = authdata.AuthData.FromUserID(cnxn, user_id, services)
+    perms = permissions.GetPermissions(user, 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):
+      logging.info('Not notifying %r: user cannot view issue', user.email)
+      continue
+
+    addr = users_by_id[user_id].email
+    if addr in omit_addrs:
+      logging.info('Not notifying %r: user already knows', user.email)
+      continue
+
+    recipient_is_member = bool(framework_bizobj.UserIsInProject(
+        project, auth.effective_ids))
+
+    reply_perm = REPLY_NOT_ALLOWED
+    if project.process_inbound_email:
+      if permissions.CanEditIssue(auth.effective_ids, perms, project, issue):
+        reply_perm = REPLY_MAY_UPDATE
+      elif permissions.CanCommentIssue(
+          auth.effective_ids, perms, project, issue):
+        reply_perm = REPLY_MAY_COMMENT
+
+    memb_addr_perm_list.append(
+      AddrPerm(recipient_is_member, addr, user, reply_perm,
+               all_user_prefs[user_id]))
+
+  logging.info('For %s %s, will notify: %r',
+               project.project_name, issue.local_id,
+               [ap.address for ap in memb_addr_perm_list])
+
+  return memb_addr_perm_list
+
+
+def ComputeProjectNotificationAddrList(
+    cnxn, services, project, contributor_could_view, omit_addrs):
+  """Return a list of non-user addresses to notify of an issue change.
+
+  The non-user addresses are specified by email address strings, not
+  user IDs.  One such address can be specified in the project PB.
+  It is not assumed to have permission to see all issues.
+
+  Args:
+    cnxn: connection to SQL database.
+    services: A Services object.
+    project: Project PB containing the issue that was updated.
+    contributor_could_view: True if any project contributor should be able to
+        see the notification email, e.g., in a mailing list archive or feed.
+    omit_addrs: set of strings for email addresses to not notify because
+        they already know.
+
+  Returns:
+    A list of tuples: [(False, email_addr, None, reply_permission_level), ...],
+    where reply_permission_level is always REPLY_NOT_ALLOWED for now.
+  """
+  memb_addr_perm_list = []
+  if contributor_could_view:
+    ml_addr = project.issue_notify_address
+    ml_user_prefs = services.user.GetUserPrefsByEmail(cnxn, ml_addr)
+
+    if ml_addr and ml_addr not in omit_addrs:
+      memb_addr_perm_list.append(
+          AddrPerm(False, ml_addr, None, REPLY_NOT_ALLOWED, ml_user_prefs))
+
+  return memb_addr_perm_list
+
+
+def ComputeIssueNotificationAddrList(cnxn, services, issue, omit_addrs):
+  """Return a list of non-user addresses to notify of an issue change.
+
+  The non-user addresses are specified by email address strings, not
+  user IDs.  They can be set by filter rules with the "Also notify" action.
+  "Also notify" addresses are assumed to have permission to see any issue,
+  even a restricted one.
+
+  Args:
+    cnxn: connection to SQL database.
+    services: A Services object.
+    issue: Issue PB for the issue that was updated.
+    omit_addrs: set of strings for email addresses to not notify because
+        they already know.
+
+  Returns:
+    A list of tuples: [(False, email_addr, None, reply_permission_level), ...],
+    where reply_permission_level is always REPLY_NOT_ALLOWED for now.
+  """
+  addr_perm_list = []
+  for addr in issue.derived_notify_addrs:
+    if addr not in omit_addrs:
+      notify_user_prefs = services.user.GetUserPrefsByEmail(cnxn, addr)
+      addr_perm_list.append(
+          AddrPerm(False, addr, None, REPLY_NOT_ALLOWED, notify_user_prefs))
+
+  return addr_perm_list
+
+
+def _GetSubscribersAddrPermList(
+    cnxn, services, issue, project, config, omit_addrs, users_by_id):
+  """Lookup subscribers, evaluate their saved queries, and decide to notify."""
+  users_to_queries = GetNonOmittedSubscriptions(
+      cnxn, services, [project.project_id], omit_addrs)
+  # TODO(jrobbins): need to pass through the user_id to use for "me".
+  subscribers_to_notify = EvaluateSubscriptions(
+      cnxn, issue, users_to_queries, services, config)
+  # TODO(jrobbins): expand any subscribers that are user groups.
+  subs_needing_user_views = [
+      uid for uid in subscribers_to_notify if uid not in users_by_id]
+  users_by_id.update(framework_views.MakeAllUserViews(
+      cnxn, services.user, subs_needing_user_views))
+  sub_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, subscribers_to_notify, project, issue, services, omit_addrs,
+      users_by_id, pref_check_function=lambda *args: True)
+
+  return sub_addr_perm_list
+
+
+def EvaluateSubscriptions(
+    cnxn, issue, users_to_queries, services, config):
+  """Determine subscribers who have subs that match the given issue."""
+  # Note: unlike filter rule, subscriptions see explicit & derived values.
+  lower_labels = [lab.lower() for lab in tracker_bizobj.GetLabels(issue)]
+  label_set = set(lower_labels)
+
+  subscribers_to_notify = []
+  for uid, saved_queries in users_to_queries.items():
+    for sq in saved_queries:
+      if sq.subscription_mode != 'immediate':
+        continue
+      if issue.project_id not in sq.executes_in_project_ids:
+        continue
+      cond = savedqueries_helpers.SavedQueryToCond(sq)
+      # TODO(jrobbins): Support linked accounts me_user_ids.
+      cond, _warnings = searchpipeline.ReplaceKeywordsWithUserIDs([uid], cond)
+      cond_ast = query2ast.ParseUserQuery(
+        cond, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+
+      if filterrules_helpers.EvalPredicate(
+          cnxn, services, cond_ast, issue, label_set, config,
+          tracker_bizobj.GetOwnerId(issue), tracker_bizobj.GetCcIds(issue),
+          tracker_bizobj.GetStatus(issue)):
+        subscribers_to_notify.append(uid)
+        break  # Don't bother looking at the user's other saved quereies.
+
+  return subscribers_to_notify
+
+
+def GetNonOmittedSubscriptions(cnxn, services, project_ids, omit_addrs):
+  """Get a dict of users w/ subscriptions in those projects."""
+  users_to_queries = services.features.GetSubscriptionsInProjects(
+      cnxn, project_ids)
+  user_emails = services.user.LookupUserEmails(
+      cnxn, list(users_to_queries.keys()))
+  for user_id, email in user_emails.items():
+    if email in omit_addrs:
+      del users_to_queries[user_id]
+  return users_to_queries
+
+
+def ComputeCustomFieldAddrPerms(
+    cnxn, config, issue, project, services, omit_addrs, users_by_id):
+  """Check the reasons to notify users named in custom fields."""
+  group_reason_list = []
+  for fd in config.field_defs:
+    (direct_named_ids,
+     transitive_named_ids) = services.usergroup.ExpandAnyGroupEmailRecipients(
+         cnxn, ComputeNamedUserIDsToNotify(issue.field_values, fd))
+    named_user_ids = direct_named_ids + transitive_named_ids
+    if named_user_ids:
+      named_addr_perms = ComputeIssueChangeAddressPermList(
+          cnxn, named_user_ids, project, issue, services, omit_addrs,
+          users_by_id, pref_check_function=lambda u: True)
+      group_reason_list.append(
+          (named_addr_perms, 'You are named in the %s field' % fd.field_name))
+
+  return group_reason_list
+
+
+def ComputeNamedUserIDsToNotify(field_values, fd):
+  """Give a list of user IDs to notify because they're in a field."""
+  if (fd.field_type == tracker_pb2.FieldTypes.USER_TYPE and
+      fd.notify_on == tracker_pb2.NotifyTriggers.ANY_COMMENT):
+    return [fv.user_id for fv in field_values
+            if fv.field_id == fd.field_id]
+
+  return []
+
+
+def ComputeComponentFieldAddrPerms(
+    cnxn, config, issue, project, services, omit_addrs, users_by_id):
+  """Return [(addr_perm_list, reason),...] for users auto-cc'd by components."""
+  component_ids = set(issue.component_ids)
+  group_reason_list = []
+  for cd in config.component_defs:
+    if cd.component_id in component_ids:
+      (direct_ccs,
+       transitive_ccs) = services.usergroup.ExpandAnyGroupEmailRecipients(
+           cnxn, component_helpers.GetCcIDsForComponentAndAncestors(config, cd))
+      cc_ids = direct_ccs + transitive_ccs
+      comp_addr_perms = ComputeIssueChangeAddressPermList(
+          cnxn, cc_ids, project, issue, services, omit_addrs,
+          users_by_id, pref_check_function=lambda u: True)
+      group_reason_list.append(
+          (comp_addr_perms,
+           'You are auto-CC\'d on all issues in component %s' % cd.path))
+
+  return group_reason_list
+
+
+def ComputeGroupReasonList(
+    cnxn, services, project, issue, config, users_by_id, omit_addrs,
+    contributor_could_view, starrer_ids=None, noisy=False,
+    old_owner_id=None, commenter_in_project=True, include_subscribers=True,
+    include_notify_all=True,
+    starrer_pref_check_function=lambda u: u.notify_starred_issue_change):
+  """Return a list [(addr_perm_list, reason),...] of addrs to notify."""
+  # Get the transitive set of owners and Cc'd users, and their UserViews.
+  starrer_ids = starrer_ids or []
+  reporter = [issue.reporter_id] if issue.reporter_id in starrer_ids else []
+  if old_owner_id:
+    old_direct_owners, old_transitive_owners = (
+        services.usergroup.ExpandAnyGroupEmailRecipients(cnxn, [old_owner_id]))
+  else:
+    old_direct_owners, old_transitive_owners = [], []
+
+  direct_owners, transitive_owners = (
+      services.usergroup.ExpandAnyGroupEmailRecipients(cnxn, [issue.owner_id]))
+  der_direct_owners, der_transitive_owners = (
+      services.usergroup.ExpandAnyGroupEmailRecipients(
+          cnxn, [issue.derived_owner_id]))
+  direct_comp, trans_comp = services.usergroup.ExpandAnyGroupEmailRecipients(
+      cnxn, component_helpers.GetComponentCcIDs(issue, config))
+  direct_ccs, transitive_ccs = services.usergroup.ExpandAnyGroupEmailRecipients(
+      cnxn, list(issue.cc_ids))
+  der_direct_ccs, der_transitive_ccs = (
+      services.usergroup.ExpandAnyGroupEmailRecipients(
+          cnxn, list(issue.derived_cc_ids)))
+  # Remove cc's derived from components, which are grouped into their own
+  # notify-reason-group in ComputeComponentFieldAddrPerms().
+  # This means that an exact email cc'd by both a component and a rule will
+  # get an email that says they are only being notified because of the
+  # component.
+  # Note that a user directly cc'd due to a rule who is also part of a
+  # group cc'd due to a component, will get a message saying they're cc'd for
+  # both the rule and the component.
+  der_direct_ccs = list(set(der_direct_ccs).difference(set(direct_comp)))
+  der_transitive_ccs = list(set(der_transitive_ccs).difference(set(trans_comp)))
+
+  users_by_id.update(framework_views.MakeAllUserViews(
+      cnxn, services.user, transitive_owners, der_transitive_owners,
+      direct_comp, trans_comp, transitive_ccs, der_transitive_ccs))
+
+  # Notify interested people according to the reason for their interest:
+  # owners, component auto-cc'd users, cc'd users, starrers, and
+  # other notification addresses.
+  reporter_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, reporter, project, issue, services, omit_addrs, users_by_id)
+  owner_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, direct_owners + transitive_owners, project, issue,
+      services, omit_addrs, users_by_id)
+  old_owner_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, old_direct_owners + old_transitive_owners, project, issue,
+      services, omit_addrs, users_by_id)
+  owner_addr_perm_set = set(owner_addr_perm_list)
+  old_owner_addr_perm_list = [ap for ap in old_owner_addr_perm_list
+                              if ap not in owner_addr_perm_set]
+  der_owner_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, der_direct_owners + der_transitive_owners, project, issue,
+      services, omit_addrs, users_by_id)
+  cc_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, direct_ccs, project, issue, services, omit_addrs, users_by_id)
+  transitive_cc_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, transitive_ccs, project, issue, services, omit_addrs, users_by_id)
+  der_cc_addr_perm_list = ComputeIssueChangeAddressPermList(
+      cnxn, der_direct_ccs + der_transitive_ccs, project, issue,
+      services, omit_addrs, users_by_id)
+
+  starrer_addr_perm_list = []
+  sub_addr_perm_list = []
+  if not noisy or commenter_in_project:
+    # Avoid an OOM by only notifying a number of starrers that we can handle.
+    # And, we really should limit the number of emails that we send anyway.
+    max_starrers = settings.max_starrers_to_notify
+    starrer_ids = starrer_ids[-max_starrers:]
+    # Note: starrers can never be user groups.
+    starrer_addr_perm_list = (
+        ComputeIssueChangeAddressPermList(
+            cnxn, starrer_ids, project, issue,
+            services, omit_addrs, users_by_id,
+            pref_check_function=starrer_pref_check_function))
+
+    if include_subscribers:
+      sub_addr_perm_list = _GetSubscribersAddrPermList(
+          cnxn, services, issue, project, config, omit_addrs,
+          users_by_id)
+
+  # Get the list of addresses to notify based on filter rules.
+  issue_notify_addr_list = ComputeIssueNotificationAddrList(
+      cnxn, services, issue, omit_addrs)
+  # Get the list of addresses to notify based on project settings.
+  proj_notify_addr_list = []
+  if include_notify_all:
+    proj_notify_addr_list = ComputeProjectNotificationAddrList(
+        cnxn, services, project, contributor_could_view, omit_addrs)
+
+  group_reason_list = [
+      (reporter_addr_perm_list, REASON_REPORTER),
+      (owner_addr_perm_list, REASON_OWNER),
+      (old_owner_addr_perm_list, REASON_OLD_OWNER),
+      (der_owner_addr_perm_list, REASON_DEFAULT_OWNER),
+      (cc_addr_perm_list, REASON_CCD),
+      (transitive_cc_addr_perm_list, REASON_GROUP_CCD),
+      (der_cc_addr_perm_list, REASON_DEFAULT_CCD),
+  ]
+  group_reason_list.extend(ComputeComponentFieldAddrPerms(
+      cnxn, config, issue, project, services, omit_addrs,
+      users_by_id))
+  group_reason_list.extend(ComputeCustomFieldAddrPerms(
+      cnxn, config, issue, project, services, omit_addrs,
+      users_by_id))
+  group_reason_list.extend([
+      (starrer_addr_perm_list, REASON_STARRER),
+      (sub_addr_perm_list, REASON_SUBSCRIBER),
+      (issue_notify_addr_list, REASON_ALSO_NOTIFY),
+      (proj_notify_addr_list, REASON_ALL_NOTIFICATIONS),
+      ])
+  return group_reason_list
