Index: uspace/srv/sysman/sysman.c
===================================================================
--- uspace/srv/sysman/sysman.c	(revision 73f7c4e70ea71349b3dc64f0afc8610f6c5ab828)
+++ uspace/srv/sysman/sysman.c	(revision 72c8f77fe49645071c65e51c20256117bc69eb5c)
@@ -69,5 +69,7 @@
 static fibril_condvar_t observed_objects_cv;
 
-/* Hash table functions */
+/*
+ * Hash table functions
+ */
 static size_t observed_objects_ht_hash(const ht_link_t *item)
 {
@@ -100,4 +102,32 @@
 };
 
+/*
+ * Static functions
+ */
+
+static observed_object_t *observed_object_create(void *object)
+{
+	observed_object_t *result = malloc(sizeof(observed_object_t));
+	if (result) {
+		result->object = object;
+		list_initialize(&result->callbacks);
+		hash_table_insert(&observed_objects, &result->ht_link);
+	}
+	return result;
+}
+
+static void observed_object_destroy(observed_object_t **ptr_observed_object)
+{
+	observed_object_t *observed_object = *ptr_observed_object;
+	if (observed_object == NULL) {
+		return;
+	}
+
+	ht_link_t *item = &observed_object->ht_link;
+	hash_table_remove_item(&observed_objects, item);
+	free(observed_object);
+	*ptr_observed_object = NULL;
+}
+
 static void notify_observers(void *object)
 {
@@ -116,4 +146,6 @@
 		free(callback);
 	}
+
+	observed_object_destroy(&observed_object);
 }
 
@@ -174,20 +206,7 @@
     callback_handler_t callback, void *callback_arg)
 {
-	job_t *job;
-
-	if (unit->job != NULL) {
-		assert(unit->job->state != JOB_UNQUEUED);
-
-		if (unit->job->target_state != target_state) {
-			return EBUSY;
-		}
-		job = unit->job;
-	} else {
-		job = job_create(unit, target_state);
-		if (job == NULL) {
-			return ENOMEM;
-		}
-		/* Reference in unit is enough */
-		job_del_ref(&job);
+	job_t *job = job_create(unit, target_state);
+	if (job == NULL) {
+		return ENOMEM;
 	}
 
@@ -197,8 +216,6 @@
 	}
 
-	if (job->state == JOB_UNQUEUED) {
-		job_add_ref(job);
-		sysman_raise_event(&sysman_event_job_process, job);
-	}
+	/* Pass reference to event */
+	sysman_raise_event(&sysman_event_job_process, job);
 
 	return EOK;
@@ -242,5 +259,7 @@
  *
  * TODO no one handles return value, it's quite fatal to lack memory for
- *      callbacks...  @return EOK on success
+ *      callbacks...
+ *
+ * @return EOK on success
  * @return ENOMEM
  */
@@ -253,14 +272,10 @@
 
 	if (ht_link == NULL) {
-		observed_object = malloc(sizeof(observed_object_t));
-		if (observed_object == NULL) {
+		new_observed_object = observed_object_create(object);
+		if (new_observed_object == NULL) {
 			rc = ENOMEM;
 			goto fail;
 		}
-		new_observed_object = observed_object;
-
-		observed_object->object = object;
-		list_initialize(&observed_object->callbacks);
-		hash_table_insert(&observed_objects, &observed_object->ht_link);
+		observed_object = new_observed_object;
 	} else {
 		observed_object =
@@ -284,4 +299,34 @@
 }
 
+int sysman_move_observers(void *src_object, void *dst_object)
+{
+	ht_link_t *src_link = hash_table_find(&observed_objects, &src_object);
+	if (src_link == NULL) {
+		return EOK;
+	}
+
+	ht_link_t *dst_link = hash_table_find(&observed_objects, &dst_object);
+	observed_object_t *dst_observed_object;
+	if (dst_link == NULL) {
+		dst_observed_object = observed_object_create(dst_object);
+		if (dst_observed_object == NULL) {
+			return ENOMEM;
+		}
+	} else {
+		dst_observed_object =
+		    hash_table_get_inst(dst_link, observed_object_t, ht_link);
+	}
+
+	observed_object_t *src_observed_object =
+	    hash_table_get_inst(src_link, observed_object_t, ht_link);
+
+	list_concat(&dst_observed_object->callbacks,
+	    &src_observed_object->callbacks);
+	observed_object_destroy(&src_observed_object);
+
+	return EOK;
+}
+
+
 /*
  * Event handlers
@@ -293,5 +338,5 @@
 	job_t *job = data;
 	dyn_array_t job_closure;
-	dyn_array_initialize(&job_closure, job_ptr_t);
+	dyn_array_initialize(&job_closure, job_t *);
 
 	int rc = job_create_closure(job, &job_closure);
@@ -306,5 +351,5 @@
 	 * otherwise, we still have the reference.
 	 */
-	rc = job_queue_add_jobs(&job_closure);
+	rc = job_queue_add_closure(&job_closure);
 	if (rc != EOK) {
 		goto fail;
@@ -321,5 +366,5 @@
 	job_del_ref(&job);
 
-	dyn_array_foreach(job_closure, job_ptr_t, closure_job) {
+	dyn_array_foreach(job_closure, job_t *, closure_job) {
 		job_del_ref(&(*closure_job));
 	}
