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:   MeanReciprocalRankComputer nonTypeMemberMrrComputer =
        MeanReciprocalRankComputer('non-type member completions');
  
    /// A list of the top [maxWorstResults] completion results with the highest
    /// (worst) ranks.
    List<CompletionResult> worstResults = [];
  
negative.code:       } else {
          metrics.nonTypeMemberMrrComputer.addRank(place.rank);
        }
  
        var charsBeforeTop =
            _computeCharsBeforeTop(expectedCompletion, suggestions);
        metrics.charsBeforeTop.addValue(charsBeforeTop);
        metrics.charsBeforeTopFive.addValue(
            _computeCharsBeforeTop(expectedCompletion, suggestions, minRank: 5));
        metrics.insertionLengthTheoretical
            .addValue(expectedCompletion.completion.length - charsBeforeTop);
      } else {
        metrics.completionCounter.count('unsuccessful');
  
  