Index: generic/include/ipc/ipc.h
===================================================================
--- generic/include/ipc/ipc.h	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/include/ipc/ipc.h	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -84,4 +84,5 @@
 	answerbox_t *callerbox;
 	int flags;
+	task_t *sender;
 	__native data[IPC_CALL_LEN];
 } call_t;
Index: generic/include/proc/task.h
===================================================================
--- generic/include/proc/task.h	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/include/proc/task.h	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -41,4 +41,6 @@
 	link_t tasks_link;	/**< Link to other tasks within the system. */
 	as_t *as;		/**< Address space. */
+	task_id_t taskid;           /**< Unique identity of task */
+
 	/* IPC stuff */
 	answerbox_t answerbox;  /**< Communication endpoint */
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/include/syscall/syscall.h	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -38,4 +38,5 @@
 	SYS_IPC_CALL_ASYNC_FAST,
 	SYS_IPC_CALL_ASYNC,
+	SYS_IPC_ANSWER_FAST,
 	SYS_IPC_ANSWER,
 	SYS_IPC_WAIT,
Index: generic/include/typedefs.h
===================================================================
--- generic/include/typedefs.h	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/include/typedefs.h	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -38,4 +38,6 @@
 typedef unsigned long count_t;
 typedef unsigned long index_t;
+
+typedef unsigned long long task_id_t;
 
 typedef struct config config_t;
Index: generic/src/ipc/ipc.c
===================================================================
--- generic/src/ipc/ipc.c	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/src/ipc/ipc.c	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -62,4 +62,5 @@
 	memsetb((__address)call, sizeof(*call), 0);
 	call->callerbox = &TASK->answerbox;
+	call->sender = TASK;
 
 	return call;
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/src/proc/task.c	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -45,4 +45,5 @@
 SPINLOCK_INITIALIZE(tasks_lock);
 LIST_INITIALIZE(tasks_head);
+static task_id_t task_counter = 0;
 
 /** Initialize tasks
@@ -86,5 +87,8 @@
 	ipl = interrupts_disable();
 	spinlock_lock(&tasks_lock);
+
+	ta->taskid = ++task_counter;
 	list_append(&ta->tasks_link, &tasks_head);
+
 	spinlock_unlock(&tasks_lock);
 	interrupts_restore(ipl);
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision d1e414c63e2033f906d3c12947392b421a0998d6)
+++ generic/src/syscall/syscall.c	(revision 286e03db2e32133734e2e925985747e123632eca)
@@ -98,5 +98,6 @@
 
 /** Synchronous IPC call allowing to send whole message */
-static __native sys_ipc_call_sync(__native phoneid, __native *data)
+static __native sys_ipc_call_sync(__native phoneid, __native *question, 
+				  __native *reply)
 {
 	call_t call;
@@ -109,9 +110,9 @@
 
 	ipc_call_init(&call);
-	copy_from_uspace(&call.data, data, sizeof(call.data));
+	copy_from_uspace(&call.data, question, sizeof(call.data));
 	
 	ipc_call_sync(phone, &call);
 
-	copy_to_uspace(data, &call.data, sizeof(call.data));
+	copy_to_uspace(reply, &call.data, sizeof(call.data));
 
 	return 0;
@@ -185,6 +186,6 @@
 
 /** Send IPC answer */
-static __native sys_ipc_answer(__native callid, __native retval, __native arg1,
-			       __native arg2)
+static __native sys_ipc_answer_fast(__native callid, __native retval, 
+				    __native arg1, __native arg2)
 {
 	call_t *call;
@@ -203,4 +204,19 @@
 }
 
+/** Send IPC answer */
+static __native sys_ipc_answer(__native callid, __native *data)
+{
+	call_t *call;
+
+	/* Check that the user is not sending us answer callid */
+	ASSERT(! (callid & 1));
+	/* TODO: Check that the callid is in the dispatch table */
+	call = (call_t *) callid;
+	copy_from_uspace(&call->data, data, sizeof(call->data));
+	ipc_answer(&TASK->answerbox, call);
+
+	return 0;
+}
+
 /** Wait for incoming ipc call or answer
  *
@@ -209,5 +225,6 @@
  * @return Callid, if callid & 1, then the call is answer
  */
-static __native sys_ipc_wait_for_call(__native *calldata, __native flags)
+static __native sys_ipc_wait_for_call(__native *calldata, task_id_t *taskid,
+				      __native flags)
 {
 	call_t *call;
@@ -223,4 +240,5 @@
 		return ((__native)call) | IPC_CALLID_ANSWERED;
 	}
+	copy_to_uspace(taskid, (void *)&TASK->taskid, sizeof(TASK->taskid));
 	return (__native)call;
 }
@@ -239,4 +257,5 @@
 	sys_ipc_call_async_fast,
 	sys_ipc_call_async,
+	sys_ipc_answer_fast,
 	sys_ipc_answer,
 	sys_ipc_wait_for_call
