@Override
 public void onTypingEnded(Member member) {
   Log.d(TAG, "Ended Typing: " + member.getUserInfo().getIdentity());
 }
 @Override
 public void onMemberDelete(Member member) {
   Log.d(TAG, "Member deleted: " + member.getUserInfo().getIdentity());
 }
 @Override
 public void onMemberJoin(Member member) {
   Log.d(TAG, "Member joined: " + member.getUserInfo().getIdentity());
 }
 @Override
 public void onMemberChange(Member member) {
   Log.d(TAG, "Member changed: " + member.getUserInfo().getIdentity());
 }
    protected Boolean doInBackground(Void... params) {
      // Find all VirgilCards for all chat members
      for (Member member : mCurrentChannel.getMembers().getMembers()) {

        String sid = member.getSid();
        if (mMembers.containsKey(sid)) {
          continue;
        }

        String identity = member.getUserInfo().getIdentity();

        // Find Virgil Card for valid emails only
        if (CommonUtils.isNicknameValid(identity)) {

          Log.d(TAG, "Looking for: " + identity);

          SearchCriteria.Builder criteriaBuilder = new SearchCriteria.Builder();
          criteriaBuilder.setValue(identity).setIncludeUnauthorized(true);
          List<VirgilCard> cards =
              clientFactory.getPublicKeyClient().search(criteriaBuilder.build());

          if (!cards.isEmpty()) {
            VirgilCard card = cards.get(cards.size() - 1);

            String cardId = card.getId();
            PublicKey publicKey = new PublicKey(Base64.decode(card.getPublicKey().getKey()));

            mMembers.put(sid, new ChatMember(cardId, publicKey));

            Log.w(TAG, "Found card: " + cardId);
          } else {
            Log.w(TAG, "No cards for: " + identity);
          }
        }
      }

      // Build recipients map
      Map<String, PublicKey> recipients = new HashMap<>();
      for (ChatMember member : mMembers.values()) {
        recipients.put(member.getCardId(), member.getPublicKey());
      }

      // Build message
      ChatMessage chatMessage = new ChatMessage();
      chatMessage.setBody(mMessageBody);
      chatMessage.setAuthor(mIdentity);
      chatMessage.setDate(new Date().getTime());
      chatMessage.setId(UUID.randomUUID().toString());

      mMessageBody = mGson.toJson(chatMessage);

      // Encode message body
      if (!recipients.isEmpty()) {
        try {
          mMessageBody = CryptoHelper.encrypt(mMessageBody, recipients);
        } catch (Exception e) {
          // TODO: show error message
        }
      }

      // If message was not encrypted, sent it as is (unencrypted)
      Message message = mCurrentChannel.getMessages().createMessage(mMessageBody);
      Log.d(TAG, "Message created");
      mCurrentChannel
          .getMessages()
          .sendMessage(
              message,
              new Constants.StatusListener() {
                @Override
                public void onSuccess() {
                  MainActivity.this.runOnUiThread(
                      new Runnable() {
                        @Override
                        public void run() {
                          // need to modify user interface elements on the UI thread
                          mWriteMessageEditText.setText("");
                        }
                      });
                }

                @Override
                public void onError(ErrorInfo errorInfo) {
                  Log.e(TAG, "Error sending message: " + errorInfo.getErrorText());
                }
              });

      return null;
    }