<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def dispatch(restricted=False):
 """ Dispatch registered handlers. When dispatching in restricted mode, only matching hook handlers are executed. Handlers are dispatched according to the following rules: * Handlers are repeatedly tested and invoked in iterations, until the system settles into quiescence (that is, until no new handlers match to be invoked). * In the first iteration, :func:`@hook <charms.reactive.decorators.hook>` and :func:`@action <charms.reactive.decorators.action>` handlers will be invoked, if they match. * In subsequent iterations, other handlers are invoked, if they match. * Added flags will not trigger new handlers until the next iteration, to ensure that chained flags are invoked in a predictable order. * Removed flags will cause the current set of matched handlers to be re-tested, to ensure that no handler is invoked after its matching flag has been removed. * Other than the guarantees mentioned above, the order in which matching handlers are invoked is undefined. * Flags are preserved between hook and action invocations, and all matching handlers are re-invoked for every hook and action. There are :doc:`decorators <charms.reactive.decorators>` and :doc:`helpers <charms.reactive.helpers>` to prevent unnecessary reinvocations, such as :func:`~charms.reactive.decorators.only_once`. """

    FlagWatch.reset()

    def _test(to_test):
        return list(filter(lambda h: h.test(), to_test))

    def _invoke(to_invoke):
        while to_invoke:
            unitdata.kv().set('reactive.dispatch.removed_state', False)
            for handler in list(to_invoke):
                to_invoke.remove(handler)
                hookenv.log('Invoking reactive handler: %s' % handler.id(), level=hookenv.INFO)
                handler.invoke()
                if unitdata.kv().get('reactive.dispatch.removed_state'):
                    # re-test remaining handlers
                    to_invoke = _test(to_invoke)
                    break
        FlagWatch.commit()

    tracer().start_dispatch()

    # When in restricted context, only run hooks for that context.
    if restricted:
        unitdata.kv().set('reactive.dispatch.phase', 'restricted')
        hook_handlers = _test(Handler.get_handlers())
        tracer().start_dispatch_phase('restricted', hook_handlers)
        _invoke(hook_handlers)
        return

    unitdata.kv().set('reactive.dispatch.phase', 'hooks')
    hook_handlers = _test(Handler.get_handlers())
    tracer().start_dispatch_phase('hooks', hook_handlers)
    _invoke(hook_handlers)

    unitdata.kv().set('reactive.dispatch.phase', 'other')
    for i in range(100):
        FlagWatch.iteration(i)
        other_handlers = _test(Handler.get_handlers())
        if i == 0:
            tracer().start_dispatch_phase('other', other_handlers)
        tracer().start_dispatch_iteration(i, other_handlers)
        if not other_handlers:
            break
        _invoke(other_handlers)

    FlagWatch.reset()