private May<uint> processV3(SessionRecord sessionRecord, PreKeyWhisperMessage message) { if (sessionRecord.hasSessionState(message.getMessageVersion(), message.getBaseKey().serialize())) { //Log.w(TAG, "We've already setup a session for this V3 message, letting bundled message fall through..."); return May<uint>.NoValue; } ECKeyPair ourSignedPreKey = signedPreKeyStore.LoadSignedPreKey(message.getSignedPreKeyId()).getKeyPair(); BobAxolotlParameters.Builder parameters = BobAxolotlParameters.newBuilder(); parameters.setTheirBaseKey(message.getBaseKey()) .setTheirIdentityKey(message.getIdentityKey()) .setOurIdentityKey(identityKeyStore.GetIdentityKeyPair()) .setOurSignedPreKey(ourSignedPreKey) .setOurRatchetKey(ourSignedPreKey); if (message.getPreKeyId().HasValue) { parameters.setOurOneTimePreKey(new May<ECKeyPair>(preKeyStore.LoadPreKey(message.getPreKeyId().ForceGetValue()).getKeyPair())); } else { parameters.setOurOneTimePreKey(May<ECKeyPair>.NoValue); } if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState(); RatchetingSession.initializeSession(sessionRecord.getSessionState(), message.getMessageVersion(), parameters.create()); sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.GetLocalRegistrationId()); sessionRecord.getSessionState().setRemoteRegistrationId(message.getRegistrationId()); sessionRecord.getSessionState().setAliceBaseKey(message.getBaseKey().serialize()); if (message.getPreKeyId().HasValue && message.getPreKeyId().ForceGetValue() != Medium.MAX_VALUE) { return message.getPreKeyId(); } else { return May<uint>.NoValue; } }