function crpmerge($MiniMe)
{
    global $Conf, $Me, $MergeError;
    if (!$MiniMe->contactId && !$Me->contactId) {
        return $MergeError = "Neither of those accounts has any data associated with this conference.";
    }
    // XXX `act as` merging might be useful?
    if (strcasecmp($Me->email, $_SESSION["trueuser"]->email)) {
        return $MergeError = "You can’t merge accounts when acting as a different user.";
    }
    // determine old & new users
    if (@$_REQUEST["prefer"]) {
        list($old_user, $new_user) = [$Me, $MiniMe];
    } else {
        list($old_user, $new_user) = [$MiniMe, $Me];
    }
    // send mail at start of process
    HotCRPMailer::send_to($old_user, "@mergeaccount", null, array("cc" => Text::user_email_to($new_user), "other_contact" => $new_user));
    // actually merge users or change email
    if ($old_user->contactId && $new_user->contactId) {
        crpmerge_database($old_user, $new_user);
    } else {
        if ($old_user->contactId) {
            $user_status = new UserStatus(["send_email" => false]);
            $user_status->save($user_status->user_to_json($new_user), $old_user);
        }
    }
    // update trueuser
    if (strcasecmp($_SESSION["trueuser"]->email, $new_user->email)) {
        $_SESSION["trueuser"] = (object) ["email" => $new_user->email];
    }
    if ($MergeError == "") {
        $Conf->confirmMsg("Merged account " . htmlspecialchars($old_user->email) . ".");
        $new_user->log_activity("Merged account {$old_user->email}");
        go(hoturl("index"));
    } else {
        $new_user->log_activity("Merged account {$old_user->email} with errors");
        $MergeError .= $Conf->db_error_html(true);
    }
}