Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 5d0500cf34f298133f120c2783fb8ef7d5fb2e9c)
+++ kernel/generic/src/ipc/sysipc.c	(revision 2c4aa3945af021ccbb121cc18872675bdb1d661a)
@@ -44,4 +44,5 @@
 #include <ipc/irq.h>
 #include <ipc/ipcrsc.h>
+#include <ipc/event.h>
 #include <ipc/kbox.h>
 #include <synch/waitq.h>
@@ -134,4 +135,5 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
+	case IPC_M_STATE_CHANGE_AUTHORIZE:
 		return true;
 	default:
@@ -164,4 +166,5 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
+	case IPC_M_STATE_CHANGE_AUTHORIZE:
 		return true;
 	default:
@@ -334,4 +337,50 @@
 		free(answer->buffer);
 		answer->buffer = NULL;
+	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
+		if (!IPC_GET_RETVAL(answer->data)) {
+			/* The recipient authorized the change of state. */
+			phone_t *recipient_phone;
+			task_t *other_task_s;
+			task_t *other_task_r;
+			int rc;
+
+			rc = phone_get(IPC_GET_ARG1(answer->data),
+			    &recipient_phone);
+			if (rc != EOK) {
+				IPC_SET_RETVAL(answer->data, ENOENT);
+				return ENOENT;
+			}
+
+			mutex_lock(&recipient_phone->lock);
+			if (recipient_phone->state != IPC_PHONE_CONNECTED) {
+				mutex_unlock(&recipient_phone->lock);
+				IPC_SET_RETVAL(answer->data, EINVAL);
+				return EINVAL;
+			}
+
+			other_task_r = recipient_phone->callee->task;
+			other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
+
+			/*
+			 * See if both the sender and the recipient meant the
+			 * same third party task.
+			 */
+			if (other_task_r != other_task_s) {
+				IPC_SET_RETVAL(answer->data, EINVAL);
+				rc = EINVAL;
+			} else {
+				rc = event_task_notify_5(other_task_r,
+				    EVENT_TASK_STATE_CHANGE, false,
+				    IPC_GET_ARG1(*olddata),
+				    IPC_GET_ARG2(*olddata),
+				    IPC_GET_ARG3(*olddata),
+				    (sysarg_t) olddata->task,
+				    (sysarg_t) TASK);
+				IPC_SET_RETVAL(answer->data, rc);
+			}
+
+			mutex_unlock(&recipient_phone->lock);
+			return rc;
+		}
 	}
 	
@@ -456,4 +505,25 @@
 		}
 		
+		break;
+	}
+	case IPC_M_STATE_CHANGE_AUTHORIZE: {
+		phone_t *sender_phone;
+		task_t *other_task_s;
+
+		if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
+			return ENOENT;
+
+		mutex_lock(&sender_phone->lock);
+		if (sender_phone->state != IPC_PHONE_CONNECTED) {
+			mutex_unlock(&sender_phone->lock);
+			return EINVAL;
+		}
+
+		other_task_s = sender_phone->callee->task;
+
+		mutex_unlock(&sender_phone->lock);
+
+		/* Remember the third party task hash. */
+		IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
 		break;
 	}
