public void selectPresence(final Conversation conversation, final OnPresenceSelected listener) {
    final Contact contact = conversation.getContact();
    if (conversation.hasValidOtrSession()) {
      SessionID id = conversation.getOtrSession().getSessionID();
      Jid jid;
      try {
        jid = Jid.fromString(id.getAccountID() + "/" + id.getUserID());
      } catch (InvalidJidException e) {
        jid = null;
      }
      conversation.setNextCounterpart(jid);
      listener.onPresenceSelected();
    } else if (!contact.showInRoster()) {
      showAddToRosterDialog(conversation);
    } else {
      Presences presences = contact.getPresences();
      if (presences.size() == 0) {
        if (!contact.getOption(Contact.Options.TO)
            && !contact.getOption(Contact.Options.ASKING)
            && contact.getAccount().getStatus() == Account.State.ONLINE) {
          showAskForPresenceDialog(contact);
        } else if (!contact.getOption(Contact.Options.TO)
            || !contact.getOption(Contact.Options.FROM)) {
          warnMutalPresenceSubscription(conversation, listener);
        } else {
          conversation.setNextCounterpart(null);
          listener.onPresenceSelected();
        }
      } else if (presences.size() == 1) {
        String presence = presences.asStringArray()[0];
        try {
          conversation.setNextCounterpart(
              Jid.fromParts(
                  contact.getJid().getLocalpart(), contact.getJid().getDomainpart(), presence));
        } catch (InvalidJidException e) {
          conversation.setNextCounterpart(null);
        }
        listener.onPresenceSelected();
      } else {
        final StringBuilder presence = new StringBuilder();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.choose_presence));
        final String[] presencesArray = presences.asStringArray();
        int preselectedPresence = 0;
        for (int i = 0; i < presencesArray.length; ++i) {
          if (presencesArray[i].equals(contact.lastseen.presence)) {
            preselectedPresence = i;
            break;
          }
        }
        presence.append(presencesArray[preselectedPresence]);
        builder.setSingleChoiceItems(
            presencesArray,
            preselectedPresence,
            new DialogInterface.OnClickListener() {

              @Override
              public void onClick(DialogInterface dialog, int which) {
                presence.delete(0, presence.length());
                presence.append(presencesArray[which]);
              }
            });
        builder.setNegativeButton(R.string.cancel, null);
        builder.setPositiveButton(
            R.string.ok,
            new OnClickListener() {

              @Override
              public void onClick(DialogInterface dialog, int which) {
                try {
                  conversation.setNextCounterpart(
                      Jid.fromParts(
                          contact.getJid().getLocalpart(),
                          contact.getJid().getDomainpart(),
                          presence.toString()));
                } catch (InvalidJidException e) {
                  conversation.setNextCounterpart(null);
                }
                listener.onPresenceSelected();
              }
            });
        builder.create().show();
      }
    }
  }
  public void parseContactPresence(final PresencePacket packet, final Account account) {
    final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
    final Jid from = packet.getFrom();
    if (from == null) {
      return;
    }
    final String type = packet.getAttribute("type");
    final Contact contact = account.getRoster().getContact(from);
    if (type == null) {
      final String resource = from.isBareJid() ? "" : from.getResourcepart();
      contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick"));
      Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
      if (avatar != null && !contact.isSelf()) {
        avatar.owner = from.toBareJid();
        if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
          if (contact.setAvatar(avatar)) {
            mXmppConnectionService.getAvatarService().clear(contact);
            mXmppConnectionService.updateConversationUi();
            mXmppConnectionService.updateRosterUi();
          }
        } else {
          mXmppConnectionService.fetchAvatar(account, avatar);
        }
      }
      int sizeBefore = contact.getPresences().size();

      final Element show = packet.findChild("show");
      final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
      final Presence presence = Presence.parse(show, caps);
      contact.updatePresence(resource, presence);
      if (presence.hasCaps() && Config.REQUEST_DISCO) {
        mXmppConnectionService.fetchCaps(account, from, presence);
      }

      PgpEngine pgp = mXmppConnectionService.getPgpEngine();
      Element x = packet.findChild("x", "jabber:x:signed");
      if (pgp != null && x != null) {
        Element status = packet.findChild("status");
        String msg = status != null ? status.getContent() : "";
        contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent()));
      }
      boolean online = sizeBefore < contact.getPresences().size();
      updateLastseen(packet, account, false);
      mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
    } else if (type.equals("unavailable")) {
      if (from.isBareJid()) {
        contact.clearPresences();
      } else {
        contact.removePresence(from.getResourcepart());
      }
      mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
    } else if (type.equals("subscribe")) {
      if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
        mXmppConnectionService.sendPresencePacket(
            account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
      } else {
        contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
        final Conversation conversation =
            mXmppConnectionService.findOrCreateConversation(
                account, contact.getJid().toBareJid(), false);
        final String statusMessage = packet.findChildContent("status");
        if (statusMessage != null
            && !statusMessage.isEmpty()
            && conversation.countMessages() == 0) {
          conversation.add(
              new Message(
                  conversation, statusMessage, Message.ENCRYPTION_NONE, Message.STATUS_RECEIVED));
        }
      }
    }
    mXmppConnectionService.updateRosterUi();
  }