diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index a43056c..f6a5cda 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -325,6 +325,272 @@ static void qdict_flatten_test(void)
     QDECREF(dict3);
 }
 
+static void qdict_unflatten_test(void)
+{
+    QDict *dict;
+    QList *list_a, *list_o;
+    QDict *dict_a1, *dict_d, *dict_df, *dict_dh, *dict_i, *dict_l;
+    const QListEntry *le;
+
+    /*
+     * Test the unflattening of
+     *
+     * {
+     *     "a.0": 0,
+     *     "a.1.b": 1,
+     *     "a.1.c": 2,
+     *     "a.2": 3,
+     *     "d.e": 4,
+     *     "d.f.g": 5,
+     *     "d.h.0": 6,
+     *     "d.h.2": 7,
+     *     "i.0": 8,
+     *     "i.j": 9,
+     *     "k": 10,
+     *     "l": {
+     *         "m": 11
+     *     },
+     *     "l.n": 12,
+     *     "o": [],
+     *     "o.0": 13
+     * }
+     *
+     * to
+     *
+     * {
+     *     "a": [
+     *         0,
+     *         {
+     *             "b": 1,
+     *             "c": 2
+     *         },
+     *         3
+     *     ],
+     *     "d": {
+     *         "e": 4,
+     *         "f": {
+     *             "g": 5
+     *         },
+     *         "h": {
+     *             "0": 6,
+     *             "2": 7
+     *         },
+     *     },
+     *     "i": {
+     *         "0": 8,
+     *         "j": 9
+     *     },
+     *     "k": 10,
+     *     "l": {
+     *         "m": 11,
+     *         "n": 12
+     *     },
+     *     "o": [
+     *         13
+     *     ]
+     * }
+     *
+     * This tests:
+     * - Unflattening in general
+     * - Conversion of "x.0", "x.2" into a dict instead of a list
+     * - Conversion of "x.0", "x.y" into a dict instead of a list
+     * - Merging of previously existing and new unflattened dicts
+     *   ({ "x": { "y": 0 }, "x.z": 1 } => { "x": { "y": 0, "z": 1 } })
+     * - Merging of previously existing and new unflattened lists; only works
+     *   if the previous list was empty
+     *   ({ "x": [], "x.0": 0 } => { "x": [ 0 ] })
+     */
+
+    dict = qdict_new();
+
+    qdict_put(dict, "a.0",   qint_from_int( 0));
+    qdict_put(dict, "a.1.b", qint_from_int( 1));
+    qdict_put(dict, "a.1.c", qint_from_int( 2));
+    qdict_put(dict, "a.2",   qint_from_int( 3));
+    qdict_put(dict, "d.e",   qint_from_int( 4));
+    qdict_put(dict, "d.f.g", qint_from_int( 5));
+    qdict_put(dict, "d.h.0", qint_from_int( 6));
+    qdict_put(dict, "d.h.2", qint_from_int( 7));
+    qdict_put(dict, "i.0",   qint_from_int( 8));
+    qdict_put(dict, "i.j",   qint_from_int( 9));
+    qdict_put(dict, "k",     qint_from_int(10));
+    qdict_put(dict, "l", qdict_new());
+    qdict_put(qdict_get_qdict(dict, "l"), "m", qint_from_int(11));
+    qdict_put(dict, "l.n",   qint_from_int(12));
+    qdict_put(dict, "o", qlist_new());
+    qdict_put(dict, "o.0",   qint_from_int(13));
+
+    qdict_unflatten(dict, &error_abort);
+
+    list_a = qdict_get_qlist(dict, "a");
+    g_assert(list_a);
+
+    /* a.0 */
+    le = qlist_first(list_a);
+    g_assert(le);
+    g_assert(qint_get_int(qobject_to_qint(le->value)) == 0);
+    /* a.1 */
+    le = qlist_next(le);
+    g_assert(le);
+    dict_a1 = qobject_to_qdict(le->value);
+    g_assert(dict_a1);
+    g_assert(qdict_get_int(dict_a1, "b") == 1);
+    g_assert(qdict_get_int(dict_a1, "c") == 2);
+    g_assert(qdict_size(dict_a1) == 2);
+    /* a.2 */
+    le = qlist_next(le);
+    g_assert(le);
+    g_assert(qint_get_int(qobject_to_qint(le->value)) == 3);
+
+    g_assert(!qlist_next(le));
+
+    dict_d = qdict_get_qdict(dict, "d");
+    g_assert(dict_d);
+    g_assert(qdict_get_int(dict_d, "e") == 4);
+
+    dict_df = qdict_get_qdict(dict_d, "f");
+    g_assert(dict_df);
+    g_assert(qdict_get_int(dict_df, "g") == 5);
+    g_assert(qdict_size(dict_df) == 1);
+
+    dict_dh = qdict_get_qdict(dict_d, "h");
+    g_assert(dict_dh);
+    g_assert(qdict_get_int(dict_dh, "0") == 6);
+    g_assert(qdict_get_int(dict_dh, "2") == 7);
+    g_assert(qdict_size(dict_dh) == 2);
+
+    g_assert(qdict_size(dict_d) == 3);
+
+    dict_i = qdict_get_qdict(dict, "i");
+    g_assert(dict_i);
+    g_assert(qdict_get_int(dict_i, "0") == 8);
+    g_assert(qdict_get_int(dict_i, "j") == 9);
+    g_assert(qdict_size(dict_i) == 2);
+
+    g_assert(qdict_get_int(dict, "k") == 10);
+
+    dict_l = qdict_get_qdict(dict, "l");
+    g_assert(dict_l);
+    g_assert(qdict_get_int(dict_l, "m") == 11);
+    g_assert(qdict_get_int(dict_l, "n") == 12);
+    g_assert(qdict_size(dict_l) == 2);
+
+    list_o = qdict_get_qlist(dict, "o");
+    g_assert(list_o);
+
+    /* o.0 */
+    le = qlist_first(list_o);
+    g_assert(le);
+    g_assert(qint_get_int(qobject_to_qint(le->value)) == 13);
+
+    g_assert(!qlist_next(le));
+
+    g_assert(qdict_size(dict) == 6);
+
+    QDECREF(dict);
+
+
+    /*
+     * Test that unflattening
+     *
+     * {
+     *     "a": 0,
+     *     "a.b": 1
+     * }
+     *
+     * fails.
+     *
+     * (Cannot create new QDict "a" because "a" is already a QString)
+     */
+
+    dict = qdict_new();
+
+    qdict_put(dict, "a", qint_from_int(0));
+    qdict_put(dict, "a.b", qint_from_int(1));
+
+    g_assert(!qdict_unflatten(dict, NULL));
+
+    QDECREF(dict);
+
+
+    /*
+     * Test that unflattening
+     *
+     * {
+     *     "a": [
+     *         0
+     *     ],
+     *     "a.0": 1
+     * }
+     *
+     * fails.
+     *
+     * (Cannot replace list member "a.0")
+     */
+
+    dict = qdict_new();
+
+    qdict_put(dict, "a", qlist_new());
+    qlist_append(qdict_get_qlist(dict, "a"), qint_from_int(0));
+    qdict_put(dict, "a.0", qint_from_int(1));
+
+    g_assert(!qdict_unflatten(dict, NULL));
+
+    QDECREF(dict);
+
+
+    /*
+     * Test that unflattening
+     *
+     * {
+     *     "a": {
+     *         "b": 0
+     *     },
+     *     "a.b": 1
+     * }
+     *
+     * fails.
+     *
+     * (Cannot replace existing nested dict member "a.b")
+     */
+
+    dict = qdict_new();
+
+    qdict_put(dict, "a", qdict_new());
+    qdict_put(qdict_get_qdict(dict, "a"), "b", qint_from_int(0));
+    qdict_put(dict, "a.b", qint_from_int(1));
+
+    g_assert(!qdict_unflatten(dict, NULL));
+
+    QDECREF(dict);
+
+
+    /*
+     * Test that unflattening
+     *
+     * {
+     *     "a": {
+     *         "b": 0
+     *     },
+     *     "a.0": 1
+     * }
+     *
+     * fails.
+     *
+     * (Cannot replace existing dict "a" by a list)
+     */
+
+    dict = qdict_new();
+
+    qdict_put(dict, "a", qdict_new());
+    qdict_put(qdict_get_qdict(dict, "a"), "b", qint_from_int(0));
+    qdict_put(dict, "a.0", qint_from_int(1));
+
+    g_assert(!qdict_unflatten(dict, NULL));
+
+    QDECREF(dict);
+}
+
 static void qdict_array_split_test(void)
 {
     QDict *test_dict = qdict_new();
@@ -736,6 +1002,7 @@ int main(int argc, char **argv)
     g_test_add_func("/public/to_qdict", qobject_to_qdict_test);
     g_test_add_func("/public/iterapi", qdict_iterapi_test);
     g_test_add_func("/public/flatten", qdict_flatten_test);
+    g_test_add_func("/public/unflatten", qdict_unflatten_test);
     g_test_add_func("/public/array_split", qdict_array_split_test);
     g_test_add_func("/public/array_entries", qdict_array_entries_test);
     g_test_add_func("/public/join", qdict_join_test);
