'Display the list of callbacks connected to the object.'

def list_callbacks(self):

    obj = self.obj
    callback_name = self.callback_name
    parameters = self.parameters
    callbacks = self.handler.get_callbacks(obj)
    types = self.handler.get_events(obj)
    if callback_name:
        created = callbacks.get(callback_name)
        if (created is None):
            self.msg('No    callback    {}    has    been    set    on    {}.'.format(callback_name, obj))
            return
        if parameters:
            try:
                number = (int(parameters) - 1)
                assert (number >= 0)
                callback = callbacks[callback_name][number]
            except (ValueError, AssertionError, IndexError):
                self.msg('The    callback    {}    {}    cannot    be    found    in    {}.'.format(callback_name, parameters, obj))
                return
            author = callback.get('author')
            author = (author.key if author else '|gUnknown|n')
            updated_by = callback.get('updated_by')
            updated_by = (updated_by.key if updated_by else '|gUnknown|n')
            created_on = callback.get('created_on')
            created_on = (created_on.strftime('%Y-%m-%d    %H:%M:%S') if created_on else '|gUnknown|n')
            updated_on = callback.get('updated_on')
            updated_on = (updated_on.strftime('%Y-%m-%d    %H:%M:%S') if updated_on else '|gUnknown|n')
            msg = 'Callback    {}    {}    of    {}:'.format(callback_name, parameters, obj)
            msg += '\nCreated    by    {}    on    {}.'.format(author, created_on)
            msg += '\nUpdated    by    {}    on    {}'.format(updated_by, updated_on)
            if self.is_validator:
                if callback.get('valid'):
                    msg += '\nThis    callback    is    |rconnected|n    and    active.'
                else:
                    msg += "\nThis    callback    |rhasn't    been|n    accepted    yet."
            msg += '\nCallback    code:\n'
            msg += raw(callback['code'])
            self.msg(msg)
            return
        cols = ['Number', 'Author', 'Updated', 'Param']
        if self.is_validator:
            cols.append('Valid')
        table = EvTable(width=78, *cols)
        table.reformat_column(0, align='r')
        now = datetime.now()
        for (i, callback) in enumerate(created):
            author = callback.get('author')
            author = (author.key if author else '|gUnknown|n')
            updated_on = callback.get('updated_on')
            if (updated_on is None):
                updated_on = callback.get('created_on')
            if updated_on:
                updated_on = '{}    ago'.format(time_format((now - updated_on).total_seconds(), 4).capitalize())
            else:
                updated_on = '|gUnknown|n'
            parameters = callback.get('parameters', '')
            row = [str((i + 1)), author, updated_on, parameters]
            if self.is_validator:
                row.append(('Yes' if callback.get('valid') else 'No'))
            table.add_row(*row)
        self.msg(unicode(table))
    else:
        names = list(set((list(types.keys()) + list(callbacks.keys()))))
        table = EvTable('Callback    name', 'Number', 'Description', valign='t', width=78)
        table.reformat_column(0, width=20)
        table.reformat_column(1, width=10, align='r')
        table.reformat_column(2, width=48)
        for name in sorted(names):
            number = len(callbacks.get(name, []))
            lines = sum((len(e['code'].splitlines()) for e in callbacks.get(name, [])))
            no = '{}    ({})'.format(number, lines)
            description = types.get(name, (None, 'Chained    event.'))[1]
            description = description.strip('\n').splitlines()[0]
            table.add_row(name, no, description)
        self.msg(unicode(table))
