 diff --git a/chat/modules/jsProtoHelper.jsm b/chat/modules/jsProtoHelper.jsm
 --- a/chat/modules/jsProtoHelper.jsm
 +++ b/chat/modules/jsProtoHelper.jsm
-@@ -467,17 +467,18 @@ const GenericConversationPrototype = {
+@@ -394,17 +394,17 @@ const GenericMessagePrototype = {
+         return buddy.buddyIconFilename;
+     }
+     return "";
+   },
+   _conversation: null,
+   get conversation() this._conversation,
+   set conversation(aConv) {
+     this._conversation = aConv;
+-    aConv.notifyObservers(this, "new-text", null);
++    aConv.notifyObservers(new imMessage(this), "new-text", null);
+   },
+ 
+   color: "",
+ 
+   outgoing: false,
+   incoming: false,
+   system: false,
+   autoResponse: false,
+@@ -425,16 +425,57 @@ const GenericMessagePrototype = {
+ };
+ 
+ function Message(aWho, aMessage, aObject) {
+   this._init(aWho, aMessage, aObject);
+ }
+ Message.prototype = GenericMessagePrototype;
+ 
+ 
++function imMessage(aPrplMessage) {
++  this.prplMessage = aPrplMessage;
++}
++imMessage.prototype = {
++  __proto__: ClassInfo(["imIMessage", "prplIMessage"], "IM Message"),
++  cancelled: false,
++  _displayMessage: null,
++
++  get displayMessage() {
++    return this._displayMessage || this.prplMessage.originalMessage;
++  },
++  set displayMessage(aMsg) { this._displayMessage = aMsg; },
++
++  get message() this.prplMessage.message,
++  set message(aMsg) { this.prplMessage.message = aMsg; },
++
++  // from prplIMessage
++  get who() this.prplMessage.who,
++  get time() this.prplMessage.time,
++  get id() this.prplMessage.id,
++  get alias() this.prplMessage.alias,
++  get iconURL() this.prplMessage.iconURL,
++  get conversation() this.prplMessage.conversation,
++  set conversation(aConv) { this.prplMessage.conversation = aConv; },
++  get color() this.prplMessage.color,
++  get outgoing() this.prplMessage.outgoing,
++  get incoming() this.prplMessage.incoming,
++  get system() this.prplMessage.system,
++  get autoResponse() this.prplMessage.autoResponse,
++  get containsNick() this.prplMessage.containsNick,
++  get noLog() this.prplMessage.noLog,
++  get error() this.prplMessage.error,
++  get delayed() this.prplMessage.delayed,
++  get noFormat() this.prplMessage.noFormat,
++  get containsImages() this.prplMessage.containsImages,
++  get notification() this.prplMessage.notification,
++  get noLinkification() this.prplMessage.noLinkification,
++  getActions: function(aCount) this.prplMessage.getActions(aCount)
++};
++
++
+ const GenericConversationPrototype = {
+   __proto__: ClassInfo("prplIConversation", "generic conversation object"),
+   get wrappedJSObject() this,
+ 
+   get DEBUG() this._account.DEBUG,
+   get LOG() this._account.LOG,
+   get WARN() this._account.WARN,
+   get ERROR() this._account.ERROR,
+@@ -467,17 +508,18 @@ const GenericConversationPrototype = {
        try {
          observer.observe(aSubject, aTopic, aData);
        } catch(e) {

       this.target = this._prplConv[aTargetId];
+
+    if (aTopic == "new-text") {
+      aSubject = new imMessage(aSubject);
+      this.notifyObservers(aSubject, "received-message");
+      if (aSubject.cancelled)
+        return;

   this._messages = [];
   this.changeTargetTo(aPrplConversation);
   let iface = Ci["prplIConv" + (aPrplConversation.isChat ? "Chat" : "IM")];
@@ -271,16 +280,23 @@ UIConversation.prototype = {
   },
 
   observeConv: function(aTargetId, aSubject, aTopic, aData) {
