public static function generate(Member $member)
    {
        if (!$member->exists()) {
            return null;
        }
        if (static::config()->force_single_token) {
            RememberLoginHash::get()->filter('MemberID', $member->ID)->removeAll();
        }
        /** @var RememberLoginHash $rememberLoginHash */
        $rememberLoginHash = RememberLoginHash::create();
        do {
            $deviceID = $rememberLoginHash->getNewDeviceID();
        } while (RememberLoginHash::get()->filter('DeviceID', $deviceID)->count());

        $rememberLoginHash->DeviceID = $deviceID;
        $rememberLoginHash->Hash = $rememberLoginHash->getNewHash($member);
        $rememberLoginHash->MemberID = $member->ID;
        $now = DBDatetime::now();
        $expiryDate = new DateTime($now->Rfc2822());
        $tokenExpiryDays = static::config()->token_expiry_days;
        $expiryDate->add(new DateInterval('P' . $tokenExpiryDays . 'D'));
        $rememberLoginHash->ExpiryDate = $expiryDate->format('Y-m-d H:i:s');
        $rememberLoginHash->extend('onAfterGenerateToken');
        $rememberLoginHash->write();
        return $rememberLoginHash;
    }