diff --git a/lib/exe/js.php b/lib/exe/js.php
index 308c1b5347a1c138f4cd651ca0e0541b33922ea1..44ab2d5ca5d0600a7d991b412f4719d4a1590791 100644
--- a/lib/exe/js.php
+++ b/lib/exe/js.php
@@ -50,6 +50,7 @@ function js_out(){
                 DOKU_INC.'lib/scripts/script.js',
                 DOKU_INC.'lib/scripts/tw-sack.js',
                 DOKU_INC.'lib/scripts/qsearch.js',
+                DOKU_INC.'lib/scripts/tree.js',
                 DOKU_INC.'lib/scripts/index.js',
                 DOKU_INC.'lib/scripts/drag.js',
                 DOKU_INC.'lib/scripts/textselection.js',
diff --git a/lib/scripts/behaviour.js b/lib/scripts/behaviour.js
index db9dbacc2bb5b01556a4a84851bab4148311cd6d..dd76764326b99cab0cf92ddf298041cb49aff8bd 100644
--- a/lib/scripts/behaviour.js
+++ b/lib/scripts/behaviour.js
@@ -124,4 +124,22 @@ var dw_behaviour = {
 
 };
 
+jQuery.fn.dw_hide = function(fn) {
+    return this.slideUp('fast', fn);
+};
+
+jQuery.fn.dw_show = function() {
+    return this.slideDown('fast');
+};
+
+jQuery.fn.dw_toggle = function(bool) {
+    return this.each(function() {
+        var $this = jQuery(this);
+        if (typeof bool === 'undefined') {
+            bool = $this.is(':hidden');
+        }
+        $this[bool ? "dw_show" : "dw_hide" ]();
+    });
+};
+
 jQuery(dw_behaviour.init);
diff --git a/lib/scripts/compatibility.js b/lib/scripts/compatibility.js
index e9d845625d0c2a024a9d99a4776601154cbe9dff..27347972a7a6524465e2bf1240b616159b0e9dc1 100644
--- a/lib/scripts/compatibility.js
+++ b/lib/scripts/compatibility.js
@@ -29,6 +29,58 @@ var linkwiz = {
     toggle: DEPRECATED_WRAP(dw_linkwiz.toggle, dw_linkwiz)
 };
 
+var media_manager = {
+    // treeattach, selectorattach, confirmattach are munched together into
+    // dw_mediamanager.init
+    attachoptions: DEPRECATED_WRAP(dw_mediamanager.attachoptions, dw_mediamanager),
+    togglekeepopen: function (event, cb) {
+        DEPRECATED('Use dw_mediamanager.toggleOption instead');
+        return dw_mediamanager.toggleOption.call(cb, 'keepopen');
+    },
+    togglehide: function (event, cb) {
+        DEPRECATED('Use dw_mediamanager.toggleOption instead');
+        return dw_mediamanager.toggleOption.call(cb, 'hide');
+    },
+    updatehide: DEPRECATED_WRAP(dw_mediamanager.updatehide, dw_mediamanager),
+    select: function (event, link) {
+        DEPRECATED('Use dw_mediamanager.select instead');
+        return dw_mediamanager.select.call(link, event);
+    },
+    initpopup: DEPRECATED_WRAP(dw_mediamanager.initpopup, dw_mediamanager),
+    insert: DEPRECATED_WRAP(dw_mediamanager.insert, dw_mediamanager),
+    list: function (event, link) {
+        DEPRECATED('Use dw_mediamanager.list instead');
+        return dw_mediamanager.list.call(link, event);
+    },
+    // toggle is handled by dw_tree
+    suggest: DEPRECATED_WRAP(dw_mediamanager.suggest, dw_mediamanager),
+    initFlashUpload: DEPRECATED_WRAP(dw_mediamanager.initFlashUpload, dw_mediamanager),
+    closePopup: function () {
+        DEPRECATED();
+        dw_mediamanager.$popup.dialog('close');
+    },
+    setalign: function (event, cb) {
+        DEPRECATED('Use dw_mediamanager.setOpt instead');
+        return dw_mediamanager.setOpt.call(this, 'align', event);
+    },
+    setlink: function (event, cb) {
+        DEPRECATED('Use dw_mediamanager.setOpt instead');
+        return dw_mediamanager.setOpt.call(this, 'link', event);
+    },
+    setsize: function (event, cb) {
+        DEPRECATED('Use dw_mediamanager.setOpt instead');
+        return dw_mediamanager.setOpt.call(this, 'size', event);
+    },
+    outSet: function (id) {
+        DEPRECATED();
+        return jQuery(id).removeClass('selected');
+    },
+    inSet: function (id) {
+        DEPRECATED();
+        return jQuery(id).addClass('selected');
+    }
+};
+
 initSizeCtl = DEPRECATED_WRAP(dw_editor.initSizeCtl);
 sizeCtl = DEPRECATED_WRAP(dw_editor.sizeCtl);
 toggleWrap = DEPRECATED_WRAP(dw_editor.toggleWrap);
diff --git a/lib/scripts/events.js b/lib/scripts/events.js
index 95564be39c7b79b6abb6cd3f6baf7231fb56715d..796d3cc4c556cc06415e7c86df557e32c8652f82 100644
--- a/lib/scripts/events.js
+++ b/lib/scripts/events.js
@@ -32,9 +32,19 @@ function addInitEvent(func) {
  * @param   mixed - any arguments to be passed to the function
  * @returns functionref
  */
-function bind (fnc) {
-    var args = Array.prototype.slice.call(arguments, 1);
-    return function() {
-        return fnc.apply(this, args);
+function bind(fnc/*, ... */) {
+    var Aps = Array.prototype.slice;
+    // Store passed arguments in this scope.
+    // Since arguments is no Array nor has an own slice method,
+    // we have to apply the slice method from the Array.prototype
+    var static_args = Aps.call(arguments, 1);
+
+    // Return a function evaluating the passed function with the
+    // given args and optional arguments passed on invocation.
+    return function (/* ... */) {
+        // Same here, but we use Array.prototype.slice solely for
+        // converting arguments to an Array.
+        return fnc.apply(this,
+                         static_args.concat(Aps.call(arguments, 0)));
     };
 }
diff --git a/lib/scripts/index.js b/lib/scripts/index.js
index c575ab6187cf8a5184a5b01969516d11a6cdb428..96d4e2fb97e10eba907839cb5e71a8df409b839b 100644
--- a/lib/scripts/index.js
+++ b/lib/scripts/index.js
@@ -1,97 +1,19 @@
 /*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, newcap: true, immed: true */
 /*global jQuery, window, DOKU_BASE, DEPRECATED, bind*/
 
-/**
- * Javascript for index view
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- * @author Pierre Spring <pierre.spring@caillou.ch>
- */
-
-var dw_index = {
-
-    /**
-     * Delay in ms before showing the throbber.
-     * Used to skip the throbber for fast AJAX calls.
-     */
-    throbber_delay: 500,
-
-    /**
-     * Initialize tree when the DOM is ready.
-     */
-    init: function () {
-        dw_index.treeattach('#index__tree');
-    },
-
-    treeattach: function (obj) {
-        jQuery(obj).delegate('a.idx_dir', 'click', dw_index.toggle);
-    },
-
-    /**
-     * Open or close a subtree using AJAX
-     * The contents of subtrees are "cached" until the page is reloaded.
-     * A "loading" indicator is shown only when the AJAX call is slow.
-     *
-     * @author Andreas Gohr <andi@splitbrain.org>
-     * @author Ben Coburn <btcoburn@silicodon.net>
-     * @author Pierre Spring <pierre.spring@caillou.ch>
-     */
-    toggle: function (e, _this) {
-        e.preventDefault();
-
-        var $listitem, $sublist, timeout, $clicky, show_sublist;
-
-        if (_this) {
-            DEPRECATED('Use dw_index.toggle(e) (or dw_index.toggle.call(clicky, e) if you need to override clicky), not dw_index.toggle(e, clicky)');
-        }
-
-        $clicky = jQuery(_this || this);
-        $listitem = $clicky.closest('li');
-        $sublist = $listitem.find('ul').first();
-
-        // if already open, close by removing the sublist
-        if ($listitem.hasClass('open')) {
-            $sublist.slideUp('fast',
-                function () {
-                    $listitem.addClass('closed').removeClass('open');
-                }
-            );
-            return;
-        }
-
-        show_sublist = function (data) {
-            if (!$listitem.hasClass('open') || $sublist.parent().length === 0) {
-                $listitem.append($sublist).addClass('open').removeClass('closed');
-            }
-            $sublist.hide();
-            if (data) {
-                $sublist.html(data);
-            }
-            $sublist.slideDown('fast');
-        };
-
-        // just show if already loaded
-        if ($sublist.length > 0) {
-            show_sublist();
-            return;
-        }
-
-        //prepare the new ul
-        $sublist = jQuery('<ul class="idx"/>');
-
-        timeout = window.setTimeout(
-            bind(show_sublist, '<li><img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="loading..." title="loading..." /></li>'), dw_index.throbber_delay);
-
+var dw_index = jQuery('#index__tree').dw_tree({deferInit: true,
+    load_data: function  (show_sublist, $clicky) {
         jQuery.post(
             DOKU_BASE + 'lib/exe/ajax.php',
             $clicky[0].search.substr(1) + '&call=index',
-            function (data) {
-                window.clearTimeout(timeout);
-                show_sublist(data);
-            },
-            'html'
+            show_sublist, 'html'
         );
     }
-};
+});
+jQuery(function () {
+    var $tree = jQuery('#index__tree');
+
+    dw_index.$obj = $tree;
 
-jQuery(dw_index.init);
+    dw_index.init();
+});
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
index ebbee5a78945354d09497098b1917caa9a03bebe..f7e78c74714411dd8641c86fcb88c4f5dca50e15 100644
--- a/lib/scripts/media.js
+++ b/lib/scripts/media.js
@@ -1,8 +1,5 @@
-/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, strict: true, newcap: true, immed: true */
-/*global jQuery, window, DOKU_BASE*/
-"use strict";
-
-// * refactor once the jQuery port is over ;)
+/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, strict: true, newcap: true, immed: true, sloppy: true, browser: true */
+/*global jQuery, DOKU_BASE, LANG, bind, DokuCookie, opener, confirm*/
 
 /**
  * JavaScript functionality for the media management popup
@@ -10,172 +7,127 @@
  * @author Andreas Gohr <andi@splitbrain.org>
  * @author Pierre Spring <pierre.spring@caillou.ch>
  */
-(function ($) {
-    var toggle, list, prepare_content, insert, confirmattach, attachoptions, initpopup, updatehide, setalign, setsize, inSet, outSet, media_manager, hasFlash;
-
-    var media_manager = {
-        keepopen: false,
-        hide: false,
-        align: false,
-        popup: false,
-        display: false,
-        link: false,
-        size: false,
-        ext: false,
-    };
-
-
-
-
-    /**
-     * build the popup window
-     *
-     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
-     */
-    initpopup = function() {
-        var popup;
-
-        popup = document.createElement('div');
-        popup.setAttribute('id','media__popup');
-        popup.style.display = "none";
-
-        var root = document.getElementById('media__manager');
-        if (root === null) return;
-        root.appendChild(popup);
-
-        var headline    = document.createElement('h1');
-        headline.innerHTML = LANG.mediatitle;
-        var headlineimg = document.createElement('img');
-        headlineimg.src = DOKU_BASE + 'lib/images/close.png';
-        headlineimg.id  = 'media__closeimg';
-        $(headlineimg).click(function () {$(popup).hide()});
-        headline.insertBefore(headlineimg, headline.firstChild);
-        popup.appendChild(headline);
-        $(popup).draggable({handle: headline});
-
-        // link
-        var linkp = document.createElement('p');
-
-        linkp.id = "media__linkstyle";
-        if (media_manager.display == "2") {
-            linkp.style.display = "none";
-        }
-
-        var linkl = document.createElement('label');
-        linkl.innerHTML = LANG.mediatarget;
-        linkp.appendChild(linkl);
-
-        var linkbtns = ['lnk', 'direct', 'nolnk', 'displaylnk'];
-        for (var i = 0 ; i < linkbtns.length ; ++i) {
-            var linkbtn = document.createElement('button');
-            linkbtn.className = 'button';
-            linkbtn.id    = "media__linkbtn" + (i+1);
-            linkbtn.title = LANG['media' + linkbtns[i]];
-            linkbtn.style.borderStyle = 'outset';
-            $(linkbtn).click(function (event) { return setlink(event,this); });
-
-            var linkimg = document.createElement('img');
-            linkimg.src = DOKU_BASE + 'lib/images/media_link_' + linkbtns[i] + '.png';
 
-            linkbtn.appendChild(linkimg);
-            linkp.appendChild(linkbtn);
-        }
-
-        popup.appendChild(linkp);
-
-        // align
+var dw_mediamanager = {
+    keepopen: false,
+    hide: false,
+    popup: false,
+    display: false,
+    ext: false,
+    $popup: null,
 
-        var alignp    = document.createElement('p');
-        var alignl    = document.createElement('label');
+    // Image insertion opts
+    align: false,
+    link: false,
+    size: false,
+    forbidden_opts: {},
 
-        alignp.appendChild(alignl);
-        alignp.id = 'media__align';
-        if (media_manager.display == "2") {
-            alignp.style.display = "none";
-        }
-        alignl.innerHTML = LANG['mediaalign'];
-
-        var alignbtns = ['noalign', 'left', 'center', 'right'];
-        for (var n = 0 ; n < alignbtns.length ; ++n) {
-            var alignbtn = document.createElement('button');
-            var alignimg = document.createElement('img');
-            alignimg.src = DOKU_BASE + 'lib/images/media_align_' + alignbtns[n] + '.png';
-
-            alignbtn.id    = "media__alignbtn" + (n+1);
-            alignbtn.title = LANG['media' + alignbtns[n]];
-            alignbtn.className = 'button';
-            alignbtn.appendChild(alignimg);
-            alignbtn.style.borderStyle = 'outset';
-            $(alignbtn).click(function (event) { return setalign(event,this); });
-
-            alignp.appendChild(alignbtn);
-        }
+    init: function () {
+        var $content, $tree;
+        $content = jQuery('#media__content');
+        $tree    = jQuery('#media__tree');
 
-        popup.appendChild(alignp);
+        dw_mediamanager.prepare_content($content);
 
-        // size
+        dw_mediamanager.attachoptions();
+        dw_mediamanager.initpopup();
 
-        var sizep    = document.createElement('p');
-        var sizel    = document.createElement('label');
-
-        sizep.id = 'media__size';
-        if (media_manager.display == "2") {
-            sizep.style.display = "none";
-        }
-        sizep.appendChild(sizel);
-        sizel.innerHTML = LANG['mediasize'];
-
-        var sizebtns = ['small', 'medium', 'large', 'original'];
-        for (var size = 0 ; size < sizebtns.length ; ++size) {
-            var sizebtn = document.createElement('button');
-            var sizeimg = document.createElement('img');
-
-            sizep.appendChild(sizebtn);
-            sizeimg.src = DOKU_BASE + 'lib/images/media_size_' + sizebtns[size] + '.png';
-
-            sizebtn.className = 'button';
-            sizebtn.appendChild(sizeimg);
-            sizebtn.id    = 'media__sizebtn' + (size + 1);
-            sizebtn.title = LANG['media' + sizebtns[size]];
-            sizebtn.style.borderStyle = 'outset';
-            $(sizebtn).click(function (event) { return setsize(event,this); });
-        }
-
-        popup.appendChild(sizep);
-
-        // send and close button
-
-        var btnp = document.createElement('p');
-        popup.appendChild(btnp);
-        btnp.setAttribute('class','btnlbl');
-
-        var btn  = document.createElement('input');
-        btn.type = 'button';
-        btn.id   = 'media__sendbtn';
-        btn.setAttribute('class','button');
-        btn.value = LANG['mediainsert'];
-        btnp.appendChild(btn);
-    };
+        // add the action to autofill the "upload as" field
+        $content.delegate('#upload__file', 'change', dw_mediamanager.suggest)
+                // Attach the image selector action to all links
+                .delegate('a.select', 'click', dw_mediamanager.select)
+                // Attach deletion confirmation dialog to the delete buttons
+                .delegate('#media__content a.btn_media_delete', 'click',
+                          dw_mediamanager.confirmattach);
+
+        $tree.dw_tree({toggle_selector: 'img',
+                       load_data: function (show_sublist, $clicky) {
+                           // get the enclosed link (is always the first one)
+                           var $link = $clicky.siblings('a').first();
+
+                           jQuery.post(
+                               DOKU_BASE + 'lib/exe/ajax.php',
+                               $link[0].search.substr(1) + '&call=medians',
+                               show_sublist,
+                               'html'
+                           );
+
+                           $clicky.attr('src', DOKU_BASE + 'lib/images/minus.gif');
+                       },
+
+                       close: function ($clicky) {
+                           $clicky.attr('src',
+                                        DOKU_BASE + 'lib/images/plus.gif');
+                       }});
+        $tree.delegate('a', 'click', dw_mediamanager.list);
+    },
 
-    // moved from helpers.js temporarily here
     /**
-     * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+     * build the popup window
      *
+     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
      */
-    hasFlash = function(version){
-        var ver = 0;
-        try{
-            if(navigator.plugins != null && navigator.plugins.length > 0){
-               ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
-            }else{
-               var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
-               ver = axo.GetVariable("$version").split(' ')[1].split(',')[0];
+    initpopup: function () {
+        var opts, $insp, $insbtn;
+
+        dw_mediamanager.$popup = jQuery(document.createElement('div'))
+                 .attr('id', 'media__popup_content')
+                 .dialog({autoOpen: false, width: 280, modal: true,
+                          draggable: true, title: LANG.mediatitle,
+                          resizable: false});
+
+        opts = [{id: 'link', label: LANG.mediatarget,
+                 btns: ['lnk', 'direct', 'nolnk', 'displaylnk']},
+                {id: 'align', label: LANG.mediaalign,
+                 btns: ['noalign', 'left', 'center', 'right']},
+                {id: 'size', label: LANG.mediasize,
+                 btns: ['small', 'medium', 'large', 'original']}
+               ];
+
+        jQuery.each(opts, function (_, opt) {
+            var $p, $l;
+            $p = jQuery(document.createElement('p'))
+                 .attr('id', 'media__' + opt.id);
+
+            if (dw_mediamanager.display === "2") {
+                $p.hide();
             }
-        }catch(e){ }
 
-        if(ver >= version) return true;
-        return false;
-    };
+            $l = jQuery(document.createElement('label'))
+                 .text(opt.label);
+            $p.append($l);
+
+            jQuery.each(opt.btns, function (i, text) {
+                var $btn, $img;
+                $btn = jQuery(document.createElement('button'))
+                       .addClass('button')
+                       .attr('id', "media__" + opt.id + "btn" + (i + 1))
+                       .attr('title', LANG['media' + text])
+                       .click(bind(dw_mediamanager.setOpt, opt.id));
+
+                $img = jQuery(document.createElement('img'))
+                       .attr('src', DOKU_BASE + 'lib/images/media_' +
+                                    opt.id + '_' + text + '.png');
+
+                $btn.append($img);
+                $p.append($btn);
+            });
+
+            dw_mediamanager.$popup.append($p);
+        });
+
+        // insert button
+        $insp = jQuery(document.createElement('p'))
+                .addClass('btnlbl');
+        dw_mediamanager.$popup.append($insp);
+
+        $insbtn = jQuery(document.createElement('input'))
+                  .attr('id', 'media__sendbtn')
+                  .attr('type', 'button')
+                  .addClass('button')
+                  .val(LANG.mediainsert);
+        $insp.append($insbtn);
+    },
 
     /**
      * Insert the clicked image into the opener's textarea
@@ -184,135 +136,81 @@
      * @author Dominik Eckelmann <eckelmann@cosmocode.de>
      * @author Pierre Spring <pierre.spring@caillou.ch>
      */
-    insert = function (id) {
-        var opts, optsstart, alignleft, alignright;
+    insert: function () {
+        var opts, alignleft, alignright, edid, s;
 
         // set syntax options
-        $('#media__popup').hide();
+        dw_mediamanager.$popup.dialog('close');
 
         opts = '';
-        optsstart = '';
         alignleft = '';
         alignright = '';
 
-        if (media_manager.ext == 'img' || media_manager.ext == 'swf') {
+        if ({img: 1, swf: 1}[dw_mediamanager.ext] === 1) {
 
-            if (media_manager.link == '4') {
+            if (dw_mediamanager.link === '4') {
                     opts = '?linkonly';
             } else {
 
-                if (media_manager.link == "3" && media_manager.ext == 'img') {
+                if (dw_mediamanager.link === "3" && dw_mediamanager.ext === 'img') {
                     opts = '?nolink';
-                    optsstart = true;
-                } else if (media_manager.link == "2" && media_manager.ext == 'img') {
+                } else if (dw_mediamanager.link === "2" && dw_mediamanager.ext === 'img') {
                     opts = '?direct';
-                    optsstart = true;
                 }
 
-                var s = parseInt(media_manager.size, 10);
+                s = parseInt(dw_mediamanager.size, 10);
 
-                if (s && s >= 1) {
-                    opts += (optsstart)?'&':'?';
-                    if (s=="1") {
-                        opts += '100';
-                        if (media_manager.ext == 'swf') {
+                if (s && s >= 1 && s < 4) {
+                    opts += (opts.length)?'&':'?';
+                    opts += dw_mediamanager.size + '00';
+                    if (dw_mediamanager.ext === 'swf') {
+                        switch (s) {
+                        case 1:
                             opts += 'x62';
-                        }
-                    } else if (s=="2") {
-                        opts += '200';
-                        if (media_manager.ext == 'swf') {
+                            break;
+                        case 2:
                             opts += 'x123';
-                        }
-                    } else if (s=="3"){
-                        opts += '300';
-                        if (media_manager.ext == 'swf') {
+                            break;
+                        case 3:
                             opts += 'x185';
+                            break;
                         }
                     }
                 }
-                if (media_manager.align == '2') {
-                    alignleft = '';
-                    alignright = ' ';
-                }
-                if (media_manager.align == '3') {
-                    alignleft = ' ';
-                    alignright = ' ';
-                }
-                if (media_manager.align == '4') {
-                    alignleft = ' ';
-                    alignright = '';
-                }
+                alignleft = dw_mediamanager.align === '2' ? '' : ' ';
+                alignright = dw_mediamanager.align === '4' ? '' : ' ';
             }
         }
-        var edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
-        edid = edid ? edid[1] : 'wiki__text';
-        opener.insertTags(edid,'{{'+alignleft+id+opts+alignright+'|','}}','');
+        edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
+        opener.insertTags(edid ? edid[1] : 'wiki__text',
+                          '{{'+alignleft+id+opts+alignright+'|','}}','');
 
-        if(!media_manager.keepopen) window.close();
+        if(!dw_mediamanager.keepopen) {
+            window.close();
+        }
         opener.focus();
         return false;
-    };
+    },
 
     /**
      * Prefills the wikiname.
      *
      * @author Andreas Gohr <andi@splitbrain.org>
      */
-    suggest = function(){
-        var file, name, text;
+    suggest: function(){
+        var $file, $name, text;
 
-        file = $(this);
-        name = $('#upload__name');
-        if(!file.size() || !name.size()) return;
-
-        text = file.val();
-        text = text.substr(text.lastIndexOf('/')+1);
-        text = text.substr(text.lastIndexOf('\\')+1);
-        name.val(text);
-    };
-
-    /**
-     * Open or close a subtree using AJAX
-     *
-     * @author Andreas Gohr <andi@splitbrain.org>
-     * @author Pierre Spring <pierre.spring@caillou.ch>
-     */
-    toggle = function (event) {
-        var clicky, listitem, sublist, link, ul;
-
-        event.preventDefault(); // TODO: really here?
-
-        var clicky = $(this);
-        var listitem = clicky.parent();
-
-        // if already open, close by removing the sublist
-        sublist = listitem.find('ul').first();
-        if(sublist.size()){
-            sublist.remove(); // TODO: really? we could just hide it, right?
-            clicky.attr('src', DOKU_BASE + 'lib/images/plus.gif');
+        $file = jQuery(this);
+        $name = jQuery('#upload__name');
+        if(!$file.length || !$name.length) {
             return;
         }
 
-        // get the enclosed link (is always the first one)
-        link = listitem.find('a').first();
-
-        //prepare the new ul
-        ul = $('<ul/>');
-
-        //fixme add classname here
-
-        $.post(
-            DOKU_BASE + 'lib/exe/ajax.php',
-            link[0].search.substr(1) + '&call=medians',
-            function (data) {
-                ul.html(data);
-                listitem.append(ul);
-            },
-            'html'
-        );
-
-        clicky.attr('src', DOKU_BASE + 'lib/images/minus.gif');
-    };
+        text = $file.val();
+        text = text.substr(text.lastIndexOf('/')+1);
+        text = text.substr(text.lastIndexOf('\\')+1);
+        $name.val(text);
+    },
 
     /**
      * list the content of a namespace using AJAX
@@ -320,178 +218,96 @@
      * @author Andreas Gohr <andi@splitbrain.org>
      * @author Pierre Spring <pierre.spring@caillou.ch>
      */
-    list = function (event) {
-        var link, content;
-        link = $(this);
+    list: function (event) {
+        var $link, $content;
 
         event.preventDefault();
 
         jQuery('div.success, div.info, div.error, div.notify').remove();
 
-        content = $('#media__content');
-        content.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />');
+        $link = jQuery(this);
+        $content = jQuery('#media__content');
+        $content.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />');
 
         // fetch the subtree
-        $.post(
+        jQuery.post(
             DOKU_BASE + 'lib/exe/ajax.php',
-            link[0].search.substr(1)+'&call=medialist',
+            $link[0].search.substr(1)+'&call=medialist',
             function (data) {
-                content.html(data);
-                prepare_content(content);
-                updatehide();
+                $content.html(data);
+                dw_mediamanager.prepare_content($content);
+                dw_mediamanager.updatehide();
             },
             'html'
         );
+    },
 
-    };
-
-    prepare_content = function (content) {
+    prepare_content: function ($content) {
         // hide syntax example
-        content.find('div.example:visible').hide();
-        initFlashUpload();
-    };
+        $content.find('div.example:visible').hide();
+        dw_mediamanager.initFlashUpload();
+    },
 
     /**
-         * shows the popup for a image link
-         */
-        select = function(event){
-            var link, id, dot, ext;
-
-            event.preventDefault();
-
-            link = $(this);
-            id = link.attr('name').substr(2);
-
-            if(!opener){
-                // if we don't run in popup display example
-                // the id's are a bit wired and $('#ex_wiki_dokuwiki-128.png') will not be found
-                // by Sizzle (the CSS Selector Engine used by jQuery),
-                // hence the document.getElementById() call
-                $(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).toggle();
-                return;
-            }
-
-            link = link[0];
-
-            media_manager.ext = false;
-            dot = id.lastIndexOf(".");
-
-            if (-1 === dot) {
-                insert(id);
-                return;
-            }
-
-            ext = id.substr(dot);
-
-            if (ext != '.jpg' && ext != '.jpeg' && ext != '.png' && ext != '.gif' && ext != '.swf') {
-                insert(id);
-                return;
-            }
-
-            // remove old callback from the insert button and set the new one.
-            $('#media__sendbtn').unbind().click(function () {insert(id)});
-
-            $('#media__popup').show()
-                .css('left', event.pageX + 'px')
-                .css('top', event.pageY + 'px');
+     * shows the popup for a image link
+     */
+    select: function(event){
+        var $link, id, dot, ext;
 
-            $('#media__popup button.button').each(function (index, element) { outSet(element) } );
+        event.preventDefault();
 
+        $link = jQuery(this);
+        id = $link.attr('name').substr(2);
 
-            if (ext == '.swf') {
-                media_manager.ext = 'swf';
+        if(!opener){
+            // if we don't run in popup display example
+            // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png')
+            // will not be found by Sizzle (the CSS Selector Engine
+            // used by jQuery), hence the document.getElementById() call
+            jQuery(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).dw_toggle();
+            return;
+        }
 
-                // disable display buttons for detail and linked image
-                $('#media__linkbtn1').hide();
-                $('#media__linkbtn2').hide();
+        dw_mediamanager.ext = false;
+        dot = id.lastIndexOf(".");
 
-                // set the link button to default
-                if (media_manager.link != false) {
-                    if ( media_manager.link == '2' || media_manager.link == '1')  {
-                        inSet('media__linkbtn3');
-                        media_manager.link = '3';
-                        DokuCookie.setValue('link','3');
-                    } else {
-                        inSet('media__linkbtn'+media_manager.link);
-                    }
-                } else if (DokuCookie.getValue('link')) {
-                    if ( DokuCookie.getValue('link') == '2' ||  DokuCookie.getValue('link') == '1')  {
-                        // this options are not availible
-                        inSet('media__linkbtn3');
-                        media_manager.link = '3';
-                        DokuCookie.setValue('link','3');
-                    } else {
-                        inSet('media__linkbtn'+DokuCookie.getValue('link'));
-                        media_manager.link = DokuCookie.getValue('link');
-                    }
-                } else {
-                    // default case
-                    media_manager.link = '3';
-                    inSet('media__linkbtn3');
-                    DokuCookie.setValue('link','3');
-                }
+        if (-1 === dot) {
+            dw_mediamanager.insert(id);
+            return;
+        }
 
-                // disable button for original size
-                $('#media__sizebtn4').hide();
+        ext = id.substr(dot);
 
-            } else {
-                media_manager.ext = 'img';
+        if ({'.jpg':1, '.jpeg':1, '.png':1, '.gif':1, '.swf':1}[ext] !== 1) {
+            dw_mediamanager.insert(id);
+            return;
+        }
 
-                // ensure that the display buttons are there
-                $('#media__linkbtn1').show();
-                $('#media__linkbtn2').show();
-                $('#media__sizebtn4').show();
+        // remove old callback from the insert button and set the new one.
+        jQuery('#media__sendbtn').unbind().click(bind(dw_mediamanager.insert, id));
 
-                // set the link button to default
-                if (DokuCookie.getValue('link')) {
-                    media_manager.link = DokuCookie.getValue('link');
-                }
-                if (media_manager.link == false) {
-                    // default case
-                    media_manager.link = '1';
-                    DokuCookie.setValue('link','1');
-                }
-                inSet('media__linkbtn'+media_manager.link);
-            }
+        dw_mediamanager.unforbid('ext');
+        if (ext === '.swf') {
+            dw_mediamanager.ext = 'swf';
+            dw_mediamanager.forbid('ext', {link: ['1', '2'],
+                                           size: ['4']});
+        } else {
+            dw_mediamanager.ext = 'img';
+        }
 
-            if (media_manager.link == '4') {
-                media_manager.align = false;
-                media_manager.size = false;
-                $('#media__align').hide();
-                $('#media__size').hide();
-            } else {
-                $('#media__align').show();
-                $('#media__size').show();
-
-                // set the align button to default
-                if (media_manager.align != false) {
-                    inSet('media__alignbtn'+media_manager.align);
-                } else if (DokuCookie.getValue('align')) {
-                    inSet('media__alignbtn'+DokuCookie.getValue('align'));
-                    media_manager.align = DokuCookie.getValue('align');
-                } else {
-                    // default case
-                    media_manager.align = '0';
-                    inSet('media__alignbtn0');
-                    DokuCookie.setValue('align','0');
-                }
+        // Set to defaults
+        dw_mediamanager.setOpt('link');
+        dw_mediamanager.setOpt('align');
+        dw_mediamanager.setOpt('size');
 
-                // set the size button to default
-                if (DokuCookie.getValue('size')) {
-                    media_manager.size = DokuCookie.getValue('size');
-                }
-                if (media_manager.size == false || (media_manager.size === '4' && ext === '.swf')) {
-                    // default case
-                    media_manager.size = '2';
-                    DokuCookie.setValue('size','2');
-                }
-                inSet('media__sizebtn'+media_manager.size);
+        // toggle buttons for detail and linked image, original size
+        jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4')
+            .toggle(dw_mediamanager.ext === 'img');
 
-                $('#media__sendbtn').focus();
-            }
+        dw_mediamanager.$popup.dialog('open');
 
-           return;
-        };
+        jQuery('#media__sendbtn').focus();
+    },
 
     /**
      * Deletion confirmation dialog to the delete buttons.
@@ -499,11 +315,11 @@
      * @author Michael Klier <chi@chimeric.de>
      * @author Pierre Spring <pierre.spring@caillou.ch>
      */
-    confirmattach = function(e){
-        if(!confirm(LANG['del_confirm'] + "\n" + jQuery(this).attr('title'))) {
+    confirmattach: function(e){
+        if(!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) {
             e.preventDefault();
         }
-    };
+    },
 
     /**
      * Creates checkboxes for additional options
@@ -511,104 +327,89 @@
      * @author Andreas Gohr <andi@splitbrain.org>
      * @author Pierre Spring <pierre.spring@caillou.ch>
      */
-    attachoptions = function(){
-        obj = $('#media__opts')[0];
-        if(!obj) return;
-
-        // keep open
-        if(opener){
-            var kobox  = document.createElement('input');
-            kobox.type = 'checkbox';
-            kobox.id   = 'media__keepopen';
-            if(DokuCookie.getValue('keepopen')){
-                kobox.checked  = true;
-                kobox.defaultChecked = true; //IE wants this
-                media_manager.keepopen = true;
-            }
+    attachoptions: function(){
+        var $obj, opts;
 
-            $(kobox).click(
-                function () {
-                    toggleOption(this, 'keepopen');
-                }
-            );
-
-            var kolbl  = document.createElement('label');
-            kolbl.htmlFor   = 'media__keepopen';
-            kolbl.innerHTML = LANG['keepopen'];
-
-            var kobr = document.createElement('br');
-
-            obj.appendChild(kobox);
-            obj.appendChild(kolbl);
-            obj.appendChild(kobr);
+        $obj = jQuery('#media__opts');
+        if($obj.length === 0) {
+            return;
         }
 
-        // hide details
-        var hdbox  = document.createElement('input');
-        hdbox.type = 'checkbox';
-        hdbox.id   = 'media__hide';
-        if(DokuCookie.getValue('hide')){
-            hdbox.checked = true;
-            hdbox.defaultChecked = true; //IE wants this
-            media_manager.hide    = true;
+        opts = [];
+        // keep open
+        if(opener){
+            opts.push(['keepopen', 'keepopen']);
         }
-        $(hdbox).click(
-            function () {
-                toggleOption(this, 'hide');
-                updatehide();
-            }
-        );
+        opts.push(['hide', 'hidedetails']);
+
+        jQuery.each(opts,
+                    function(_, opt) {
+                        var $box, $lbl;
+                        $box = jQuery(document.createElement('input'))
+                                 .attr('type', 'checkbox')
+                                 .attr('id', 'media__' + opt[0])
+                                 .click(bind(dw_mediamanager.toggleOption,
+                                             opt[0]));
+
+                        if(DokuCookie.getValue(opt[0])){
+                            $box.prop('checked', true);
+                            dw_mediamanager[opt[0]] = true;
+                        }
 
-        var hdlbl  = document.createElement('label');
-        hdlbl.htmlFor   = 'media__hide';
-        hdlbl.innerHTML = LANG['hidedetails'];
+                        $lbl = jQuery(document.createElement('label'))
+                                 .attr('for', 'media__' + opt[0])
+                                 .text(LANG[opt[1]]);
 
-        var hdbr = document.createElement('br');
+                        $obj.append($box, $lbl, document.createElement('br'));
+                    });
 
-        obj.appendChild(hdbox);
-        obj.appendChild(hdlbl);
-        obj.appendChild(hdbr);
-        updatehide();
-    };
+        dw_mediamanager.updatehide();
+    },
 
     /**
      * Generalized toggler
      *
      * @author Pierre Spring <pierre.spring@caillou.ch>
      */
-    toggleOption = function (checkbox, variable) {
-        if (checkbox.checked) {
+    toggleOption: function (variable) {
+        if (jQuery(this).prop('checked')) {
             DokuCookie.setValue(variable, 1);
-            media_manager[variable] = true;
+            dw_mediamanager[variable] = true;
         } else {
             DokuCookie.setValue(variable, '');
-            media_manager[variable] = false;
+            dw_mediamanager[variable] = false;
         }
-    };
-
-    initFlashUpload = function () {
-        var oform, oflash, title;
-        if(!hasFlash(8)) return;
+        if (variable === 'hide') {
+            dw_mediamanager.updatehide();
+        }
+    },
 
-        oform  = $('#dw__upload');
-        oflash = $('#dw__flashupload');
+    initFlashUpload: function () {
+        var $oform, $oflash;
+        if(!hasFlash(8)) {
+            return;
+        }
 
-        if(!oform.size() || !oflash.size()) return;
+        $oform  = jQuery('#dw__upload');
+        $oflash = jQuery('#dw__flashupload');
 
-        title = LANG['mu_btn'];
+        if(!$oform.length || !$oflash.length) {
+            return;
+        }
 
-        $('<img/>').attr('src', DOKU_BASE+'lib/images/multiupload.png')
-            .attr('title', title)
-            .attr('alt', title)
+        jQuery(document.createElement('img'))
+            .attr('src', DOKU_BASE+'lib/images/multiupload.png')
+            .attr('title', LANG.mu_btn)
+            .attr('alt', LANG.mu_btn)
             .css('cursor', 'pointer')
             .click(
                 function () {
-                    oform.hide();
-                    oflash.show();
+                    $oform.hide();
+                    $oflash.show();
                 }
             )
-            .appendTo(oform);
-    };
+            .appendTo($oform);
+    },
 
     /**
      * Sets the visibility of the image details accordingly to the
@@ -616,137 +417,109 @@
      *
      * @author Andreas Gohr <andi@splitbrain.org>
      */
-    updatehide = function(){
-        var content = $('#media__content');
-        if(0 === content.size()) {
-            return;
-        }
-        content.find('div.detail').each(
-            function (index, element) {
-                if(media_manager.hide){
-                    element.style.display = 'none';
-                }else{
-                    element.style.display = '';
-                }
-            }
-
-        );
-    };
+    updatehide: function(){
+        jQuery('#media__content div.detail').dw_toggle(!dw_mediamanager.hide);
+    },
 
     /**
-     * set the align
+     * set media insertion option
      *
      * @author Dominik Eckelmann <eckelmann@cosmocode.de>
      */
-    setalign = function(event,cb){
-
-        var id = cb.id.substring(cb.id.length -1);
-        if(id){
-            DokuCookie.setValue('align',id);
-            media_manager.align = id;
-            for (var i = 1; i<=4; i++) {
-                outSet("media__alignbtn" + i);
-            }
-            inSet("media__alignbtn"+id);
-        }else{
-            DokuCookie.setValue('align','');
-            media_manager.align = false;
+    setOpt: function(opt, e){
+        var val, i;
+        if (typeof e !== 'undefined') {
+            val = this.id.substring(this.id.length - 1);
+        } else {
+            val = dw_mediamanager.getOpt(opt);
         }
-    };
 
-    /**
-     * set the link type
-     *
-     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
-     */
-    setlink = function(event,cb){
-        var id = cb.id.substring(cb.id.length -1);
-        if(id){
-            DokuCookie.setValue('link',id);
-            for (var i = 1; i<=4; i++) {
-                outSet("media__linkbtn"+i);
-            }
-            inSet("media__linkbtn"+id);
-
-            var size = $("#media__size");
-            var align = $("#media__align");
-            if (id != '4') {
-                size.show();
-                align.show();
-                if (media_manager.link == '4') {
-                    media_manager.align = '1';
-                    DokuCookie.setValue('align', '1');
-                    inSet('media__alignbtn1');
-
-                    media_manager.size = '2';
-                    DokuCookie.setValue('size', '2');
-                    inSet('media__sizebtn2');
-                }
-
-            } else {
-                size.hide();
-                align.hide();
-            }
-            media_manager.link = id;
-        }else{
-            DokuCookie.setValue('link','');
-            media_manager.link = false;
+        if (val === false) {
+            DokuCookie.setValue(opt,'');
+            dw_mediamanager[opt] = false;
+            return;
         }
-    };
 
-    /**
-     * set the image size
-     *
-     * @author Dominik Eckelmann <eckelmann@cosmocode.de>
-     */
-    setsize = function(event,cb){
-        var id = cb.id.substring(cb.id.length -1);
-        if (id) {
-            DokuCookie.setValue('size',id);
-            media_manager.size = id;
-            for (var i = 1 ; i <=4 ; ++i) {
-                outSet("media__sizebtn" + i);
+        if (opt === 'link') {
+            if (val !== '4' && dw_mediamanager.link === '4') {
+                dw_mediamanager.unforbid('linkonly');
+                dw_mediamanager.setOpt('align');
+                dw_mediamanager.setOpt('size');
+            } else if (val === '4') {
+                dw_mediamanager.forbid('linkonly', {align: false, size: false});
             }
-            inSet("media__sizebtn"+id);
-        } else {
-            DokuCookie.setValue('size','');
-            media_manager.width = false;
+
+            jQuery("#media__size, #media__align").dw_toggle(val !== '4');
         }
-    };
 
-    /**
-     * sets the border to inset
-     */
-    inSet = function(id) {
-        var ele = $('#' + id).css('border-style', 'inset');
-    };
+        DokuCookie.setValue(opt, val);
+        dw_mediamanager[opt] = val;
 
-    /**
-     * sets the border to outset
-     */
-    outSet = function(element) {
-        if ('string' === typeof element) {
-            element = '#' + element;
+        for (i = 1; i <= 4; i++) {
+            jQuery("#media__" + opt + "btn" + i).removeClass('selected');
+        }
+        jQuery('#media__' + opt + 'btn' + val).addClass('selected');
+    },
+
+    unforbid: function (group) {
+        delete dw_mediamanager.forbidden_opts[group];
+    },
+
+    forbid: function (group, forbids) {
+        dw_mediamanager.forbidden_opts[group] = forbids;
+    },
+
+    allowedOpt: function (opt, val) {
+        var ret = true;
+        jQuery.each(dw_mediamanager.forbidden_opts,
+                    function (_, forbids) {
+                        ret = forbids[opt] !== false &&
+                              jQuery.inArray(val, forbids[opt]) === -1;
+                        return ret;
+                    });
+        return ret;
+    },
+
+    getOpt: function (opt) {
+        var allowed = bind(dw_mediamanager.allowedOpt, opt);
+
+        // Current value
+        if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt]) {
+            return dw_mediamanager[opt];
         }
-        $(element).css('border-style', 'outset');
-    };
 
-    $(function () {
-        var content = $('#media__content');
-        prepare_content(content);
+        // From cookie
+        if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) {
+            return DokuCookie.getValue(opt);
+        }
 
-        attachoptions();
-        initpopup();
+        // size default
+        if (opt === 'size' && allowed('2')) {
+            return '2';
+        }
 
-        // add the action to autofill the "upload as" field
-        content.delegate('#upload__file', 'change', suggest)
-            // Attach the image selector action to all links
-            .delegate('a.select', 'click', select)
-            // Attach deletion confirmation dialog to the delete buttons
-            .delegate('#media__content a.btn_media_delete', 'click', confirmattach);
+        // Whatever is allowed, and be it false
+        return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false;
+    }
+};
+
+// moved from helpers.js temporarily here
+/**
+ * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+ *
+ */
+function hasFlash(version){
+    var ver = 0, axo;
+    try{
+        if(navigator.plugins !== null && navigator.plugins.length > 0){
+           ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
+        }else{
+           axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+           ver = axo.GetVariable("$version").split(' ')[1].split(',')[0];
+        }
+    }catch(e){ }
 
+    return ver >= version;
+}
 
-        $('#media__tree').delegate('img', 'click', toggle)
-            .delegate('a', 'click', list);
-    });
-}(jQuery));
+jQuery(dw_mediamanager.init);
diff --git a/lib/scripts/subscriptions.js b/lib/scripts/subscriptions.js
index 565ea33eb2631e3036521d4e1f6a88cb83ebce51..b7bffb1584a3d7421daf4f15343460930bbd7cc5 100644
--- a/lib/scripts/subscriptions.js
+++ b/lib/scripts/subscriptions.js
@@ -21,18 +21,15 @@ jQuery(function () {
     $form.find("input[name='sub_target']")
         .click(
             function () {
-                var $input = jQuery(this);
-                if (!$input.prop('checked')) {
+                var $this = jQuery(this), show_list;
+                if (!$this.prop('checked')) {
                     return;
                 }
 
-                if ($input.val().match(/:$/)) {
-                    $list.parent().slideDown('fast');
-                } else {
-                    $list.parent().slideUp('fast');
-                    if ($list.prop('checked')) {
-                        $digest.prop('checked', 'checked');
-                    }
+                show_list = $this.val().match(/:$/);
+                $list.parent().dw_toggle(show_list);
+                if (!show_list && $list.prop('checked')) {
+                    $digest.prop('checked', 'checked');
                 }
             }
         )
diff --git a/lib/scripts/tree.js b/lib/scripts/tree.js
new file mode 100644
index 0000000000000000000000000000000000000000..46b0f669517122513c6be8761e9d050fcabc8478
--- /dev/null
+++ b/lib/scripts/tree.js
@@ -0,0 +1,94 @@
+/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: false, newcap: true, immed: true, sloppy: true */
+/*global jQuery, window, DOKU_BASE, DEPRECATED, bind*/
+
+jQuery.fn.dw_tree = function(overrides) {
+    var dw_tree = {
+
+        /**
+         * Delay in ms before showing the throbber.
+         * Used to skip the throbber for fast AJAX calls.
+         */
+        throbber_delay: 500,
+
+        $obj: this,
+
+        toggle_selector: 'a.idx_dir',
+
+        init: function () {
+            this.$obj.delegate(this.toggle_selector, 'click', this,
+                               this.toggle);
+        },
+
+        /**
+         * Open or close a subtree using AJAX
+         * The contents of subtrees are "cached" until the page is reloaded.
+         * A "loading" indicator is shown only when the AJAX call is slow.
+         *
+         * @author Andreas Gohr <andi@splitbrain.org>
+         * @author Ben Coburn <btcoburn@silicodon.net>
+         * @author Pierre Spring <pierre.spring@caillou.ch>
+         */
+        toggle: function (e) {
+            var $listitem, $sublist, timeout, $clicky, show_sublist, dw_tree;
+
+            e.preventDefault();
+
+            $clicky = jQuery(this);
+            $listitem = $clicky.closest('li');
+            $sublist = $listitem.find('ul').first();
+            dw_tree = e.data;
+
+            // if already open, close by hiding the sublist
+            if ($listitem.hasClass('open')) {
+                $sublist.dw_hide(function () {
+                    dw_tree.close($clicky);
+                    $listitem.addClass('closed').removeClass('open');
+                });
+                return;
+            }
+
+            show_sublist = function (data) {
+                if (!$listitem.hasClass('open') || $sublist.parent().length === 0) {
+                    $listitem.append($sublist).addClass('open').removeClass('closed');
+                }
+                $sublist.hide();
+                if (data) {
+                    $sublist.html(data);
+                }
+                $sublist.dw_show();
+            };
+
+            // just show if already loaded
+            if ($sublist.length > 0) {
+                show_sublist();
+                return;
+            }
+
+            //prepare the new ul
+            $sublist = jQuery('<ul class="idx"/>');
+
+            timeout = window.setTimeout(
+                bind(show_sublist, '<li><img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="loading..." title="loading..." /></li>'), dw_tree.throbber_delay);
+
+            dw_tree.load_data(function (data) {
+                                  window.clearTimeout(timeout);
+                                  show_sublist(data);
+                              }, $clicky);
+        },
+
+        close: function ($clicky) {
+        },
+
+        load_data: function (show_data, $clicky) {
+            show_data();
+        }
+    };
+
+    jQuery.extend(dw_tree, overrides);
+
+    if (!overrides.deferInit) {
+        dw_tree.init();
+    }
+
+    return dw_tree;
+};
diff --git a/lib/styles/print.css b/lib/styles/print.css
index 16543473a431b5d9900dd5db98faf7cfcf3fbce0..76bc6d3bc123c2f7a3f7f0304c65d580018b13b5 100644
--- a/lib/styles/print.css
+++ b/lib/styles/print.css
@@ -18,7 +18,6 @@ div.notify {
 
 /* modal windows */
 .JSpopup,
-#link__wiz,
-#media__popup {
+#link__wiz {
     display: none;
 }
diff --git a/lib/styles/screen.css b/lib/styles/screen.css
index 0a6a4f295ce1f3e2a4d86af1fabe2239a4d7a9ec..80a161f1911bbc4a0d3a699912d92637e226fc80 100644
--- a/lib/styles/screen.css
+++ b/lib/styles/screen.css
@@ -44,8 +44,7 @@ div.notify {
 
 /* modal windows */
 .JSpopup,
-#link__wiz,
-#media__popup {
+#link__wiz {
     position: absolute;
     background-color: #fff;
     color: #000;
@@ -53,6 +52,16 @@ div.notify {
     overflow: hidden;
 }
 
+/* media manager popup toggle buttons */
+
+#media__popup_content button.button {
+    border-style: outset;
+}
+
+#media__popup_content button.selected {
+    border-style: inset;
+}
+
 
 /* syntax highlighting code */
 .code .br0  { color: #66cc66; }
diff --git a/lib/tpl/default/_mediaoptions.css b/lib/tpl/default/_mediaoptions.css
index 19e2c485320f50319115907b67226d56d4cd2b08..68a5b9fa792eafe7cdec07f874b2e3f5bb170148 100644
--- a/lib/tpl/default/_mediaoptions.css
+++ b/lib/tpl/default/_mediaoptions.css
@@ -1,24 +1,6 @@
 /* --- popup --- */
 
-#media__popup {
-    background-color:__background__;
-    display:none;
-    border: 1px solid __border__;
-    position: absolute;
-    width:280px;
-}
-
-#media__popup h1 {
-    text-align:center;
-    font-weight:normal;
-    background-color: __background_alt__;
-    height: 16px;
-    margin-bottom: 5px;
-    font-size:12px;
-    border-bottom: 0;
-}
-
-#media__popup p {
+#media__popup_content p {
     display:block;
     line-height:14pt;
     margin:0.5em;
@@ -28,28 +10,24 @@
     padding:4px 0;
 }
 
-#media__popup label {
+#media__popup_content label {
     float:left;
     width:9em;
 }
 
-#media__popup .button {
+#media__popup_content .button {
     margin-left:auto;
     margin-right:auto;
 }
 
-#media__popup .btnlbl {
+#media__popup_content .btnlbl {
     text-align:center;
 }
 
-#media__popup .btnlbl input {
+#media__popup_content .btnlbl input {
     margin:0 1em;
 }
 
-#media__closeimg {
-    float:right;
-}
-
 /* --- display options --- */
 
 #media__linkopts label,