Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/lib/c/Makefile	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -145,5 +145,4 @@
 	generic/loader.c \
 	generic/getopt.c \
-	generic/adt/array.c \
 	generic/adt/checksum.c \
 	generic/adt/circ_buf.c \
@@ -192,5 +191,4 @@
 
 TEST_SOURCES = \
-	test/adt/array.c \
 	test/adt/circ_buf.c \
 	test/adt/odict.c \
Index: pace/lib/c/generic/adt/array.c
===================================================================
--- uspace/lib/c/generic/adt/array.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ 	(revision )
@@ -1,192 +1,0 @@
-/*
- * Copyright (c) 2015 Michal Koutny
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- *
- * Implementation of dynamic array that grows or shrinks based upon no. of
- * items it contains. Non-negligible part of implementation is in @ref
- * array.h because of type genericity.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <adt/array.h>
-#include <macros.h>
-#include <mem.h>
-#include <stdlib.h>
-
-static errno_t array_realloc(array_t *da, size_t capacity)
-{
-	if (capacity == da->capacity) {
-		return EOK;
-	}
-
-	void *new_data = realloc(da->_data, da->_item_size * capacity);
-	if (new_data) {
-		da->_data = new_data;
-		da->capacity = capacity;
-	}
-	return (new_data == NULL) ? ENOMEM : EOK;
-}
-
-void array_destroy(array_t *da)
-{
-	array_clear(da);
-	free(da->_data);
-	da->capacity = 0;
-}
-
-/** Remove item at given position, shift rest of array */
-void array_remove(array_t *da, size_t index)
-{
-	assert(index < da->size);
-	_array_unshift(da, index, 1);
-	errno_t rc = array_reserve(da, da->size);
-	assert(rc == EOK);
-}
-
-/** Clear dynamic array (empty) */
-void array_clear(array_t *da)
-{
-	da->size = 0;
-}
-
-/** Clear subsequence of array
- *
- * @param[in/out]  da
- * @param[in]      begin  index of first item to remove
- * @param[in]      end    index behind last item to remove
- */
-void array_clear_range(array_t *da, size_t begin, size_t end)
-{
-	assert(begin < da->size);
-	assert(end <= da->size);
-
-	_array_unshift(da, begin, end - begin);
-	errno_t rc = array_reserve(da, da->size);
-	assert(rc == EOK);
-}
-
-/** Concatenate two arrays
- *
- * @param[in/out]  da1  first array and concatenated output
- * @param[in]      da2  second array, it is untouched
- *
- * @return EOK on success
- * @return ENOMEM when allocation fails
- */
-errno_t array_concat(array_t *da1, array_t *da2)
-{
-	assert(da1->_item_size == da2->_item_size);
-
-	errno_t rc = array_reserve(da1, da1->size + da2->size);
-	if (rc != EOK) {
-		return rc;
-	}
-	void *dst = da1->_data + da1->size * da1->_item_size;
-	void *src = da2->_data;
-	size_t size = da1->_item_size * da2->size;
-	memcpy(dst, src, size);
-	da1->size += da2->size;
-
-	return EOK;
-}
-
-/** Grows/shrinks array so that it effeciently stores desired capacity
- *
- * @param      da
- * @param[in]  desired capacity of array (items)
- *
- * @return EOK
- * @return ENOMEM
- */
-errno_t array_reserve(array_t *da, size_t capacity)
-{
-	const size_t factor = 2;
-	size_t new_capacity;
-	if (capacity > da->capacity) {
-		new_capacity = max(da->capacity * factor, capacity);
-	} else if (capacity < da->capacity / factor) {
-		new_capacity = min(da->capacity / factor, capacity);
-	} else {
-		new_capacity = capacity;
-	}
-
-	return array_realloc(da, new_capacity);
-}
-
-void _array_initialize(array_t *da, size_t item_size)
-{
-	da->_item_size = item_size;
-	da->_data = NULL;
-
-	da->capacity = 0;
-	da->size = 0;
-}
-
-/** Shift block of array
- *
- * Extends size of dynamic array, assumes sufficient capacity.
- *
- * @param      da
- * @param[in]  index   first item shifted
- * @param[in]  offset  shift in no. of items
- */
-void _array_shift(array_t *da, size_t index, size_t offset)
-{
-	assert(da->capacity >= da->size + offset);
-
-	void *src = da->_data + index * da->_item_size;
-	void *dst = da->_data + (index + offset) * da->_item_size;
-	size_t size = (da->size - index) * da->_item_size;
-	memmove(dst, src, size);
-	da->size += offset;
-}
-
-/** Unshift block of array
- *
- * Reduce size of dynamic array
- *
- * @param      da
- * @param[in]  index   first item unshifted (removed)
- * @param[in]  offset  shift in no. of items
- */
-void _array_unshift(array_t *da, size_t index, size_t offset)
-{
-	void *src = da->_data + (index + offset) * da->_item_size;
-	void *dst = da->_data + index * da->_item_size;
-	size_t size = (da->size - index - offset) * da->_item_size;
-	memmove(dst, src, size);
-	da->size -= offset;
-}
-
-/** @}
- */
Index: pace/lib/c/include/adt/array.h
===================================================================
--- uspace/lib/c/include/adt/array.h	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ 	(revision )
@@ -1,147 +1,0 @@
-/*
- * Copyright (c) 2015 Michal Koutny
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ARRAY_H_
-#define LIBC_ARRAY_H_
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-typedef struct {
-	/** Data buffer of array */
-	void *_data;
-	/** Size on bytes of a single item */
-	size_t _item_size;
-
-	/** Allocated space (in items) of the array */
-	size_t capacity;
-	/** No. of items in the array */
-	size_t size;
-} array_t;
-
-/** Initialize dynamic array
- *
- * @param[in]  capacity  initial capacity of array
- *
- * @return void
- */
-#define array_initialize(array, type)                                  \
-	_array_initialize((array), sizeof(type))
-
-/** Dynamic array accessor
- *
- * @return lvalue for the given item
- */
-#define array_at(array, type, index)                                   \
-	(*((type *) (array)->_data + index))
-
-/** Access last element
- *
- * @return lvalue for the last item
- */
-#define array_last(array, type)                                        \
-	(*((type *) (array)->_data + ((array)->size - 1)))
-
-/** Insert item at given position, shift rest of array
- *
- * @return EOK on success
- * @return ENOMEM on failure
- */
-#define array_insert(array, type, index, value)                        \
-({                                                                     \
- 	size_t _index = (index);                                           \
- 	array_t *_da = (array);                                            \
-	errno_t rc = array_reserve(_da, _da->size + 1);                    \
-	if (!rc) {                                                         \
-		_array_shift(_da, _index, 1);                                  \
-	        array_at(_da, type, _index) = (value);                     \
-	}                                                                  \
-	rc;                                                                \
-})
-
-/** Insert item at the end of array
- *
- * @return EOK on success
- * @return ENOMEM on failure
- */
-#define array_append(array, type, value)                               \
-	array_insert(array, type, (array)->size, (value))
-
-/** Dynamic array iteration
- *
- * @param[in]  array   array_t (not pointer)
- * @param[in]  it      name of variable used as iterator, it's pointer
- *                     to @p type
- */
-#define array_foreach(array, type, it)                                 \
-	for (type *it = NULL; it == NULL; it = (type *)1)                  \
-	    for (type *_it = (type *)(array)._data;                        \
-	    it = _it, _it != ((type *)(array)._data + (array).size);       \
-	    ++_it)
-
-/** Find first occurence of value
- *
- * @param[in]  array   array_t *
- * @param[in]  value       value to search for
- *
- * @return  index of found value or size of array when no found
- */
-#define array_find(array, type, value)                                 \
-({                                                                     \
- 	size_t _result = (array)->size;                                    \
-	array_foreach(*(array), type, _it) {                               \
- 		if (*_it == value) {                                           \
-			_result = _it - (type *)(array)->_data;                    \
- 			break;                                                     \
- 		}                                                              \
- 	}                                                                  \
- 	_result;                                                           \
-})
-
-extern void array_destroy(array_t *);
-extern void array_remove(array_t *, size_t);
-void array_clear(array_t *);
-void array_clear_range(array_t *, size_t, size_t);
-extern errno_t array_concat(array_t *, array_t *);
-extern errno_t array_reserve(array_t *, size_t);
-
-extern void _array_initialize(array_t *, size_t);
-extern void _array_shift(array_t *, size_t, size_t);
-extern void _array_unshift(array_t *, size_t, size_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/c/test/adt/array.c
===================================================================
--- uspace/lib/c/test/adt/array.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ 	(revision )
@@ -1,235 +1,0 @@
-/*
- * Copyright (c) 2015 Michal Koutny
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <adt/array.h>
-#include <assert.h>
-#include <pcut/pcut.h>
-
-PCUT_INIT
-
-PCUT_TEST_SUITE(array);
-
-typedef int data_t;
-static array_t da;
-
-PCUT_TEST_BEFORE
-{
-	array_initialize(&da, data_t);
-	errno_t rc = array_reserve(&da, 3);
-	assert(rc == EOK);
-}
-
-PCUT_TEST_AFTER
-{
-	array_destroy(&da);
-}
-
-PCUT_TEST(initialization)
-{
-	PCUT_ASSERT_INT_EQUALS(da.capacity, 3);
-	PCUT_ASSERT_INT_EQUALS(da.size, 0);
-}
-
-PCUT_TEST(append)
-{
-	array_append(&da, data_t, 42);
-	array_append(&da, data_t, 666);
-
-	PCUT_ASSERT_INT_EQUALS(2, da.size);
-	PCUT_ASSERT_INT_EQUALS(42, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(666, array_at(&da, data_t, 1));
-}
-
-PCUT_TEST(assign)
-{
-	array_append(&da, data_t, 42);
-	array_at(&da, data_t, 0) = 112;
-
-	PCUT_ASSERT_INT_EQUALS(112, array_at(&da, data_t, 0));
-}
-
-PCUT_TEST(remove)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-
-	array_remove(&da, 0);
-
-	PCUT_ASSERT_INT_EQUALS(1, da.size);
-	PCUT_ASSERT_INT_EQUALS(11, array_at(&da, data_t, 0));
-}
-
-PCUT_TEST(insert)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-	array_append(&da, data_t, 12);
-	array_insert(&da, data_t, 1, 99);
-
-	PCUT_ASSERT_INT_EQUALS(4, da.size);
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-	PCUT_ASSERT_INT_EQUALS(11, array_at(&da, data_t, 2));
-	PCUT_ASSERT_INT_EQUALS(12, array_at(&da, data_t, 3));
-}
-
-PCUT_TEST(capacity_grow)
-{
-	array_append(&da, data_t, 42);
-	array_append(&da, data_t, 666);
-	array_append(&da, data_t, 42);
-	array_append(&da, data_t, 666);
-
-	PCUT_ASSERT_TRUE(da.capacity > 3);
-}
-
-PCUT_TEST(capacity_shrink)
-{
-	array_append(&da, data_t, 42);
-	array_append(&da, data_t, 666);
-	array_append(&da, data_t, 42);
-
-	array_remove(&da, 0);
-	array_remove(&da, 0);
-	array_remove(&da, 0);
-
-	PCUT_ASSERT_TRUE(da.capacity < 3);
-}
-
-PCUT_TEST(iterator)
-{
-	for (int i = 0; i < 10; ++i) {
-		array_append(&da, data_t, i * i);
-	}
-
-	int i = 0;
-	array_foreach(da, data_t, it) {
-		PCUT_ASSERT_INT_EQUALS(i * i, *it);
-		++i;
-	}
-}
-
-PCUT_TEST(find)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-	array_append(&da, data_t, 12);
-	array_append(&da, data_t, 99);
-
-	PCUT_ASSERT_INT_EQUALS(0, array_find(&da, data_t, 10));
-	PCUT_ASSERT_INT_EQUALS(3, array_find(&da, data_t, 99));
-	PCUT_ASSERT_INT_EQUALS(4, array_find(&da, data_t, 666));
-}
-
-PCUT_TEST(clear_range_middle)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-	array_append(&da, data_t, 12);
-	array_append(&da, data_t, 99);
-
-	array_clear_range(&da, 1, 3);
-	PCUT_ASSERT_INT_EQUALS(2, da.size);
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-}
-
-PCUT_TEST(clear_range_begin)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-	array_append(&da, data_t, 12);
-	array_append(&da, data_t, 99);
-
-	array_clear_range(&da, 0, 2);
-	PCUT_ASSERT_INT_EQUALS(2, da.size);
-	PCUT_ASSERT_INT_EQUALS(12, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-}
-
-PCUT_TEST(clear_range_end)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 11);
-	array_append(&da, data_t, 12);
-	array_append(&da, data_t, 99);
-
-	array_clear_range(&da, 2, 4);
-	PCUT_ASSERT_INT_EQUALS(2, da.size);
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(11, array_at(&da, data_t, 1));
-}
-
-PCUT_TEST(clear_range_empty)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 99);
-
-	array_clear_range(&da, 0, 0);
-	PCUT_ASSERT_INT_EQUALS(2, da.size);
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-}
-
-PCUT_TEST(concat_simple)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 99);
-
-	array_t da2;
-	array_initialize(&da2, data_t);
-	array_append(&da2, data_t, 30);
-	array_append(&da2, data_t, 31);
-
-	array_concat(&da, &da2);
-	PCUT_ASSERT_INT_EQUALS(4, da.size);
-	PCUT_ASSERT_INT_EQUALS(2, da2.size);
-
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-	PCUT_ASSERT_INT_EQUALS(30, array_at(&da, data_t, 2));
-	PCUT_ASSERT_INT_EQUALS(31, array_at(&da, data_t, 3));
-
-	array_destroy(&da2);
-}
-
-PCUT_TEST(concat_self)
-{
-	array_append(&da, data_t, 10);
-	array_append(&da, data_t, 99);
-
-	array_concat(&da, &da);
-	PCUT_ASSERT_INT_EQUALS(4, da.size);
-
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 0));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 1));
-	PCUT_ASSERT_INT_EQUALS(10, array_at(&da, data_t, 2));
-	PCUT_ASSERT_INT_EQUALS(99, array_at(&da, data_t, 3));
-}
-
-PCUT_EXPORT(array);
Index: uspace/lib/c/test/main.c
===================================================================
--- uspace/lib/c/test/main.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/lib/c/test/main.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -32,5 +32,4 @@
 PCUT_INIT;
 
-PCUT_IMPORT(array);
 PCUT_IMPORT(cap);
 PCUT_IMPORT(casting);
Index: uspace/srv/sysman/job.c
===================================================================
--- uspace/srv/sysman/job.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/job.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -70,5 +70,5 @@
 	job->unit = u;
 
-	array_initialize(&job->blocked_jobs, job_t *);
+	list_initialize(&job->blocked_jobs);
 	job->blocking_jobs = 0;
 	job->blocking_job_failed = false;
@@ -120,8 +120,9 @@
 	assert(!link_used(&job->job_queue));
 
-	array_foreach(job->blocked_jobs, job_t *, job_it) {
-		job_del_ref(&(*job_it));
-	}
-	array_destroy(&job->blocked_jobs);
+	while (!list_empty(&job->blocked_jobs)) {
+		job_link_t *job_it = list_pop(&job->blocked_jobs, job_link_t, link);
+		job_del_ref(&job_it->job);
+		free(job_it);
+	}
 
 	free(job);
@@ -256,9 +257,11 @@
 
 	/* First remove references, then clear the array */
-	assert(job->blocked_jobs.size == job->blocked_jobs_count);
-	array_foreach(job->blocked_jobs, job_t *, job_it) {
-		job_unblock(*job_it, job);
-	}
-	array_clear(&job->blocked_jobs);
+	assert(list_count(&job->blocked_jobs) == job->blocked_jobs_count);
+
+	while (!list_empty(&job->blocked_jobs)) {
+		job_link_t *job_it = list_pop(&job->blocked_jobs, job_link_t, link);
+		job_unblock(job_it->job, job);
+		free(job_it);
+	}
 
 	/* Add reference for event handler */
Index: uspace/srv/sysman/job.h
===================================================================
--- uspace/srv/sysman/job.h	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/job.h	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -30,5 +30,4 @@
 #define SYSMAN_JOB_H
 
-#include <adt/array.h>
 #include <adt/list.h>
 #include <stdatomic.h>
@@ -56,4 +55,9 @@
 typedef struct job job_t;
 
+typedef struct {
+	link_t link;
+	job_t *job;
+} job_link_t;
+
 struct job {
 	link_t job_queue;
@@ -64,5 +68,5 @@
 
 	/** Jobs that this job is preventing from running */
-	array_t blocked_jobs;
+	list_t blocked_jobs;
 	/**
 	 * No. of jobs that the job is actually blocking (may differ from size
Index: uspace/srv/sysman/job_closure.c
===================================================================
--- uspace/srv/sysman/job_closure.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/job_closure.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -63,12 +63,16 @@
 static errno_t job_add_blocked_job(job_t *blocking_job, job_t *blocked_job)
 {
-	assert(blocking_job->blocked_jobs.size ==
+	assert(list_count(&blocking_job->blocked_jobs) ==
 	    blocking_job->blocked_jobs_count);
 
-	errno_t rc = array_append(&blocking_job->blocked_jobs, job_t *,
-	    blocked_job);
-	if (rc != EOK) {
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	if (job_link == NULL) {
 		return ENOMEM;
 	}
+
+	job_link->job = blocked_job;
+
+	list_append(&job_link->link, &blocking_job->blocked_jobs);
+
 	job_add_ref(blocked_job);
 
@@ -97,5 +101,8 @@
 			goto finish;
 		}
-		job_t *first_job = array_last(closure, job_t *);
+
+		link_t *last_link = list_last(closure);
+		job_link_t *job_link = list_get_instance(last_link, job_link_t, link);
+		job_t *first_job = job_link->job;
 
 		job_add_ref(first_job);
@@ -118,9 +125,13 @@
 		}
 
+		job_link_t *job_link = calloc(1, sizeof(job_link_t));
+		if (job_link == NULL) {
+			goto finish;
+		}
+
+		job_link->job = created_job;
+
 		/* Pass job reference to closure and add one for unit */
-		rc = array_append(closure, job_t *, created_job);
-		if (rc != EOK) {
-			goto finish;
-		}
+		list_append(&job_link->link, closure);
 
 		job_add_ref(created_job);
@@ -164,9 +175,13 @@
 		}
 
+		job_link_t *job_link = calloc(1, sizeof(job_link_t));
+		if (job_link == NULL) {
+			goto finish;
+		}
+
+		job_link->job = created_job;
+
 		/* Pass job reference to closure and add one for unit */
-		rc = array_append(closure, job_t *, created_job);
-		if (rc != EOK) {
-			goto finish;
-		}
+		list_append(&job_link->link, closure);
 	}
 	rc = visit_propagate_job(u, e, ops, closure);
@@ -308,8 +323,13 @@
 	}
 
-	errno_t rc = array_append(job_closure, job_t *, main_job);
-	if (rc != EOK) {
-		return rc;
-	}
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	if (job_link == NULL) {
+		return ENOMEM;
+	}
+
+	job_link->job = main_job;
+
+	list_append(&job_link->link, job_closure);
+
 	job_add_ref(main_job); /* Add one for the closure */
 
@@ -330,5 +350,5 @@
 	}
 
-	rc = bfs_traverse_component(main_job->unit, &propagate_ops, job_closure);
+	errno_t rc = bfs_traverse_component(main_job->unit, &propagate_ops, job_closure);
 
 	sysman_log(LVL_DEBUG2, "%s: %i&%i", __func__, flags, CLOSURE_ISOLATE);
@@ -343,18 +363,19 @@
 
 	if (rc == EOK) {
-		array_foreach(*job_closure, job_t *, job_it) {
+		list_foreach(*job_closure, link, job_link_t, job_it) {
+			job_t *job = job_it->job;
 			sysman_log(LVL_DEBUG2, "%s\t%s, refs: %u", __func__,
-			    unit_name((*job_it)->unit), atomic_load(&(*job_it)->refcnt));
+			    unit_name(job->unit), atomic_load(&job->refcnt));
 		}
 	}
 
 	/* Clean after ourselves (BFS tag jobs) */
-	array_foreach(*job_closure, job_t *, job_it) {
-		job_t *j = (*job_it)->unit->bfs_data;
-		assert(*job_it == j);
+	list_foreach(*job_closure, link, job_link_t, job_it) {
+		job_t *j = job_it->job->unit->bfs_data;
+		assert(job_it->job == j);
 		job_del_ref(&j);
-		(*job_it)->unit->bfs_data = NULL;
-	}
-
-	return rc;
-}
+		job_it->job->unit->bfs_data = NULL;
+	}
+
+	return rc;
+}
Index: uspace/srv/sysman/job_closure.h
===================================================================
--- uspace/srv/sysman/job_closure.h	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/job_closure.h	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -30,5 +30,5 @@
 #define SYSMAN_JOB_CLOSURE_H
 
-#include <adt/array.h>
+#include <adt/list.h>
 
 #include "job.h"
@@ -36,5 +36,5 @@
 #define CLOSURE_ISOLATE 0x1
 
-typedef array_t job_closure_t;
+typedef list_t job_closure_t;
 
 extern errno_t job_create_closure(job_t *, job_closure_t *, int);
Index: uspace/srv/sysman/job_queue.c
===================================================================
--- uspace/srv/sysman/job_queue.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/job_queue.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -103,29 +103,28 @@
  * @return error code on fail
  */
-static errno_t job_pre_merge(job_t *trunk, job_t *other)
+static void job_pre_merge(job_t *trunk, job_t *other)
 {
 	assert(trunk->unit == other->unit);
 	assert(trunk->target_state == other->target_state);
-	assert(trunk->blocked_jobs.size == trunk->blocked_jobs_count);
+	assert(list_count(&trunk->blocked_jobs) == trunk->blocked_jobs_count);
 	assert(other->merged_into == NULL);
 
-	errno_t rc = array_concat(&trunk->blocked_jobs, &other->blocked_jobs);
-	if (rc != EOK) {
-		return rc;
-	}
-	array_clear(&other->blocked_jobs);
+	list_concat(&trunk->blocked_jobs, &other->blocked_jobs);
+
+	while (!list_empty(&other->blocked_jobs)) {
+		job_link_t *job_link = list_pop(&other->blocked_jobs, job_link_t, link);
+		free(job_link);
+	}
 
 	// TODO allocate observed object
 
 	other->merged_into = trunk;
-
-	return EOK;
 }
 
 static void job_finish_merge(job_t *trunk, job_t *other)
 {
-	assert(trunk->blocked_jobs.size >= trunk->blocked_jobs_count);
+	assert(list_count(&trunk->blocked_jobs) >= trunk->blocked_jobs_count);
 	//TODO aggregate merged blocked_jobs
-	trunk->blocked_jobs_count = other->blocked_jobs.size;
+	trunk->blocked_jobs_count = list_count(&other->blocked_jobs);
 
 	/*
@@ -144,7 +143,13 @@
 static void job_undo_merge(job_t *trunk)
 {
-	assert(trunk->blocked_jobs.size >= trunk->blocked_jobs_count);
-	array_clear_range(&trunk->blocked_jobs,
-	    trunk->blocked_jobs_count, trunk->blocked_jobs.size);
+	unsigned long count = list_count(&trunk->blocked_jobs);
+	assert(count >= trunk->blocked_jobs_count);
+
+	while (count-- > 0) {
+		link_t *last_link = list_last(&trunk->blocked_jobs);
+		job_link_t *job_link = list_get_instance(last_link, job_link_t, link);
+		list_remove(last_link);
+		free(job_link);
+	}
 }
 
@@ -172,6 +177,6 @@
 
 	/* Check consistency with existing jobs. */
-	array_foreach(*closure, job_t *, job_it) {
-		job_t *job = *job_it;
+	list_foreach(*closure, link, job_link_t, job_it) {
+		job_t *job = job_it->job;
 		job_t *other_job = job->unit->job;
 
@@ -205,8 +210,5 @@
 			// TODO think about other options to merging
 			//      (replacing, cancelling)
-			rc = job_pre_merge(other_job, job);
-			if (rc != EOK) {
-				break;
-			}
+			job_pre_merge(other_job, job);
 		}
 	}
@@ -214,12 +216,13 @@
 	/* Aggregate merged jobs, or rollback any changes in existing jobs */
 	bool finish_merge = (rc == EOK) && !has_error;
-	array_foreach(*closure, job_t *, job_it) {
-		if ((*job_it)->merged_into == NULL) {
+	list_foreach(*closure, link, job_link_t, job_it) {
+		job_t *job = job_it->job;
+		if (job->merged_into == NULL) {
 			continue;
 		}
 		if (finish_merge) {
-			job_finish_merge((*job_it)->merged_into, *job_it);
+			job_finish_merge(job->merged_into, job);
 		} else {
-			job_undo_merge((*job_it)->merged_into);
+			job_undo_merge(job->merged_into);
 		}
 	}
@@ -236,6 +239,6 @@
 	 *      in their blocked_jobs array.
 	 */
-	array_foreach(*closure, job_t *, job_it) {
-		job_t *job = (*job_it);
+	list_foreach(*closure, link, job_link_t, job_it) {
+		job_t *job = job_it->job;
 		if (job->merged_into != NULL) {
 			job_del_ref(&job);
@@ -255,5 +258,8 @@
 
 	/* We've stolen references from the closure, so erase it */
-	array_clear(closure);
+	while (!list_empty(closure)) {
+		job_link_t *job_link = list_pop(closure, job_link_t, link);
+		free(job_link);
+	}
 
 	return EOK;
Index: uspace/srv/sysman/sysman.c
===================================================================
--- uspace/srv/sysman/sysman.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/sysman.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -366,6 +366,6 @@
 	job_t *job = job_args->job;
 	int flags = job_args->flags;
-	array_t job_closure;
-	array_initialize(&job_closure, job_t *);
+	list_t job_closure;
+	list_initialize(&job_closure);
 
 	if (job_args->callback != NULL) {
@@ -402,8 +402,9 @@
 	job_del_ref(&job);
 
-	array_foreach(job_closure, job_t *, closure_job) {
-		job_del_ref(&(*closure_job));
-	}
-	array_destroy(&job_closure);
+	while (!list_empty(&job_closure)) {
+		job_link_t *job_link = list_pop(&job_closure, job_link_t, link);
+		job_del_ref(&job_link->job);
+		free(job_link);
+	}
 }
 
Index: uspace/srv/sysman/test/job_closure.c
===================================================================
--- uspace/srv/sysman/test/job_closure.c	(revision a73aaec1377f591ca7758369aabdeb8caf4dfecc)
+++ uspace/srv/sysman/test/job_closure.c	(revision 81c4e6ecbffdcfdb959ea053c3155ebde310d3f0)
@@ -40,6 +40,6 @@
 PCUT_TEST_SUITE(job_closure);
 
-static array_t exp_closure;
-static array_t act_closure;
+static list_t exp_closure;
+static list_t act_closure;
 
 static bool same_job(job_t *expected, job_t *actual)
@@ -49,17 +49,17 @@
 }
 
-static bool same_jobs(array_t *expected, array_t *actual)
-{
-	if (expected->size != actual->size) {
+static bool same_jobs(list_t *expected, list_t *actual)
+{
+	if (list_count(expected) != list_count(actual)) {
 		printf("%s: |expected|, |actual| = %zu, %zu\n",
-		    __func__, expected->size, actual->size);
+		    __func__, list_count(expected), list_count(actual));
 		return false;
 	}
 
 	/* Verify expected \subseteq actual (we've compared sizes) */
-	array_foreach(*expected, job_t *, it_exp) {
+	list_foreach(*expected, link, job_link_t, it_exp) {
 		bool found = false;
-		array_foreach(*actual, job_t *, it_act) {
-			if (same_job(*it_exp, *it_act)) {
+		list_foreach(*actual, link, job_link_t, it_act) {
+			if (same_job(it_exp->job, it_act->job)) {
 				found = true;
 				break;
@@ -68,5 +68,5 @@
 		if (!found) {
 			printf("%s: expected job for %s\n",
-			    __func__, unit_name((*it_exp)->unit));
+			    __func__, unit_name(it_exp->job->unit));
 			return false;
 		}
@@ -79,6 +79,6 @@
 {
 	bool found = false;
-	array_foreach(blocking_job->blocked_jobs, job_t *, it) {
-		if (*it == blocked_job) {
+	list_foreach(blocking_job->blocked_jobs, link, job_link_t, it) {
+		if (it->job == blocked_job) {
 			found = true;
 			break;
@@ -94,15 +94,15 @@
 }
 
-static void dummy_add_closure(array_t *closure)
-{
-	array_foreach(*closure, job_t *, it) {
-		(*it)->unit->job = *it;
-	}
-}
-
-static void destroy_job_closure(array_t *closure)
-{
-	array_foreach(*closure, job_t *, it) {
-		job_del_ref(&(*it));
+static void dummy_add_closure(list_t *closure)
+{
+	list_foreach(*closure, link, job_link_t, it) {
+		it->job->unit->job = it->job;
+	}
+}
+
+static void destroy_job_closure(list_t *closure)
+{
+	list_foreach(*closure, link, job_link_t, it) {
+		job_del_ref(&it->job);
 	}
 }
@@ -113,11 +113,6 @@
 	mock_set_units_state(STATE_STOPPED);
 
-	array_initialize(&exp_closure, job_t *);
-	errno_t rc = array_reserve(&exp_closure, MAX_TYPES * MAX_UNITS);
-	assert(rc == EOK);
-
-	array_initialize(&act_closure, job_t *);
-	rc = array_reserve(&act_closure, MAX_TYPES * MAX_UNITS);
-	assert(rc == EOK);
+	list_initialize(&exp_closure);
+	list_initialize(&act_closure);
 
 	repo_init();
@@ -127,8 +122,14 @@
 {
 	destroy_job_closure(&act_closure);
-	array_destroy(&act_closure);
+	while (!list_empty(&act_closure)) {
+		job_link_t *job_link = list_pop(&act_closure, job_link_t, link);
+		free(job_link);
+	}
 
 	destroy_job_closure(&exp_closure);
-	array_destroy(&exp_closure);
+	while (!list_empty(&exp_closure)) {
+		job_link_t *job_link = list_pop(&exp_closure, job_link_t, link);
+		free(job_link);
+	}
 
 	mock_destroy_units();
@@ -156,7 +157,21 @@
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
-	array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STARTED));
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u1, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u2, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u3, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
 
 	dummy_add_closure(&act_closure);
@@ -188,7 +203,21 @@
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
-	array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STARTED));
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u1, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u2, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u3, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
 
 	dummy_add_closure(&act_closure);
@@ -222,7 +251,21 @@
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
-	array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STARTED));
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u1, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u2, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u3, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
 
 	dummy_add_closure(&act_closure);
@@ -270,11 +313,45 @@
 	PCUT_ASSERT_INT_EQUALS(EOK, rc);
 
-	array_append(&exp_closure, job_t *, dummy_job(u0, STATE_STOPPED));
-	array_append(&exp_closure, job_t *, dummy_job(u1, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u2, STATE_STARTED));
-	array_append(&exp_closure, job_t *, dummy_job(u3, STATE_STOPPED));
-	array_append(&exp_closure, job_t *, dummy_job(u4, STATE_STOPPED));
-	array_append(&exp_closure, job_t *, dummy_job(u5, STATE_STOPPED));
-	array_append(&exp_closure, job_t *, dummy_job(u6, STATE_STOPPED));
+	job_link_t *job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u0, STATE_STOPPED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u1, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u2, STATE_STARTED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u3, STATE_STOPPED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u4, STATE_STOPPED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u5, STATE_STOPPED);
+
+	list_append(&job_link->link, &exp_closure);
+
+	job_link = calloc(1, sizeof(job_link_t));
+	PCUT_ASSERT_NOT_NULL(job_link);
+	job_link->job = dummy_job(u6, STATE_STOPPED);
+
+	list_append(&job_link->link, &exp_closure);
 
 	dummy_add_closure(&act_closure);
