Program: 87828
Project: 87828
Buggy source:
/** 
 * Returns the text surrounding the cursor.
 * @param sep a string of characters that split words.
 * @param additionalPrecedingWordsCount the number of words before the current word that shouldbe included in the returned range
 * @return a range containing the text surrounding the cursor
 */
public Range getWordRangeAtCursor(final String sep,final int additionalPrecedingWordsCount){
  mIC=mParent.getCurrentInputConnection();
  if (mIC == null || sep == null) {
    return null;
  }
  final CharSequence before=mIC.getTextBeforeCursor(1000,0);
  final CharSequence after=mIC.getTextAfterCursor(1000,0);
  if (before == null || after == null) {
    return null;
  }
  int count=additionalPrecedingWordsCount;
  int start=before.length();
  boolean isStoppingAtWhitespace=true;
  while (true) {
    while (start > 0) {
      final int codePoint=Character.codePointBefore(before,start);
      if (isStoppingAtWhitespace == isSeparator(codePoint,sep)) {
        break;
      }
      --start;
      if (Character.isSupplementaryCodePoint(codePoint)) {
        --start;
      }
    }
    if (isStoppingAtWhitespace && (--count < 0)) {
      break;
    }
    isStoppingAtWhitespace=!isStoppingAtWhitespace;
  }
  int end=-1;
  while (++end < after.length()) {
    final int codePoint=Character.codePointAt(after,end);
    if (isSeparator(codePoint,sep)) {
      break;
    }
    if (Character.isSupplementaryCodePoint(codePoint)) {
      ++end;
    }
  }
  final int cursor=getCursorPosition();
  if (start >= 0 && cursor + end <= after.length() + before.length()) {
    String word=before.toString().substring(start,before.length()) + after.toString().substring(0,end);
    return new Range(before.length() - start,end,word);
  }
  return null;
}

Fixed version (ground truth):
/** 
 * Returns the text surrounding the cursor.
 * @param sep a string of characters that split words.
 * @param additionalPrecedingWordsCount the number of words before the current word that shouldbe included in the returned range
 * @return a range containing the text surrounding the cursor
 */
public Range getWordRangeAtCursor(final String sep,final int additionalPrecedingWordsCount){
  mIC=mParent.getCurrentInputConnection();
  if (mIC == null || sep == null) {
    return null;
  }
  final CharSequence before=mIC.getTextBeforeCursor(1000,0);
  final CharSequence after=mIC.getTextAfterCursor(1000,0);
  if (before == null || after == null) {
    return null;
  }
  int count=additionalPrecedingWordsCount;
  int start=before.length();
  boolean isStoppingAtWhitespace=true;
  while (true) {
    while (start > 0) {
      final int codePoint=Character.codePointBefore(before,start);
      if (isStoppingAtWhitespace == isSeparator(codePoint,sep)) {
        break;
      }
      --start;
      if (Character.isSupplementaryCodePoint(codePoint)) {
        --start;
      }
    }
    if (isStoppingAtWhitespace && (--count < 0)) {
      break;
    }
    isStoppingAtWhitespace=!isStoppingAtWhitespace;
  }
  int end=-1;
  while (++end < after.length()) {
    final int codePoint=Character.codePointAt(after,end);
    if (isSeparator(codePoint,sep)) {
      break;
    }
    if (Character.isSupplementaryCodePoint(codePoint)) {
      ++end;
    }
  }
  final String word=before.toString().substring(start,before.length()) + after.toString().substring(0,end);
  return new Range(before.length() - start,end,word);
}