Index: generic/include/ipc/ipc.h
===================================================================
--- generic/include/ipc/ipc.h	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/include/ipc/ipc.h	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -123,4 +123,10 @@
 /** Interrupt notification */
 #define IPC_M_INTERRUPT         4
+/** Send as_area over ipc 
+ * - ARG2 - src base address
+ * - ARG3 - size of src as(filled automatically by kernel)
+ * - on answer ARG1 - dst base adress
+ */
+#define IPC_M_AS_SEND           5
 
 
Index: generic/include/mm/as.h
===================================================================
--- generic/include/mm/as.h	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/include/mm/as.h	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -30,4 +30,13 @@
 #define __AS_H__
 
+/** Address space area flags. */
+#define AS_AREA_READ	1
+#define AS_AREA_WRITE	2
+#define AS_AREA_EXEC	4
+#define AS_AREA_DEVICE	8
+
+
+#ifdef KERNEL
+
 #include <mm/as_arg.h>
 #include <arch/mm/page.h>
@@ -54,9 +63,4 @@
 #define FLAG_AS_KERNEL	    (1 << 0)	/**< Kernel address space. */
 
-/** Address space area flags. */
-#define AS_AREA_READ	1
-#define AS_AREA_WRITE	2
-#define AS_AREA_EXEC	4
-#define AS_AREA_DEVICE	8
 
 /** Address space area attributes. */
@@ -130,4 +134,6 @@
 extern void as_switch(as_t *old, as_t *new);
 extern void as_free(as_t *as);
+int as_area_steal(task_t *src_task, __address src_base, size_t acc_size, __address dst_base);
+extern size_t as_get_size(__address base);
 
 /* Interface to be implemented by architectures. */
@@ -140,6 +146,6 @@
 extern __native sys_as_area_resize(__address address, size_t size, int flags);
 extern __native sys_as_area_destroy(__address address);
-extern __native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg);
-extern __native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg);
+
+#endif /* KERNEL */
 
 #endif
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/include/syscall/syscall.h	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -41,6 +41,4 @@
 	SYS_AS_AREA_RESIZE,
 	SYS_AS_AREA_DESTROY,
-	SYS_AS_AREA_ACCEPT,
-	SYS_AS_AREA_SEND,
 	SYS_IPC_CALL_SYNC_FAST,
 	SYS_IPC_CALL_SYNC,
Index: generic/src/ipc/sysipc.c
===================================================================
--- generic/src/ipc/sysipc.c	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/src/ipc/sysipc.c	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -41,4 +41,5 @@
 #include <syscall/copy.h>
 #include <security/cap.h>
+#include <mm/as.h>
 
 #define GET_CHECK_PHONE(phone,phoneid,err) { \
@@ -83,9 +84,11 @@
 	if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO)
 		return 1;
+	if (IPC_GET_METHOD(call->data) == IPC_M_AS_SEND)
+		return 1;
 	return 0;
 }
 
 /** Interpret process answer as control information */
-static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata)
+static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
 	int phoneid;
@@ -106,5 +109,5 @@
 
 	if (!olddata)
-		return;
+		return 0;
 
 	if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
@@ -125,5 +128,12 @@
 					  &TASK->answerbox);
 		}
-	}
+	} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_SEND) {
+		if (!IPC_GET_RETVAL(answer->data)) { /* Accepted, handle As_area receival */
+			return as_area_steal(answer->sender,
+					     IPC_GET_ARG2(*olddata),IPC_GET_ARG3(*olddata),
+					     IPC_GET_ARG1(answer->data));
+		}
+	}
+	return 0;
 }
 
@@ -135,4 +145,5 @@
 {
 	int newphid;
+	size_t size;
 
 	switch (IPC_GET_METHOD(call->data)) {
@@ -146,4 +157,11 @@
 		call->private = newphid;
 		break;
+	case IPC_M_AS_SEND:
+		size = as_get_size(IPC_GET_ARG2(call->data));
+		if (!size) {
+			return EPERM;
+		}
+		IPC_SET_ARG3(call->data, size);
+		break;
 	default:
 		break;
@@ -377,4 +395,5 @@
 	ipc_data_t saved_data;
 	int saveddata = 0;
+	int rc;
 
 	call = get_call(callid);
@@ -390,8 +409,8 @@
 	IPC_SET_ARG1(call->data, arg1);
 	IPC_SET_ARG2(call->data, arg2);
-	answer_preprocess(call, saveddata ? &saved_data : NULL);
+	rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
 
 	ipc_answer(&TASK->answerbox, call);
-	return 0;
+	return rc;
 }
 
@@ -417,9 +436,9 @@
 		return rc;
 
-	answer_preprocess(call, saveddata ? &saved_data : NULL);
+	rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
 	
 	ipc_answer(&TASK->answerbox, call);
 
-	return 0;
+	return rc;
 }
 
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/src/mm/as.c	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -365,16 +365,16 @@
 }
 
-/** Send address space area to another task.
- *
- * Address space area is sent to the specified task.
- * If the destination task is willing to accept the
- * area, a new area is created according to the
- * source area. Moreover, any existing mapping
+/** Steal address space area from another task.
+ *
+ * Address space area is stolen from another task
+ * Moreover, any existing mapping
  * is copied as well, providing thus a mechanism
  * for sharing group of pages. The source address
  * space area and any associated mapping is preserved.
  *
- * @param dst_id Task ID of the accepting task.
+ * @param src_task Pointer of source task
  * @param src_base Base address of the source address space area.
+ * @param acc_size Expected size of the source area
+ * @param dst_base Target base address
  *
  * @return Zero on success or ENOENT if there is no such task or
@@ -384,49 +384,26 @@
  *	   address space area.
  */
-int as_area_send(task_id_t dst_id, __address src_base)
+int as_area_steal(task_t *src_task, __address src_base, size_t acc_size,
+		  __address dst_base)
 {
 	ipl_t ipl;
-	task_t *t;
 	count_t i;
-	as_t *dst_as;
-	__address dst_base;
+	as_t *src_as;       
 	int src_flags;
 	size_t src_size;
 	as_area_t *src_area, *dst_area;
-	
+
 	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	
-	t = task_find_by_id(dst_id);
-	if (!NULL) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
-		return ENOENT;
-	}
-
-	spinlock_lock(&t->lock);
-	spinlock_unlock(&tasks_lock);
-
-	dst_as = t->as;
-	dst_base = (__address) t->accept_arg.base;
-	
-	if (dst_as == AS) {
-		/*
-		 * The two tasks share the entire address space.
-		 * Return error since there is no point in continuing.
-		 */
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
-		return EPERM;
-	}
-	
-	spinlock_lock(&AS->lock);
-	src_area = find_area_and_lock(AS, src_base);
+	spinlock_lock(&src_task->lock);
+	src_as = src_task->as;
+	
+	spinlock_lock(&src_as->lock);
+	src_area = find_area_and_lock(src_as, src_base);
 	if (!src_area) {
 		/*
 		 * Could not find the source address space area.
 		 */
-		spinlock_unlock(&t->lock);
-		spinlock_unlock(&AS->lock);
+		spinlock_unlock(&src_task->lock);
+		spinlock_unlock(&src_as->lock);
 		interrupts_restore(ipl);
 		return ENOENT;
@@ -435,16 +412,12 @@
 	src_flags = src_area->flags;
 	spinlock_unlock(&src_area->lock);
-	spinlock_unlock(&AS->lock);
-
-	if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != src_size) ||
-	    (t->accept_arg.flags != src_flags)) {
-		/*
-		 * Discrepancy in either task ID, size or flags.
-		 */
-		spinlock_unlock(&t->lock);
+	spinlock_unlock(&src_as->lock);
+
+
+	if (src_size != acc_size) {
+		spinlock_unlock(&src_task->lock);
 		interrupts_restore(ipl);
 		return EPERM;
 	}
-	
 	/*
 	 * Create copy of the source address space area.
@@ -453,26 +426,25 @@
 	 * preliminary as_page_fault() calls.
 	 */
-	dst_area = as_area_create(dst_as, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL);
+	dst_area = as_area_create(AS, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL);
 	if (!dst_area) {
 		/*
 		 * Destination address space area could not be created.
 		 */
-		spinlock_unlock(&t->lock);
+		spinlock_unlock(&src_task->lock);
 		interrupts_restore(ipl);
 		return ENOMEM;
 	}
 	
-	memsetb((__address) &t->accept_arg, sizeof(as_area_acptsnd_arg_t), 0);
-	spinlock_unlock(&t->lock);
+	spinlock_unlock(&src_task->lock);
 	
 	/*
 	 * Avoid deadlock by first locking the address space with lower address.
 	 */
-	if (dst_as < AS) {
-		spinlock_lock(&dst_as->lock);
+	if (AS < src_as) {
 		spinlock_lock(&AS->lock);
+		spinlock_lock(&src_as->lock);
 	} else {
 		spinlock_lock(&AS->lock);
-		spinlock_lock(&dst_as->lock);
+		spinlock_lock(&src_as->lock);
 	}
 	
@@ -481,6 +453,6 @@
 		__address frame;
 			
-		page_table_lock(AS, false);
-		pte = page_mapping_find(AS, src_base + i*PAGE_SIZE);
+		page_table_lock(src_as, false);
+		pte = page_mapping_find(src_as, src_base + i*PAGE_SIZE);
 		if (pte && PTE_VALID(pte)) {
 			ASSERT(PTE_PRESENT(pte));
@@ -488,13 +460,13 @@
 			if (!(src_flags & AS_AREA_DEVICE))
 				frame_reference_add(ADDR2PFN(frame));
-			page_table_unlock(AS, false);
+			page_table_unlock(src_as, false);
 		} else {
-			page_table_unlock(AS, false);
+			page_table_unlock(src_as, false);
 			continue;
 		}
 		
-		page_table_lock(dst_as, false);
-		page_mapping_insert(dst_as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags));
-		page_table_unlock(dst_as, false);
+		page_table_lock(AS, false);
+		page_mapping_insert(AS, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags));
+		page_table_unlock(AS, false);
 	}
 
@@ -509,5 +481,5 @@
 	
 	spinlock_unlock(&AS->lock);
-	spinlock_unlock(&dst_as->lock);
+	spinlock_unlock(&src_as->lock);
 	interrupts_restore(ipl);
 	
@@ -946,4 +918,23 @@
 }
 
+/** Return size of address space of current task pointed to by base */
+size_t as_get_size(__address base)
+{
+	ipl_t ipl;
+	as_area_t *src_area;
+	size_t size;
+
+	ipl = interrupts_disable();
+	src_area = find_area_and_lock(AS, base);
+	if (src_area){
+		size = src_area->pages * PAGE_SIZE;
+		spinlock_unlock(&src_area->lock);
+	} else {
+		size = 0;
+	}
+	interrupts_restore(ipl);
+	return size;
+}
+
 /*
  * Address space related syscalls.
@@ -971,55 +962,2 @@
 }
 
-/** Prepare task for accepting address space area from another task.
- *
- * @param uspace_accept_arg Accept structure passed from userspace.
- *
- * @return EPERM if the task ID encapsulated in @uspace_accept_arg references
- *	   TASK. Otherwise zero is returned.
- */
-__native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg)
-{
-	as_area_acptsnd_arg_t arg;
-	int rc;
-	
-	rc = copy_from_uspace(&arg, uspace_accept_arg, sizeof(as_area_acptsnd_arg_t));
-	if (rc != 0)
-		return rc;
-	
-	if (!arg.size)
-		return (__native) EPERM;
-	
-	if (arg.task_id == TASK->taskid) {
-		/*
-		 * Accepting from itself is not allowed.
-		 */
-		return (__native) EPERM;
-	}
-	
-	memcpy(&TASK->accept_arg, &arg, sizeof(as_area_acptsnd_arg_t));
-	
-        return 0;
-}
-
-/** Wrapper for as_area_send. */
-__native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg)
-{
-	as_area_acptsnd_arg_t arg;
-	int rc;
-	
-	rc = copy_from_uspace(&arg, uspace_send_arg, sizeof(as_area_acptsnd_arg_t));
-	if (rc != 0)
-		return rc;
-
-	if (!arg.size)
-		return (__native) EPERM;
-	
-	if (arg.task_id == TASK->taskid) {
-		/*
-		 * Sending to itself is not allowed.
-		 */
-		return (__native) EPERM;
-	}
-
-	return (__native) as_area_send(arg.task_id, (__address) arg.base);
-}
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision b1b723ef197f2004f5da6d7c8f3e77a5d52e8b94)
+++ generic/src/syscall/syscall.c	(revision 7c23af9e20bd84c4a0b29ce3856deb6c8d86aaf5)
@@ -87,6 +87,4 @@
 	sys_as_area_resize,
 	sys_as_area_destroy,
-	sys_as_area_accept,
-	sys_as_area_send,
 
 	/* IPC related syscalls. */
