private function update_user(array $externaldata, $userdata) {
        $user = (object) [
            'id' => $userdata->id,
        ];

        // We can only update if the default authentication type of the user is set to OAuth2 as well. Otherwise, we might mess
        // up the user data of other users that use different authentication mechanisms (e.g. linked logins).
        if ($userdata->auth !== $this->authtype) {
            return $userdata;
        }

        // Go through each field from the external data.
        foreach ($externaldata as $fieldname => $value) {
            if (!in_array($fieldname, $this->userfields)) {
                // Skip if this field doesn't belong to the list of fields that can be synced with the OAuth2 issuer.
                continue;
            }

            if (!property_exists($userdata, $fieldname)) {
                // Just in case this field is on the list, but not part of the user data. This shouldn't happen though.
                continue;
            }

            // Get the old value.
            $oldvalue = (string)$userdata->$fieldname;

            // Get the lock configuration of the field.
            $lockvalue = $this->config->{'field_lock_' . $fieldname};

            // We should update fields that meet the following criteria:
            // - Lock value set to 'unlocked'; or 'unlockedifempty', given the current value is empty.
            // - The value has changed.
            if ($lockvalue === 'unlocked' || ($lockvalue === 'unlockedifempty' && empty($oldvalue))) {
                $value = (string)$value;
                if ($oldvalue !== $value) {
                    $user->$fieldname = $value;
                }
            }
        }
        // Update the user data.
        user_update_user($user, false);

        // Save user profile data.
        profile_save_data($user);

        // Refresh user for $USER variable.
        return get_complete_user_data('id', $user->id);
    }