diff --git a/features/filterrules_helpers.py b/features/filterrules_helpers.py
new file mode 100644
index 0000000..22acc7d
--- /dev/null
+++ b/features/filterrules_helpers.py
@@ -0,0 +1,848 @@
+# 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
+
+"""Implementation of the filter rules helper functions."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import logging
+import re
+import six
+
+from six import string_types
+
+import settings
+from features import features_constants
+from framework import cloud_tasks_helpers
+from framework import exceptions
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import urls
+from framework import validate
+from proto import ast_pb2
+from proto import tracker_pb2
+from search import query2ast
+from search import searchpipeline
+from tracker import component_helpers
+from tracker import tracker_bizobj
+from tracker import tracker_constants
+from tracker import tracker_helpers
+
+
+# Maximum number of filer rules that can be specified in a given
+# project.  This helps us bound the amount of time needed to
+# (re)compute derived fields.
+MAX_RULES = 200
+
+BLOCK = tracker_constants.RECOMPUTE_DERIVED_FIELDS_BLOCK_SIZE
+
+
+# TODO(jrobbins): implement a more efficient way to update just those
+# issues affected by a specific component change.
+def RecomputeAllDerivedFields(cnxn, services, project, config):
+  """Create work items to update all issues after filter rule changes.
+
+  Args:
+    cnxn: connection to SQL database.
+    services: connections to backend services.
+    project: Project PB for the project that was edited.
+    config: ProjectIssueConfig PB for the project that was edited,
+        including the edits made.
+  """
+  if not settings.recompute_derived_fields_in_worker:
+    # Background tasks are not enabled, just do everything in the servlet.
+    RecomputeAllDerivedFieldsNow(cnxn, services, project, config)
+    return
+
+  highest_id = services.issue.GetHighestLocalID(cnxn, project.project_id)
+  if highest_id == 0:
+    return  # No work to do.
+
+  # Enqueue work items for blocks of issues to recompute.
+  steps = list(range(1, highest_id + 1, BLOCK))
+  steps.reverse()  # Update higher numbered issues sooner, old issues last.
+  # Cycle through shard_ids just to load-balance among the replicas.  Each
+  # block includes all issues in that local_id range, not just 1/10 of them.
+  shard_id = 0
+  for step in steps:
+    params = {
+        'project_id': project.project_id,
+        'lower_bound': step,
+        'upper_bound': min(step + BLOCK, highest_id + 1),
+        'shard_id': shard_id,
+    }
+    task = cloud_tasks_helpers.generate_simple_task(
+        urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', params)
+    cloud_tasks_helpers.create_task(
+        task, queue=features_constants.QUEUE_RECOMPUTE_DERIVED_FIELDS)
+
+    shard_id = (shard_id + 1) % settings.num_logical_shards
+
+
+def RecomputeAllDerivedFieldsNow(
+    cnxn, services, project, config, lower_bound=None, upper_bound=None):
+  """Re-apply all filter rules to all issues in a project.
+
+  Args:
+    cnxn: connection to SQL database.
+    services: connections to persistence layer.
+    project: Project PB for the project that was changed.
+    config: ProjectIssueConfig for that project.
+    lower_bound: optional int lowest issue ID to consider, inclusive.
+    upper_bound: optional int highest issue ID to consider, exclusive.
+
+  SIDE-EFFECT: updates all issues in the project. Stores and re-indexes
+  all those that were changed.
+  """
+  if lower_bound is not None and upper_bound is not None:
+    issues = services.issue.GetIssuesByLocalIDs(
+        cnxn, project.project_id, list(range(lower_bound, upper_bound)),
+        use_cache=False)
+  else:
+    issues = services.issue.GetAllIssuesInProject(
+        cnxn, project.project_id, use_cache=False)
+
+  rules = services.features.GetFilterRules(cnxn, project.project_id)
+  predicate_asts = ParsePredicateASTs(rules, config, [])
+  modified_issues = []
+  for issue in issues:
+    any_change, _traces = ApplyGivenRules(
+        cnxn, services, issue, config, rules, predicate_asts)
+    if any_change:
+      modified_issues.append(issue)
+
+  services.issue.UpdateIssues(cnxn, modified_issues, just_derived=True)
+
+  # Doing the FTS indexing can be too slow, so queue up the issues
+  # that need to be re-indexed by a cron-job later.
+  services.issue.EnqueueIssuesForIndexing(
+      cnxn, [issue.issue_id for issue in modified_issues])
+
+
+def ParsePredicateASTs(rules, config, me_user_ids):
+  """Parse the given rules in QueryAST PBs."""
+  predicates = [rule.predicate for rule in rules]
+  if me_user_ids:
+    predicates = [
+      searchpipeline.ReplaceKeywordsWithUserIDs(me_user_ids, pred)[0]
+      for pred in predicates]
+  predicate_asts = [
+      query2ast.ParseUserQuery(pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+      for pred in predicates]
+  return predicate_asts
+
+
+def ApplyFilterRules(cnxn, services, issue, config):
+  """Apply the filter rules for this project to the given issue.
+
+  Args:
+    cnxn: database connection, used to look up user IDs.
+    services: persistence layer for users, issues, and projects.
+    issue: An Issue PB that has just been updated with new explicit values.
+    config: The project's issue tracker config PB.
+
+  Returns:
+    A pair (any_changes, traces) where any_changes is true if any changes
+    were made to the issue derived fields, and traces is a dictionary
+    {(field_id, new_value): explanation_str} of traces that
+    explain which rule generated each derived value.
+
+  SIDE-EFFECT: update the derived_* fields of the Issue PB.
+  """
+  rules = services.features.GetFilterRules(cnxn, issue.project_id)
+  predicate_asts = ParsePredicateASTs(rules, config, [])
+  return ApplyGivenRules(cnxn, services, issue, config, rules, predicate_asts)
+
+
+def ApplyGivenRules(cnxn, services, issue, config, rules, predicate_asts):
+  """Apply the filter rules for this project to the given issue.
+
+  Args:
+    cnxn: database connection, used to look up user IDs.
+    services: persistence layer for users, issues, and projects.
+    issue: An Issue PB that has just been updated with new explicit values.
+    config: The project's issue tracker config PB.
+    rules: list of FilterRule PBs.
+
+  Returns:
+    A pair (any_changes, traces) where any_changes is true if any changes
+    were made to the issue derived fields, and traces is a dictionary
+    {(field_id, new_value): explanation_str} of traces that
+    explain which rule generated each derived value.
+
+  SIDE-EFFECT: update the derived_* fields of the Issue PB.
+  """
+  (derived_owner_id, derived_status, derived_cc_ids,
+   derived_labels, derived_notify_addrs, traces,
+   new_warnings, new_errors) = _ComputeDerivedFields(
+       cnxn, services, issue, config, rules, predicate_asts)
+
+  any_change = (derived_owner_id != issue.derived_owner_id or
+                derived_status != issue.derived_status or
+                derived_cc_ids != issue.derived_cc_ids or
+                derived_labels != issue.derived_labels or
+                derived_notify_addrs != issue.derived_notify_addrs)
+
+  # Remember any derived values.
+  issue.derived_owner_id = derived_owner_id
+  issue.derived_status = derived_status
+  issue.derived_cc_ids = derived_cc_ids
+  issue.derived_labels = derived_labels
+  issue.derived_notify_addrs = derived_notify_addrs
+  issue.derived_warnings = new_warnings
+  issue.derived_errors = new_errors
+
+  return any_change, traces
+
+
+def _ComputeDerivedFields(cnxn, services, issue, config, rules, predicate_asts):
+  """Compute derived field values for an issue based on filter rules.
+
+  Args:
+    cnxn: database connection, used to look up user IDs.
+    services: persistence layer for users, issues, and projects.
+    issue: the issue to examine.
+    config: ProjectIssueConfig for the project containing the issue.
+    rules: list of FilterRule PBs.
+    predicate_asts: QueryAST PB for each rule.
+
+  Returns:
+    A 8-tuple of derived values for owner_id, status, cc_ids, labels,
+    notify_addrs, traces, warnings, and errors.  These values are the result
+    of applying all rules in order.  Filter rules only produce derived values
+    that do not conflict with the explicit field values of the issue.
+  """
+  excl_prefixes = [
+      prefix.lower() for prefix in config.exclusive_label_prefixes]
+  # Examine the explicit labels and Cc's on the issue.
+  lower_labels = [lab.lower() for lab in issue.labels]
+  label_set = set(lower_labels)
+  cc_set = set(issue.cc_ids)
+  excl_prefixes_used = set()
+  for lab in lower_labels:
+    prefix = lab.split('-')[0]
+    if prefix in excl_prefixes:
+      excl_prefixes_used.add(prefix)
+  prefix_values_added = {}
+
+  # Start with the assumption that rules don't change anything, then
+  # accumulate changes.
+  derived_owner_id = framework_constants.NO_USER_SPECIFIED
+  derived_status = ''
+  derived_cc_ids = []
+  derived_labels = []
+  derived_notify_addrs = []
+  traces = {}  # {(field_id, new_value): explanation_str}
+  new_warnings = []
+  new_errors = []
+
+  def AddLabelConsideringExclusivePrefixes(label):
+    lab_lower = label.lower()
+    if lab_lower in label_set:
+      return False  # We already have that label.
+    prefix = lab_lower.split('-')[0]
+    if '-' in lab_lower and prefix in excl_prefixes:
+      if prefix in excl_prefixes_used:
+        return False  # Issue already has that prefix.
+      # Replace any earlied-added label that had the same exclusive prefix.
+      if prefix in prefix_values_added:
+        label_set.remove(prefix_values_added[prefix].lower())
+        derived_labels.remove(prefix_values_added[prefix])
+      prefix_values_added[prefix] = label
+
+    derived_labels.append(label)
+    label_set.add(lab_lower)
+    return True
+
+  # Apply component labels and auto-cc's before doing the rules.
+  components = tracker_bizobj.GetIssueComponentsAndAncestors(issue, config)
+  for cd in components:
+    for cc_id in cd.cc_ids:
+      if cc_id not in cc_set:
+        derived_cc_ids.append(cc_id)
+        cc_set.add(cc_id)
+        traces[(tracker_pb2.FieldID.CC, cc_id)] = (
+            'Added by component %s' % cd.path)
+
+    for label_id in cd.label_ids:
+      lab = services.config.LookupLabel(cnxn, config.project_id, label_id)
+      if AddLabelConsideringExclusivePrefixes(lab):
+        traces[(tracker_pb2.FieldID.LABELS, lab)] = (
+            'Added by component %s' % cd.path)
+
+  # Apply each rule in order. Later rules see the results of earlier rules.
+  # Later rules can overwrite or add to results of earlier rules.
+  # TODO(jrobbins): also pass in in-progress values for owner and CCs so
+  # that early rules that set those can affect later rules that check them.
+  for rule, predicate_ast in zip(rules, predicate_asts):
+    (rule_owner_id, rule_status, rule_add_cc_ids,
+     rule_add_labels, rule_add_notify, rule_add_warning,
+     rule_add_error) = _ApplyRule(
+         cnxn, services, rule, predicate_ast, issue, label_set, config)
+
+    # logging.info(
+    #    'rule "%s" gave %r, %r, %r, %r, %r',
+    #     rule.predicate, rule_owner_id, rule_status, rule_add_cc_ids,
+    #     rule_add_labels, rule_add_notify)
+
+    if rule_owner_id and not issue.owner_id:
+      derived_owner_id = rule_owner_id
+      traces[(tracker_pb2.FieldID.OWNER, rule_owner_id)] = (
+        'Added by rule: IF %s THEN SET DEFAULT OWNER' % rule.predicate)
+
+    if rule_status and not issue.status:
+      derived_status = rule_status
+      traces[(tracker_pb2.FieldID.STATUS, rule_status)] = (
+        'Added by rule: IF %s THEN SET DEFAULT STATUS' % rule.predicate)
+
+    for cc_id in rule_add_cc_ids:
+      if cc_id not in cc_set:
+        derived_cc_ids.append(cc_id)
+        cc_set.add(cc_id)
+        traces[(tracker_pb2.FieldID.CC, cc_id)] = (
+          'Added by rule: IF %s THEN ADD CC' % rule.predicate)
+
+    for lab in rule_add_labels:
+      if AddLabelConsideringExclusivePrefixes(lab):
+        traces[(tracker_pb2.FieldID.LABELS, lab)] = (
+            'Added by rule: IF %s THEN ADD LABEL' % rule.predicate)
+
+    for addr in rule_add_notify:
+      if addr not in derived_notify_addrs:
+        derived_notify_addrs.append(addr)
+        # Note: No trace because also-notify addresses are not shown in the UI.
+
+    if rule_add_warning:
+      new_warnings.append(rule_add_warning)
+      traces[(tracker_pb2.FieldID.WARNING, rule_add_warning)] = (
+        'Added by rule: IF %s THEN ADD WARNING' % rule.predicate)
+
+    if rule_add_error:
+      new_errors.append(rule_add_error)
+      traces[(tracker_pb2.FieldID.ERROR, rule_add_error)] = (
+        'Added by rule: IF %s THEN ADD ERROR' % rule.predicate)
+
+  return (derived_owner_id, derived_status, derived_cc_ids, derived_labels,
+          derived_notify_addrs, traces, new_warnings, new_errors)
+
+
+def EvalPredicate(
+    cnxn, services, predicate_ast, issue, label_set, config, owner_id, cc_ids,
+    status):
+  """Return True if the given issue satisfies the given predicate.
+
+  Args:
+    cnxn: Connection to SQL database.
+    services: persistence layer for users and issues.
+    predicate_ast: QueryAST for rule or saved query string.
+    issue: Issue PB of the issue to evaluate.
+    label_set: set of lower-cased labels on the issue.
+    config: ProjectIssueConfig for the project that contains the issue.
+    owner_id: int user ID of the issue owner.
+    cc_ids: list of int user IDs of the users Cc'd on the issue.
+    status: string status value of the issue.
+
+  Returns:
+    True if the issue satisfies the predicate.
+
+  Note: filter rule evaluation passes in only the explicit owner_id,
+  cc_ids, and status whereas subscription evaluation passes in the
+  combination of explicit values and derived values.
+  """
+  # TODO(jrobbins): Call ast2ast to simplify the predicate and do
+  # most lookups.  Refactor to allow that to be done once.
+  project = services.project.GetProject(cnxn, config.project_id)
+  for conj in predicate_ast.conjunctions:
+    if all(_ApplyCond(cnxn, services, project, cond, issue, label_set, config,
+                      owner_id, cc_ids, status)
+            for cond in conj.conds):
+      return True
+
+  # All OR-clauses were evaluated, but none of them was matched.
+  return False
+
+
+def _ApplyRule(
+    cnxn, services, rule_pb, predicate_ast, issue, label_set, config):
+  """Test if the given rule should fire and return its result.
+
+  Args:
+    cnxn: database connection, used to look up user IDs.
+    services: persistence layer for users and issues.
+    rule_pb: FilterRule PB instance with a predicate and various actions.
+    predicate_ast: QueryAST for the rule predicate.
+    issue: The Issue PB to be considered.
+    label_set: set of lowercased labels from an issue's explicit
+      label_list plus and labels that have accumlated from previous rules.
+    config: ProjectIssueConfig for the project containing the issue.
+
+  Returns:
+    A 6-tuple of the results from this rule: derived owner id, status,
+    cc_ids to add, labels to add, notify addresses to add, and a warning
+    string.  Currently only one will be set and the others will all be
+    None or an empty list.
+  """
+  if EvalPredicate(
+      cnxn, services, predicate_ast, issue, label_set, config,
+      issue.owner_id, issue.cc_ids, issue.status):
+    logging.info('rule adds: %r', rule_pb.add_labels)
+    return (rule_pb.default_owner_id, rule_pb.default_status,
+            rule_pb.add_cc_ids, rule_pb.add_labels,
+            rule_pb.add_notify_addrs, rule_pb.warning, rule_pb.error)
+  else:
+    return None, None, [], [], [], None, None
+
+
+def _ApplyCond(
+    cnxn, services, project, term, issue, label_set, config, owner_id, cc_ids,
+    status):
+  """Return True if the given issue satisfied the given predicate term."""
+  op = term.op
+  vals = term.str_values or term.int_values
+  # Since rules are per-project, there'll be exactly 1 field
+  fd = term.field_defs[0]
+  field = fd.field_name
+
+  if field == 'label':
+    return _Compare(op, vals, label_set)
+  if field == 'component':
+    return _CompareComponents(config, op, vals, issue.component_ids)
+  if field == 'any_field':
+    return _Compare(op, vals, label_set) or _Compare(op, vals, [issue.summary])
+  if field == 'attachments':
+    return _Compare(op, term.int_values, [issue.attachment_count])
+  if field == 'blocked':
+    return _Compare(op, vals, issue.blocked_on_iids)
+  if field == 'blockedon':
+    return _CompareIssueRefs(
+        cnxn, services, project, op, term.str_values, issue.blocked_on_iids)
+  if field == 'blocking':
+    return _CompareIssueRefs(
+        cnxn, services, project, op, term.str_values, issue.blocking_iids)
+  if field == 'cc':
+    return _CompareUsers(cnxn, services.user, op, vals, cc_ids)
+  if field == 'closed':
+    return (issue.closed_timestamp and
+            _Compare(op, vals, [issue.closed_timestamp]))
+  if field == 'id':
+    return _Compare(op, vals, [issue.local_id])
+  if field == 'mergedinto':
+    return _CompareIssueRefs(
+        cnxn, services, project, op, term.str_values, [issue.merged_into or 0])
+  if field == 'modified':
+    return (issue.modified_timestamp and
+            _Compare(op, vals, [issue.modified_timestamp]))
+  if field == 'open':
+    # TODO(jrobbins): this just checks the explicit status, not the result
+    # of any previous rules.
+    return tracker_helpers.MeansOpenInProject(status, config)
+  if field == 'opened':
+    return (issue.opened_timestamp and
+            _Compare(op, vals, [issue.opened_timestamp]))
+  if field == 'owner':
+    return _CompareUsers(cnxn, services.user, op, vals, [owner_id])
+  if field == 'reporter':
+    return _CompareUsers(cnxn, services.user, op, vals, [issue.reporter_id])
+  if field == 'stars':
+    return _Compare(op, term.int_values, [issue.star_count])
+  if field == 'status':
+    return _Compare(op, vals, [status.lower()])
+  if field == 'summary':
+    return _Compare(op, vals, [issue.summary])
+
+  # Since rules are per-project, it makes no sense to support field project.
+  # We would need to load comments to support fields comment, commentby,
+  # description, attachment.
+  # Supporting starredby is probably not worth the complexity.
+
+  logging.info('Rule with unsupported field %r was False', field)
+  return False
+
+
+def _CheckTrivialCases(op, issue_values):
+  """Check has:x and -has:x terms and no values.  Otherwise, return None."""
+  # We can do these operators without looking up anything or even knowing
+  # which field is being checked.
+  issue_values_exist = bool(
+      issue_values and issue_values != [''] and issue_values != [0])
+  if op == ast_pb2.QueryOp.IS_DEFINED:
+    return issue_values_exist
+  elif op == ast_pb2.QueryOp.IS_NOT_DEFINED:
+    return not issue_values_exist
+  elif not issue_values_exist:
+    # No other operator can match empty values.
+    return op in (ast_pb2.QueryOp.NE, ast_pb2.QueryOp.NOT_TEXT_HAS)
+
+  return None  # Caller should continue processing the term.
+
+def _CompareComponents(config, op, rule_values, issue_values):
+  """Compare the components specified in the rule vs those in the issue."""
+  trivial_result = _CheckTrivialCases(op, issue_values)
+  if trivial_result is not None:
+    return trivial_result
+
+  exact = op in (ast_pb2.QueryOp.EQ, ast_pb2.QueryOp.NE)
+  rule_component_ids = set()
+  for path in rule_values:
+    rule_component_ids.update(tracker_bizobj.FindMatchingComponentIDs(
+        path, config, exact=exact))
+
+  if op == ast_pb2.QueryOp.TEXT_HAS or op == ast_pb2.QueryOp.EQ:
+    return any(rv in issue_values for rv in rule_component_ids)
+  elif op == ast_pb2.QueryOp.NOT_TEXT_HAS or op == ast_pb2.QueryOp.NE:
+    return all(rv not in issue_values for rv in rule_component_ids)
+
+  return False
+
+
+def _CompareIssueRefs(
+  cnxn, services, project, op, rule_str_values, issue_values):
+  """Compare the issues specified in the rule vs referenced in the issue."""
+  trivial_result = _CheckTrivialCases(op, issue_values)
+  if trivial_result is not None:
+    return trivial_result
+
+  rule_refs = []
+  for str_val in rule_str_values:
+    ref = tracker_bizobj.ParseIssueRef(str_val)
+    if ref:
+      rule_refs.append(ref)
+  rule_ref_project_names = set(
+      pn for pn, local_id in rule_refs if pn)
+  rule_ref_projects_dict = services.project.GetProjectsByName(
+      cnxn, rule_ref_project_names)
+  rule_ref_projects_dict[project.project_name] = project
+  rule_iids, _misses = services.issue.ResolveIssueRefs(
+      cnxn, rule_ref_projects_dict, project.project_name, rule_refs)
+
+  if op == ast_pb2.QueryOp.TEXT_HAS:
+    op = ast_pb2.QueryOp.EQ
+  if op == ast_pb2.QueryOp.NOT_TEXT_HAS:
+    op = ast_pb2.QueryOp.NE
+
+  return _Compare(op, rule_iids, issue_values)
+
+
+def _CompareUsers(cnxn, user_service, op, rule_values, issue_values):
+  """Compare the user(s) specified in the rule and the issue."""
+  # Note that all occurances of "me" in rule_values should have already
+  # been resolved to str(user_id) of the subscribing user.
+  # TODO(jrobbins): Project filter rules should not be allowed to have "me".
+
+  trivial_result = _CheckTrivialCases(op, issue_values)
+  if trivial_result is not None:
+    return trivial_result
+
+  try:
+    return _CompareUserIDs(op, rule_values, issue_values)
+  except ValueError:
+    return _CompareEmails(cnxn, user_service, op, rule_values, issue_values)
+
+
+def _CompareUserIDs(op, rule_values, issue_values):
+  """Compare users according to specified user ID integer strings."""
+  rule_user_ids = [int(uid_str) for uid_str in rule_values]
+
+  if op == ast_pb2.QueryOp.TEXT_HAS or op == ast_pb2.QueryOp.EQ:
+    return any(rv in issue_values for rv in rule_user_ids)
+  elif op == ast_pb2.QueryOp.NOT_TEXT_HAS or op == ast_pb2.QueryOp.NE:
+    return all(rv not in issue_values for rv in rule_user_ids)
+
+  logging.info('unexpected numeric user operator %r %r %r',
+               op, rule_values, issue_values)
+  return False
+
+
+def _CompareEmails(cnxn, user_service, op, rule_values, issue_values):
+  """Compare users based on email addresses."""
+  issue_emails = list(
+      user_service.LookupUserEmails(cnxn, issue_values).values())
+
+  if op == ast_pb2.QueryOp.TEXT_HAS:
+    return any(_HasText(rv, issue_emails) for rv in rule_values)
+  elif op == ast_pb2.QueryOp.NOT_TEXT_HAS:
+    return all(not _HasText(rv, issue_emails) for rv in rule_values)
+  elif op == ast_pb2.QueryOp.EQ:
+    return any(rv in issue_emails for rv in rule_values)
+  elif op == ast_pb2.QueryOp.NE:
+    return all(rv not in issue_emails for rv in rule_values)
+
+  logging.info('unexpected user operator %r %r %r',
+               op, rule_values, issue_values)
+  return False
+
+
+def _Compare(op, rule_values, issue_values):
+  """Compare the values specified in the rule and the issue."""
+  trivial_result = _CheckTrivialCases(op, issue_values)
+  if trivial_result is not None:
+    return trivial_result
+
+  if (op in [ast_pb2.QueryOp.TEXT_HAS, ast_pb2.QueryOp.NOT_TEXT_HAS] and
+      issue_values and not isinstance(min(issue_values), string_types)):
+    return False  # Empty or numeric fields cannot match substrings
+  elif op == ast_pb2.QueryOp.TEXT_HAS:
+    return any(_HasText(rv, issue_values) for rv in rule_values)
+  elif op == ast_pb2.QueryOp.NOT_TEXT_HAS:
+    return all(not _HasText(rv, issue_values) for rv in rule_values)
+
+  val_type = type(min(issue_values))
+  if val_type in six.integer_types:
+    try:
+      rule_values = [int(rv) for rv in rule_values]
+    except ValueError:
+      logging.info('rule value conversion to int failed: %r', rule_values)
+      return False
+
+  if op == ast_pb2.QueryOp.EQ:
+    return any(rv in issue_values for rv in rule_values)
+  elif op == ast_pb2.QueryOp.NE:
+    return all(rv not in issue_values for rv in rule_values)
+
+  if val_type not in six.integer_types:
+    return False  # Inequalities only work on numeric fields
+
+  if op == ast_pb2.QueryOp.GT:
+    return min(issue_values) > min(rule_values)
+  elif op == ast_pb2.QueryOp.GE:
+    return min(issue_values) >= min(rule_values)
+  elif op == ast_pb2.QueryOp.LT:
+    return max(issue_values) < max(rule_values)
+  elif op == ast_pb2.QueryOp.LE:
+    return max(issue_values) <= max(rule_values)
+
+  logging.info('unexpected operator %r %r %r', op, rule_values, issue_values)
+  return False
+
+
+def _HasText(rule_text, issue_values):
+  """Return True if the issue contains the rule text, case insensitive."""
+  rule_lower = rule_text.lower()
+  for iv in issue_values:
+    if iv is not None and rule_lower in iv.lower():
+      return True
+
+  return False
+
+
+def MakeRule(
+    predicate, default_status=None, default_owner_id=None, add_cc_ids=None,
+    add_labels=None, add_notify=None, warning=None, error=None):
+  """Make a FilterRule PB with the supplied information.
+
+  Args:
+    predicate: string query that will trigger the rule if satisfied.
+    default_status: optional default status to set if rule fires.
+    default_owner_id: optional default owner_id to set if rule fires.
+    add_cc_ids: optional cc ids to set if rule fires.
+    add_labels: optional label strings to set if rule fires.
+    add_notify: optional notify email addresses to set if rule fires.
+    warning: optional string for a software development process warning.
+    error: optional string for a software development process error.
+
+  Returns:
+    A new FilterRule PB.
+  """
+  rule_pb = tracker_pb2.FilterRule()
+  rule_pb.predicate = predicate
+
+  if add_labels:
+    rule_pb.add_labels = add_labels
+  if default_status:
+    rule_pb.default_status = default_status
+  if default_owner_id:
+    rule_pb.default_owner_id = default_owner_id
+  if add_cc_ids:
+    rule_pb.add_cc_ids = add_cc_ids
+  if add_notify:
+    rule_pb.add_notify_addrs = add_notify
+  if warning:
+    rule_pb.warning = warning
+  if error:
+    rule_pb.error = error
+
+  return rule_pb
+
+
+def ParseRules(cnxn, post_data, user_service, errors, prefix=''):
+  """Parse rules from the user and return a list of FilterRule PBs.
+
+  Args:
+    cnxn: connection to database.
+    post_data: dictionary of html form data.
+    user_service: connection to user backend services.
+    errors: EZTErrors message used to display field validation errors.
+    prefix: optional string prefix used to differentiate the form fields
+      for existing rules from the form fields for new rules.
+
+  Returns:
+    A list of FilterRule PBs
+  """
+  rules = []
+
+  # The best we can do for now is show all validation errors at the bottom of
+  # the filter rules section, not directly on the rule that had the error :(.
+  error_list = []
+
+  for i in range(1, MAX_RULES + 1):
+    if ('%spredicate%s' % (prefix, i)) not in post_data:
+      continue  # skip any entries that are blank or have no predicate.
+    predicate = post_data['%spredicate%s' % (prefix, i)].strip()
+    action_type = post_data.get('%saction_type%s' % (prefix, i),
+                                'add_labels').strip()
+    action_value = post_data.get('%saction_value%s' % (prefix, i),
+                                 '').strip()
+    if predicate:
+      # Note: action_value may be '', meaning no-op.
+      rules.append(_ParseOneRule(
+          cnxn, predicate, action_type, action_value, user_service, i,
+          error_list))
+
+  if error_list:
+    errors.rules = error_list
+
+  return rules
+
+
+def _ParseOneRule(
+    cnxn, predicate, action_type, action_value, user_service,
+    rule_num, error_list):
+  """Parse one FilterRule based on the action type."""
+
+  if action_type == 'default_status':
+    status = framework_bizobj.CanonicalizeLabel(action_value)
+    rule = MakeRule(predicate, default_status=status)
+
+  elif action_type == 'default_owner':
+    if action_value:
+      try:
+        user_id = user_service.LookupUserID(cnxn, action_value)
+      except exceptions.NoSuchUserException:
+        user_id = framework_constants.NO_USER_SPECIFIED
+        error_list.append(
+            'Rule %d: No such user: %s' % (rule_num, action_value))
+    else:
+      user_id = framework_constants.NO_USER_SPECIFIED
+    rule = MakeRule(predicate, default_owner_id=user_id)
+
+  elif action_type == 'add_ccs':
+    cc_ids = []
+    for email in re.split('[,;\s]+', action_value):
+      if not email.strip():
+        continue
+      try:
+        user_id = user_service.LookupUserID(
+            cnxn, email.strip(), autocreate=True)
+        cc_ids.append(user_id)
+      except exceptions.NoSuchUserException:
+        error_list.append(
+            'Rule %d: No such user: %s' % (rule_num, email.strip()))
+
+    rule = MakeRule(predicate, add_cc_ids=cc_ids)
+
+  elif action_type == 'add_labels':
+    add_labels = framework_constants.IDENTIFIER_RE.findall(action_value)
+    rule = MakeRule(predicate, add_labels=add_labels)
+
+  elif action_type == 'also_notify':
+    add_notify = []
+    for addr in re.split('[,;\s]+', action_value):
+      if validate.IsValidEmail(addr.strip()):
+        add_notify.append(addr.strip())
+      else:
+        error_list.append(
+            'Rule %d: Invalid email address: %s' % (rule_num, addr.strip()))
+
+    rule = MakeRule(predicate, add_notify=add_notify)
+
+  elif action_type == 'warning':
+    rule = MakeRule(predicate, warning=action_value)
+
+  elif action_type == 'error':
+    rule = MakeRule(predicate, error=action_value)
+
+  else:
+    logging.info('unexpected action type, probably tampering:%r', action_type)
+    raise exceptions.InputException()
+
+  return rule
+
+
+def OwnerCcsInvolvedInFilterRules(rules):
+  """Finds all user_ids in the given rules and returns them.
+
+  Args:
+    rules: a list of FilterRule PBs.
+
+  Returns:
+    A set of user_ids.
+  """
+  user_ids = set()
+  for rule in rules:
+    if rule.default_owner_id:
+      user_ids.add(rule.default_owner_id)
+    user_ids.update(rule.add_cc_ids)
+  return user_ids
+
+
+def BuildFilterRuleStrings(filter_rules, emails_by_id):
+  """Builds strings that represent filter rules.
+
+  Args:
+    filter_rules: a list of FilterRule PBs.
+    emails_by_id: a dict of {user_id: email, ..} of user_ids in the FilterRules.
+
+  Returns:
+    A list of strings each representing a FilterRule.
+    eg. "if predicate then consequence"
+  """
+  rule_strs = []
+  for rule in filter_rules:
+    cons = ""
+    if rule.add_labels:
+      cons = 'add label(s): %s' % ', '.join(rule.add_labels)
+    elif rule.default_status:
+      cons = 'set default status: %s' % rule.default_status
+    elif rule.default_owner_id:
+      cons = 'set default owner: %s' % emails_by_id.get(
+          rule.default_owner_id, 'user not found')
+    elif rule.add_cc_ids:
+      cons = 'add cc(s): %s' % ', '.join(
+        [emails_by_id.get(user_id, 'user not found')
+         for user_id in rule.add_cc_ids])
+    elif rule.add_notify_addrs:
+      cons = 'notify: %s' % ', '.join(rule.add_notify_addrs)
+
+    rule_strs.append('if %s then %s' % (rule.predicate, cons))
+
+  return rule_strs
+
+
+def BuildRedactedFilterRuleStrings(
+    cnxn, rules_by_project, user_service, hide_emails):
+  """Converts FilterRule PBs in strings that hide references to hide_emails.
+
+  Args:
+    rules_by_project: a dict of {project_id, [filter_rule, ...], ...}
+      with FilterRule PBs.
+    user_service:
+    hide_emails: a list of emails that should not be shown in rule strings.
+  """
+  rule_strs_by_project = {}
+  prohibited_re = re.compile(
+      r'\b%s\b' % r'\b|\b'.join(map(re.escape, hide_emails)))
+  for project_id, rules in rules_by_project.items():
+    user_ids_in_rules = OwnerCcsInvolvedInFilterRules(rules)
+    emails_by_id = user_service.LookupUserEmails(
+        cnxn, user_ids_in_rules, ignore_missed=True)
+    rule_strs = BuildFilterRuleStrings(rules, emails_by_id)
+    censored_strs = [
+        prohibited_re.sub(framework_constants.DELETED_USER_NAME, rule_str)
+        for rule_str in rule_strs]
+
+    rule_strs_by_project[project_id] = censored_strs
+
+  return rule_strs_by_project
