Index: /trunk/roundcubemail/CHANGELOG
===================================================================
--- /trunk/roundcubemail/CHANGELOG	(revision 3649)
+++ /trunk/roundcubemail/CHANGELOG	(revision 3650)
@@ -2,4 +2,6 @@
 ===========================
 
+- Added 'actionbefore', 'actionafter', 'responsebefore', 'responseafter' events
+- Removed response.callbacks feature
 - Fix double-addition of e-mail domain to content ID in HTML images
 - Read and send messages with format=flowed (#1484370), fixes word wrapping issues (#1486543)
Index: /trunk/roundcubemail/program/js/app.js
===================================================================
--- /trunk/roundcubemail/program/js/app.js	(revision 3649)
+++ /trunk/roundcubemail/program/js/app.js	(revision 3650)
@@ -440,5 +440,6 @@
     }
 
-    // trigger plugin hook
+    // trigger plugin hooks
+    this.triggerEvent('actionbefore', {props:props, action:command});
     var event_ret = this.triggerEvent('before'+command, props);
     if (typeof event_ret != 'undefined') {
@@ -866,5 +867,5 @@
         this.set_busy(true, 'sendingmessage');
         var form = this.gui_objects.messageform;
-        form.target = "savetarget";     
+        form.target = 'savetarget';
         form._draft.value = '';
         form.submit();
@@ -881,5 +882,5 @@
         self.clearTimeout(this.save_timer);
 
-        this.upload_file(props)      
+        this.upload_file(props)
         break;
 
@@ -897,5 +898,5 @@
         if (uid = this.get_single_uid())
           this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
-        break;      
+        break;
 
       case 'forward':
@@ -1046,4 +1047,5 @@
 
     this.triggerEvent('after'+command, props);
+    this.triggerEvent('actionafter', {props:props, action:command});
 
     return obj ? false : true;
@@ -4909,4 +4911,7 @@
       this.set_busy(false);
 
+    this.triggerEvent('responsebefore', {response: response});
+    this.triggerEvent('responsebefore'+response.action, {response: response});
+
     // set env vars
     if (response.env)
@@ -4924,10 +4929,4 @@
       console.log(response.exec);
       eval(response.exec);
-    }
-
-    // execute callback functions of plugins
-    if (response.callbacks && response.callbacks.length) {
-      for (var i=0; i < response.callbacks.length; i++)
-        this.triggerEvent(response.callbacks[i][0], response.callbacks[i][1]);
     }
 
@@ -4990,4 +4989,7 @@
         break;
     }
+
+    this.triggerEvent('responseafter', {response: response});
+    this.triggerEvent('responseafter'+response.action, {response: response});
   };
 
