anchor.diff:        print('Preceeding: $preceeding');
         print('Suggestion: ${suggestions[rank - 1]}');
       }
  +  }
  +
  +  int _computeCharsBeforeTop(
  +      ExpectedCompletion target, List<CompletionSuggestion> suggestions,
  +      {int minRank = 1}) {
  +    var rank = placementInSuggestionList(suggestions, target).rank;
  +    if (rank <= minRank) {
  +      return 0;
  +    }
  +    var expected = target.completion;
  +    for (var i = 1; i < expected.length + 1; i++) {
  +      var prefix = expected.substring(0, i);
  +      var filteredSuggestions = _filterSuggestions(prefix, suggestions);
  +      rank = placementInSuggestionList(filteredSuggestions, target).rank;
  +      if (rank <= minRank) {
  +        return i;
  +      }
  +    }
  +    return expected.length;
     }
   
     Future<List<CompletionSuggestion>> _computeCompletionSuggestions(
  
positive.code:       } else {
          metrics.nonTypeMemberMrrComputer.addRank(place.rank);
        }
      } else {
        metrics.completionCounter.count('unsuccessful');
  
  
negative.code:     }
    }
  
    List<CompletionSuggestion> _filterSuggestions(
        String prefix, List<CompletionSuggestion> suggestions) {
      // TODO(brianwilkerson) Replace this with a more realistic filtering algorithm.
      return suggestions
          .where((suggestion) => suggestion.completion.startsWith(prefix))
          .toList();
    }
  
    /// Given some [ResolvedUnitResult] return the first error of high severity
    /// if such an error exists, `null` otherwise.
    static err.AnalysisError getFirstErrorOrNull(
  