@Override
 void executeOnUiThread(MessageContextMenu menu, MessageEditorData editorData) {
   Uri uri =
       MatchedUri.getTimelineItemUri(
           editorData.ma.getUserId(),
           menu.messageList.getTimelineType(),
           menu.messageList.isTimelineCombined(),
           menu.messageList.getSelectedUserId(),
           menu.getMsgId());
   String action = menu.messageList.getActivity().getIntent().getAction();
   if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
     if (MyLog.isLoggable(this, MyLog.DEBUG)) {
       MyLog.d(this, "onItemClick, setData=" + uri);
     }
     menu.messageList.getActivity().setResult(Activity.RESULT_OK, new Intent().setData(uri));
   } else {
     if (MyLog.isLoggable(this, MyLog.DEBUG)) {
       MyLog.d(this, "onItemClick, startActivity=" + uri);
     }
     menu.messageList.getActivity().startActivity(MyAction.VIEW_CONVERSATION.getIntent(uri));
   }
 }
 @Override
 void executeOnUiThread(MessageContextMenu menu, MessageEditorData editorData) {
   Uri uri =
       MatchedUri.getUserListUri(
           editorData.ma.getUserId(),
           UserListType.USERS_OF_MESSAGE,
           menu.messageList.isTimelineCombined(),
           menu.getMsgId());
   if (MyLog.isLoggable(this, MyLog.DEBUG)) {
     MyLog.d(this, "onItemClick, startActivity=" + uri);
   }
   menu.messageList.getActivity().startActivity(MyAction.VIEW_USERS.getIntent(uri));
 }
  /** Formats message as a View suitable for a conversation list */
  private View oneMessageToView(ConversationOneMessage oMsg) {
    final String method = "oneMessageToView";
    if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
      MyLog.v(
          this,
          method
              + ": msgId="
              + oMsg.msgId
              + (oMsg.avatarDrawable != null
                  ? ", avatar=" + oMsg.avatarDrawable.getFileName()
                  : ""));
    }
    LayoutInflater inflater = LayoutInflater.from(context);
    int layoutResource = R.layout.message_conversation;
    if (!Activity.class.isAssignableFrom(context.getClass())) {
      MyLog.w(this, "Context should be from an Activity");
    }
    View messageView = inflater.inflate(layoutResource, null);
    messageView.setOnCreateContextMenuListener(contextMenu);

    float displayDensity = context.getResources().getDisplayMetrics().density;
    // See
    // http://stackoverflow.com/questions/2238883/what-is-the-correct-way-to-specify-dimensions-in-dip-from-java-code
    int indent0 = (int) (10 * displayDensity);
    int indentPixels = indent0 * oMsg.indentLevel;

    LinearLayout messageIndented = (LinearLayout) messageView.findViewById(R.id.message_indented);
    if (oMsg.msgId == selectedMessageId && oMsgs.size() > 1) {
      messageIndented.setBackgroundDrawable(
          context.getResources().getDrawable(R.drawable.message_current_background));
    }

    int viewToTheLeftId = 0;
    if (oMsg.indentLevel > 0) {
      View divider = messageView.findViewById(R.id.divider);
      RelativeLayout.LayoutParams layoutParams =
          new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
      layoutParams.leftMargin = indentPixels - 4;
      divider.setLayoutParams(layoutParams);

      if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
        MyLog.v(this, "density=" + displayDensity);
      }
      viewToTheLeftId = 2;
      ImageView indentView =
          new ConversationIndentImageView(context, messageIndented, indentPixels);
      indentView.setId(viewToTheLeftId);
      ((ViewGroup) messageIndented.getParent()).addView(indentView);
    }

    if (MyPreferences.showAvatars()) {
      ImageView avatarView = new ImageView(context);
      int size = Math.round(AvatarDrawable.AVATAR_SIZE_DIP * displayDensity);
      avatarView.setScaleType(ScaleType.FIT_CENTER);
      RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(size, size);
      layoutParams.topMargin = 3;
      if (oMsg.indentLevel > 0) {
        layoutParams.leftMargin = 1;
      }
      if (viewToTheLeftId == 0) {
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
      } else {
        layoutParams.addRule(RelativeLayout.RIGHT_OF, viewToTheLeftId);
      }
      avatarView.setLayoutParams(layoutParams);
      avatarView.setImageDrawable(oMsg.avatarDrawable.getDrawable());
      indentPixels += size;
      ((ViewGroup) messageIndented.getParent()).addView(avatarView);
    }
    messageIndented.setPadding(indentPixels + 6, 2, 6, 2);

    TextView id = (TextView) messageView.findViewById(R.id.id);
    id.setText(Long.toString(oMsg.msgId));
    TextView linkedUserId = (TextView) messageView.findViewById(R.id.linked_user_id);
    linkedUserId.setText(Long.toString(oMsg.linkedUserId));

    TextView author = (TextView) messageView.findViewById(R.id.message_author);
    TextView body = (TextView) messageView.findViewById(R.id.message_body);
    TextView details = (TextView) messageView.findViewById(R.id.message_details);

    author.setText(oMsg.author);

    TextView number = (TextView) messageView.findViewById(R.id.message_number);
    number.setText(Integer.toString(oMsg.historyOrder));

    if (!TextUtils.isEmpty(oMsg.body)) {
      body.setLinksClickable(true);
      body.setMovementMethod(LinkMovementMethod.getInstance());
      body.setFocusable(true);
      body.setFocusableInTouchMode(true);
      Spanned spanned = Html.fromHtml(oMsg.body);
      body.setText(spanned);
      if (!MbMessage.hasUrlSpans(spanned)) {
        Linkify.addLinks(body, Linkify.ALL);
      }
    }

    // Everything else goes to messageDetails
    String messageDetails = RelativeTime.getDifference(context, oMsg.createdDate);
    if (!SharedPreferencesUtil.isEmpty(oMsg.via)) {
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_from).toString(),
                  oMsg.via);
    }
    if (oMsg.inReplyToMsgId != 0) {
      String inReplyToName = oMsg.inReplyToName;
      if (SharedPreferencesUtil.isEmpty(inReplyToName)) {
        inReplyToName = "...";
      }
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_in_reply_to).toString(),
                  oMsg.inReplyToName)
              + " ("
              + msgIdToHistoryOrder(oMsg.inReplyToMsgId)
              + ")";
    }
    if (!SharedPreferencesUtil.isEmpty(oMsg.rebloggersString)
        && !oMsg.rebloggersString.equals(oMsg.author)) {
      if (!SharedPreferencesUtil.isEmpty(oMsg.inReplyToName)) {
        messageDetails += ";";
      }
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context
                      .getText(ma.alternativeTermForResourceId(R.string.reblogged_by))
                      .toString(),
                  oMsg.rebloggersString);
    }
    if (!SharedPreferencesUtil.isEmpty(oMsg.recipientName)) {
      messageDetails +=
          " "
              + String.format(
                  MyContextHolder.get().getLocale(),
                  context.getText(R.string.message_source_to).toString(),
                  oMsg.recipientName);
    }
    if (MyLog.isLoggable(this, MyLog.VERBOSE)) {
      messageDetails = messageDetails + " (i" + oMsg.indentLevel + ",r" + oMsg.replyLevel + ")";
    }
    details.setText(messageDetails);
    ImageView favorited = (ImageView) messageView.findViewById(R.id.message_favorited);
    favorited.setImageResource(
        oMsg.favorited ? android.R.drawable.star_on : android.R.drawable.star_off);
    return messageView;
  }