<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_observer( self, callable_, entity_type=None, action=None, entity_id=None, predicate=None):
 """Register an "on-model-change" callback Once the model is connected, ``callable_`` will be called each time the model changes. ``callable_`` should be Awaitable and accept the following positional arguments: delta - An instance of :class:`juju.delta.EntityDelta` containing the raw delta data recv'd from the Juju websocket. old_obj - If the delta modifies an existing object in the model, old_obj will be a copy of that object, as it was before the delta was applied. Will be None if the delta creates a new entity in the model. new_obj - A copy of the new or updated object, after the delta is applied. Will be None if the delta removes an entity from the model. model - The :class:`Model` itself. Events for which ``callable_`` is called can be specified by passing entity_type, action, and/or entitiy_id filter criteria, e.g.:: add_observer( myfunc, entity_type='application', action='add', entity_id='ubuntu') For more complex filtering conditions, pass a predicate function. It will be called with a delta as its only argument. If the predicate function returns True, the ``callable_`` will be called. """

        observer = _Observer(
            callable_, entity_type, action, entity_id, predicate)
        self._observers[observer] = callable_