<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def when_change( self, *keys: Hashable, exclude: bool = False, live: bool = False, timeout: float = None, identical_okay: bool = False, start_time: bool = None, count: int = None, ) -> StateWatcher: """ Block until a change is observed, and then return a copy of the state. .. include:: /api/state/get_when_change.rst """

        if not keys:

            def callback(update: StateUpdate) -> dict:
                return update.after

        else:
            if identical_okay:
                raise ValueError(
                    "Passing both `identical_okay` and `keys` is not possible. "
                    "(Hint: Omit `keys`)"
                )

            key_set = set(keys)

            def select(before, after):
                selected = {*before.keys(), *after.keys()}
                if exclude:
                    return selected - key_set
                else:
                    return selected & key_set

            def callback(update: StateUpdate) -> dict:
                before, after = update.before, update.after
                try:
                    if not any(before[k] != after[k] for k in select(before, after)):
                        raise _SkipStateUpdate
                except KeyError:  # this indirectly implies that something has changed
                    pass
                return update.after

        return StateWatcher(
            state=self,
            live=live,
            timeout=timeout,
            identical_okay=identical_okay,
            start_time=start_time,
            count=count,
            callback=callback,
        )