private void processImage(boolean opening, Editable output) {
    Object[] spans = output.getSpans(0, output.length(), ImageSpan.class);
    if (spans.length == 0) {
      return;
    }

    ImageSpan imageSpan = (ImageSpan) spans[0];
    String imageUrl = imageSpan.getSource();

    // Handle image video thumbnail clicked
    if (imageUrl.startsWith(BBCodeParser.VIDEO_URL_PREFIX)) {
      VideoClickableSpan clickableSpan = mVideoClickableSpanProvider.get();
      clickableSpan.setVideoUrl(imageUrl.substring(BBCodeParser.VIDEO_URL_PREFIX.length()));
      output.setSpan(
          clickableSpan,
          output.getSpanStart(imageSpan),
          output.length(),
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
      return;
    }

    // Not Image Video Thumbnail, This is normal image
    if (TextUtils.isEmpty(imageUrl) || !RichTextUtils.isUrl(imageUrl)) {
      return;
    }

    ImageClickableSpan clickableSpan = mImageClickableSpanProvider.get();
    clickableSpan.setImageUrl(imageUrl);
    output.setSpan(
        clickableSpan,
        output.getSpanStart(imageSpan),
        output.length(),
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  }
  private void process(boolean opening, Editable output, CharacterStyle... spanStyles) {
    int len = output.length();
    if (opening) {
      for (CharacterStyle style : spanStyles) {
        output.setSpan(style, len, len, Spannable.SPAN_MARK_MARK);
      }
    } else {
      for (CharacterStyle style : spanStyles) {
        Object obj = getLast(output, style.getClass());
        int where = output.getSpanStart(obj);

        output.removeSpan(obj);

        if (where != len) {
          if (style instanceof VideoClickableSpan) {
            // Need to set the video url to this span.
            String url = output.subSequence(where, len).toString();
            ((VideoClickableSpan) style).setVideoUrl(url);
          }
          output.setSpan(style, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
  }