             return 1 - i
         return ord(a) - ord(b) or a > b
 
-    set_selected_category: (level, selected, idx) ->
+    cursor : (dir) ->
+        # dir: only 1 or -1!
+        # +1 → downward, higher idx number, first in list
+        # -1 → upwards, lower index, last in list
+        cat0 = @get('cat0')
+        cat1 = @get('cat1')
+        cat2 = @get('cat2')
+        # console.log 'cat0', cat0, 'cat1', cat1, 'cat2', cat2
+        top_or_bottom = (list) ->
+            if dir < 0 then list.length - 1 else 0
+        # dealing with some corner cases first
+        if not cat0?
+            catlist0 = @get_catlist0()
+            if catlist0?.length > 0
+                @set_selected_category(0, top_or_bottom(catlist0))
+        else if not cat1?
+            catlist1 = @get_catlist1()
+            if catlist1?.length > 0
+                @set_selected_category(1, top_or_bottom(catlist1))
+        else if not cat2?
+            catlist2 = @get_catlist2()
+            if catlist2?.length > 0
+                idx = if dir > 0 then 0 else catlist2.length - 1
+                @set_selected_category(2, idx)
+        else # cat0 1 and 2 are defined (i.e. we have a selection)
+            l0 = @get('catlist0').size
+            l1 = @get('catlist1').size
+            l2 = @get('catlist2').size
+            cat2_next = cat2 + dir
+
+            if cat2_next < 0
+                cat1_next = cat1 - 1
+            else if cat2_next >= l2
+                cat2_next = 0
+                cat1_next = cat1 + 1
+
+            if cat1_next < 0
+                cat0_next = cat0 - 1
+            else if cat1_next >= l1
+                cat1_next = 0
+                cat0_next = cat0 + 1
+
+            cat0_next = (cat0_next) % l0
+            if cat0_next < 0
+                cat0_next = l0 - 1
+
+            if cat0_next?
+                @set_selected_category(0, cat0_next)
+            if cat1_next?
+                @set_selected_category(1, cat1_next)
+            @set_selected_category(2, cat2_next)
+
+    set_selected_category: (level, idx) ->
         lang = @data_lang()
         switch level
             when 0, 1
-                @set(code: '', descr: '', cat2 : null)
+                @set(code: '', descr: '', cat2 : null, submittable: false)
         switch level
             when 0
-                catlist1 = lang.get(selected).keySeq().toArray().sort(@cat_sort)
+                @set(cat0: if idx == -1 then @get('catlist0').size - 1 else idx)
+                catlist1 = @get_catlist1()
                 @set
-                    cat0     : selected
                     cat1     : null
                     cat2     : null
                     catlist1 : catlist1
                     catlist2 : []
                 if catlist1.length == 1
-                    @set_selected_category(1, catlist1[0], 0)
+                    @set_selected_category(1, 0)
             when 1
                 cat0     = @get('cat0')
-                catlist2 = lang.getIn([cat0, selected]).map((el) -> el.get(0)).toArray()
+                @set(cat1 : if idx == -1 then @get('catlist1').size - 1 else idx)
+                catlist2 = @get_catlist2()
                 @set
-                    cat1     : selected
                     cat2     : null
                     catlist2 : catlist2
                 if catlist2.length == 1
-                    @set_selected_category(2, catlist2[0], 0)
+                    @set_selected_category(2, 0)
             when 2
-                cat0 = @get('cat0')
-                cat1 = @get('cat1')
-                doc  = lang.getIn([cat0, cat1, idx])
-                @set
-                    cat2  : idx
+                k0 = @get('catlist0').get(@get('cat0'))
+                k1 = @get('catlist1').get(@get('cat1'))
+                idx = if idx == -1 then @get('catlist2').size - 1 else idx
+                doc = lang.getIn([k0, k1, idx])
+                @set(cat2 : idx)
                 @show_doc(doc)
 
 WizardHeader = rclass

        # this is the essential task of the wizard:
        # call the callback with the selected code snippet
        cb
            code  : 'code'
            lang  : @get('lang')
            title : 'title'
            descr : 'description'
    load_data: () ->
        if not DATA?
            require.ensure [], =>


    show_doc: (doc) ->
        @set
            code        : doc.getIn([1, 0])
            descr       : doc.getIn([1, 1])
            submittable : true

    cat_sort: (a, b) =>
        # ordering operator, such that some entries are in front
