function execute($par)
 {
     global $wgRequest, $wgOut, $wgUser;
     $this->cat_stack = new MsCategoryStack($wgRequest->getArray('ms-cat'));
     $chosen_db = $wgRequest->getText('ms-db', false);
     if ($chosen_db) {
         // there's an "ms-db" argument present. So redirect directly
         // to that db.
         $db = new MsDatabase($chosen_db);
         $subtitle = $db->is_driver_type('proxydriver') ? 'proxy' : 'query';
         $wgOut->redirect($this->special_page->get_sub_title($subtitle)->getLocalUrl($this->cat_stack->build_query('ms-cat') . '&' . $db->build_query('ms-db')));
         return;
     }
     if ($this->cat_stack->get_top()->has_sub_categories()) {
         // display category chooser
         $this->display_cat_chooser();
     } else {
         // no more categories to choose of.
         // Check what we've got for databases:
         $dbs = $this->cat_stack->get_top()->get_databases(MsCategory::AS_OBJECTS);
         // das ist nicht mehr umbedingt schlimm -- wird
         // halt nix angezeigt in dem dbchooser.
         /*
         if(empty($dbs)) {
         	throw new MsException("Top cat of {$this->cat_stack} has no databases attached!",
         		MsException::BAD_CONFIGURATION);
         }
         */
         if (count($dbs) > 1) {
             // the cat has more than one database
             if (MsDatabase::are_query_databases($dbs)) {
                 // but they are all Query Databases, so
                 // let MsQueryPage do it's job
                 $this->redirect('query');
                 return;
             } else {
                 // Since we cannot merge different databases on
                 // one page, display a database chooser.
                 $template = new MsChooserTemplate();
                 $this->display_cat_chooser($template);
             }
         } else {
             // Only one database in this cat.
             // Relaxed situation :-)
             // Since 04.07: test to display a chooser... too ;-)
             /*
             $db = $dbs[0];
             $this->redirect_to_db($db);
             
             $subtitle = $db->is_driver_type('proxydriver') ? 'proxy' : 'query';
             $this->redirect( $subtitle );
             */
             $this->display_cat_chooser();
         }
     }
     // if ...->has_sub_categories()
 }
 function category_tree($leaf = false, $level = 1)
 {
     if (!$leaf) {
         $leaf = MsCategoryFactory::get_root_category();
     }
     $indent = str_repeat('#', $level);
     $name = $leaf->get('name');
     if (!$name) {
         $name = "''no name set!''";
     }
     $id = $leaf->id;
     $r = "{$indent} '''[[MediaWiki:ms-{$id}-category|{$id}]]''' " . ($leaf->exists() ? '' : "'''DOES NOT EXIST'''") . "\n";
     $r .= "{$indent}* ''MSGS'': [[MediaWiki:ms-{$id}-record|record]], [[MediaWiki:ms-{$id}-category-input|input]], [[MediaWiki:ms-{$id}-presearch-box|presearch]], [[MediaWiki:ms-{$id}-postsearch-box|postsearch]]\n";
     $r .= "{$indent}* ''DATABASES'': ";
     foreach ($leaf->get_databases() as $db) {
         $r .= "[[MediaWiki:ms-{$db}-database|{$db}]], ";
         $msg = MsDatabase::get_conf_msg_name($db);
         if (wfMsgExists($msg)) {
             $this->list_of_msgs[] = $msg;
         }
     }
     $r .= "\n";
     foreach ($leaf->get_conf_array() as $k => $v) {
         $r .= "{$indent}* ''{$k}'': {$v}\n";
     }
     #if(wfMsgExists($msg)) $this->list_of_msgs += $msg;
     $this->list_of_msgs = array_merge($this->list_of_msgs, $leaf->get_messages());
     $this->list_of_dbs = array_merge($this->list_of_dbs, $leaf->get_databases());
     foreach ($leaf->get_sub_categories(MsCategory::AS_OBJECTS) as $subcat) {
         $r .= $this->category_tree($subcat, $level + 1);
     }
     return $r;
 }