anchor.diff:        // doesn't place any constraint on the suffix.
         if (ruleValue == null) continue;
   
  -      // If a rule in the prefix implies a rule in the suffix, then we need to
  -      // preserve that implication. In particular, if the prefix rule did split
  -      // (i.e. it has a non-zero value), then we can't allow the suffix rule to
  -      // be unsplit.
         if (ruleValue != 0) {
  +        // A rule in the prefix implies a rule in the suffix, so we need to
  +        // preserve that implication. In particular, if the prefix rule split
  +        // (i.e. it has a non-zero value), then we can't allow the suffix rule
  +        // to be unsplit.
           for (var suffixRule in suffixRules) {
             // If we already have a harder constraint, keep it.
             if (updatedValues.containsKey(suffixRule)) continue;
  
positive.code:     assert(value >= 0);
  
      var chunk = _chunks[prefix.length];
      var ruleValues = _advancePrefix(prefix, value);
  
      // If the rule causes this chunk to split, recurse and find the best
      // solution for the suffix following this chunk.
      if (!chunk.rule.isSplit(value, chunk)) {
        // If this chunk bumps us past the page limit and we already have a
        // solution that fits, no solution after this chunk will beat that, so
        // stop looking.
  
negative.code:     // Seed with the direct implications.
      for (var rule in rules) {
        _ruleImplications[rule] = rule.implies.toSet();
        // TODO(bob): Is it worth filtering hard splits out of this?
      }
  
      // TODO(rnystrom): This is a hotspot right now. Can we optimize it? One
      // idea is to renumber the rule IDs to be their index in the rule set/list.
      // That would let us avoid the map and directly index.
      hasPath(int from, int to) =>
          _ruleImplications[rules[from]].contains(rules[to]);
  
      // Calculate the transitive closure.
      for (var i = 0; i < rules.length; i++) {
  