@Override
  protected void replaceText(CharSequence text) {
    clearComposingText();
    SpannableStringBuilder ssb = buildSpannableForText(text);
    TokenImageSpan tokenSpan = buildSpanForObject(selectedObject);

    Editable editable = getText();
    int end = getSelectionEnd();
    int start = tokenizer.findTokenStart(editable, end);
    if (start < prefix.length()) {
      start = prefix.length();
    }
    String original = TextUtils.substring(editable, start, end);

    if (editable != null) {
      if (tokenSpan == null) {
        editable.replace(start, end, " ");
      } else if (!allowDuplicates && objects.contains(tokenSpan.getToken())) {
        editable.replace(start, end, " ");
      } else {
        QwertyKeyListener.markAsReplaced(editable, start, end, original);
        editable.replace(start, end, ssb);
        editable.setSpan(
            tokenSpan, start, start + ssb.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
    }
  }
  protected String currentCompletionText() {
    if (hintVisible) return ""; // Can't have any text if the hint is visible

    Editable editable = getText();
    int end = getSelectionEnd();
    int start = tokenizer.findTokenStart(editable, end);
    if (start < prefix.length()) {
      start = prefix.length();
    }
    return TextUtils.substring(editable, start, end);
  }
  public String getComposingText() {
    final Editable content = getEditable();
    if (content == null) {
      return null;
    }
    int a = getComposingSpanStart(content);
    int b = getComposingSpanEnd(content);

    if (a < 0 || b < 0) return null;

    if (b < a) {
      int tmp = a;
      a = b;
      b = tmp;
    }

    return TextUtils.substring(content, a, b);
  }