public ChatSessionAdapter(
      ChatSession chatSession, ImConnectionAdapter connection, boolean isNewSession) {

    mChatSession = chatSession;
    mConnection = connection;

    service = connection.getContext();
    mContentResolver = service.getContentResolver();
    mStatusBarNotifier = service.getStatusBarNotifier();
    mChatSessionManager = (ChatSessionManagerAdapter) connection.getChatSessionManager();

    mListenerAdapter = new ListenerAdapter();

    mOtrChatSessions = new HashMap<String, OtrChatSessionAdapter>();

    ImEntity participant = mChatSession.getParticipant();

    if (participant instanceof ChatGroup) {
      init((ChatGroup) participant, isNewSession);
    } else {
      init((Contact) participant, isNewSession);
    }

    initOtrChatSession(participant);
  }
  synchronized void sendPostponedMessages() {
    String[] projection =
        new String[] {
          BaseColumns._ID,
          Imps.Messages.BODY,
          Imps.Messages.PACKET_ID,
          Imps.Messages.DATE,
          Imps.Messages.TYPE,
          Imps.Messages.IS_DELIVERED
        };
    String selection = Imps.Messages.TYPE + "=?";

    Cursor c =
        mContentResolver.query(
            mMessageURI,
            projection,
            selection,
            new String[] {Integer.toString(Imps.MessageType.POSTPONED)},
            null);
    if (c == null) {
      RemoteImService.debug("Query error while querying postponed messages");
      return;
    }

    ArrayList<String> messages = new ArrayList<String>();

    while (c.moveToNext()) messages.add(c.getString(1));

    c.close();

    removeMessageInDb(Imps.MessageType.POSTPONED);

    for (String body : messages) sendMessage(body, false);
  }
  boolean hasPostponedMessages() {
    String[] projection =
        new String[] {
          BaseColumns._ID,
          Imps.Messages.BODY,
          Imps.Messages.PACKET_ID,
          Imps.Messages.DATE,
          Imps.Messages.TYPE,
          Imps.Messages.IS_DELIVERED
        };
    String selection = Imps.Messages.TYPE + "=?";

    boolean result = false;

    Cursor c =
        mContentResolver.query(
            mMessageURI,
            projection,
            selection,
            new String[] {Integer.toString(Imps.MessageType.POSTPONED)},
            null);
    if (c == null) {
      RemoteImService.debug("Query error while querying postponed messages");
      return false;
    } else if (c.getCount() > 0) {
      result = true;
    }

    c.close();
    return true;
  }
  private void initOtrChatSession(ImEntity participant) {
    try {
      if (mConnection != null) {
        mDataHandler = new OtrDataHandler(mChatSession);
        mDataHandlerListener = new DataHandlerListenerImpl();
        mDataHandler.setDataListener(mDataHandlerListener);

        OtrChatManager cm = service.getOtrChatManager();
        cm.addOtrEngineListener(mListenerAdapter);
        mChatSession.setMessageListener(new OtrChatListener(cm, mListenerAdapter));

        if (participant instanceof Contact) {
          String key = participant.getAddress().getAddress();
          if (!mOtrChatSessions.containsKey(key)) {
            OtrChatSessionAdapter adapter =
                new OtrChatSessionAdapter(
                    mConnection.getLoginUser().getAddress().getAddress(), participant, cm);
            mOtrChatSessions.put(key, adapter);
          }
        } else if (participant instanceof ChatGroup) {
          ChatGroup group = (ChatGroup) mChatSession.getParticipant();

          for (Contact contact : group.getMembers()) {
            String key = contact.getAddress().getAddress();
            if (!mOtrChatSessions.containsKey(key)) {
              OtrChatSessionAdapter adapter =
                  new OtrChatSessionAdapter(
                      mConnection.getLoginUser().getAddress().getAddress(), contact, cm);
              mOtrChatSessions.put(key, adapter);
            }
          }
        }

        mDataHandler.setChatId(getId());
      }
    } catch (NullPointerException npe) {
      Log.e(ImApp.LOG_TAG, "error init OTR session", npe);
    }
  }