def to_dict(cls, convert_datetime=True):
    """
    return a dict representation of the Event and its sub-objects
    `convert_datetime` controls whether datetime objects are converted to strings or not
    :rtype: dict
    """
    def todict(obj):
        """
        recurse the objects and represent as a dict
        use the registered handlers if possible
        """
        data = {}
        if isinstance(obj, dict):
            for (key, val) in obj.items():
                data[key] = todict(val)
            return data
        if not convert_datetime and isinstance(obj, datetime):
            return obj
        elif type_handler_value(obj):
            return type_handler_value(obj)
        elif isinstance(obj, collections.Sequence) and not isinstance(obj, basestring):
            return [todict(v) for v in obj]
        elif hasattr(obj, "__dict__"):
            for key, value in obj.__dict__.items():
                if not callable(value) and not key.startswith('_'):
                    data[key] = todict(value)
            return data
        else:
            return obj

    return todict(cls)
return a dict representation of the Event and its sub-objects
    `convert_datetime` controls whether datetime objects are converted to strings or not
    :rtype: dict