class Message(object):
    implements(IObserver)

    def __init__(self, from_header, to_header, route_header, content_type, body, credentials=None, extra_headers=[]):
        self._request = Request("MESSAGE", from_header, to_header, to_header.uri, route_header,
                                credentials=credentials, extra_headers=extra_headers, content_type=content_type, body=body)
        self._lock = RLock()

    from_header = property(lambda self: self._request.from_header)
    to_header = property(lambda self: self._request.to_header)
    route_header = property(lambda self: self._request.route_header)
    content_type = property(lambda self: self._request.content_type)
    body = property(lambda self: self._request.body)
    credentials = property(lambda self: self._request.credentials)
    is_sent = property(lambda self: self._request.state != "INIT")
    in_progress = property(lambda self: self._request.state == "IN_PROGRESS")

    def send(self, timeout=None):
        notification_center = NotificationCenter()
        with self._lock:
            if self.is_sent:
                raise RuntimeError("This MESSAGE was already sent")
            notification_center.add_observer(self, sender=self._request)
            try:
                self._request.send(timeout)
            except:
                notification_center.remove_observer(self, sender=self._request)

    def end(self):
        with self._lock:
            self._request.end()

    def handle_notification(self, notification):
        handler = getattr(self, '_NH_%s' % notification.name, Null)
        handler(notification)

    def _NH_SIPRequestDidSucceed(self, notification):
        with self._lock:
            if notification.data.expires:
                # this shouldn't happen really
                notification.sender.end()
            NotificationCenter().post_notification("SIPMessageDidSucceed", sender=self,
                                                   data=TimestampedNotificationData(code=notification.data.code,
                                                                                    reason=notification.data.reason))

    def _NH_SIPRequestDidFail(self, notification):
        with self._lock:
            NotificationCenter().post_notification("SIPMessageDidFail", sender=self,
                                                   data=TimestampedNotificationData(code=notification.data.code,
                                                                                    reason=notification.data.reason))

    def _NH_SIPRequestDidEnd(self, notification):
        with self._lock:
            NotificationCenter().remove_observer(self, sender=notification.sender)
class Message(object):
    implements(IObserver)

    def __init__(self,
                 from_header,
                 to_header,
                 route_header,
                 content_type,
                 body,
                 credentials=None,
                 extra_headers=[]):
        self._request = Request("MESSAGE",
                                from_header,
                                to_header,
                                to_header.uri,
                                route_header,
                                credentials=credentials,
                                extra_headers=extra_headers,
                                content_type=content_type,
                                body=body)
        self._lock = RLock()

    from_header = property(lambda self: self._request.from_header)
    to_header = property(lambda self: self._request.to_header)
    route_header = property(lambda self: self._request.route_header)
    content_type = property(lambda self: self._request.content_type)
    body = property(lambda self: self._request.body)
    credentials = property(lambda self: self._request.credentials)
    is_sent = property(lambda self: self._request.state != "INIT")
    in_progress = property(lambda self: self._request.state == "IN_PROGRESS")

    def send(self, timeout=None):
        notification_center = NotificationCenter()
        with self._lock:
            if self.is_sent:
                raise RuntimeError("This MESSAGE was already sent")
            notification_center.add_observer(self, sender=self._request)
            try:
                self._request.send(timeout)
            except:
                notification_center.remove_observer(self, sender=self._request)

    def end(self):
        with self._lock:
            self._request.end()

    def handle_notification(self, notification):
        handler = getattr(self, '_NH_%s' % notification.name, Null)
        handler(notification)

    def _NH_SIPRequestDidSucceed(self, notification):
        with self._lock:
            if notification.data.expires:
                # this shouldn't happen really
                notification.sender.end()
            NotificationCenter().post_notification(
                "SIPMessageDidSucceed",
                sender=self,
                data=TimestampedNotificationData(
                    code=notification.data.code,
                    reason=notification.data.reason))

    def _NH_SIPRequestDidFail(self, notification):
        with self._lock:
            NotificationCenter().post_notification(
                "SIPMessageDidFail",
                sender=self,
                data=TimestampedNotificationData(
                    code=notification.data.code,
                    reason=notification.data.reason))

    def _NH_SIPRequestDidEnd(self, notification):
        with self._lock:
            NotificationCenter().remove_observer(self,
                                                 sender=notification.sender)