protected void finishLogin(final byte[] privateKeyData, final byte[] publicKeyData) {
    Log.v(TAG, "finishing login");

    // update public key
    try {
      mKey.update(publicKeyData);
    } catch (IOException e) {
      Log.v(TAG, "error decoding public key", e);
      // TODO what now??
    }

    if (mProgress == null) startProgress();
    mProgress.setCancelable(false);
    setProgressMessage(getString(R.string.msg_initializing));

    final Account account = new Account(mPhoneNumber, Authenticator.ACCOUNT_TYPE);

    // generate the bridge certificate
    byte[] bridgeCertData;
    try {
      // TODO subjectAltName?
      bridgeCertData =
          X509Bridge.createCertificate(privateKeyData, publicKeyData, mPassphrase, null)
              .getEncoded();
    } catch (Exception e) {
      // abort
      throw new RuntimeException("unable to build X.509 bridge certificate", e);
    }

    // workaround for bug in AccountManager (http://stackoverflow.com/a/11698139/1045199)
    // procedure will continue in removeAccount callback
    mAccountManager.removeAccount(
        account,
        new AccountRemovalCallback(
            this, account, mPassphrase, privateKeyData, publicKeyData, bridgeCertData, mName),
        mHandler);
  }
  @Override
  public void processPacket(Stanza packet) {
    PublicKeyPublish p = (PublicKeyPublish) packet;

    if (p.getType() == IQ.Type.result) {
      byte[] _publicKey = p.getPublicKey();

      if (_publicKey != null) {
        String from = XmppStringUtils.parseBareJid(p.getFrom());
        boolean selfJid = Authenticator.isSelfJID(getContext(), from);

        // is this our key?
        if (selfJid) {
          byte[] bridgeCertData;
          try {
            PersonalKey key = getApplication().getPersonalKey();

            bridgeCertData =
                X509Bridge.createCertificate(_publicKey, key.getAuthKeyPair().getPrivateKey())
                    .getEncoded();
          } catch (Exception e) {
            Log.e(MessageCenterService.TAG, "error decoding key data", e);
            bridgeCertData = null;
          }

          if (bridgeCertData != null) {
            // store key data in AccountManager
            Authenticator.setDefaultPersonalKey(
                getContext(), _publicKey, null, bridgeCertData, null);
            // invalidate cached personal key
            getApplication().invalidatePersonalKey();

            Log.v(MessageCenterService.TAG, "personal key updated.");
          }
        }

        String id = p.getStanzaId();

        // broadcast key update
        Intent i = new Intent(ACTION_PUBLICKEY);
        i.putExtra(EXTRA_PACKET_ID, id);
        i.putExtra(EXTRA_FROM, p.getFrom());
        i.putExtra(EXTRA_TO, p.getTo());
        i.putExtra(EXTRA_PUBLIC_KEY, _publicKey);
        sendBroadcast(i);

        // if we are not syncing and this is not a response for the Syncer
        // save the key immediately
        if (!SyncAdapter.getIQPacketId().equals(id) || !SyncAdapter.isActive(getContext())) {

          // updating server key
          if (XmppStringUtils.parseDomain(from).equals(from)) {
            Log.v("pubkey", "Updating server key for " + from);
            try {
              Keyring.setKey(getContext(), from, _publicKey);
            } catch (Exception e) {
              // TODO warn user
              Log.e(MessageCenterService.TAG, "unable to update user key", e);
            }
          } else {
            try {
              Log.v("pubkey", "Updating key for " + from);
              Keyring.setKey(
                  getContext(), from, _publicKey, selfJid ? MyUsers.Keys.TRUST_VERIFIED : -1);

              // update display name with uid (if empty)
              PGPUserID keyUid = PGP.parseUserId(_publicKey, getConnection().getServiceName());
              if (keyUid != null && keyUid.getName() != null)
                UsersProvider.updateDisplayNameIfEmpty(getContext(), from, keyUid.getName());

              // invalidate cache for this user
              Contact.invalidate(from);
            } catch (Exception e) {
              // TODO warn user
              Log.e(MessageCenterService.TAG, "unable to update user key", e);
            }
          }
        }
      }
    }
  }