private void handleUntrustedIdentityMessage(
      MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
    try {
      EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
      Recipients recipients =
          RecipientFactory.getRecipientsFromString(context, envelope.getSource(), false);
      long recipientId = recipients.getPrimaryRecipient().getRecipientId();
      PreKeyWhisperMessage whisperMessage = new PreKeyWhisperMessage(envelope.getMessage());
      IdentityKey identityKey = whisperMessage.getIdentityKey();
      String encoded = Base64.encodeBytes(envelope.getMessage());
      IncomingTextMessage textMessage =
          new IncomingTextMessage(
              envelope.getSource(),
              envelope.getSourceDevice(),
              envelope.getTimestamp(),
              encoded,
              Optional.<TextSecureGroup>absent());

      if (!smsMessageId.isPresent()) {
        IncomingPreKeyBundleMessage bundleMessage =
            new IncomingPreKeyBundleMessage(textMessage, encoded);
        Pair<Long, Long> messageAndThreadId =
            database.insertMessageInbox(masterSecret, bundleMessage);

        database.setMismatchedIdentity(messageAndThreadId.first, recipientId, identityKey);
        MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
      } else {
        database.updateMessageBody(masterSecret, smsMessageId.get(), encoded);
        database.markAsPreKeyBundle(smsMessageId.get());
        database.setMismatchedIdentity(smsMessageId.get(), recipientId, identityKey);
      }
    } catch (InvalidMessageException | InvalidVersionException e) {
      throw new AssertionError(e);
    }
  }
  private void handleEndSessionMessage(
      MasterSecret masterSecret,
      TextSecureEnvelope envelope,
      TextSecureMessage message,
      Optional<Long> smsMessageId) {
    EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
    IncomingTextMessage incomingTextMessage =
        new IncomingTextMessage(
            envelope.getSource(),
            envelope.getSourceDevice(),
            message.getTimestamp(),
            "",
            Optional.<TextSecureGroup>absent());

    long threadId;

    if (!smsMessageId.isPresent()) {
      IncomingEndSessionMessage incomingEndSessionMessage =
          new IncomingEndSessionMessage(incomingTextMessage);
      Pair<Long, Long> messageAndThreadId =
          smsDatabase.insertMessageInbox(masterSecret, incomingEndSessionMessage);
      threadId = messageAndThreadId.second;
    } else {
      smsDatabase.markAsEndSession(smsMessageId.get());
      threadId = smsDatabase.getThreadIdForMessage(smsMessageId.get());
    }

    SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
    sessionStore.deleteAllSessions(envelope.getSource());

    SecurityEvent.broadcastSecurityUpdateEvent(context, threadId);
    MessageNotifier.updateNotification(context, masterSecret, threadId);
  }
  private void handleLegacyMessage(
      MasterSecret masterSecret, TextSecureEnvelope envelope, Optional<Long> smsMessageId) {
    EncryptingSmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);

    if (!smsMessageId.isPresent()) {
      Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
      smsDatabase.markAsLegacyVersion(messageAndThreadId.first);
      MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
    } else {
      smsDatabase.markAsLegacyVersion(smsMessageId.get());
    }
  }
  private void handleTextMessage(
      MasterSecret masterSecret,
      TextSecureEnvelope envelope,
      TextSecureMessage message,
      Optional<Long> smsMessageId) {
    Pair<Long, Long> messageAndThreadId;

    if (message.getSyncContext().isPresent()) {
      messageAndThreadId = insertSyncTextMessage(masterSecret, envelope, message, smsMessageId);
    } else {
      messageAndThreadId = insertStandardTextMessage(masterSecret, envelope, message, smsMessageId);
    }

    MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
  }
  // TODO: handleSMPMessage
  private void handleSMPMessage(
      MasterSecret masterSecret, TextSecureEnvelope envelope, TextSecureSMPMessage message) {
    Pair<Long, Long> messageAndThreadId;

    // TODO: make this a boolean flag
    Log.d(TAG, "handleSMPMessage isSMPSyncMessage: " + message.isSMPSyncMessage());
    if (message.isSMPSyncMessage()) {
      Log.d(TAG, "isSMPSyncContext: true");
      messageAndThreadId = insertSyncSMPMessage(masterSecret, envelope, message);
    } else {
      Log.d(TAG, "isStandardSMPMessage: true");
      messageAndThreadId = insertStandardSMPMessage(masterSecret, envelope, message);
    }

    MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
  }
  private void handleMediaMessage(
      MasterSecret masterSecret,
      TextSecureEnvelope envelope,
      TextSecureMessage message,
      Optional<Long> smsMessageId)
      throws MmsException {
    Pair<Long, Long> messageAndThreadId;

    if (message.getSyncContext().isPresent()) {
      messageAndThreadId = insertSyncMediaMessage(masterSecret, envelope, message);
    } else {
      messageAndThreadId = insertStandardMediaMessage(masterSecret, envelope, message);
    }

    ApplicationContext.getInstance(context)
        .getJobManager()
        .add(new AttachmentDownloadJob(context, messageAndThreadId.first));

    if (smsMessageId.isPresent()) {
      DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
    }

    MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
  }
 @Override
 public void onAdded() {
   if (KeyCachingService.getMasterSecret(context) == null) {
     MessageNotifier.updateNotification(context, null, -2);
   }
 }