removed mods directory from the ATutor codebase
[atutor.git] / mods / phpdoc2 / PhpDocumentor / phpDocumentor / Converter.inc
diff --git a/mods/phpdoc2/PhpDocumentor/phpDocumentor/Converter.inc b/mods/phpdoc2/PhpDocumentor/phpDocumentor/Converter.inc
deleted file mode 100644 (file)
index f36a1cd..0000000
+++ /dev/null
@@ -1,5441 +0,0 @@
-<?php\r
-/**\r
- * Base class for all Converters\r
- *\r
- * phpDocumentor :: automatic documentation generator\r
- * \r
- * PHP versions 4 and 5\r
- *\r
- * Copyright (c) 2001-2006 Gregory Beaver\r
- * \r
- * LICENSE:\r
- * \r
- * This library is free software; you can redistribute it\r
- * and/or modify it under the terms of the GNU Lesser General\r
- * Public License as published by the Free Software Foundation;\r
- * either version 2.1 of the License, or (at your option) any\r
- * later version.\r
- * \r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- * \r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- *\r
- * @package    Converters\r
- * @author     Greg Beaver <cellog@php.net>\r
- * @copyright  2001-2006 Gregory Beaver\r
- * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL\r
- * @version    CVS: $Id: Converter.inc,v 1.38 2007/04/25 19:02:42 ashnazg Exp $\r
- * @filesource\r
- * @link       http://www.phpdoc.org\r
- * @link       http://pear.php.net/PhpDocumentor\r
- * @see        parserDocBlock, parserInclude, parserPage, parserClass\r
- * @see        parserDefine, parserFunction, parserMethod, parserVar\r
- * @since      1.0rc1\r
- */\r
-/**\r
- * Smarty template files\r
- */\r
-include_once("phpDocumentor/Smarty-2.6.0/libs/Smarty.class.php");\r
-/**\r
- * Base class for all output converters.\r
- *\r
- * The Converter marks the final stage in phpDocumentor.  phpDocumentor works\r
- * in this order:\r
- *\r
- * <pre>Parsing => Intermediate Parsing organization => Conversion to output</pre>\r
- *\r
- * A Converter takes output from the {@link phpDocumentor_IntermediateParser} and\r
- * converts it to output.  With version 1.2, phpDocumentor includes a variety\r
- * of output converters:\r
- * <ul>\r
- *  <li>{@link HTMLframesConverter}</li>\r
- *  <li>{@link HTMLSmartyConverter}</li>\r
- *  <li>{@link PDFdefaultConverter}</li>\r
- *  <li>{@link CHMdefaultConverter}</li>\r
- *  <li>{@link CSVdia2codeConverter}</li>\r
- *  <li>{@link XMLDocBookConverter}</li>\r
- * </ul>\r
- * {@internal\r
- * The converter takes output directly from {@link phpDocumentor_IntermediateParser}\r
- * and using {@link walk()} or {@link walk_everything} (depending on the value of\r
- * {@link $sort_absolutely_everything}) it "walks" over an array of phpDocumentor elements.}}\r
- *\r
- * @package Converters\r
- * @abstract\r
- * @author Greg Beaver <cellog@php.net>\r
- * @since 1.0rc1\r
- * @version $Id: Converter.inc,v 1.38 2007/04/25 19:02:42 ashnazg Exp $\r
- */\r
-class Converter\r
-{\r
-    /**\r
-     * This converter knows about the new root tree processing\r
-     * In order to fix PEAR Bug #6389\r
-     * @var boolean\r
-     */\r
-    var $processSpecialRoots = false;\r
-    /**\r
-     * output format of this converter\r
-     *\r
-     * in Child converters, this will match the first part of the -o command-line\r
-     * as in -o HTML:frames:default "HTML"\r
-     * @tutorial phpDocumentor.howto.pkg#using.command-line.output\r
-     * @var string\r
-     */\r
-    var $outputformat = 'Generic';\r
-    /**\r
-     * package name currently being converted\r
-     * @var string\r
-     */\r
-    var $package = 'default';\r
-    /**\r
-     * subpackage name currently being converted\r
-     * @var string\r
-     */\r
-    var $subpackage = '';\r
-    /**\r
-     * set to a classname if currently parsing a class, false if not\r
-     * @var string|false\r
-     */\r
-    var $class = false;\r
-    /**#@+\r
-     * @access private\r
-     */\r
-    /**\r
-     * the workhorse of linking.\r
-     *\r
-     * This array is an array of link objects of format:\r
-     * [package][subpackage][eltype][elname] = descendant of {@link abstractLink}\r
-     * eltype can be page|function|define|class|method|var\r
-     * if eltype is method or var, the array format is:\r
-     * [package][subpackage][eltype][class][elname]\r
-     * @var array\r
-     * @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink\r
-     */\r
-    var $links = array();\r
-\r
-    /**\r
-     * the workhorse of linking, with allowance for support of multiple\r
-     * elements in different files.\r
-     *\r
-     * This array is an array of link objects of format:\r
-     * [package][subpackage][eltype][file][elname] = descendant of {@link abstractLink}\r
-     * eltype can be function|define|class|method|var\r
-     * if eltype is method or var, the array format is:\r
-     * [package][subpackage][eltype][file][class][elname]\r
-     * @var array\r
-     * @see functionLink, pageLink, classLink, defineLink, methodLink, varLink, globalLink\r
-    */\r
-    var $linkswithfile = array();\r
-    /**#@-*/\r
-    /**\r
-     * set to value of -po commandline\r
-     * @tutorial phpDocumentor.howto.pkg#using.command-line.packageoutput\r
-     * @var mixed\r
-     */\r
-    var $package_output;\r
-\r
-    /**\r
-     * name of current page being converted\r
-     * @var string\r
-     */\r
-    var $page;\r
-\r
-    /**\r
-     * path of current page being converted\r
-     * @var string\r
-     */\r
-    var $path;\r
-\r
-    /**\r
-     * template for the procedural page currently being processed\r
-     * @var Smarty\r
-     */\r
-    var $page_data;\r
-\r
-    /**\r
-     * template for the class currently being processed\r
-     * @var Smarty\r
-     */\r
-    var $class_data;\r
-\r
-    /**\r
-     * current procedural page being processed\r
-     * @var parserPage\r
-     */\r
-    var $curpage;\r
-    /**\r
-     * alphabetical index of all elements sorted by package, subpackage, page,\r
-     * and class.\r
-     * @var array Format: array(package => array(subpackage => array('page'|'class' => array(path|classname => array(element, element,...)))))\r
-     * @uses $sort_absolutely_everything if true, then $package_elements is used,\r
-     *       otherwise, the {@link ParserData::$classelements} and\r
-     *       {@link ParserData::$pageelements} variables are used\r
-     */\r
-    var $package_elements = array();\r
-    /**\r
-     * alphabetical index of all elements\r
-     *\r
-     * @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))\r
-     * @see formatIndex(), HTMLframesConverter::formatIndex()\r
-     */\r
-    var $elements = array();\r
-    /**\r
-     * alphabetized index of procedural pages by package\r
-     *\r
-     * @see $leftindex\r
-     * @var array Format: array(package => array(subpackage => array({@link pageLink} 1,{@link pageLink} 2,...)\r
-     */\r
-    var $page_elements = array();\r
-    /**\r
-     * alphabetized index of defines by package\r
-     *\r
-     * @see $leftindex\r
-     * @var array Format: array(package => array(subpackage => array({@link defineLink} 1,{@link defineLink} 2,...)\r
-     */\r
-    var $define_elements = array();\r
-    /**\r
-     * alphabetized index of classes by package\r
-     *\r
-     * @see $leftindex\r
-     * @var array Format: array(package => array(subpackage => array({@link classLink} 1,{@link classLink} 2,...)\r
-     */\r
-    var $class_elements = array();\r
-    /**\r
-     * alphabetized index of global variables by package\r
-     *\r
-     * @see $leftindex\r
-     * @var array Format: array(package => array(subpackage => array({@link globalLink} 1,{@link globalLink} 2,...)\r
-     */\r
-    var $global_elements = array();\r
-    /**\r
-     * alphabetized index of functions by package\r
-     *\r
-     * @see $leftindex\r
-     * @var array Format: array(package => array(subpackage => array({@link functionLink} 1,{@link functionLink} 2,...)\r
-     */\r
-    var $function_elements = array();\r
-    /**\r
-     * alphabetical index of all elements, indexed by package/subpackage\r
-     *\r
-     * @var array Format: array(first letter of element name => array({@link parserElement} or {@link parserPage},...))\r
-     * @see formatPkgIndex(), HTMLframesConverter::formatPkgIndex()\r
-     */\r
-    var $pkg_elements = array();\r
-\r
-    /**\r
-     * alphabetical index of all elements on a page by package/subpackage\r
-     *\r
-     * The page itself has a link under ###main\r
-     * @var array Format: array(package => array(subpackage => array(path => array({@link abstractLink} descendant 1, ...)))\r
-     * @see formatLeftIndex()\r
-     */\r
-    var $page_contents = array();\r
-\r
-    /**\r
-     * This determines whether the {@link $page_contents} array should be sorted by element type as well as alphabetically by name\r
-     * @see sortPageContentsByElementType()\r
-     * @var boolean\r
-     */\r
-    var $sort_page_contents_by_type = false;\r
-    /**\r
-     * This is used if the content must be passed in the order it should be read, i.e. by package, procedural then classes\r
-     *\r
-     * This fixes bug 637921, and is used by {@link PDFdefaultConverter}\r
-     */\r
-    var $sort_absolutely_everything = false;\r
-    /**\r
-     * alphabetical index of all methods and vars in a class by package/subpackage\r
-     *\r
-     * The class itself has a link under ###main\r
-     * @var array\r
-     * Format:<pre>\r
-     * array(package =>\r
-     *       array(subpackage =>\r
-     *             array(path =>\r
-     *                   array(class =>\r
-     *                         array({@link abstractLink} descendant 1, ...\r
-     *                        )\r
-     *                  )\r
-     *            )\r
-     *      )</pre>\r
-     * @see formatLeftIndex()\r
-     */\r
-    var $class_contents = array();\r
-    /**\r
-     * controls processing of elements marked private with @access private\r
-     *\r
-     * defaults to false.  Set with command-line --parseprivate or -pp\r
-     * @var bool\r
-     */\r
-    var $parseprivate;\r
-    /**\r
-     * controls display of progress information while parsing.\r
-     *\r
-     * defaults to false.  Set to true for cron jobs or other situations where no visual output is necessary\r
-     * @var bool\r
-     */\r
-    var $quietmode;\r
-\r
-    /**\r
-     * directory that output is sent to. -t command-line sets this.\r
-     * @tutorial phpDocumentor.howto.pkg#using.command-line.target\r
-     */\r
-    var $targetDir = '';\r
-\r
-    /**\r
-     * Directory that the template is in, relative to phpDocumentor root directory\r
-     * @var string\r
-     */\r
-    var $templateDir = '';\r
-\r
-    /**\r
-     * Directory that the smarty templates are in\r
-     * @var string\r
-     */\r
-    var $smarty_dir = '';\r
-\r
-    /**\r
-     * Name of the template, from last part of -o\r
-     * @tutorial phpDocumentor.howto.pkg#using.command-line.output\r
-     * @var string\r
-     */\r
-    var $templateName = '';\r
-\r
-    /**\r
-     * full path of the current file being converted\r
-     */\r
-    var $curfile;\r
-\r
-    /**\r
-     * All class information, organized by path, and by package\r
-     * @var Classes\r
-     */\r
-    var $classes;\r
-\r
-    /**\r
-     * Flag used to help converters determine whether to do special source highlighting\r
-     * @var boolean\r
-     */\r
-    var $highlightingSource = false;\r
-\r
-    /**\r
-     * Hierarchy of packages\r
-     *\r
-     * Every package that contains classes may have parent or child classes\r
-     * in other packages.  In other words, this code is legal:\r
-     *\r
-     * <code>\r
-     * /**\r
-     *  * @package one\r
-     *  * /\r
-     * class one {}\r
-     *\r
-     * /**\r
-     *  * @package two\r
-     *  * /\r
-     * class two extends one {}\r
-     * </code>\r
-     *\r
-     * In this case, package one is a parent of package two\r
-     * @var array\r
-     * @see phpDocumentor_IntermediateParser::$package_parents\r
-     */\r
-    var $package_parents;\r
-\r
-    /**\r
-     * Packages associated with categories\r
-     *\r
-     * Used by the XML:DocBook/peardoc2 converter, and available to others, to\r
-     * group many packages into categories\r
-     * @see phpDocumentor_IntermediateParser::$packagecategories\r
-     * @var array\r
-     */\r
-    var $packagecategories;\r
-\r
-    /**\r
-     * All packages encountered in parsing\r
-     * @var array\r
-     * @see phpDocumentor_IntermediateParser::$all_packages\r
-     */\r
-    var $all_packages;\r
-\r
-    /**\r
-     * A list of files that have had source code generated\r
-     * @var array\r
-     */\r
-    var $sourcePaths = array();\r
-\r
-    /**\r
-     * Controls which of the one-element-only indexes are generated.\r
-     *\r
-     * Generation of these indexes for large packages is time-consuming.  This is an optimization feature.  An\r
-     * example of how to use this is in {@link HTMLframesConverter::$leftindex}, and in {@link HTMLframesConverter::formatLeftIndex()}.\r
-     * These indexes are intended for use as navigational aids through documentation, but can be used for anything by converters.\r
-     * @see $class_elements, $page_elements, $function_elements, $define_elements, $global_elements\r
-     * @see formatLeftIndex()\r
-     * @var array\r
-     */\r
-    var $leftindex = array('classes' => true, 'pages' => true, 'functions' => true, 'defines' => true, 'globals' => true);\r
-\r
-    /** @access private */\r
-    var $killclass = false;\r
-    /**\r
-     * @var string\r
-     * @see phpDocumentor_IntermediateParser::$title\r
-     */\r
-    var $title = 'Generated Documentation';\r
-\r
-    /**\r
-     * Options for each template, parsed from the options.ini file in the template base directory\r
-     * @tutorial phpDocumentor/tutorials.pkg#conversion.ppage\r
-     * @var array\r
-     */\r
-    var $template_options;\r
-\r
-    /**\r
-     * Tutorials and Extended Documentation parsed from a tutorials/package[/subpackage] directory\r
-     * @tutorial tutorials.pkg\r
-     * @access private\r
-     */\r
-    var $tutorials = array();\r
-\r
-    /**\r
-     * tree-format structure of tutorials and their child tutorials, if any\r
-     * @var array\r
-     * @access private\r
-     */\r
-    var $tutorial_tree = false;\r
-\r
-    /**\r
-     * list of tutorials that have already been processed. Used by @link _setupTutorialTree()\r
-     * @var array\r
-     * @access private\r
-     */\r
-    var $processed_tutorials;\r
-\r
-    /**\r
-     * List of all @todo tags and a link to the element with the @todo\r
-     *\r
-     * Format: array(package => array(link to element, array(todo {@link parserTag},...)),...)\r
-     * @tutorial tags.todo.pkg\r
-     * @var array\r
-     */\r
-    var $todoList = array();\r
-\r
-    /**\r
-     * Directory where compiled templates go - will be deleted on exit\r
-     *\r
-     * @var string\r
-     * @access private\r
-     */\r
-     var $_compiledDir = array();\r
-\r
-    /**\r
-     * Initialize Converter data structures\r
-     * @param array {@link $all_packages} value\r
-     * @param array {@link $package_parents} value\r
-     * @param Classes {@link $classes} value\r
-     * @param ProceduralPages {@link $proceduralpages} value\r
-     * @param array {@link $package_output} value\r
-     * @param boolean {@link $parseprivate} value\r
-     * @param boolean {@link $quietmode} value\r
-     * @param string {@link $targetDir} value\r
-     * @param string {@link $templateDir} value\r
-     * @param string (@link $title} value\r
-     */\r
-    function Converter(&$allp, &$packp, &$classes, &$procpages, $po, $pp, $qm, $targetDir, $template, $title)\r
-    {\r
-        $this->all_packages = $allp;\r
-        $this->package_parents = $packp;\r
-        $this->package = $GLOBALS['phpDocumentor_DefaultPackageName'];\r
-        $this->proceduralpages = &$procpages;\r
-        $this->package_output = $po;\r
-        if (is_array($po))\r
-        {\r
-            $a = $po[0];\r
-            $this->all_packages = array_flip($po);\r
-            $this->all_packages[$a] = 1;\r
-        }\r
-        $this->parseprivate = $pp;\r
-        $this->quietmode = $qm;\r
-        $this->classes = &$classes;\r
-        $this->roots = $classes->getRoots($this->processSpecialRoots);\r
-        $this->title = $title;\r
-        $this->setTemplateDir($template);\r
-        $this->setTargetdir($targetDir);\r
-    }\r
-\r
-    /**\r
-     * Called by IntermediateParser after creation\r
-     * @access private\r
-     */\r
-    function setTutorials($tutorials)\r
-    {\r
-        $this->tutorials = $tutorials;\r
-    }\r
-\r
-    /**\r
-     * @param pkg|cls|proc the tutorial type to search for\r
-     * @param tutorial name\r
-     * @param string package name\r
-     * @param string subpackage name, if any\r
-     * @return false|parserTutorial if the tutorial exists, return it\r
-     */\r
-    function hasTutorial($type, $name, $package, $subpackage = '')\r
-    {\r
-        if (isset($this->tutorials[$package][$subpackage][$type][$name . '.' . $type]))\r
-            return $this->tutorials[$package][$subpackage][$type][$name . '.' . $type];\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Called by {@link walk()} while converting, when the last class element\r
-     * has been parsed.\r
-     *\r
-     * A Converter can use this method in any way it pleases. HTMLframesConverter\r
-     * uses it to complete the template for the class and to output its\r
-     * documentation\r
-     * @see HTMLframesConverter::endClass()\r
-     * @abstract\r
-     */\r
-    function endClass()\r
-    {\r
-    }\r
-\r
-    /**\r
-    * Called by {@link walk()} while converting, when the last procedural page\r
-    * element has been parsed.\r
-    *\r
-    * A Converter can use this method in any way it pleases. HTMLframesConverter\r
-    * uses it to complete the template for the procedural page and to output its\r
-    * documentation\r
-    * @see HTMLframesConverter::endClass()\r
-    * @abstract\r
-    */\r
-    function endPage()\r
-    {\r
-    }\r
-\r
-    /**\r
-    * Called by {@link walk()} while converting.\r
-    *\r
-    * This method is intended to be the place that {@link $pkg_elements} is\r
-    * formatted for output.\r
-    * @see HTMLframesConverter::formatPkgIndex()\r
-    * @abstract\r
-    */\r
-    function formatPkgIndex()\r
-    {\r
-    }\r
-\r
-    /**\r
-    * Called by {@link walk()} while converting.\r
-    *\r
-    * This method is intended to be the place that {@link $elements} is\r
-    * formatted for output.\r
-    * @see HTMLframesConverter::formatIndex()\r
-    * @abstract\r
-    */\r
-    function formatIndex()\r
-    {\r
-    }\r
-\r
-    /**\r
-    * Called by {@link walk()} while converting.\r
-    *\r
-    * This method is intended to be the place that any of\r
-    * {@link $class_elements, $function_elements, $page_elements},\r
-    * {@link $define_elements}, and {@link $global_elements} is formatted for\r
-    * output, depending on the value of {@link $leftindex}\r
-    * @see HTMLframesConverter::formatLeftIndex()\r
-    * @abstract\r
-    */\r
-    function formatLeftIndex()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Called by {@link parserSourceInlineTag::stringConvert()} to allow\r
-     * converters to format the source code the way they'd like.\r
-     *\r
-     * default returns it unchanged (html with xhtml tags)\r
-     * @param string output from highlight_string() - use this function to\r
-     * reformat the returned data for Converter-specific output\r
-     * @return string\r
-     * @deprecated in favor of tokenizer-based highlighting.  This will be\r
-     *             removed for 2.0\r
-     */\r
-    function unmangle($sourcecode)\r
-    {\r
-        return $sourcecode;\r
-    }\r
-\r
-    /**\r
-     * Initialize highlight caching\r
-     */\r
-    function startHighlight()\r
-    {\r
-        $this->_highlightCache = array(false, false);\r
-        $this->_appendHighlight = '';\r
-    }\r
-\r
-    function getHighlightState()\r
-    {\r
-        return $this->_highlightCache;\r
-    }\r
-\r
-    function _setHighlightCache($type, $token)\r
-    {\r
-        $test = ($this->_highlightCache[0] === $type && $this->_highlightCache[1] == $token);\r
-        if (!$test) {\r
-            $this->_appendHighlight = $this->flushHighlightCache();\r
-        } else {\r
-            $this->_appendHighlight = '';\r
-        }\r
-        $this->_highlightCache = array($type, $token);\r
-        return $test;\r
-    }\r
-\r
-    /**\r
-     * Return the close text for the current token\r
-     * @return string\r
-     */\r
-    function flushHighlightCache()\r
-    {\r
-        $hc = $this->_highlightCache;\r
-        $this->_highlightCache = array(false, false);\r
-        if ($hc[0]) {\r
-            if (!isset($this->template_options[$hc[0]]['/'.$hc[1]])) {\r
-                return '';\r
-            }\r
-               return $this->template_options[$hc[0]]['/'.$hc[1]];\r
-        }\r
-        return '';\r
-    }\r
-\r
-    /**\r
-     * Used to allow converters to format the source code the way they'd like.\r
-     *\r
-     * default returns it unchanged.  Mainly used by the {@link HighlightParser}\r
-     * {@internal\r
-     * The method takes information from options.ini, the template options\r
-     * file, specifically the [highlightSourceTokens] and [highlightSource]\r
-     * sections, and uses them to enclose tokens.\r
-     *\r
-     * {@source}}}\r
-     * @param integer token value from {@link PHP_MANUAL#tokenizer tokenizer constants}\r
-     * @param string contents of token\r
-     * @param boolean whether the contents are preformatted or need modification\r
-     * @return string\r
-     */\r
-    function highlightSource($token, $word, $preformatted = false)\r
-    {\r
-        if ($token !== false)\r
-        {\r
-            if (!$preformatted) $word = $this->postProcess($word);\r
-            if (isset($this->template_options['highlightSourceTokens'][token_name($token)]))\r
-            {\r
-                if ($this->_setHighlightCache('highlightSourceTokens', token_name($token))) {\r
-                    return $word;\r
-                }\r
-                $e = $this->_appendHighlight;\r
-                return $e . $this->template_options['highlightSourceTokens'][token_name($token)] . $word;\r
-            } else\r
-            {\r
-                $this->_setHighlightCache(false, false);\r
-                $e = $this->_appendHighlight;\r
-                return $e . $word;\r
-            }\r
-        } else\r
-        {\r
-            if (isset($this->template_options['highlightSource'][$word]))\r
-            {\r
-                $newword = ($preformatted ? $word : $this->postProcess($word));\r
-                if ($this->_setHighlightCache('highlightSource', $word)) {\r
-                    return $newword;\r
-                }\r
-                $e = $this->_appendHighlight;\r
-                return $e . $this->template_options['highlightSource'][$word] . $newword;\r
-            } else\r
-            {\r
-                $this->_setHighlightCache(false, false);\r
-                $e = $this->_appendHighlight;\r
-                return $e . ($preformatted ? $word : $this->postProcess($word));\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Used to allow converters to format the source code of DocBlocks the way\r
-     * they'd like.\r
-     *\r
-     * default returns it unchanged.  Mainly used by the {@link HighlightParser}\r
-     * {@internal\r
-     * The method takes information from options.ini, the template options\r
-     * file, specifically the [highlightDocBlockSourceTokens] section, and uses\r
-     * it to enclose tokens.\r
-     *\r
-     * {@source}}}\r
-     * @param string name of docblock token type\r
-     * @param string contents of token\r
-     * @param boolean whether the contents are preformatted or need modification\r
-     * @return string\r
-     */\r
-    function highlightDocBlockSource($token, $word, $preformatted = false)\r
-    {\r
-        if (empty($word)) {\r
-            $this->_setHighlightCache(false, false);\r
-            $e = $this->_appendHighlight;\r
-            return $e . $word;\r
-        }\r
-        if (isset($this->template_options['highlightDocBlockSourceTokens'][$token]))\r
-        {\r
-            if (!$preformatted) $word = $this->postProcess($word);\r
-            if ($this->_setHighlightCache('highlightDocBlockSourceTokens', $token)) {\r
-                return $word;\r
-            }\r
-            $e = $this->_appendHighlight;\r
-            return $e . $this->template_options['highlightDocBlockSourceTokens'][$token] . $word;\r
-        } else {\r
-            $this->_setHighlightCache(false, false);\r
-            $e = $this->_appendHighlight;\r
-            return $e . ($preformatted ? $word : $this->postProcess($word));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Used to allow converters to format the source code of Tutorial XML the way\r
-     * they'd like.\r
-     *\r
-     * default returns it unchanged.  Mainly used by the {@link HighlightParser}\r
-     * {@internal\r
-     * The method takes information from options.ini, the template options\r
-     * file, specifically the [highlightDocBlockSourceTokens] section, and uses\r
-     * it to enclose tokens.\r
-     *\r
-     * {@source}}}\r
-     * @param string name of docblock token type\r
-     * @param string contents of token\r
-     * @param boolean whether the contents are preformatted or need modification\r
-     * @return string\r
-     */\r
-    function highlightTutorialSource($token, $word, $preformatted = false)\r
-    {\r
-        if (empty($word)) {\r
-            $this->_setHighlightCache(false, false);\r
-            $e = $this->_appendHighlight;\r
-            return $e . $word;\r
-        }\r
-        if (isset($this->template_options['highlightTutorialSourceTokens'][$token]))\r
-        {\r
-            if (!$preformatted) $word = $this->postProcess($word);\r
-            if ($this->_setHighlightCache('highlightTutorialSourceTokens', $token)) {\r
-                return $word;\r
-            }\r
-            $e = $this->_appendHighlight;\r
-            return $e . $this->template_options['highlightTutorialSourceTokens'][$token] . $word;\r
-        } else {\r
-            $this->_setHighlightCache(false, false);\r
-            $e = $this->_appendHighlight;\r
-            return $e . ($preformatted ? $word : $this->postProcess($word));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Called by {@link parserReturnTag::Convert()} to allow converters to\r
-     * change type names to desired formatting\r
-     *\r
-     * Used by {@link XMLDocBookConverter::type_adjust()} to change true and\r
-     * false to the peardoc2 values\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function type_adjust($typename)\r
-    {\r
-        return $typename;\r
-    }\r
-\r
-    /**\r
-     * Used to convert the {@}example} inline tag in a docblock.\r
-     *\r
-     * By default, this just wraps ProgramExample\r
-     * @see XMLDocBookpeardoc2Converter::exampleProgramExample\r
-     * @param string\r
-     * @param boolean true if this is to highlight a tutorial <programlisting>\r
-     * @return string\r
-     */\r
-    function exampleProgramExample($example, $tutorial = false, $inlinesourceparse = null/*false*/,\r
-                            $class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/)\r
-    {\r
-        return $this->ProgramExample($example, $tutorial, $inlinesourceparse, $class, $linenum, $filesourcepath);\r
-    }\r
-\r
-    /**\r
-     * Used to convert the <<code>> tag in a docblock\r
-     * @param string\r
-     * @param boolean true if this is to highlight a tutorial <programlisting>\r
-     * @return string\r
-     */\r
-    function ProgramExample($example, $tutorial = false, $inlinesourceparse = null/*false*/,\r
-                            $class = null/*false*/, $linenum = null/*false*/, $filesourcepath = null/*false*/)\r
-    {\r
-        $this->highlightingSource = true;\r
-        if (tokenizer_ext)\r
-        {\r
-            $e = $example;\r
-            if (!is_array($example))\r
-            {\r
-                $obj = new phpDocumentorTWordParser;\r
-                $obj->setup($example);\r
-                $e = $obj->getFileSource();\r
-                $bOpenTagFound = false;\r
-                foreach ($e as $ke => $ee)\r
-                {\r
-                    foreach ($ee as $kee => $eee)\r
-                    {\r
-                        if ((int) $e[$ke][$kee][0] == T_OPEN_TAG)\r
-                        {\r
-                            $bOpenTagFound = true;\r
-                        }\r
-                    }\r
-                }\r
-                if (!$bOpenTagFound) {\r
-                    $example = "<?php\n".$example;\r
-                    $obj->setup($example);\r
-                    $e = $obj->getFileSource();\r
-                    unset($e[0]);\r
-                    $e = array_values($e);\r
-                }\r
-                unset($obj);\r
-            }\r
-            $saveclass = $this->class;\r
-            $parser = new phpDocumentor_HighlightParser;\r
-            if (!isset($inlinesourceparse))\r
-            {\r
-                $example = $parser->parse($e, $this, true); // force php mode\r
-            } else\r
-            {\r
-                if (isset($filesourcepath))\r
-                {\r
-                    $example = $parser->parse($e, $this, $inlinesourceparse, $class, $linenum, $filesourcepath);\r
-                } elseif (isset($linenum))\r
-                {\r
-                    $example = $parser->parse($e, $this, $inlinesourceparse, $class, $linenum);\r
-                } elseif (isset($class))\r
-                {\r
-                    $example = $parser->parse($e, $this, $inlinesourceparse, $class);\r
-                } else\r
-                {\r
-                    $example = $parser->parse($e, $this, $inlinesourceparse);\r
-                }\r
-            }\r
-            $this->class = $saveclass;\r
-        } else\r
-        {\r
-            $example = $this->postProcess($example);\r
-        }\r
-        $this->highlightingSource = false;\r
-\r
-        if ($tutorial)\r
-        {\r
-            return $example;\r
-        }\r
-\r
-        if (!isset($this->template_options['desctranslate'])) return $example;\r
-        if (!isset($this->template_options['desctranslate']['code'])) return $example;\r
-        $example = $this->template_options['desctranslate']['code'] . $example;\r
-        if (!isset($this->template_options['desctranslate']['/code'])) return $example;\r
-        return $example . $this->template_options['desctranslate']['/code'];\r
-    }\r
-\r
-    /**\r
-     * @param string\r
-     */\r
-    function TutorialExample($example)\r
-    {\r
-        $this->highlightingSource = true;\r
-        $parse = new phpDocumentor_TutorialHighlightParser;\r
-        $x = $parse->parse($example, $this);\r
-        $this->highlightingSource = false;\r
-        return $x;\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<li>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function ListItem($item)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $item;\r
-        if (!isset($this->template_options['desctranslate']['li'])) return $item;\r
-        $item = $this->template_options['desctranslate']['li'] . $item;\r
-        if (!isset($this->template_options['desctranslate']['/li'])) return $item;\r
-        return $item . $this->template_options['desctranslate']['/li'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<ol>> or <<ul>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function EncloseList($list,$ordered)\r
-    {\r
-        $listname = ($ordered ? 'ol' : 'ul');\r
-        if (!isset($this->template_options['desctranslate'])) return $list;\r
-        if (!isset($this->template_options['desctranslate'][$listname])) return $list;\r
-        $list = $this->template_options['desctranslate'][$listname] . $list;\r
-        if (!isset($this->template_options['desctranslate']['/'.$listname])) return $list;\r
-        return $list . $this->template_options['desctranslate']['/'.$listname];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<pre>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function PreserveWhiteSpace($string)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $string;\r
-        if (!isset($this->template_options['desctranslate']['pre'])) return $string;\r
-        $string = $this->template_options['desctranslate']['pre'] . $string;\r
-        if (!isset($this->template_options['desctranslate']['/pre'])) return $string;\r
-        return $string . $this->template_options['desctranslate']['/pre'];\r
-    }\r
-\r
-    /**\r
-     * Used to enclose a paragraph in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function EncloseParagraph($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['p'])) return $para;\r
-        $para = $this->template_options['desctranslate']['p'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/p'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/p'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<b>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Bolden($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['b'])) return $para;\r
-        $para = $this->template_options['desctranslate']['b'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/b'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/b'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<i>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Italicize($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['i'])) return $para;\r
-        $para = $this->template_options['desctranslate']['i'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/i'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/i'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<var>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Varize($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['var'])) return $para;\r
-        $para = $this->template_options['desctranslate']['var'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/var'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/var'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<kbd>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Kbdize($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['kbd'])) return $para;\r
-        $para = $this->template_options['desctranslate']['kbd'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/kbd'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/kbd'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert the contents of <<samp>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Sampize($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['samp'])) return $para;\r
-        $para = $this->template_options['desctranslate']['samp'] . $para;\r
-        if (!isset($this->template_options['desctranslate']['/samp'])) return $para;\r
-        return $para . $this->template_options['desctranslate']['/samp'];\r
-    }\r
-\r
-    /**\r
-     * Used to convert <<br>> in a docblock\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function Br($para)\r
-    {\r
-        if (!isset($this->template_options['desctranslate'])) return $para;\r
-        if (!isset($this->template_options['desctranslate']['br'])) return $para;\r
-        $para = $this->template_options['desctranslate']['br'] . $para;\r
-        return $para;\r
-    }\r
-\r
-    /**\r
-     * This version does nothing\r
-     *\r
-     * Perform necessary post-processing of string data.  For example, the HTML\r
-     * Converters should escape < and > to become &lt; and &gt;\r
-     * @return string\r
-     */\r
-    function postProcess($text)\r
-    {\r
-        return $text;\r
-    }\r
-\r
-    /**\r
-     * Creates a table of contents for a {@}toc} inline tag in a tutorial\r
-     *\r
-     * This function should return a formatted table of contents.  By default, it\r
-     * does nothing, it is up to the converter to format the TOC\r
-     * @abstract\r
-     * @return string table of contents formatted for use in the current output format\r
-     * @param array format: array(array('tagname' => section, 'link' => returnsee link, 'id' => anchor name, 'title' => from title tag),...)\r
-     */\r
-    function formatTutorialTOC($toc)\r
-    {\r
-        return '';\r
-    }\r
-\r
-    /**\r
-     * Write out the formatted source code for a php file\r
-     *\r
-     * This function provides the primary functionality for the\r
-     * {@tutorial tags.filesource.pkg} tag.\r
-     * @param string full path to the file\r
-     * @param string fully highlighted/linked source code of the file\r
-     * @abstract\r
-     */\r
-    function writeSource($filepath, $source)\r
-    {\r
-        debug($source);\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * Write out the formatted source code for an example php file\r
-     *\r
-     * This function provides the primary functionality for the\r
-     * {@tutorial tags.example.pkg} tag.\r
-     * @param string example title\r
-     * @param string example filename (no path)\r
-     * @param string fully highlighted/linked source code of the file\r
-     * @abstract\r
-     */\r
-    function writeExample($title, $path, $source)\r
-    {\r
-        return;\r
-    }\r
-\r
-    /** Translate the path info into a unique file name for the highlighted\r
-     * source code.\r
-     * @param string $pathinfo\r
-     * @return string\r
-     */\r
-    function getFileSourceName($path)\r
-    {\r
-        global $_phpDocumentor_options;\r
-        $pathinfo = $this->proceduralpages->getPathInfo($path, $this);\r
-        $pathinfo['source_loc'] = str_replace($_phpDocumentor_options['Program_Root'].'/','',$pathinfo['source_loc']);\r
-        $pathinfo['source_loc'] = str_replace('/','_',$pathinfo['source_loc']);\r
-        return "fsource_{$pathinfo['package']}_{$pathinfo['subpackage']}_{$pathinfo['source_loc']}";\r
-    }\r
-\r
-    /** Return the fixed path to the source-code file folder.\r
-     * @param string $base Path is relative to this folder\r
-     * @return string\r
-     */\r
-    function getFileSourcePath($base)\r
-    {\r
-        if (substr($base, strlen($base) - 1) != PATH_DELIMITER) {\r
-            $base .= PATH_DELIMITER;\r
-        }\r
-        return $base . '__filesource';\r
-    }\r
-\r
-    /** Return the path to the current\r
-     * @param string $pathinfo\r
-     * @return string\r
-     */\r
-    function getCurrentPageURL()\r
-    {\r
-        return '{$srcdir}' . PATH_DELIMITER . $this->page_dir;\r
-    }\r
-\r
-    /**\r
-     * @return string an output-format dependent link to phpxref-style highlighted\r
-     * source code\r
-     * @abstract\r
-     */\r
-    function getSourceLink($path)\r
-    {\r
-        return '';\r
-    }\r
-\r
-    /**\r
-     * @return string Link to the current page being parsed.\r
-     * Should return {@link $curname} and a converter-specific extension.\r
-     * @abstract\r
-     */\r
-    function getCurrentPageLink()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Return a line of highlighted source code with formatted line number\r
-     *\r
-     * If the $path is a full path, then an anchor to the line number will be\r
-     * added as well\r
-     * @param integer line number\r
-     * @param string highlighted source code line\r
-     * @param false|string full path to @filesource file this line is a part of,\r
-     *        if this is a single line from a complete file.\r
-     * @return string formatted source code line with line number\r
-     */\r
-    function sourceLine($linenumber, $line, $path = false)\r
-    {\r
-        if ($path)\r
-        {\r
-            return $this->getSourceAnchor($path, $linenumber) .\r
-                   $this->Br(sprintf('%-6u',$linenumber).str_replace("\n",'',$line));\r
-        } else\r
-        {\r
-            return $this->Br(sprintf('%-6u',$linenumber).str_replace("\n",'',$line));\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Determine whether an element's file has generated source code, used for\r
-     * linking to line numbers of source.\r
-     *\r
-     * Wrapper for {@link $sourcePaths} in this version\r
-     * @param string full path to the source code file\r
-     * @return boolean\r
-     */\r
-    function hasSourceCode($path)\r
-    {\r
-        return isset($this->sourcePaths[$path]);\r
-    }\r
-\r
-    /**\r
-     * Mark a file as having had source code highlighted\r
-     * @param string full path of source file\r
-     */\r
-    function setSourcePaths($path)\r
-    {\r
-        $this->sourcePaths[$path] = true;\r
-    }\r
-\r
-    /**\r
-     * Used to translate an XML DocBook entity like &rdquo; from a tutorial by\r
-     * reading the options.ini file for the template.\r
-     * @param string entity name\r
-     */\r
-    function TranslateEntity($name)\r
-    {\r
-        if (!isset($this->template_options['ppage']))\r
-        {\r
-            if (!$this->template_options['preservedocbooktags'])\r
-            return '';\r
-            else\r
-            return '&'.$name.';';\r
-        }\r
-        if (isset($this->template_options['ppage']['&'.$name.';']))\r
-        {\r
-            return $this->template_options['ppage']['&'.$name.';'];\r
-        } else\r
-        {\r
-            if (!$this->template_options['preservedocbooktags'])\r
-            return '';\r
-            else\r
-            return '&'.$name.';';\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Used to translate an XML DocBook tag from a tutorial by reading the\r
-     * options.ini file for the template.\r
-     * @param string tag name\r
-     * @param string any attributes Format: array(name => value)\r
-     * @param string the tag contents, if any\r
-     * @param string the tag contents, if any, unpost-processed\r
-     * @return string\r
-     */\r
-    function TranslateTag($name,$attr,$cdata,$unconvertedcdata)\r
-    {\r
-        if (!isset($this->template_options['ppage']))\r
-        {\r
-            if (!$this->template_options['preservedocbooktags'])\r
-            return $cdata;\r
-            else\r
-            return '<'.$name.$this->AttrToString($name,$attr,true).'>'.$cdata.'</'.$name.'>'."\n";\r
-        }\r
-        // make sure this template transforms the tag into something\r
-        if (isset($this->template_options['ppage'][$name]))\r
-        {\r
-            // test for global attribute transforms like $attr$role = class, changing\r
-            // all role="*" attributes to class="*" in html, for example\r
-            foreach($attr as $att => $val)\r
-            {\r
-                if (isset($this->template_options['$attr$'.$att]))\r
-                {\r
-                    $new = '';\r
-                    if (!isset($this->template_options['$attr$'.$att]['close']))\r
-                    {\r
-                        $new .= '<'.$this->template_options['$attr$'.$att]['open'];\r
-                        if (isset($this->template_options['$attr$'.$att]['cdata!']))\r
-                        {\r
-                            if (isset($this->template_options['$attr$'.$att]['separateall']))\r
-                            $new .= $this->template_options['$attr$'.$att]['separator'];\r
-                            else\r
-                            $new .= ' ';\r
-                            $new .= $this->template_options['$attr$'.$att]['$'.$att];\r
-                            $new .= $this->template_options['$attr$'.$att]['separator'];\r
-                            if ($this->template_options['$attr$'.$att]['quotevalues']) $val = '"'.$val.'"';\r
-                            $new .= $val.'>';\r
-                        } else\r
-                        {\r
-                            $new .= '>'.$val;\r
-                        }\r
-                        $new .= '</'.$this->template_options['$attr$'.$att]['open'].'>';\r
-                    } else\r
-                    {\r
-                        $new .= $this->template_options['$attr$'.$att]['open'] . $val . $this->template_options['$attr$'.$att]['close'];\r
-                    }\r
-                    unset($attr[$att]);\r
-                    $cdata = $new . $cdata;\r
-                }\r
-            }\r
-\r
-            if (!isset($this->template_options['ppage']['/'.$name]))\r
-            {// if the close tag isn't specified, we put opening and closing tags around it, with translated attributes\r
-                if (isset($this->template_options['ppage'][$name.'/']))\r
-                $cdata = '<'.$this->template_options['ppage'][$name].$this->AttrToString($name,$attr).'/>' . $cdata;\r
-                else\r
-                $cdata = '<'.$this->template_options['ppage'][$name].$this->AttrToString($name,$attr).'>' . $cdata .\r
-                         '</'.$this->template_options['ppage'][$name].'>';\r
-            } else\r
-            { // if close tag is specified, use the open and close as literal\r
-                if ($name == 'programlisting' && isset($attr['role']) &&\r
-                      ($attr['role'] == 'php' || $attr['role'] == 'tutorial' || $attr['role'] == 'html'))\r
-                { // highlight PHP source\r
-//                    var_dump($unconvertedcdata, $cdata);exit;\r
-                    if ($attr['role'] == 'php') {\r
-                        $cdata = $this->ProgramExample($unconvertedcdata, true);\r
-                    } elseif ($attr['role'] == 'tutorial') {\r
-                        $cdata = $this->TutorialExample($unconvertedcdata);\r
-                    } elseif ($attr['role'] == 'html') {\r
-                        $cdata = $unconvertedcdata;\r
-                    }\r
-                } else\r
-                {// normal case below\r
-                    $cdata = $this->template_options['ppage'][$name].$this->AttrToString($name,$attr). $cdata .$this->template_options['ppage']['/'.$name];\r
-                }\r
-            }\r
-            return $cdata;\r
-        } else\r
-        {\r
-            if ($this->template_options['preservedocbooktags'])\r
-            {\r
-                return '<'.$name.$this->AttrToString($name,$attr,true).'>' . $cdata .\r
-                         '</'.$name.'>'."\n";\r
-            } else\r
-            {\r
-                return $cdata;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Convert the attribute of a Tutorial docbook tag's attribute list\r
-     * to a string based on the template options.ini\r
-     * @param string tag name\r
-     * @param attribute array\r
-     * @param boolean if true, returns attrname="value"...\r
-     * @return string\r
-     */\r
-    function AttrToString($tag,$attr,$unmodified = false)\r
-    {\r
-        $ret = '';\r
-        if ($unmodified)\r
-        {\r
-            $ret = ' ';\r
-            foreach($attr as $n => $v)\r
-            {\r
-                $ret .= $n.' = "'.$v.'"';\r
-            }\r
-            return $ret;\r
-        }\r
-        // no_attr tells us to ignore all attributes\r
-        if (isset($this->template_options['no_attr'])) return $ret;\r
-        // tagname! tells us to ignore all attributes for this tag\r
-        if (isset($this->template_options['ppage'][$tag.'!'])) return $ret;\r
-        if (count($attr)) $ret = ' ';\r
-        // pass 1, check to see if any attributes add together\r
-        $same = array();\r
-        foreach($attr as $n => $v)\r
-        {\r
-            if (isset($this->template_options['ppage'][$tag.'->'.$n]))\r
-            {\r
-                $same[$this->template_options['ppage'][$tag.'->'.$n]][] = $n;\r
-            }\r
-        }\r
-        foreach($attr as $n => $v)\r
-        {\r
-            if (isset($this->template_options['ppage'][$tag.'->'.$n]))\r
-            {\r
-                if (count($same[$this->template_options['ppage'][$tag.'->'.$n]]) == 1)\r
-                { // only 1 attribute translated for this one\r
-                    // this is useful for equivalent value names\r
-                    if (isset($this->template_options['ppage'][$tag.'->'.$n.'+'.$v])) $v = $this->template_options['ppage'][$tag.'->'.$n.'+'.$v];\r
-                } else\r
-                { // more than 1 attribute combines to make the new attribute\r
-                    $teststrtemp = array();\r
-                    foreach($same[$this->template_options['ppage'][$tag.'->'.$n]] as $oldattr)\r
-                    {\r
-                        $teststrtemp[] = $oldattr.'+'.$attr[$oldattr];\r
-                    }\r
-                    $teststrs = array();\r
-                    $num = count($same[$this->template_options['ppage'][$tag.'->'.$n]]);\r
-                    for($i=0;$i<$num;$i++)\r
-                    {\r
-                        $started = false;\r
-                        $a = '';\r
-                        for($j=$i;!$started || $j != $i;$j = ($j + $i) % $num)\r
-                        {\r
-                            if (!empty($a)) $a .= '|';\r
-                            $a .= $teststrtemp[$j];\r
-                        }\r
-                        $teststrs[$i] = $a;\r
-                    }\r
-                    $done = false;\r
-                    foreach($teststrs as $test)\r
-                    {\r
-                        if ($done) break;\r
-                        if (isset($this->template_options['ppage'][$tag.'->'.$test]))\r
-                        {\r
-                            $done = true;\r
-                            $v = $this->template_options['ppage'][$tag.'->'.$test];\r
-                        }\r
-                    }\r
-                }\r
-                $ret .= $this->template_options['ppage'][$tag.'->'.$n].' = "'.$v.'"';\r
-            } else\r
-            {\r
-                if (!isset($this->template_options['ppage'][$tag.'!'.$n]))\r
-                {\r
-                    if (isset($this->template_options['ppage']['$attr$'.$n]))\r
-                    $ret .= $this->template_options['ppage']['$attr$'.$n].' = "'.$v.'"';\r
-                    else\r
-                    $ret .= $n.' = "'.$v.'"';\r
-                }\r
-            }\r
-        }\r
-        return $ret;\r
-    }\r
-\r
-    /**\r
-     * Convert the title of a Tutorial docbook tag section\r
-     * to a string based on the template options.ini\r
-     * @param string tag name\r
-     * @param array\r
-     * @param string title text\r
-     * @param string\r
-     * @return string\r
-     */\r
-    function ConvertTitle($tag,$attr,$title,$cdata)\r
-    {\r
-        if (!isset($this->template_options[$tag.'_title'])) return array($attr,$cdata);\r
-        if (isset($this->template_options[$tag.'_title']['tag_attr']))\r
-        {\r
-            $attr[$this->template_options[$tag.'_title']['tag_attr']] = urlencode($cdata);\r
-            $cdata = '';\r
-        } elseif(isset($this->template_options[$tag.'_title']['cdata_start']))\r
-        {\r
-            $cdata = $this->template_options[$tag.'_title']['open'] . $title .\r
-                     $this->template_options[$tag.'_title']['close'] . $cdata;\r
-        } else $cdata = $title.$cdata;\r
-        return array($attr,$cdata);\r
-    }\r
-\r
-    /**\r
-     * Return a converter-specific id to distinguish tutorials and their\r
-     * sections\r
-     *\r
-     * Used by {@}id}\r
-     * @return string\r
-     */\r
-    function getTutorialId($package,$subpackage,$tutorial,$id)\r
-    {\r
-        return $package.$subpackage.$tutorial.$id;\r
-    }\r
-\r
-    /**\r
-     * Create the {@link $elements, $pkg_elements} and {@link $links} arrays\r
-     * @access private\r
-     * @todo version 2.0 - faulty package_output logic should be removed\r
-     *\r
-     *       in this version, if the parent file isn't in the package, all\r
-     *       the procedural elements are simply shunted to another package!\r
-     */\r
-    function _createPkgElements(&$pages)\r
-    {\r
-        if (empty($this->elements))\r
-        {\r
-            $this->elements = array();\r
-            $this->pkg_elements = array();\r
-            $this->links = array();\r
-            phpDocumentor_out('Building indexes...');\r
-            flush();\r
-            foreach($pages as $j => $flub)\r
-            {\r
-                $this->package = $pages[$j]->parent->package;\r
-                $this->subpackage = $pages[$j]->parent->subpackage;\r
-                $this->class = false;\r
-                $this->curfile = $pages[$j]->parent->getFile();\r
-                $this->curname = $this->getPageName($pages[$j]->parent);\r
-                $this->curpath = $pages[$j]->parent->getPath();\r
-                $use = true;\r
-                if ($this->package_output)\r
-                {\r
-                    if (in_array($this->package,$this->package_output))\r
-                    {\r
-                        $this->addElement($pages[$j]->parent,$pages[$j]);\r
-                    } else\r
-                    {\r
-                        if (count($pages[$j]->classelements))\r
-                        {\r
-                            list(,$pages[$j]->parent->package) = each($this->package_output);\r
-                            reset($this->package_output);\r
-                            $pages[$j]->parent->subpackage = '';\r
-                            $this->addElement($pages[$j]->parent,$pages[$j]);\r
-                        } else\r
-                        {\r
-                            unset($pages[$j]);\r
-                            continue;\r
-                        }\r
-                    }\r
-                } else\r
-                {\r
-                    $this->addElement($pages[$j]->parent,$pages[$j]);\r
-                }\r
-                if ($use)\r
-                for($i=0; $i<count($pages[$j]->elements); $i++)\r
-                {\r
-                    $pages[$j]->elements[$i]->docblock->package = $this->package;\r
-                    $pages[$j]->elements[$i]->docblock->subpackage = $this->subpackage;\r
-                    $this->proceduralpages->replaceElement($pages[$j]->elements[$i]);\r
-                    $this->addElement($pages[$j]->elements[$i]);\r
-                }\r
-                for($i=0; $i<count($pages[$j]->classelements); $i++)\r
-                {\r
-                    if ($this->class)\r
-                    {\r
-                        if ($pages[$j]->classelements[$i]->type == 'class')\r
-                        {\r
-                            if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;\r
-                            $this->package = $pages[$j]->classelements[$i]->docblock->package;\r
-                            if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;\r
-                            $this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;\r
-                            $this->class = $pages[$j]->classelements[$i]->name;\r
-                        } else\r
-                        {\r
-                            if ($this->killclass) continue;\r
-                            // force all contained elements to have parent package/subpackage\r
-                            $pages[$j]->classelements[$i]->docblock->package = $this->package;\r
-                            $pages[$j]->classelements[$i]->docblock->subpackage = $this->subpackage;\r
-                        }\r
-                    }\r
-                    if ($pages[$j]->classelements[$i]->type == 'class')\r
-                    {\r
-                        if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;\r
-                        $this->package = $pages[$j]->classelements[$i]->docblock->package;\r
-                        if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;\r
-                        $this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;\r
-                        $this->class = $pages[$j]->classelements[$i]->name;\r
-                    }\r
-                    if (!$this->killclass) $this->addElement($pages[$j]->classelements[$i]);\r
-                }\r
-            }\r
-            phpDocumentor_out("done\n");\r
-            flush();\r
-        }\r
-        $this->sortIndexes();\r
-        $this->sortTodos();\r
-        if ($this->sort_page_contents_by_type) $this->sortPageContentsByElementType($pages);\r
-    }\r
-\r
-    /**\r
-     * Process the {@link $tutorials} array\r
-     *\r
-     * Using the tutorialname.ext.ini files, this method sets up tutorial\r
-     * hierarchy.  There is some minimal error checking to make sure that no\r
-     * tutorial links to itself, even two levels deep as in tute->next->tute.\r
-     *\r
-     * If all tests pass, it creates the hierarchy\r
-     * @uses generateTutorialOrder()\r
-     * @uses _setupTutorialTree()\r
-     * @access private\r
-     */\r
-    function _processTutorials()\r
-    {\r
-        $parents = $all = array();\r
-        foreach($this->tutorials as $package => $els)\r
-        {\r
-            if ($this->package_output)\r
-            {\r
-                if (!in_array($package,$this->package_output))\r
-                {\r
-                    unset($this->tutorials[$package]);\r
-                    continue;\r
-                }\r
-            }\r
-            if (!isset($this->pkg_elements[$package]))\r
-            {\r
-                unset($this->tutorials[$package]);\r
-                continue;\r
-            }\r
-            foreach($els as $subpackage => $els2)\r
-            {\r
-                foreach($els2 as $type => $tutorials)\r
-                {\r
-                    foreach($tutorials as $tutorial)\r
-                    {\r
-                        if ($tutorial->ini)\r
-                        {\r
-                            if (isset($tutorial->ini['Linked Tutorials']))\r
-                            {\r
-                                foreach($tutorial->ini['Linked Tutorials'] as $child)\r
-                                {\r
-                                    $sub = (empty($tutorial->subpackage) ? '' : $tutorial->subpackage . '/');\r
-                                    $kid = $tutorial->package . '/' . $sub . $child . '.' . $tutorial->tutorial_type;\r
-                                    // parent includes self as a linked tutorial?\r
-                                    $kidlink = $this->getTutorialLink($kid,false,false,array($tutorial->package));\r
-                                    if (is_object($kidlink) && $this->returnSee($kidlink) == $tutorial->getLink($this))\r
-                                    { // bad!\r
-                                        addErrorDie(PDERROR_TUTORIAL_IS_OWN_CHILD,$tutorial->name,$tutorial->name.'.ini');\r
-                                    }\r
-                                }\r
-                                $parents[] = $tutorial;\r
-                            }\r
-                        }\r
-                        $all[$package][$subpackage][$type][] = $tutorial;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        // loop error-checking, use this to eliminate possibility of accidentally linking to a parent as a child\r
-        $testlinks = array();\r
-        foreach($parents as $parent)\r
-        {\r
-            $testlinks[$parent->name]['links'][] = $parent->getLink($this);\r
-            $testlinks[$parent->name]['name'][$parent->getLink($this)] = $parent->name;\r
-        }\r
-        // generate the order of tutorials, and link them together\r
-        foreach($parents as $parent)\r
-        {\r
-            foreach($parent->ini['Linked Tutorials'] as $child)\r
-            {\r
-                $sub = (empty($parent->subpackage) ? '' : $parent->subpackage . '/');\r
-                $kid = $parent->package . '/' . $sub . $child . '.' . $parent->tutorial_type;\r
-                // child tutorials must be in the same package AND subpackage\r
-                // AND have the same extension as the parent, makes things clearer for both ends\r
-                if (in_array($this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package))),$testlinks[$parent->name]['links']))\r
-                    addErrorDie(PDERROR_TUTORIAL_IS_OWN_GRANDPA,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name,$testlinks[$parent->name][$this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package)))],$kid->name.'.ini');\r
-                if ($this->returnSee($this->getTutorialLink($kid,false,false,array($parent->package))) == $kid)\r
-                {\r
-                    addWarning(PDERROR_CHILD_TUTORIAL_NOT_FOUND, $child . '.' . $parent->tutorial_type, $parent->name .'.ini',$parent->package, $parent->subpackage);\r
-                }\r
-            }\r
-        }\r
-        $new = $tree = $roots = array();\r
-        // build a list of all 'root' tutorials (tutorials without parents).\r
-        foreach($parents as $i => $parent)\r
-        {\r
-            if (! $parent->isChildOf($parents)) {\r
-                $roots[] = $parent;\r
-            }\r
-        }\r
-        $parents = $roots;\r
-        // add the parents and all child tutorials in order to the list of tutorials to process\r
-        foreach($parents as $parent)\r
-        {\r
-            $this->generateTutorialOrder($parent,$all,$new);\r
-        }\r
-        if (count($all))\r
-        {\r
-            // add the leftover tutorials\r
-            foreach($all as $package => $els)\r
-            {\r
-                foreach($els as $subpackage => $els2)\r
-                {\r
-                    foreach($els2 as $type => $tutorials)\r
-                    {\r
-                        foreach($tutorials as $tutorial)\r
-                        {\r
-                            $new[$package][$subpackage][$type][] = $tutorial;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        // remove the old, unprocessed tutorials, and set it up with the next code\r
-        $this->tutorials = array();\r
-        // reset integrity of the tutorial list\r
-        $prev = false;\r
-        uksort($new, 'tutorialcmp');\r
-//        debug($this->vardump_tree($new));exit;\r
-        foreach($new as $package => $els)\r
-        {\r
-            foreach($els as $subpackage => $els2)\r
-            {\r
-                foreach($els2 as $type => $tutorials)\r
-                {\r
-                    foreach($tutorials as $tutorial)\r
-                    {\r
-                        if ($prev)\r
-                        {\r
-                            $this->tutorials[$prevpackage][$prevsubpackage][$prevtype][$prevname]->setNext($tutorial,$this);\r
-                            $tutorial->setPrev($prev,$this);\r
-                        }\r
-                        $this->tutorials[$package][$subpackage][$type][$tutorial->name] = $tutorial;\r
-                        $prev = $tutorial->getLink($this,true);\r
-                        $prevpackage = $package;\r
-                        $prevsubpackage = $subpackage;\r
-                        $prevtype = $type;\r
-                        $prevname = $tutorial->name;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        $this->tutorial_tree = $this->_setupTutorialTree();\r
-        return $new;\r
-    }\r
-\r
-    /**\r
-    * called by {@link phpDocumentor_IntermediateParser::Convert()} to traverse\r
-    * the array of pages and their elements, converting them to the output format\r
-    *\r
-    * The walk() method should be flexible enough such that it never needs\r
-    * modification.  walk() sets up all of the indexes, and sorts everything in\r
-    * logical alphabetical order.  It then passes each element individually to\r
-    * {@link Convert()}, which then passes to the Convert*() methods.  A child\r
-    * Converter need not override any of these unless special functionality must\r
-    * be added. see {@tutorial Converters/template.vars.cls} for details.\r
-    * {@internal\r
-    * walk() first creates all of the indexes {@link $elements, $pkg_elements}\r
-    * and the left indexes specified by {@link $leftindexes},\r
-    * and then sorts them by calling {@link sortIndexes()}.\r
-    *\r
-    * Next, it converts all README/CHANGELOG/INSTALL-style files, using\r
-    * {@link Convert_RIC}.\r
-    *\r
-    * After this, it\r
-    * passes all package-level docs to Convert().  Then, it calls the index\r
-    * sorting functions {@link formatPkgIndex(), formatIndex()} and\r
-    * {@link formatLeftIndex()}.\r
-    *\r
-    * Finally, it converts each procedural page in alphabetical order.  This\r
-    * stage passes elements from the physical file to Convert() in alphabetical\r
-    * order.  First, procedural page elements {@link parserDefine, parserInclude}\r
-    * {@link parserGlobal}, and {@link parserFunction} are passed to Convert().\r
-    *\r
-    * Then, class elements are passed in this order: {@link parserClass}, then\r
-    * all of the {@link parserVar}s in the class and all of the\r
-    * {@link parserMethod}s in the class.  Classes are in alphabetical order,\r
-    * and both vars and methods are in alphabetical order.\r
-    *\r
-    * Finally, {@link ConvertErrorLog()} is called and the data walk is complete.}}\r
-    * @param array Format: array(fullpath => {@link parserData} structure with full {@link parserData::$elements}\r
-    *                                         and {@link parserData::$class_elements}.\r
-    * @param array Format: array({@link parserPackagePage} 1, {@link parserPackagePage} 2,...)\r
-    * @uses Converter::_createPkgElements() sets up {@link $elements} and\r
-    *       {@link $pkg_elements} array, as well as {@link $links}\r
-    */\r
-    function walk(&$pages,&$package_pages)\r
-    {\r
-        if (empty($pages))\r
-        {\r
-            die("<b>ERROR</b>: nothing parsed");\r
-        }\r
-        $this->_createPkgElements($pages);\r
-        if (count($this->ric))\r
-        {\r
-            phpDocumentor_out("Converting README/INSTALL/CHANGELOG contents...\n");\r
-            flush();\r
-            foreach($this->ric as $name => $contents)\r
-            {\r
-                phpDocumentor_out("$name...");\r
-                flush();\r
-                $this->Convert_RIC($name,$contents);\r
-            }\r
-            phpDocumentor_out("\ndone\n");\r
-            flush();\r
-        }\r
-        foreach($package_pages as $i => $perp)\r
-        {\r
-            if ($this->package_output)\r
-            {\r
-                if (!in_array($package_pages[$i]->package,$this->package_output)) continue;\r
-            }\r
-            phpDocumentor_out('Converting package page for package '.$package_pages[$i]->package.'... ');\r
-            flush();\r
-            $this->package = $package_pages[$i]->package;\r
-            $this->subpackage = '';\r
-            $this->class = false;\r
-            $this->Convert($package_pages[$i]);\r
-            phpDocumentor_out("done\n");\r
-            flush();\r
-        }\r
-        phpDocumentor_out("Converting tutorials/extended docs\n");\r
-        flush();\r
-        // get tutorials into the order they will display, and set next/prev links\r
-        $new = $this->_processTutorials();\r
-        foreach($this->tutorials as $package => $els)\r
-        {\r
-            foreach($els as $subpackage => $els2)\r
-            {\r
-                foreach($els2 as $type => $tutorials)\r
-                {\r
-                    foreach($tutorials as $tutorial)\r
-                    {\r
-                        switch ($type)\r
-                        {\r
-                            case 'pkg' :\r
-                                $a = '';\r
-                                if ($tutorial->ini)\r
-                                $a .= 'Top-level ';\r
-                                if (!empty($tutorial->subpackage))\r
-                                $a .= 'Sub-';\r
-                                $ptext = "Converting ${a}Package-level tutorial ".$tutorial->name.'...';\r
-                            break;\r
-                            case 'cls' :\r
-                                $a = '';\r
-                                if ($tutorial->ini)\r
-                                $a .= 'Top-level ';\r
-                                $ptext = "Converting ${a}Class-level tutorial " . $tutorial->name ." and associating...";\r
-                                $link = Converter::getClassLink(str_replace('.cls','',$tutorial->name), $tutorial->package);\r
-                                if (is_object($link))\r
-                                {\r
-                                    if ($this->sort_absolutely_everything)\r
-                                    {\r
-                                        $addend = 'unsuccessful ';\r
-                                        if (isset($this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name]))\r
-                                        {\r
-                                            $this->package_elements[$tutorial->package][$tutorial->subpackage]['class'][$link->name][0]->addTutorial($tutorial,$this);\r
-                                            $addend = 'success ';\r
-                                        }\r
-                                    } else\r
-                                    {\r
-                                        $addend = 'unsuccessful ';\r
-                                        if (!isset($this->classes->killclass[str_replace('.cls','',$tutorial->name)]) && !isset($this->classes->killclass[str_replace('.cls','',$tutorial->name)][$tutorial->path]))\r
-                                        {\r
-                                            foreach($pages as $j => $inf)\r
-                                            {\r
-                                                foreach($inf->classelements as $i => $class)\r
-                                                {\r
-                                                    if ($class->type == 'class' && $class->name == str_replace('.cls','',$tutorial->name) && $class->path == $link->path)\r
-                                                    {\r
-                                                        $pages[$j]->classelements[$i]->addTutorial($tutorial,$this);\r
-                                                        $addend = 'success ';\r
-                                                    }\r
-                                                }\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                    $ptext .= $addend;\r
-                                } else $ptext .= "unsuccessful ";\r
-                            break;\r
-                            case 'proc' :\r
-                                $a = '';\r
-                                if ($tutorial->ini)\r
-                                $a .= 'Top-level ';\r
-                                $ptext = "Converting ${a}Procedural-level tutorial ".$tutorial->name." and associating...";\r
-                                $link = Converter::getPageLink(str_replace('.proc','',$tutorial->name), $tutorial->package);\r
-                                if (is_object($link))\r
-                                {\r
-                                    $addend = 'unsuccessful ';\r
-                                    if ($this->sort_absolutely_everything)\r
-                                    {\r
-                                        if (isset($this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path]))\r
-                                        {\r
-                                            $this->package_elements[$tutorial->package][$tutorial->subpackage]['page'][$link->path][0]->addTutorial($tutorial,$this);\r
-                                            $addend = "success ";\r
-                                        }\r
-                                    } else\r
-                                    {\r
-                                        foreach($pages as $j => $info)\r
-                                        {\r
-                                            if ($j == $link->path)\r
-                                            {\r
-                                                $pages[$j]->addTutorial($tutorial,$this);\r
-                                                $addend = "success ";\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                    $ptext .= $addend;\r
-                                } else $ptext .= "unsuccessful ";\r
-                            break;\r
-                        }\r
-                        phpDocumentor_out($ptext);\r
-                        flush();\r
-                        $this->package = $tutorial->package;\r
-                        $this->subpackage = $tutorial->subpackage;\r
-                        $this->Convert($tutorial);\r
-                        phpDocumentor_out("done\n");\r
-                        flush();\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        phpDocumentor_out("Formatting Package Indexes...");\r
-        flush();\r
-        $this->formatPkgIndex();\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-        phpDocumentor_out("Formatting Index...");\r
-        flush();\r
-        $this->formatIndex();\r
-        phpDocumentor_out("done\n\n");\r
-        flush();\r
-        phpDocumentor_out("Formatting Left Quick Index...");\r
-        flush();\r
-        $this->formatLeftIndex();\r
-        phpDocumentor_out("done\n\n");\r
-        flush();\r
-        if ($this->sort_absolutely_everything) return $this->walk_everything();\r
-        foreach($pages as $j => $flub)\r
-        {\r
-            phpDocumentor_out('Converting '.$pages[$j]->parent->getPath());\r
-            flush();\r
-            $this->package = $pages[$j]->parent->package;\r
-            $this->subpackage = $pages[$j]->parent->subpackage;\r
-            $this->class = false;\r
-            $this->curfile = $pages[$j]->parent->getFile();\r
-            $this->curname = $this->getPageName($pages[$j]->parent);\r
-            $this->curpath = $pages[$j]->parent->getPath();\r
-            $use = true;\r
-            if ($this->package_output)\r
-            {\r
-                if (in_array($this->package,$this->package_output))\r
-                {\r
-                    $this->Convert($pages[$j]);\r
-                } else\r
-                {\r
-                    $use = false;\r
-                }\r
-            } else\r
-            {\r
-                $this->Convert($pages[$j]);\r
-            }\r
-            phpDocumentor_out(" Procedural Page Elements...");\r
-            flush();\r
-            if ($use)\r
-            for($i=0; $i<count($pages[$j]->elements); $i++)\r
-            {\r
-                $a = $pages[$j]->elements[$i]->docblock->getKeyword('access');\r
-                if (is_object($a)) $a = $a->getString();\r
-                if (!$this->parseprivate && ($a == 'private'))\r
-                    continue;\r
-//                phpDocumentor_out("    ".$pages[$j]->elements[$i]->name."\n");\r
-                $pages[$j]->elements[$i]->docblock->package = $this->package;\r
-                $pages[$j]->elements[$i]->docblock->subpackage = $this->subpackage;\r
-                $this->Convert($pages[$j]->elements[$i]);\r
-            }\r
-            phpDocumentor_out(" Classes...");\r
-            $this->class = false;\r
-            flush();\r
-            for($i=0; $i<count($pages[$j]->classelements); $i++)\r
-            {\r
-                if ($this->class)\r
-                {\r
-                    if ($pages[$j]->classelements[$i]->type == 'class')\r
-                    {\r
-                        if (!$this->killclass) $this->endClass();\r
-                        $this->killclass = false;\r
-                        if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;\r
-                        $this->package = $pages[$j]->classelements[$i]->docblock->package;\r
-                        if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;\r
-                        $this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;\r
-                        $this->class = $pages[$j]->classelements[$i]->name;\r
-                    } else\r
-                    {\r
-                        $a = $pages[$j]->classelements[$i]->docblock->getKeyword('access');\r
-                        if (is_object($a)) $a = $a->getString();\r
-                        if (!$this->parseprivate && ($a == 'private'))\r
-                            continue;\r
-                        if ($this->killclass) continue;\r
-                        // force all contained elements to have parent package/subpackage\r
-                        $pages[$j]->classelements[$i]->docblock->package = $this->package;\r
-                        $pages[$j]->classelements[$i]->docblock->subpackage = $this->subpackage;\r
-                    }\r
-                }\r
-                if ($pages[$j]->classelements[$i]->type == 'class')\r
-                {\r
-                    $this->killclass = false;\r
-                    if ($this->checkKillClass($pages[$j]->classelements[$i]->getName(),$pages[$j]->classelements[$i]->getPath())) continue;\r
-                    $this->package = $pages[$j]->classelements[$i]->docblock->package;\r
-                    if ($this->package_output) if (!in_array($this->package,$this->package_output)) continue;\r
-                    $this->subpackage = $pages[$j]->classelements[$i]->docblock->subpackage;\r
-                    $this->class = $pages[$j]->classelements[$i]->name;\r
-                }\r
-                if ($this->killclass) continue;\r
-//                phpDocumentor_out("    ".$pages[$j]->classelements[$i]->name."\n");\r
-                $this->Convert($pages[$j]->classelements[$i]);\r
-            }\r
-            if (count($pages[$j]->classelements) && !$this->killclass) $this->endClass();\r
-            phpDocumentor_out(" done\n");\r
-            flush();\r
-            $this->endPage();\r
-        }\r
-        phpDocumentor_out("\nConverting @todo List...");\r
-        flush();\r
-        if (count($this->todoList))\r
-        {\r
-            $this->ConvertTodoList();\r
-        }\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-        phpDocumentor_out("\nConverting Error Log...");\r
-        flush();\r
-        $this->ConvertErrorLog();\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-    }\r
-\r
-\r
-    /**\r
-     * Get a tree structure representing the hierarchy of tutorials\r
-     *\r
-     * Returns an array in format:\r
-     * <pre>\r
-     * array('tutorial' => {@link parserTutorial},\r
-     *       'kids' => array( // child tutorials\r
-     *                   array('tutorial' => child {@link parserTutorial},\r
-     *                         'kids' => array(...)\r
-     *                        )\r
-     *                      )\r
-     *      )\r
-     * </pre>\r
-     * @param parserTutorial|array\r
-     * @tutorial tutorials.pkg\r
-     * @return array\r
-     */\r
-    function getTutorialTree($tutorial)\r
-    {\r
-        if (is_object($tutorial))\r
-        {\r
-            $path = $this->_tutorial_path($tutorial,$tutorial,$tutorial);\r
-            if (isset($this->tutorial_tree[$path])) {\r
-                $tutorial = $this->tutorial_tree[$path];\r
-            } else {\r
-                return false;\r
-            }\r
-        }\r
-        $tree = array();\r
-        if (isset($tutorial['tutorial']))\r
-        {\r
-            $tree['tutorial'] = $tutorial['tutorial'];\r
-            if (isset($tutorial['child']))\r
-            {\r
-                foreach($tutorial['child'] as $a => $b)\r
-                {\r
-                    $btut = $b['tutorial'];\r
-                    $res['tutorial'] = $this->tutorials[$btut->package][$btut->subpackage][$btut->tutorial_type][$btut->name];\r
-                    if (isset($b['child']))\r
-                    {\r
-                         $tempres = Converter::getTutorialTree($b);\r
-                         $res['kids'] = $tempres['kids'];\r
-                    }\r
-                    $tree['kids'][] = $res;\r
-                }\r
-            }\r
-        }\r
-        return $tree;\r
-    }\r
-\r
-    /**\r
-     * Remove tutorials one by one from $all, and transfer them into $new in the\r
-     * order they should be parsed\r
-     * @param parserTutorial\r
-     * @param array\r
-     * @param array\r
-     * @access private\r
-     */\r
-    function generateTutorialOrder($parent,&$all,&$new)\r
-    {\r
-        // remove from the list of tutorials to process\r
-        foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $t)\r
-        {\r
-            if ($t->name == $parent->name) {\r
-                unset($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]);\r
-            }\r
-        }\r
-        // add to the new ordered list of tutorials\r
-        $x = &$new[$parent->package][$parent->subpackage][$parent->tutorial_type];\r
-        if (!is_object($x[count($x) - 1]) || $x[count($x) - 1]->name != $parent->name)\r
-        { // only add if the parent isn't also a child\r
-            $new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = $parent;\r
-            // add a new branch to the tree\r
-        }\r
-        // process all child tutorials, and insert them in order\r
-//        debug("processing parent ".$parent->name);\r
-        if ($parent->ini)\r
-        {\r
-            foreach($parent->ini['Linked Tutorials'] as $child)\r
-            {\r
-                $sub = (empty($parent->subpackage) ? '' : $parent->subpackage . '/');\r
-                $kid = $parent->package . '/' . $sub . $child . '.' . $parent->tutorial_type;\r
-                $_klink = $this->getTutorialLink($kid,false,false,array($parent->package));\r
-                if (is_object($_klink)) {\r
-                    $klink = $this->returnSee($_klink);\r
-                } else {\r
-                    $klink = false;\r
-                }\r
-                // remove the child from the list of remaining tutorials\r
-                foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $tute)\r
-                {\r
-                    if ($klink && $tute->getLink($this) == $klink)\r
-                    {\r
-                        // set up parent, next and prev links\r
-                        $tute->setParent($parent, $this);\r
-                        // remove the child from the list of tutorials to process\r
-                        foreach($all[$parent->package][$parent->subpackage][$parent->tutorial_type] as $ind => $t)\r
-                        {\r
-                            if ($t->name == $tute->name)\r
-                            unset($all[$parent->package][$parent->subpackage][$parent->tutorial_type][$ind]);\r
-                        }\r
-                        // add to the new ordered list of tutorials\r
-                        $new[$parent->package][$parent->subpackage][$parent->tutorial_type][] = $tute;\r
-                        if ($tute->ini)\r
-                        {\r
-                            // add all the child's child tutorials to the list\r
-                            $this->generateTutorialOrder($tute,$all,$new);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return;\r
-    }\r
-\r
-               /** Returns the path to this tutorial as a string\r
-                * @param parserTutorial $pkg\r
-                * @param parserTutorial $subpkg\r
-                * @param parserTutorial $namepkg\r
-                * @return string */\r
-               function _tutorial_path($pkg, $subpkg = 0, $namepkg = 0)\r
-               {\r
-                       if (!$subpkg) {\r
-                               $subpkg = $pkg;\r
-                       }\r
-                       if (!$namepkg) {\r
-                               $namepkg = $pkg;\r
-                       }\r
-                       $subpackagename = ($subpkg->subpackage ? '/' . $subpkg->subpackage : '');\r
-                       return $pkg->package . $subpackagename . '/' . $namepkg->name;\r
-               }\r
-\r
-\r
-    /**\r
-     * Creates a tree structure of tutorials\r
-     *\r
-     * Format:\r
-     * <pre>\r
-     * array('package/subpackage/tutorial1.ext' =>\r
-     *          array('tutorial' => {@link parserTutorial},\r
-     *                'child'    =>\r
-     *                    array('package/subpackage/child1tutorial.ext' => ...,\r
-     *                          'package/subpackage/child2tutorial.ext' => ...,\r
-     *                          ...\r
-     *                         )\r
-     *       'package/subpackage/tutorial2.ext' => ...,\r
-     *       ...\r
-     *       )\r
-     * </pre>\r
-     * @return array the tutorial tree\r
-     * @access private\r
-     */\r
-    function _setupTutorialTree($parent = false)\r
-    {\r
-        if (! isset($this->processed_tutorials)) {\r
-            $this->processed_tutorials = array();\r
-        }\r
-        $tree = array();\r
-        if (!$parent)\r
-        {\r
-            foreach($this->tutorials as $package => $s)\r
-            {\r
-                foreach($s as $subpackage => $t)\r
-                {\r
-                    foreach($t as $type => $n)\r
-                    {\r
-                        foreach($n as $name => $tutorial)\r
-                        {\r
-                            if ($tutorial->parent) {\r
-                                continue;\r
-                            }\r
-                            \r
-                            $child_path = $this->_tutorial_path($tutorial,$tutorial,$tutorial);\r
-                            if (isset($this->processed_tutorials[$child_path])) {\r
-                                continue;\r
-                            }\r
-                            $this->processed_tutorials[$child_path] = $tutorial;\r
-                            //debug("parent ".$tutorial->name);\r
-                            $ret = $this->_setupTutorialTree($tutorial);\r
-                            if (!count($tree)) {\r
-                                $tree = $ret;\r
-                            } else {\r
-                                $tree = array_merge($tree,$ret);\r
-                            }\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            return $tree;\r
-        }\r
-        $parent_path = $this->_tutorial_path($parent);\r
-        $tree[$parent_path]['tutorial'] = $parent;\r
-        // process all child tutorials, and insert them in order\r
-        if ($parent->ini)\r
-        {\r
-            foreach($parent->ini['Linked Tutorials'] as $child)\r
-            {\r
-                if (isset($this->tutorials[$parent->package][$parent->subpackage]\r
-                                          [$parent->tutorial_type][$child . '.' .\r
-                                           $parent->tutorial_type])) {\r
-                    // remove the child from the list of remaining tutorials\r
-                    $tute = $this->tutorials[$parent->package][$parent->subpackage]\r
-                                            [$parent->tutorial_type][$child . '.' .\r
-                                             $parent->tutorial_type];\r
-                } else {\r
-                    $tute = false;\r
-                }\r
-\r
-                if (!$tute) {\r
-                    continue;\r
-                }\r
-                $child_path = $this->_tutorial_path($parent,$parent,$tute);\r
-                if (isset($this->processed_tutorials[$child_path])) {\r
-                    continue;\r
-                }\r
-                $this->processed_tutorials[$child_path] = $tute;\r
-                if ($tute->name != $child . '.' . $parent->tutorial_type) {\r
-                    continue;\r
-                }\r
-                //echo "Adding [$child_path] to [$parent_path]<br>";\r
-                $tree[$parent_path]['child'][$this->_tutorial_path($parent,$parent,$tute)]['tutorial']\r
-                    = $tute;\r
-                if (!$tute->ini) {\r
-                    continue;\r
-                }\r
-                // add all the child's child tutorials to the list\r
-                if (!isset($tree[$parent_path]['child'])) {\r
-                    $tree[$parent_path]['child'] = $this->_setupTutorialTree($tute);\r
-                } else {\r
-                    $tree[$parent_path]['child'] = array_merge($tree[$parent_path]['child'],\r
-                        $this->_setupTutorialTree($tute));\r
-                }\r
-            }\r
-        }\r
-        return $tree;\r
-    }\r
-\r
-    /**\r
-     * Debugging function for dumping {@link $tutorial_tree}\r
-     * @return string\r
-     */\r
-    function vardump_tree($tree,$indent='')\r
-    {\r
-        if (phpDocumentor_get_class($tree) == 'parsertutorial') return $tree->name.' extends '.($tree->parent? $tree->parent->name : 'nothing');\r
-        $a = '';\r
-        foreach($tree as $ind => $stuff)\r
-        {\r
-            $x = $this->vardump_tree($stuff,"$indent   ");\r
-            $a .= $indent.'['.$ind." => \n   ".$indent.$x."]\n";\r
-        }\r
-        return substr($a,0,strlen($a) - 1);\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     */\r
-    function sort_package_elements($a,$b)\r
-    {\r
-        if (($a->type == $b->type) && (isset($a->isConstructor) && $a->isConstructor)) return -1;\r
-        if (($a->type == $b->type) && (isset($b->isConstructor) && $b->isConstructor)) return 1;\r
-        if ($a->type == $b->type) return strnatcasecmp($a->name,$b->name);\r
-        if ($a->type == 'class') return -1;\r
-        if ($b->type == 'class') return 1;\r
-        if ($a->type == 'const') return -1;\r
-        if ($b->type == 'const') return 1;\r
-        if ($a->type == 'var') return -1;\r
-        if ($b->type == 'var') return 1;\r
-        if ($a->type == 'page') return -1;\r
-        if ($b->type == 'page') return 1;\r
-        if ($a->type == 'include') return -1;\r
-        if ($b->type == 'include') return 1;\r
-        if ($a->type == 'define') return -1;\r
-        if ($b->type == 'define') return 1;\r
-        if ($a->type == 'global') return -1;\r
-        if ($b->type == 'global') return 1;\r
-        if ($a->type == 'function') return -1;\r
-        if ($b->type == 'function') return 1;\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     */\r
-    function defpackagesort($a,$b)\r
-    {\r
-        if ($a == $GLOBALS['phpDocumentor_DefaultPackageName']) return -1;\r
-        if ($b == $GLOBALS['phpDocumentor_DefaultPackageName']) return 0;\r
-        return strnatcasecmp($a,$b);\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     */\r
-    function Pc_sort($a,$b)\r
-    {\r
-        return strnatcasecmp(key($a),key($b));\r
-    }\r
-\r
-    /**\r
-     * walk over elements by package rather than page\r
-     *\r
-     * This method is designed for converters like the PDF converter that need\r
-     * everything passed in alphabetical order by package/subpackage and by\r
-     * procedural and then class information\r
-     * @see PDFdefaultConverter\r
-     * @see walk()\r
-     */\r
-    function walk_everything()\r
-    {\r
-        global $hooser;\r
-        $hooser = false;\r
-        uksort($this->package_elements,array($this,'defpackagesort'));\r
-        foreach($this->package_elements as $package => $r)\r
-        {\r
-            if ($this->package_output)\r
-            {\r
-                if (!in_array($this->package,$this->package_output))\r
-                {\r
-                    unset($this->package_elements[$package]);\r
-                    continue;\r
-                }\r
-            }\r
-            uksort($this->package_elements[$package],'strnatcasecmp');\r
-        }\r
-        foreach($this->package_elements as $package => $r)\r
-        {\r
-            foreach($this->package_elements[$package] as $subpackage => $r)\r
-            {\r
-                if (isset($r['page']))\r
-                {\r
-                    uksort($r['page'],'strnatcasecmp');\r
-                    foreach($r['page'] as $page => $oo)\r
-                    {\r
-                        usort($this->package_elements[$package][$subpackage]['page'][$page],array($this,'sort_package_elements'));\r
-                    }\r
-                }\r
-                if (isset($r['class']))\r
-                {\r
-                    uksort($r['class'],'strnatcasecmp');\r
-                    foreach($r['class'] as $page => $oo)\r
-                    {\r
-                        usort($r['class'][$page],array($this,'sort_package_elements'));\r
-                    }\r
-                }\r
-                $this->package_elements[$package][$subpackage] = $r;\r
-            }\r
-        }\r
-        foreach($this->package_elements as $package => $s)\r
-        {\r
-            $notyet = false;\r
-            foreach($s as $subpackage => $r)\r
-            {\r
-                $this->package = $package;\r
-                $this->subpackage = $subpackage;\r
-                if (isset($r['page']))\r
-                {\r
-                    $this->class = false;\r
-                    foreach($r['page'] as $page => $elements)\r
-                    {\r
-                        if (is_array($elements))\r
-                        {\r
-                            foreach($elements as $element)\r
-                            {\r
-                                if ($element->type == 'page')\r
-                                {\r
-                                    phpDocumentor_out('Converting '.$element->parent->getPath());\r
-                                    flush();\r
-                                    $this->curfile = $element->parent->getFile();\r
-                                    $this->curname = $this->getPageName($element->parent);\r
-                                    $this->curpath = $element->parent->getPath();\r
-                                    $notyet = true;\r
-                                } else\r
-                                {\r
-                                    // force all contained elements to have parent package/subpackage\r
-                                    $element->docblock->package = $this->package;\r
-                                    $element->docblock->subpackage = $this->subpackage;\r
-                                    $a = $element->docblock->getKeyword('access');\r
-                                    if (is_object($a)) $a = $a->getString();\r
-                                    if (!$this->parseprivate && ($a == 'private'))\r
-                                        continue;\r
-                                }\r
-                                if ($notyet)\r
-                                {\r
-                                    phpDocumentor_out(" Procedural Page Elements...");\r
-                                    flush();\r
-                                    $notyet = false;\r
-                                }\r
-                                $this->Convert($element);\r
-                            }\r
-                        }\r
-                        $this->endPage();\r
-                        phpDocumentor_out("done\n");\r
-                        flush();\r
-                    }\r
-                }\r
-                $start_classes = true;\r
-                if (isset($r['class']))\r
-                {\r
-                    foreach($r['class'] as $class => $elements)\r
-                    {\r
-                        foreach($elements as $element)\r
-                        {\r
-                            if ($element->type == 'class')\r
-                            {\r
-                                if (!$start_classes)\r
-                                {\r
-                                    if (count($elements) && !$this->killclass) $this->endClass();\r
-                                    phpDocumentor_out("done\n");\r
-                                    flush();\r
-                                }\r
-                                $start_classes = false;\r
-                                $this->class = $element->getName();\r
-                                $this->killclass = false;\r
-                                if ($this->checkKillClass($element->getName(),$element->getPath())) continue;\r
-                                if (!$this->killclass)\r
-                                {\r
-                                    phpDocumentor_out('Converting '.$this->class."...");\r
-                                    flush();\r
-                                    $notyet = true;\r
-                                }\r
-                            } else\r
-                            {\r
-                                if ($notyet)\r
-                                {\r
-                                    phpDocumentor_out("Variables/methods/Class constants...\n");\r
-                                    flush();\r
-                                    $notyet = false;\r
-                                }\r
-                                $a = $element->docblock->getKeyword('access');\r
-                                if (is_object($a)) $a = $a->getString();\r
-                                if (!$this->parseprivate && ($a == 'private'))\r
-                                    continue;\r
-                                if ($this->killclass) continue;\r
-                                // force all contained elements to have parent package/subpackage\r
-                                $element->docblock->package = $this->package;\r
-                                $element->docblock->subpackage = $this->subpackage;\r
-                            }\r
-                            if ($this->killclass) continue;\r
-                            $this->Convert($element);\r
-                        }\r
-                    }\r
-                    if (count($elements) && !$this->killclass) $this->endClass();\r
-                    phpDocumentor_out("done\n");\r
-                    flush();\r
-                } // if isset($r['class'])\r
-            } // foreach($s\r
-        } // foreach($this->package_elements)\r
-        phpDocumentor_out("\nConverting @todo List...");\r
-        flush();\r
-        if (count($this->todoList))\r
-        {\r
-            $this->ConvertTodoList();\r
-        }\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-        phpDocumentor_out("\nConverting Error Log...");\r
-        flush();\r
-        $this->ConvertErrorLog();\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-    }\r
-\r
-    /**\r
-     * Convert the phpDocumentor parsing/conversion error log\r
-     * @abstract\r
-     */\r
-    function ConvertErrorLog()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Convert the list of all @todo tags\r
-     * @abstract\r
-     */\r
-    function ConvertTodoList()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Sorts the @todo list - do not override or modify this function\r
-     * @access private\r
-     * @uses _sortTodos passed to {@link usort()} to sort the todo list\r
-     */\r
-    function sortTodos()\r
-    {\r
-        phpDocumentor_out("\nSorting @todo list...");\r
-        flush();\r
-        foreach($this->todoList as $package => $r) {\r
-            usort($this->todoList[$package], array('Converter', '_sortTodoPackage'));\r
-            foreach ($r as $a => $sub) {\r
-                if (is_array($this->todoList[$package][$a][1])) {\r
-                    usort($this->todoList[$package][$a][1],array('Converter', '_sortTodos'));\r
-                }\r
-            }\r
-        }\r
-        phpDocumentor_out("done\n");\r
-    }\r
-\r
-    /** @access private */\r
-    function _sortTodoPackage($a, $b)\r
-    {\r
-        return strnatcasecmp($a[0]->name, $b[0]->name);\r
-    }\r
-\r
-    /** @access private */\r
-    function _sortTodos($a, $b)\r
-    {\r
-        if (!is_object($a)) {\r
-            var_dump($a);\r
-        }\r
-        return strnatcasecmp($a->getString(), $b->getString());\r
-    }\r
-\r
-    /**\r
-     * Sorts all indexes - do not override or modify this function\r
-     * @uses $leftindex based on the value of leftindex, sorts link arrays\r
-     * @uses $class_elements sorts with {@link compareLink}\r
-     * @uses $page_elements sorts with {@link compareLink}\r
-     * @uses $define_elements sorts with {@link compareLink}\r
-     * @uses $global_elements sorts with {@link compareLink}\r
-     * @uses $function_elements sorts with {@link compareLink}\r
-     * @uses $elements sorts with {@link elementCmp}\r
-     * @uses $pkg_elements sorts with {@link elementCmp} after sorting by\r
-     *                     package/subpackage alphabetically\r
-     * @access private\r
-     */\r
-    function sortIndexes()\r
-    {\r
-        phpDocumentor_out("\nSorting Indexes...");\r
-        flush();\r
-        uksort($this->elements,'strnatcasecmp');\r
-        if ($this->leftindex['classes'])\r
-        {\r
-            foreach($this->class_elements as $package => $o1)\r
-            {\r
-                foreach($o1 as $subpackage => $links)\r
-                {\r
-                    usort($this->class_elements[$package][$subpackage],array($this,'compareLink'));\r
-                }\r
-            }\r
-        }\r
-        if ($this->leftindex['pages'])\r
-        {\r
-            foreach($this->page_elements as $package => $o1)\r
-            {\r
-                uksort($this->page_elements[$package],'strnatcasecmp');\r
-                foreach($o1 as $subpackage => $links)\r
-                {\r
-                    usort($this->page_elements[$package][$subpackage],array($this,'compareLink'));\r
-                }\r
-            }\r
-        }\r
-        if ($this->leftindex['defines'])\r
-        {\r
-            foreach($this->define_elements as $package => $o1)\r
-            {\r
-                uksort($this->define_elements[$package],'strnatcasecmp');\r
-                foreach($o1 as $subpackage => $links)\r
-                {\r
-                    usort($this->define_elements[$package][$subpackage],array($this,'compareLink'));\r
-                }\r
-            }\r
-        }\r
-        if ($this->leftindex['globals'])\r
-        {\r
-            foreach($this->global_elements as $package => $o1)\r
-            {\r
-                uksort($this->global_elements[$package],'strnatcasecmp');\r
-                foreach($o1 as $subpackage => $links)\r
-                {\r
-                    usort($this->global_elements[$package][$subpackage],array($this,'compareLink'));\r
-                }\r
-            }\r
-        }\r
-        if ($this->leftindex['functions'])\r
-        {\r
-            foreach($this->function_elements as $package => $o1)\r
-            {\r
-                uksort($this->function_elements[$package],'strnatcasecmp');\r
-                foreach($o1 as $subpackage => $links)\r
-                {\r
-                    usort($this->function_elements[$package][$subpackage],array($this,'compareLink'));\r
-                }\r
-            }\r
-        }\r
-        foreach($this->elements as $letter => $nothuing)\r
-        {\r
-            uasort($this->elements[$letter],array($this,"elementCmp"));\r
-        }\r
-        foreach($this->pkg_elements as $package => $els)\r
-        {\r
-            uksort($this->pkg_elements[$package],'strnatcasecmp');\r
-            foreach($this->pkg_elements[$package] as $subpackage => $els)\r
-            {\r
-                if (empty($els)) continue;\r
-                uksort($this->pkg_elements[$package][$subpackage],'strnatcasecmp');\r
-                foreach($els as $letter => $yuh)\r
-                {\r
-                    usort($this->pkg_elements[$package][$subpackage][$letter],array($this,"elementCmp"));\r
-                }\r
-            }\r
-        }\r
-        phpDocumentor_out("done\n");\r
-        flush();\r
-    }\r
-\r
-    /**\r
-     * sorts {@link $page_contents} by element type as well as alphabetically\r
-     * @see $sort_page_contents_by_element_type\r
-     */\r
-    function sortPageContentsByElementType(&$pages)\r
-    {\r
-        foreach($this->page_contents as $package => $els)\r
-        {\r
-            foreach($this->page_contents[$package] as $subpackage => $els)\r
-            {\r
-                if (empty($els)) continue;\r
-                foreach($this->page_contents[$package][$subpackage] as $path => $stuff)\r
-                {\r
-                    if (!count($pages[$path]->elements)) continue;\r
-                    usort($pages[$path]->elements,array($this,'eltypecmp'));\r
-                    usort($this->page_contents[$package][$subpackage][$path],array($this,'eltypecmp'));\r
-                    if (isset($this->page_contents[$package][$subpackage][$path][0]))\r
-                    $this->page_contents[$package][$subpackage][$path]['###main'] = $this->page_contents[$package][$subpackage][$path][0];\r
-                    unset($this->page_contents[$package][$subpackage][$path][0]);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     * @see Converter::sortIndexes()\r
-     */\r
-    function compareLink($a, $b)\r
-    {\r
-         return strnatcasecmp($a->name,$b->name);\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     * @see Converter::sortPageContentsByElementType()\r
-     */\r
-    function eltypecmp($a, $b)\r
-    {\r
-        if ($a->type == 'page') return -1;\r
-        if ($b->type == 'page') return 1;\r
-         return strnatcasecmp($a->type.$a->name,$b->type.$b->name);\r
-    }\r
-\r
-    /**\r
-     * does a nat case sort on the specified second level value of the array\r
-     *\r
-     * @param    mixed    $a\r
-     * @param    mixed    $b\r
-     * @return    int\r
-     * @access private\r
-     */\r
-    function elementCmp ($a, $b)\r
-    {\r
-        return strnatcasecmp($a->getName(), $b->getName());\r
-    }\r
-\r
-    /**\r
-     * Used to stop conversion of @ignored or private @access classes\r
-     * @uses $killclass sets killclass based on the value of {@link Classes::$killclass}\r
-     *       and {@link $package_output}\r
-     * @access private\r
-     */\r
-    function checkKillClass($class, $path)\r
-    {\r
-        $this->killclass = false;\r
-        if (isset($this->classes->killclass[$class]) && isset($this->classes->killclass[$class][$path])) $this->killclass = true;\r
-        if ($this->package_output)\r
-        {\r
-            $a = $this->classes->getClass($class, $path);\r
-            if (!in_array($a->docblock->package,$this->package_output)) $this->killclass = true;\r
-        }\r
-        if (PHPDOCUMENTOR_DEBUG && $this->killclass) debug("$class $path killed");\r
-        return $this->killclass;\r
-    }\r
-\r
-    /**\r
-     * @param abstractLink descendant of abstractLink\r
-     * @param array|parserTag list of @todos|@todo tag\r
-     * @access private\r
-     */\r
-    function addTodoLink($link, $todos)\r
-    {\r
-        $this->todoList[$link->package][] = array($link, $todos);\r
-    }\r
-\r
-    /**\r
-     * Adds all elements to the {@link $elements, $pkg_elements, $links},\r
-     * {@link $linkswithfile} and left indexes - Do not modify or override\r
-     * @access private\r
-     * @param parserBase any documentable element descendant of parserBase\r
-     *                   except parserTutorial\r
-     * @param false|parserPage only used to add a {@link parserPage} if the\r
-     *                         $element passed is a parserPage\r
-     * @staticvar string path of current page, used for {@link $page_contents} setup\r
-     */\r
-    function addElement(&$element,$pageel=false)\r
-    {\r
-        static $curpath = '';\r
-        if ($this->package_output)\r
-        {\r
-            if (!in_array($this->package, $this->package_output)) return;\r
-        }\r
-        if ($pageel && phpDocumentor_get_class($pageel) == 'parserdata')\r
-        {\r
-            if (isset($pageel->docblock) && phpDocumentor_get_class($pageel->docblock) == 'parserdocblock')\r
-            {\r
-                $a = $pageel->docblock->getKeyword('todo');\r
-                if ($a)\r
-                {\r
-                    $this->addTodoLink($this->addLink($element),$a);\r
-                }\r
-            }\r
-        }\r
-        if (isset($element->docblock))\r
-        {\r
-            $a = $element->docblock->getKeyword('access');\r
-            if (is_object($a)) $a = $a->getString();\r
-            if (!$this->parseprivate && ($a == 'private'))\r
-                return;\r
-            $a = $element->docblock->getKeyword('todo');\r
-            if ($a)\r
-            {\r
-                if ($element->type != 'include') {\r
-                    $this->addTodoLink($this->addLink($element),$a);\r
-                } else {\r
-                    addWarning(PDERROR_NOTODO_INCLUDE, $element->getLineNumber(),\r
-                        $element->getPath());\r
-                }\r
-            }\r
-        }\r
-        $startPositionOfElementName = 0;    // which character of the element name actually starts its textual name\r
-        switch($element->type)\r
-        {\r
-            case 'page' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->package][$element->subpackage]['page'][$element->getPath()][] = $pageel;\r
-                }\r
-                $link = $this->addLink($element);\r
-                $curpath = $element->getPath();\r
-                if ($this->leftindex['pages'])\r
-                $this->page_elements[$element->package][$element->subpackage][] = $link;\r
-                $this->page_contents[$element->package][$element->subpackage][$curpath]['###main'] = $link;\r
-            break;\r
-            case 'class' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                if ($this->leftindex['classes'])\r
-                $this->class_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;\r
-                $this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class]['###main'] = $link;\r
-            break;\r
-            case 'include' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-            break;\r
-            case 'define' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                if ($this->leftindex['defines'])\r
-                $this->define_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;\r
-                $this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;\r
-            break;\r
-            case 'global' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                $startPositionOfElementName = 1;    // lose the leading "$" character\r
-                if ($this->leftindex['globals'])\r
-                $this->global_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;\r
-                $this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;\r
-            break;\r
-            case 'var' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                $startPositionOfElementName = 1;    // lose the leading "$" character\r
-                $this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;\r
-            break;\r
-            case 'const' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                $this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;\r
-            break;\r
-            case 'method' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['class'][$this->class][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                $this->class_contents[$element->docblock->package][$element->docblock->subpackage][$this->class][] = $link;\r
-            break;\r
-            case 'function' :\r
-                if ($this->sort_absolutely_everything)\r
-                {\r
-                    $this->package_elements[$element->docblock->package][$element->docblock->subpackage]['page'][$curpath][] = $element;\r
-                }\r
-                $link = $this->addLink($element);\r
-                if ($this->leftindex['functions'])\r
-                $this->function_elements[$element->docblock->package][$element->docblock->subpackage][] = $link;\r
-                $this->page_contents[$element->docblock->package][$element->docblock->subpackage][$curpath][] = $link;\r
-            break;\r
-            default :\r
-            break;\r
-        }\r
-        if ($element->getType() != 'include')\r
-        {\r
-            if ($element->getType() == 'var' || $element->getType() == 'method'|| $element->getType() == 'const')\r
-            {\r
-                $this->links[$this->package][$this->subpackage][$element->getType()][$element->class][$element->getName()] = $link;\r
-                $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->class][$element->getName()] = $link;\r
-            } else\r
-            {\r
-                if ($element->type == 'page')\r
-                {\r
-                    $this->links[$this->package][$this->subpackage][$element->getType()][$element->getFile()] = $link;\r
-                    $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getFile()] = $link;\r
-                } else\r
-                {\r
-                    $this->links[$this->package][$this->subpackage][$element->getType()][$element->getName()] = $link;\r
-                    $this->linkswithfile[$this->package][$this->subpackage][$element->getType()][$element->getPath()][$element->getName()] = $link;\r
-                }\r
-            }\r
-        }\r
-        if ($element->type == 'page')\r
-        {\r
-            $this->elements[substr(strtolower($element->getFile()),$startPositionOfElementName,1)][] = $element;\r
-            $this->pkg_elements[$this->package][$this->subpackage][substr(strtolower($element->getFile()),$startPositionOfElementName,1)][] = $element;\r
-        } else\r
-        {\r
-            $this->elements[substr(strtolower($element->getName()),$startPositionOfElementName,1)][] = $element;\r
-            $this->pkg_elements[$this->package][$this->subpackage][substr(strtolower($element->getName()),$startPositionOfElementName,1)][] = $element;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * returns an abstract link to element.  Do not modify or override\r
-     *\r
-     * This method should only be called in process of Conversion, unless\r
-     * $element is a parserPage, or $page is set to true, and $element is\r
-     * not a parserPage\r
-     * @return abstractLink abstractLink descendant\r
-     * @access private\r
-     * @param parserElement element to add a new link (descended from\r
-     *                      {@link abstractLink})to the {@link $links} array\r
-     * @param string classname for elements that are class-based (this may be\r
-     *               deprecated in the future, as the classname\r
-     *               should be contained within the element.  if $element is a\r
-     *               page, this parameter is a package name\r
-     * @param string subpackage name for page elements\r
-     */\r
-    function addLink(&$element,$page = false)\r
-    {\r
-        if ($page)\r
-        {\r
-            // create a fake parserPage to extract the fileAlias for this link\r
-            $fakepage = new parserPage;\r
-            $fakepage->setPath($element->getPath());\r
-            $fakepage->setFile(basename($element->getPath()));\r
-            $this->curname = $this->getPageName($fakepage);\r
-        }\r
-        switch($element->type)\r
-        {\r
-            case 'function':\r
-                $x = new functionLink;\r
-                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'define':\r
-                $x = new defineLink;\r
-                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'global':\r
-                $x = new globalLink;\r
-                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'class':\r
-                $x = new classLink;\r
-                $x->addLink($element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'method':\r
-                $x = new methodLink;\r
-                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'var':\r
-                $x = new varLink;\r
-                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'const':\r
-                $x = new constLink;\r
-                $x->addLink($this->class, $element->getPath(), $this->curname, $element->name, $element->docblock->package, $element->docblock->subpackage, $element->docblock->category);\r
-                return $x;\r
-            break;\r
-            case 'page':\r
-                $x = new pageLink;\r
-                $x->addLink($element->getPath(),$this->getPageName($element),$element->file,$element->package, $element->subpackage, $element->category);\r
-                return $x;\r
-            break;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Return a tree of all classes that extend this class\r
-     *\r
-     * The data structure returned is designed for a non-recursive algorithm,\r
-     * and is somewhat complex.\r
-     * In most cases, the array returned is:\r
-     *\r
-     * <pre>\r
-     * array('#root' =>\r
-     *         array('link' => {@link classLink} to $class,\r
-     *               'parent' => false,\r
-     *               'children' => array(array('class' => 'childclass1',\r
-     *                                         'package' => 'child1package'),\r
-     *                                    array('class' => 'childclass2',\r
-     *                                         'package' => 'child2package'),...\r
-     *                                  )\r
-     *               ),\r
-     *       'child1package#childclass1' =>\r
-     *         array('link' => {@link classLink} to childclass1,\r
-     *               'parent' => '#root',\r
-     *               'children' => array(array('class' => 'kidclass',\r
-     *                                         'package' => 'kidpackage'),...\r
-     *                                  )\r
-     *              ),\r
-     *       'kidpackage#kidclass' =>\r
-     *         array('link' => {@link classLink} to kidclass,\r
-     *               'parent' => 'child1package#childclass1',\r
-     *               'children' => array() // no children\r
-     *              ),\r
-     *      ....\r
-     *      )\r
-     *</pre>\r
-     *\r
-     * To describe this format using language, every class in the tree has an\r
-     * entry in the first level of the array.  The index for all child\r
-     * classes that extend the root class is childpackage#childclassname.\r
-     * Each entry in the array has 3 elements: link, parent, and children.\r
-     * <ul>\r
-     *  <li>link - a {@link classLink} to the current class</li>\r
-     *  <li>parent - a {@link classLink} to the class's parent, or false (except for one special case described below)</li>\r
-     *  <li>children - an array of arrays, each entry has a 'class' and 'package' index to the child class,\r
-     * used to find the entry in the big array</li>\r
-     * </ul>\r
-     *\r
-     * special cases are when the #root class has a parent in another package,\r
-     * or when the #root class extends a class not found\r
-     * by phpDocumentor.  In the first case, parent will be a\r
-     * classLink to the parent class.  In the second, parent will be the\r
-     * extends clause, as in:\r
-     * <code>\r
-     * class X extends Y\r
-     * {\r
-     * ...\r
-     * }\r
-     * </code>\r
-     * in this case, the #root entry will be array('link' => classLink to X, 'parent' => 'Y', children => array(...))\r
-     *\r
-     * The fastest way to design a method to process the array returned\r
-     * is to copy HTMLframesConverter::getRootTree() into\r
-     * your converter and to modify the html to whatever output format you are going to use\r
-     * @see HTMLframesConverter::getRootTree()\r
-     * @param string class name\r
-     * @param string\r
-     * @param string\r
-     * @return array Format: see docs\r
-     */\r
-    function getSortedClassTreeFromClass($class,$package,$subpackage)\r
-    {\r
-        $my_tree = array();\r
-        $root = $this->classes->getClassByPackage($class,$package);\r
-        if (!$root) return false;\r
-        $class_children = $this->classes->getDefiniteChildren($class,$root->curfile);\r
-        if (!$class_children)\r
-        {\r
-            // special case: parent class is found, but is not part of this package, class has no children\r
-            if (is_array($root->parent))\r
-            {\r
-                $x = $root->getParent($this);\r
-                if ($x->docblock->package != $package)\r
-                {\r
-                    $v = Converter::getClassLink($root->getName(),$package,$root->getPath());\r
-                    return array('#root' => array('link' => $v,'parent' => Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => array()));\r
-                }\r
-            } else\r
-            { // class has normal situation, no children\r
-                if (is_string($root->getParent($this)))\r
-                return array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => $root->getExtends(),'children' => array()));\r
-                else\r
-                return array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => false, 'children' => array()));\r
-            }\r
-        }\r
-        // special case: parent class is found, but is not part of this package, class has children\r
-        if (is_array($root->parent))\r
-        {\r
-            $x = $root->getParent($this);\r
-            if ($x->docblock->package != $package)\r
-            {\r
-                $v = Converter::getClassLink($root->getName(),$package,$root->getPath());\r
-                $my_tree = array('#root' => array('link' => $v, 'parent' => Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath()), 'children' => array()));\r
-            } else\r
-            {\r
-            }\r
-        } else\r
-        $my_tree = array('#root' => array('link' => Converter::getClassLink($root->getName(),$package,$root->getPath()), 'parent' => false, 'children' => array()));\r
-        // location of tree walker\r
-        $cur = '#root';\r
-        $lastcur = array(array(false,0));\r
-        $childpos = 0;\r
-        if (isset($class_children))\r
-        {\r
-            do\r
-            {\r
-                if (!$class_children)\r
-                {\r
-                    list($cur, $childpos) = array_pop($lastcur);\r
-                    if (isset($my_tree[$cur]['children'][$childpos + 1]))\r
-                    {\r
-                        array_push($lastcur, array($cur, $childpos + 1));\r
-                        $par = $cur;\r
-                        $cur = $my_tree[$cur]['children'][$childpos + 1];\r
-                        $x = $this->classes->getClassByPackage($cur['class'],$cur['package']);\r
-                        $childpos = 0;\r
-                        $cur = $cur['package'] . '#' . $cur['class'];\r
-                        $my_tree[$cur]['link'] = Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath());\r
-                        $my_tree[$cur]['parent'] = $par;\r
-                        $my_tree[$cur]['children'] = array();\r
-                        $class_children = $this->classes->getDefiniteChildren($x->getName(), $x->curfile);\r
-                        continue;\r
-                    } else\r
-                    {\r
-                        $class_children = false;\r
-                        continue;\r
-                    }\r
-                }\r
-                foreach($class_children as $chileclass => $chilefile)\r
-                {\r
-                    $ch = $this->classes->getClass($chileclass,$chilefile);\r
-                    $my_tree[$cur]['children'][] = array('class' => $ch->getName(), 'package' => $ch->docblock->package);\r
-                }\r
-                usort($my_tree[$cur]['children'],'rootcmp');\r
-                if (isset($my_tree[$cur]['children'][$childpos]))\r
-                {\r
-                    array_push($lastcur, array($cur, $childpos));\r
-                    $par = $cur;\r
-                    $cur = $my_tree[$cur]['children'][$childpos];\r
-                    $x = $this->classes->getClassByPackage($cur['class'],$cur['package']);\r
-                    $cur = $cur['package'] . '#' . $cur['class'];\r
-                    $my_tree[$cur]['link'] = Converter::getClassLink($x->getName(),$x->docblock->package,$x->getPath());\r
-                    $my_tree[$cur]['parent'] = $par;\r
-                    $my_tree[$cur]['children'] = array();\r
-                    $childpos = 0;\r
-                    $class_children = $this->classes->getDefiniteChildren($x->getName(), $x->curfile);\r
-                } else\r
-                {\r
-                    list($cur, $childpos) = array_pop($lastcur);\r
-                }\r
-            } while ($cur);\r
-        }\r
-        return $my_tree;\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this class exists in package $package and subpackage $subpackage\r
-     * @param string $expr class name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedClass($expr,$package,$subpackage,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['class'][$file][$expr]);\r
-        return isset($this->links[$package][$subpackage]['class'][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this function exists in package $package and subpackage $subpackage\r
-     * @param string $expr function name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedFunction($expr,$package,$subpackage,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['function'][$file][$expr]);\r
-        return isset($this->links[$package][$subpackage]['function'][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this define exists in package $package and subpackage $subpackage\r
-     * @param string $expr define name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedDefine($expr,$package,$subpackage,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['define'][$file][$expr]);\r
-        return isset($this->links[$package][$subpackage]['define'][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this define exists in package $package and subpackage $subpackage\r
-     * @param string $expr define name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedGlobal($expr,$package,$subpackage,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['global'][$file][$expr]);\r
-        return isset($this->links[$package][$subpackage]['global'][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this procedural page exists in package $package and subpackage $subpackage\r
-     * @param string $expr procedural page name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedPage($expr,$package,$subpackage,$path=false)\r
-    {\r
-        if ($path)\r
-        return isset($this->linkswithfile[$package][$subpackage]['page'][$path][$expr]);\r
-        return isset($this->links[$package][$subpackage]['page'][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class\r
-     * @param string $expr method name\r
-     * @param string $class class name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedMethod($expr,$package,$subpackage,$class,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr]);\r
-        return isset($this->links[$package][$subpackage]['method'][$class][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class\r
-     * @param string $expr var name\r
-     * @param string $class class name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedVar($expr,$package,$subpackage,$class,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr]);\r
-        return isset($this->links[$package][$subpackage]['var'][$class][$expr]);\r
-    }\r
-\r
-    /**\r
-     * do not override\r
-     * @return bool true if a link to this method exists in package $package, subpackage $subpackage and class $class\r
-     * @param string $expr constant name\r
-     * @param string $class class name\r
-     * @param string $package package to search in\r
-     * @param string $subpackage subpackage to search in\r
-     * @access private\r
-     */\r
-    function isLinkedConst($expr,$package,$subpackage,$class,$file=false)\r
-    {\r
-        if ($file)\r
-        return isset($this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr]);\r
-        return isset($this->links[$package][$subpackage]['const'][$class][$expr]);\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link classLink} to $expr\r
-     * @param string $expr class name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link classLink} or false if the element is not found in package $package\r
-     * @see classLink\r
-     */\r
-    function getClassLink($expr,$package,$file=false, $text = false)\r
-    {\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedClass($expr,$package,$subpackage,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['class'][$file][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['class'][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link functionLink} to $expr\r
-     * @param string $expr function name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link functionLink} or false if the element is not found in package $package\r
-     * @see functionLink\r
-     */\r
-    function getFunctionLink($expr,$package,$file=false, $text = false)\r
-    {\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedFunction($expr,$package,$subpackage,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['function'][$file][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['function'][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link defineLink} to $expr\r
-     * @param string $expr constant name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link defineLink} or false if the element is not found in package $package\r
-     * @see defineLink\r
-     */\r
-    function getDefineLink($expr,$package,$file=false, $text = false)\r
-    {\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedDefine($expr,$package,$subpackage,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['define'][$file][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['define'][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link globalLink} to $expr\r
-     * @param string $expr global variable name (with leading $)\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link defineLink} or false if the element is not found in package $package\r
-     * @see defineLink\r
-     */\r
-    function getGlobalLink($expr,$package,$file=false, $text = false)\r
-    {\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedGlobal($expr,$package,$subpackage,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['global'][$file][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['global'][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link pageLink} to $expr\r
-     * @param string $expr procedural page name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link pageLink} or false if the element is not found in package $package\r
-     * @see pageLink\r
-     */\r
-    function getPageLink($expr,$package,$path = false, $text = false, $packages = false)\r
-    {\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedPage($expr,$package,$subpackage,$path))\r
-            {\r
-                if ($path)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['page'][$path][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['page'][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link methodLink} to $expr in $class\r
-     * @param string $expr method name\r
-     * @param string $class class name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link methodLink} or false if the element is not found in package $package, class $class\r
-     * @see methodLink\r
-     */\r
-    function getMethodLink($expr,$class,$package,$file=false, $text = false)\r
-    {\r
-        $expr = trim($expr);\r
-        $class = trim($class);\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedMethod($expr,$package,$subpackage,$class,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['method'][$file][$class][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['method'][$class][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link varLink} to $expr in $class\r
-     * @param string $expr var name\r
-     * @param string $class class name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class\r
-     * @see varLink\r
-     */\r
-    function getVarLink($expr,$class,$package,$file=false, $text = false)\r
-    {\r
-        $expr = trim($expr);\r
-        $class = trim($class);\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedVar($expr,$package,$subpackage,$class,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['var'][$file][$class][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['var'][$class][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * return false or a {@link constLink} to $expr in $class\r
-     * @param string $expr constant name\r
-     * @param string $class class name\r
-     * @param string $package package name\r
-     * @return mixed returns a {@link varLink} or false if the element is not found in package $package, class $class\r
-     * @see constLink\r
-     */\r
-    function getConstLink($expr,$class,$package,$file=false, $text = false)\r
-    {\r
-        $expr = trim($expr);\r
-        $class = trim($class);\r
-        if (!isset($this->links[$package])) return false;\r
-        foreach($this->links[$package] as $subpackage => $notused)\r
-        {\r
-            if ($this->isLinkedConst($expr,$package,$subpackage,$class,$file))\r
-            {\r
-                if ($file)\r
-                {\r
-                    return $this->linkswithfile[$package][$subpackage]['const'][$file][$class][$expr];\r
-                }\r
-                return $this->links[$package][$subpackage]['const'][$class][$expr];\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * The meat of the @tutorial tag and inline {@}tutorial} tag\r
-     *\r
-     * Take a string and return an abstract link to the tutorial it represents.\r
-     * Since tutorial naming literally works like the underlying filesystem, the\r
-     * way to reference the tutorial is similar.  Tutorials are located in a\r
-     * subdirectory of any directory parsed, which is named 'tutorials/' (we\r
-     * try to make things simple when we can :).  They are further organized by\r
-     * package and subpackage as:\r
-     *\r
-     * tutorials/package/subpackage\r
-     *\r
-     * and the files are named *.cls, *.pkg, or *.proc, and so a link to a tutorial\r
-     * named file.cls can be referenced (depending on context) as any of:\r
-     *\r
-     * <code>\r
-     * * @tutorial package/subpackage/file.cls\r
-     * * @tutorial package/file.cls\r
-     * * @tutorial file.cls\r
-     * </code>\r
-     *\r
-     * The first case will only be needed if file.cls exists in both the current\r
-     * package, in anotherpackage/file.cls and in anotherpackage/subpackage/file.cls\r
-     * and you wish to reference the one in anotherpackage/subpackage.\r
-     * The second case is only needed if you wish to reference file.cls in another\r
-     * package and it is unique in that package. the third will link to the first\r
-     * file.cls it finds using this search method:\r
-     *\r
-     * <ol>\r
-     *    <li>current package/subpackage</li>\r
-     *    <li>all other subpackages of current package</li>\r
-     *    <li>parent package, if this package has classes that extend classes in\r
-     *    another package</li>\r
-     *    <li>all other packages</li>\r
-     * </ol>\r
-     * @return tutorialLink|string returns either a link, or the original text, if not found\r
-     * @param string the original expression\r
-     * @param string package to look in first\r
-     * @param string subpackage to look in first\r
-     * @param array array of package names to search in if not found in parent packages.\r
-     *              This is used to limit the search, phpDocumentor automatically searches\r
-     *              all packages\r
-     * @since 1.2\r
-     */\r
-    function getTutorialLink($expr, $package = false, $subpackage = false, $packages = false)\r
-    {\r
-        // is $expr a comma-delimited list?\r
-        if (strpos($expr,','))\r
-        {\r
-            $a = explode(',',$expr);\r
-            $b = array();\r
-            for($i=0;$i<count($a);$i++)\r
-            {\r
-                // if so return each component with a link\r
-                $b[] = Converter::getTutorialLink(trim($a[$i]));\r
-            }\r
-            return $b;\r
-        }\r
-        $subsection = '';\r
-        if (strpos($expr,'#'))\r
-        {\r
-            $a = explode('#',$expr);\r
-            $org = $expr;\r
-            $expr = $a[0];\r
-            $subsection = $a[1];\r
-        }\r
-        if (strpos($expr,'/'))\r
-        {\r
-            $a = explode('/',$expr);\r
-            if (count($a) == 3)\r
-            {\r
-                return Converter::getTutorialLink($a[2],$a[0],$a[1],array());\r
-            }\r
-            if (count($a) == 2)\r
-            {\r
-                return Converter::getTutorialLink($a[1],$a[0],false,array());\r
-            }\r
-        }\r
-        if (!$package) $package = $this->package;\r
-        if (!$subpackage) $subpackage = $this->subpackage;\r
-        if (!isset($this->all_packages[$package])) return $expr;\r
-        elseif (isset($packages[$package])) unset($packages[$package]);\r
-        $ext = pathinfo($expr, PATHINFO_EXTENSION);\r
-        if (isset($this->tutorials[$package][$subpackage][$ext][$expr]))\r
-        {\r
-            $a = $this->tutorials[$package][$subpackage][$ext][$expr];\r
-            $link = new tutorialLink;\r
-            $link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this,$subsection));\r
-            return $link;\r
-        }\r
-        do\r
-        {\r
-            if (!is_array($packages))\r
-            {\r
-                $packages = $this->all_packages;\r
-                if (isset($packages[$package])) unset($packages[$package]);\r
-            }\r
-            if (isset($this->tutorials[$package]))\r
-            {\r
-                if (isset($this->tutorials[$package][$subpackage][$ext][$expr]))\r
-                {\r
-                    $a = $this->tutorials[$package][$subpackage][$ext][$expr];\r
-                    $link = new tutorialLink;\r
-                    $link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this));\r
-                    return $link;\r
-                } else\r
-                {\r
-                    foreach($this->tutorials[$package] as $subpackage => $stuff)\r
-                    {\r
-                        if (isset($stuff[$ext][$expr]))\r
-                        {\r
-                            $a = $stuff[$ext][$expr];\r
-                            $link = new tutorialLink;\r
-                            $link->addLink($subsection,$a->path,$a->name,$a->package,$a->subpackage,$a->getTitle($this));\r
-                            return $link;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-            // try other packages\r
-            // look in parent package first, if found\r
-            if (isset($this->package_parents[$package]))\r
-            {\r
-                $p1 = $package;\r
-                $package = $this->package_parents[$package];\r
-            } else\r
-            {\r
-                // no parent package, so start with the first one that's left\r
-                list($package,) = @each($packages);\r
-            }\r
-            if ($package)\r
-            {\r
-                if (isset($packages[$package])) unset($packages[$package]);\r
-            }\r
-        } while (count($packages) || $package);\r
-        addWarning(PDERROR_TUTORIAL_NOT_FOUND,$expr);\r
-        return $expr;\r
-    }\r
-\r
-    /**\r
-     * The meat of the @see tag and inline {@}link} tag\r
-     *\r
-     * $expr is a string with many allowable formats:\r
-     * <ol>\r
-     *  <li>proceduralpagename.ext</li>\r
-     *  <li>constant_name</li>\r
-     *  <li>classname::function()</li>\r
-     *  <li>classname::constantname</li> (new 1.2.4)\r
-     *  <li>classname::$variablename</li>\r
-     *  <li>classname</li>\r
-     *  <li>object classname</li>\r
-     *  <li>function functionname()</li>\r
-     *  <li>global $globalvarname</li>\r
-     *  <li>packagename#expr where expr is any of the above</li>\r
-     * </ol>\r
-     *\r
-     * New in version 1.1, you can explicitly specify a package to link to that\r
-     * is different from the current package.  Use the # operator\r
-     * to specify a new package, as in tests#bug-540368.php (which should appear\r
-     * as a link like: "{@link tests#bug-540368.php}").  This\r
-     * example links to the procedural page bug-540368.php in package\r
-     * tests.  Also, the "function" operator is now used to specifically\r
-     * link to a function instead of a method in the current class.\r
-     *\r
-     * <code>\r
-     * class myclass\r
-     * {\r
-     *  // from inside the class definition, use "function conflict()" to refer to procedural function "conflict()"\r
-     *    function conflict()\r
-     *    {\r
-     *    }\r
-     * }\r
-     *\r
-     * function conflict()\r
-     * {\r
-     * }\r
-     * </code>\r
-     *\r
-     * If classname:: is not present, and the see tag is in a documentation\r
-     * block within a class, then the function uses the classname to\r
-     * search for $expr as a function or variable within classname, or any of its parent classes.\r
-     * given an $expr without '$', '::' or '()' getLink first searches for\r
-     * classes, procedural pages, constants, global variables, and then searches for\r
-     * methods and variables within the default class, and finally for any function\r
-     *\r
-     * @param string $expr expression to search for a link\r
-     * @param string $package package to start searching in\r
-     * @param array $packages list of all packages to search in\r
-     * @return mixed getLink returns a descendant of {@link abstractLink} if it finds a link, otherwise it returns a string\r
-     * @see getPageLink(), getDefineLink(), getVarLink(), getFunctionLink(), getClassLink()\r
-     * @see pageLink, functionLink, defineLink, classLink, methodLink, varLink\r
-     */\r
-    function &getLink($expr, $package = false, $packages = false)\r
-    {\r
-        // is $expr a comma-delimited list?\r
-        if (strpos($expr,','))\r
-        {\r
-            $a = explode(',',$expr);\r
-            $b = array();\r
-            for($i=0;$i<count($a);$i++)\r
-            {\r
-                // if so return each component with a link\r
-                $b[] = Converter::getLink(trim($a[$i]));\r
-            }\r
-            return $b;\r
-        }\r
-        if (strpos($expr,'#'))\r
-        {\r
-            $a = explode('#',$expr);\r
-            if (count($a) == 2)\r
-            { // can have exactly 1 package override, otherwise it's ignored\r
-                // feature 564991, link to php manual\r
-                if ($a[0] == 'PHP_MANUAL') {\r
-                    $s = 'http://www.php.net/'.$a[1];\r
-                    return $s;\r
-                }\r
-                $s = &Converter::getLink($a[1],$a[0],array());\r
-                return $s;\r
-            }\r
-        }\r
-        $a = &$this->_getLink($expr, $package, $packages);\r
-        return $a;\r
-    }\r
-\r
-    /**\r
-     * @access private\r
-     */\r
-    function &_getLink($expr, $package = false, $packages = false)\r
-    {\r
-        if (!$package) $package = $this->package;\r
-        //\r
-        if (!isset($this->all_packages[$package])) return $expr;\r
-        elseif (isset($packages[$package])) unset($packages[$package]);\r
-        $links = &$this->links;\r
-        $class = $this->class;\r
-        if (strpos($expr,'function ') === 0)\r
-        { // asking for a function, not a method\r
-            if ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;\r
-            else return $expr;\r
-        }\r
-        if (strpos($expr,'global ') === 0)\r
-        { // asking for a global variable\r
-            if ($test = Converter::getGlobalLink(str_replace('global ','',$expr), $package)) return $test;\r
-            else return $expr;\r
-        }\r
-        if (strpos($expr,'object ') === 0)\r
-        { // asking for a class\r
-            if ($test = Converter::getClassLink(str_replace('object ','',$expr), $package)) return $test;\r
-            else return $expr;\r
-        }\r
-        if (strpos($expr,'constant ') === 0)\r
-        { // asking for a class\r
-            if ($test = Converter::getDefineLink(str_replace('constant ','',$expr), $package)) return $test;\r
-            else return $expr;\r
-        }\r
-        // are we in a class?\r
-        if ($class)\r
-        {\r
-            // is $expr simply a word? see if it is the class\r
-            if (trim($expr) == $class)\r
-            {\r
-                if ($test = Converter::getClassLink(trim(str_replace('object ','',$expr)),$package)) return $test;\r
-            }\r
-            // if not, check to see if it is a method or variable of this class tree\r
-            if (!strpos($expr,'::'))\r
-            {\r
-                // if get is neither get() nor $get, assume get is a function, add () to make get()\r
-                if (strpos($expr,'$') !== 0 && !strpos($expr,'()')) //$get = $get.'()';\r
-                {\r
-                    if ($a = $this->getLinkMethod($expr,$class,$package)) return $a;\r
-                    if ($a = $this->getLinkConst($expr,$class,$package)) return $a;\r
-                    if ($a = $this->getLinkVar('$'.$expr,$class,$package)) return $a;\r
-                }\r
-                if (strpos($expr,'()')) if ($a = $this->getLinkMethod($expr,$class,$package)) return $a;\r
-                if (is_numeric(strpos($expr,'$'))) if ($a = $this->getLinkVar($expr,$class,$package)) return $a;\r
-            }\r
-        }\r
-        if ($test = Converter::getClassLink(trim(str_replace('object ','',$expr)),$package)) return $test;\r
-        if ($test = Converter::getPageLink(trim($expr),$package)) return $test;\r
-        if ($test = Converter::getDefineLink(trim($expr),$package)) return $test;\r
-        if ($test = Converter::getGlobalLink(trim($expr),$package)) return $test;\r
-//        if (strpos($expr,'.'))\r
-        // package specified\r
-\r
-        if (!is_array($packages))\r
-        {\r
-            $packages = $this->all_packages;\r
-        }\r
-        do\r
-        {\r
-            if (isset($packages[$package])) unset($packages[$package]);\r
-            if ($test = Converter::getClassLink(str_replace('object ','',$expr),$package)) return $test;\r
-            if ($test = Converter::getPageLink($expr,$package)) return $test;\r
-            if ($test = Converter::getDefineLink($expr,$package)) return $test;\r
-            if ($test = Converter::getGlobalLink($expr,$package)) return $test;\r
-            // is $expr in class::method() or class::$variable format?\r
-            if (strpos($expr,'function ') === 0)\r
-            { // asking for a function, not a method\r
-                if ($test = Converter::getFunctionLink(str_replace('function','',str_replace('()','',$expr)), $package)) return $test;\r
-                else return $expr;\r
-            }\r
-            $test = $this->_getDoubleColon($expr, $package, $packages, $class, $links);\r
-            if (!is_string($test)) return $test;\r
-            if (strpos($test, 'parent::') === 0) return $test;\r
-            // $expr does not have ::\r
-            if (is_numeric(@strpos('$',$expr)))\r
-            {\r
-                // default to current class, whose name is contained in $this->render->parent\r
-                if ($test = Converter::getVarLink($expr, $class, $package)) return $test;\r
-            }\r
-            // $expr is a function? (non-method)\r
-            if (@strpos($expr,'()'))\r
-            {\r
-                // otherwise, see if it is a method\r
-                if ($class)\r
-                {\r
-                    if ($test = Converter::getMethodLink(str_replace('()','',$expr), $class, $package)) return $test;\r
-                }\r
-                // extract the function name, use it to retrieve the file that the function is in\r
-    //            $page = $this->func_page[str_replace('function ','',str_replace('()','',$expr))];\r
-                // return the link\r
-                if ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;\r
-            }\r
-            // $expr is just a word.  First, test to see if it is a function of the current package\r
-            if ($test = Converter::getFunctionLink(str_replace('function ','',str_replace('()','',$expr)), $package)) return $test;\r
-            // try other packages\r
-            // look in parent package first, if found\r
-            if (isset($this->package_parents[$package]) && in_array($this->package_parents[$package], $packages))\r
-            {\r
-                $p1 = $package;\r
-                $package = $this->package_parents[$package];\r
-                if ($package)\r
-                {\r
-                    if (isset($packages[$package])) unset($packages[$package]);\r
-                }\r
-                continue;\r
-            }\r
-            // no parent package, so start with the first one that's left\r
-            $package = @array_shift(@array_keys($packages));\r
-            if ($package && isset($packages[$package]))\r
-            {\r
-                unset($packages[$package]);\r
-            }\r
-        } while (count($packages) || $package);\r
-        $funcs = get_defined_functions();\r
-        // feature 564991, link to php manual\r
-        if (in_array(str_replace(array('(',')'),array('',''),$expr),$funcs['internal']))\r
-        {\r
-            $return = 'http://www.php.net/'.str_replace(array('(',')'),array('',''),$expr);\r
-            return $return;\r
-        }\r
-        // no links found\r
-        return $expr;\r
-    }\r
-\r
-    /**\r
-     * Split up getLink to make it easier to debug\r
-     * @access private\r
-     */\r
-    function _getDoubleColon(&$expr, &$package, &$packages, $class, $links)\r
-    {\r
-        if (@strpos($expr,'::'))\r
-        {\r
-            $class_method = explode('::',$expr);\r
-            if ($class_method[0] == 'parent')\r
-            {\r
-                // can only have parent in the same package as the class!  subtle bug\r
-                $package = $this->package;\r
-                $packages = array();\r
-                $cl = $this->classes->getClassByPackage($class,$package);\r
-                if (!$cl)\r
-                { // this is possible if an example file has parent::method()\r
-                    return $expr;\r
-                }\r
-                $par = $cl->getParent($this);\r
-                $phpparent = false;\r
-                if (is_object($par))\r
-                {\r
-                    $package = $par->docblock->package;\r
-                    $phpparent = $par->getName();\r
-                } else\r
-                {\r
-                    addWarning(PDERROR_CLASS_PARENT_NOT_FOUND,$class,$package,$class_method[1]);\r
-                    return $expr;\r
-                }\r
-                if ($phpparent) $class_method[0] = $phpparent;\r
-            }\r
-            if (strpos($class_method[1],'()'))\r
-            {\r
-                // strip everything but the function name, return a link\r
-                if ($test = Converter::getMethodLink(str_replace('()','',$class_method[1]), $class_method[0], $package)) return $test;\r
-            }\r
-            if ($test = Converter::getVarLink($class_method[1], $class_method[0], $package)) return $test;\r
-            if ($test = Converter::getConstLink($class_method[1], $class_method[0], $package)) return $test;\r
-        }\r
-        return $expr;\r
-    }\r
-\r
-    /**\r
-     * cycle through parent classes to retrieve a link to a method\r
-     * do not use or override, used by getLink\r
-     * @access private\r
-     */\r
-    function &getLinkMethod($expr, $class, $package)\r
-    {\r
-        $links = &$this->links;\r
-        do\r
-        {\r
-            // is $expr in class::method() or class::$variable format?\r
-            if (@strpos($expr,'::'))\r
-            {\r
-                $class_method = explode('::',$expr);\r
-                if ($class_method[0] == 'parent')\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                    $par = $cl->getParent($this);\r
-                    $phpparent = false;\r
-                    if (is_object($par))\r
-                    {\r
-                        $package = $par->docblock->package;\r
-                        $phpparent = $par->getName();\r
-                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);\r
-                    if ($phpparent) $class_method[0] = $phpparent;\r
-                } else\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                }\r
-                if (strpos($class_method[1],'()'))\r
-                {\r
-                    // strip everything but the function name, return a link\r
-                    if ($test = Converter::getMethodLink(str_replace('function ','',str_replace('()','',$class_method[1])), $class_method[0], $package)) return $test;\r
-                }\r
-            }\r
-            if ($test = Converter::getMethodLink(str_replace('()','',$expr), $class, $package)) return $test;\r
-            $cl = $this->classes->getClassByPackage($class,$package);\r
-            if ($cl)\r
-            {\r
-                $par = $cl->getParent($this);\r
-                if (is_object($par))\r
-                {\r
-                    $package = $par->docblock->package;\r
-                    $class = $par->getName();\r
-                } else $class = $par;\r
-            } else $class = false;\r
-        } while ($class);\r
-        // no links found\r
-        $flag = false;\r
-        return $flag;\r
-    }\r
-\r
-    /**\r
-     * cycle through parent classes to retrieve a link to a var\r
-     * do not use or override, used by getLink\r
-     * @access private\r
-     */\r
-    function &getLinkVar($expr, $class, $package)\r
-    {\r
-        $links = &$this->links;\r
-        do\r
-        {\r
-            // is $expr in class::method() or class::$variable format?\r
-            if (@strpos($expr,'::'))\r
-            {\r
-                $class_method = explode('::',$expr);\r
-                if ($class_method[0] == 'parent')\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                    $phpparent = false;\r
-                    $par = $cl->getParent($this);\r
-                    if (is_object($par))\r
-                    {\r
-                        $package = $par->docblock->package;\r
-                        $phpparent = $par->getName();\r
-                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);\r
-                    if ($phpparent) $class_method[0] = $phpparent;\r
-                } else\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                }\r
-                if ($test = Converter::getVarLink($class_method[1], $class_method[0], $package)) return $test;\r
-                if ($test = Converter::getVarLink('$'.$class_method[1], $class_method[0], $package)) return $test;\r
-            }\r
-            if ($test = Converter::getVarLink($expr, $class, $package)) return $test;\r
-            if ($test = Converter::getVarLink('$'.$expr, $class, $package)) return $test;\r
-            $cl = $this->classes->getClassByPackage($class,$package);\r
-            if ($cl)\r
-            {\r
-                $par = $cl->getParent($this);\r
-                if (is_object($par))\r
-                {\r
-                    $package = $par->docblock->package;\r
-                    $class = $par->getName();\r
-                } else $class = $par;\r
-            } else $class = false;\r
-        } while ($class);\r
-        // no links found\r
-        $class = false;\r
-        return $class;\r
-    }\r
-\r
-    /**\r
-     * cycle through parent classes to retrieve a link to a class constant\r
-     * do not use or override, used by getLink\r
-     * @access private\r
-     * @since 1.2.4\r
-     */\r
-    function &getLinkConst($expr, $class, $package)\r
-    {\r
-        $links = &$this->links;\r
-        do\r
-        {\r
-            // is $expr in class::method() or class::$variable format?\r
-            if (@strpos($expr,'::'))\r
-            {\r
-                $class_method = explode('::',$expr);\r
-                if ($class_method[0] == 'parent')\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                    $phpparent = false;\r
-                    $par = $cl->getParent($this);\r
-                    if (is_object($par))\r
-                    {\r
-                        $package = $par->docblock->package;\r
-                        $phpparent = $par->getName();\r
-                    } else addWarning(PDERROR_CLASSPARENT_NOTFOUND,$class,$package,$class_method[1]);\r
-                    if ($phpparent) $class_method[0] = $phpparent;\r
-                } else\r
-                {\r
-                    $cl = $this->classes->getClassByPackage($class,$package);\r
-                }\r
-                if ($test = Converter::getConstLink($class_method[1], $class_method[0], $package)) return $test;\r
-            }\r
-            if ($test = Converter::getConstLink($expr, $class, $package)) return $test;\r
-            $cl = $this->classes->getClassByPackage($class,$package);\r
-            if ($cl)\r
-            {\r
-                $par = $cl->getParent($this);\r
-                if (is_object($par))\r
-                {\r
-                    $package = $par->docblock->package;\r
-                    $class = $par->getName();\r
-                } else $class = $par;\r
-            } else $class = false;\r
-        } while ($class);\r
-        // no links found\r
-        $flag = false;\r
-        return $flag;\r
-    }\r
-\r
-    /**\r
-     * take URL $link and text $text and return a link in the format needed for the Converter\r
-     * @param string URL\r
-     * @param string text to display\r
-     * @return string link to $link\r
-     * @abstract\r
-     */\r
-    function returnLink($link,$text)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * take {@link abstractLink} descendant and text $eltext and return a link\r
-     * in the format needed for the Converter\r
-     * @param abstractLink\r
-     * @param string\r
-     * @return string link to $element\r
-     * @abstract\r
-     */\r
-    function returnSee(&$link, $eltext = false)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * take {@link abstractLink} descendant and text $eltext and return a\r
-     * unique ID in the format needed for the Converter\r
-     * @param abstractLink\r
-     * @return string unique identifier of $element\r
-     * @abstract\r
-     */\r
-    function getId(&$link)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Convert README/INSTALL/CHANGELOG file contents to output format\r
-     * @param README|INSTALL|CHANGELOG\r
-     * @param string contents of the file\r
-     * @abstract\r
-     */\r
-    function Convert_RIC($name, $contents)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Convert all elements to output format\r
-     *\r
-     * This will call ConvertXxx where Xxx is {@link ucfirst}($element->type).\r
-     * It is expected that a child converter defines a handler for every\r
-     * element type, even if that handler does nothing.  phpDocumentor will\r
-     * terminate with an error if a handler doesn't exist.\r
-     * {@internal\r
-     * Since 1.2.0 beta 3, this function has been moved from child converters\r
-     * to the parent, because it doesn't really make sense to put it in the\r
-     * child converter, and we can add error handling.\r
-     *\r
-     * {@source}}}\r
-     * @throws {@link PDERROR_NO_CONVERT_HANDLER}\r
-     * @param mixed {@link parserElement} descendant or {@link parserPackagePage} or {@link parserData}\r
-     */\r
-    function Convert(&$element)\r
-    {\r
-        $handler = 'convert'.ucfirst($element->type);\r
-        if (method_exists($this,$handler))\r
-        {\r
-            $this->$handler($element);\r
-        } else\r
-        {\r
-            addErrorDie(PDERROR_NO_CONVERTER_HANDLER,$element->type,$handler,phpDocumentor_get_class($this));\r
-        }\r
-    }\r
-    /**#@+\r
-     * Conversion Handlers\r
-     *\r
-     * All of the convert* handlers set up template variables for the Smarty\r
-     * template.{@internal  In addition, the {@link newSmarty()} method is\r
-     * called to retrieve the global Smarty template}}\r
-     */\r
-    /**\r
-     * Default Tutorial Handler\r
-     *\r
-     * Sets up the tutorial template, and its prev/next/parent links\r
-     * {@internal\r
-     * Retrieves the title using {@link parserTutorial::getTitle()} and uses the\r
-     * {@link parserTutorial::prev, parserTutorial::next, parserTutorial::parent}\r
-     * links to set up those links.}}\r
-     * @param parserTutorial\r
-     */\r
-    function &convertTutorial(&$element)\r
-    {\r
-        $this->package = $element->package;\r
-        $this->subpackage = $element->subpackage;\r
-        $x = $element->Convert($this);\r
-        $template = &$this->newSmarty();\r
-        $template->assign('contents',$x);\r
-        $template->assign('title',$element->getTitle($this));\r
-        $template->assign('nav',$element->parent || $element->prev || $element->next);\r
-        if ($element->parent)\r
-        {\r
-            $template->assign('up',$this->getId($element->parent));\r
-            $template->assign('uptitle',$element->parent->title);\r
-        }\r
-        if ($element->prev)\r
-        {\r
-            $template->assign('prev',$this->getId($element->prev));\r
-            $template->assign('prevtitle',$element->prev->title);\r
-        }\r
-        if ($element->next)\r
-        {\r
-            $template->assign('next',$this->getId($element->next));\r
-            $template->assign('nexttitle',$element->next->title);\r
-        }\r
-        return $template;\r
-    }\r
-    /**\r
-     * Default Class Handler\r
-     *\r
-     * Sets up the class template.\r
-     * {@internal special methods\r
-     * {@link generateChildClassList(), generateFormattedClassTree()},\r
-     * {@link getFormattedConflicts, getFormattedInheritedMethods},\r
-     * and {@link getFormattedInheritedVars} are called to complete vital\r
-     * template setup.}}\r
-     */\r
-    function convertClass(&$element)\r
-    {\r
-        $this->class = $element->getName();\r
-        $this->class_data = &$this->newSmarty();\r
-        $this->class_data->assign("class_name",$element->getName());\r
-        $this->class_data->assign("vars",array());\r
-        $this->class_data->assign("methods",array());\r
-        $this->class_data->assign("consts",array());\r
-        $this->class_data->assign("is_interface", $element->isInterface());\r
-        $this->class_data->assign("implements", $this->getFormattedImplements($element));\r
-        $this->class_data->assign("package",$element->docblock->package);\r
-        $this->class_data->assign("line_number",$element->getLineNumber());\r
-        $this->class_data->assign("source_location",$element->getSourceLocation($this));\r
-                               $this->class_data->assign("page_link",$this->getCurrentPageLink());\r
-        $docblock = $this->prepareDocBlock($element, false);\r
-        $this->class_data->assign("sdesc",$docblock['sdesc']);\r
-        $this->class_data->assign("desc",$docblock['desc']);\r
-                               $this->class_data->assign("access", $docblock['access']);\r
-                               $this->class_data->assign("abstract", $docblock['abstract']);\r
-        $this->class_data->assign("tags",$docblock['tags']);\r
-        $this->class_data->assign("api_tags",$docblock['api_tags']);\r
-        $this->class_data->assign("info_tags",$docblock['info_tags']);\r
-        $this->class_data->assign("utags",$docblock['utags']);\r
-        $this->class_data->assign( "prop_tags", $docblock['property_tags'] );\r
-        if ($this->hasSourceCode($element->getPath())) {\r
-        $this->class_data->assign("class_slink",$this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true));\r
-        }\r
-\r
-        else\r
-        $this->class_data->assign("class_slink",false);\r
-        $this->class_data->assign("children", $this->generateChildClassList($element));\r
-        $this->class_data->assign("class_tree", $this->generateFormattedClassTree($element));\r
-        $this->class_data->assign("conflicts", $this->getFormattedConflicts($element,"classes"));\r
-        $inherited_methods = $this->getFormattedInheritedMethods($element);\r
-        if (!empty($inherited_methods))\r
-        {\r
-            $this->class_data->assign("imethods",$inherited_methods);\r
-        } else\r
-        {\r
-            $this->class_data->assign("imethods",false);\r
-        }\r
-        $inherited_vars = $this->getFormattedInheritedVars($element);\r
-        if (!empty($inherited_vars))\r
-        {\r
-            $this->class_data->assign("ivars",$inherited_vars);\r
-        } else\r
-        {\r
-            $this->class_data->assign("ivars",false);\r
-        }\r
-        $inherited_consts = $this->getFormattedInheritedConsts($element);\r
-        if (!empty($inherited_consts))\r
-        {\r
-            $this->class_data->assign("iconsts",$inherited_consts);\r
-        } else\r
-        {\r
-            $this->class_data->assign("iconsts",false);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Converts method for template output\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * @param parserMethod\r
-     */\r
-    function convertMethod(&$element, $additions = array())\r
-    {\r
-        $fname = $element->getName();\r
-        $docblock = $this->prepareDocBlock($element);\r
-        $returntype = 'void';\r
-        if ($element->isConstructor) $returntype = $element->class;\r
-        if ($element->docblock->return)\r
-        {\r
-            $a = $element->docblock->return->Convert($this);\r
-            $returntype = $element->docblock->return->converted_returnType;\r
-        }\r
-        $params = $param_i = array();\r
-        if (count($element->docblock->params))\r
-        foreach($element->docblock->params as $param => $val)\r
-        {\r
-            $a = $val->Convert($this);\r
-            $params[] = $param_i[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);\r
-        }\r
-\r
-        if ($element->docblock->hasaccess) {\r
-            $acc = $docblock['access'];\r
-        } else {\r
-            $acc = 'public';\r
-        }\r
-\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->class_data->append('methods',array_merge(\r
-                                             array('sdesc' => $docblock['sdesc'],\r
-                                                   'desc' => $docblock['desc'],\r
-                                                   'static' => $docblock['static'],\r
-                                                   'abstract' => $docblock['abstract'],\r
-                                                   'tags' => $docblock['tags'],\r
-                                                   'api_tags' => $docblock['api_tags'],\r
-                                                   'see_tags' => $docblock['see_tags'],\r
-                                                   'info_tags_sorted' => $docblock['info_tags_sorted'],\r
-                                                   'info_tags' => $docblock['info_tags'],\r
-                                                   'utags' => $docblock['utags'],\r
-                                                   'constructor' => $element->isConstructor,\r
-                                                   'access' => $acc,\r
-                                                   'function_name'     => $fname,\r
-                                                   'function_return'    => $returntype,\r
-                                                   'function_call'     => $element->getFunctionCall(),\r
-                                                   'ifunction_call'     => $element->getIntricateFunctionCall($this, $param_i),\r
-                                                   'descmethod'    => $this->getFormattedDescMethods($element),\r
-                                                   'method_overrides'    => $this->getFormattedOverrides($element),\r
-                                                   'method_implements'    => $this->getFormattedMethodImplements($element),\r
-                                                   'line_number' => $element->getLineNumber(),\r
-                                                   'id' => $this->getId($element),\r
-                                                   'params' => $params),\r
-                                             $additions));\r
-    }\r
-\r
-    /**\r
-     * Converts class variables for template output.\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * @param parserVar\r
-     */\r
-    function convertVar(&$element, $additions = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-        $b = 'mixed';\r
-\r
-        if ($element->docblock->hasaccess)\r
-            $acc = $element->docblock->tags['access'][0]->value;\r
-        else\r
-            $acc = 'public';\r
-\r
-        if ($element->docblock->var)\r
-        {\r
-            $b = $element->docblock->var->converted_returnType;\r
-        }\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->class_data->append('vars',array_merge(\r
-                                          array('sdesc' => $docblock['sdesc'],\r
-                                                'desc' => $docblock['desc'],\r
-                                                'static' => $docblock['static'],\r
-                                                'abstract' => $docblock['abstract'],\r
-                                                'utags' => $docblock['utags'],\r
-                                                'tags' => $docblock['tags'],\r
-                                                'api_tags' => $docblock['api_tags'],\r
-                                                'info_tags' => $docblock['info_tags'],\r
-                                                'var_name' => $element->getName(),\r
-                                                'has_default' => strlen($element->getValue()),\r
-                                                'var_default' => $this->postProcess($element->getValue()),\r
-                                                'var_type' => $b,\r
-                                                'access' => $acc,\r
-                                                'line_number' => $element->getLineNumber(),\r
-                                                'descvar'    => $this->getFormattedDescVars($element),\r
-                                                'var_overrides' => $this->getFormattedOverrides($element),\r
-                                                'id' => $this->getId($element)),\r
-                                          $additions));\r
-    }\r
-\r
-    /**\r
-     * Converts class constants for template output.\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * @param parserConst\r
-     */\r
-    function convertConst(&$element, $additions = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-\r
-        if ($element->docblock->hasaccess)\r
-               $acc = $element->docblock->tags['access'][0]->value;\r
-        else\r
-               $acc = 'public';\r
-\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $additions["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->class_data->append('consts',array_merge(\r
-                                          array('sdesc' => $docblock['sdesc'],\r
-                                                'desc' => $docblock['desc'],\r
-                                                'access' => $docblock['access'],\r
-                                                'abstract' => $docblock['abstract'],\r
-                                                'utags' => $docblock['utags'],\r
-                                                'tags' => $docblock['tags'],\r
-                                                'api_tags' => $docblock['api_tags'],\r
-                                                'info_tags' => $docblock['info_tags'],\r
-                                                'const_name' => $element->getName(),\r
-                                                'const_value' => $this->postProcess($element->getValue()),\r
-                                                'access' => $acc,\r
-                                                'line_number' => $element->getLineNumber(),\r
-                                                'id' => $this->getId($element)),\r
-                                          $additions));\r
-    }\r
-\r
-    /**\r
-     * Default Page Handler\r
-     *\r
-     * {@internal In addition to setting up the smarty template with {@link newSmarty()},\r
-     * this class uses {@link getSourceLocation()} and {@link getClassesOnPage()}\r
-     * to set template variables.  Also used is {@link getPageName()}, to get\r
-     * a Converter-specific name for the page.}}\r
-     * @param parserPage\r
-     */\r
-    function convertPage(&$element)\r
-    {\r
-        $this->page_data = &$this->newSmarty(true);\r
-        $this->page = $this->getPageName($element->parent);\r
-        $this->path = $element->parent->getPath();\r
-        $this->curpage = &$element->parent;\r
-        $this->page_data->assign("source_location",$element->parent->getSourceLocation($this));\r
-        $this->page_data->assign("functions",array());\r
-        $this->page_data->assign("includes",array());\r
-        $this->page_data->assign("defines",array());\r
-        $this->page_data->assign("globals",array());\r
-        $this->page_data->assign("classes",$this->getClassesOnPage($element));\r
-        $this->page_data->assign("hasclasses",$element->hasClasses());\r
-        $this->page_data->assign("hasinterfaces",$element->hasInterfaces());\r
-        $this->page_data->assign("name", $element->parent->getFile());\r
-        if ($t = $element->getTutorial())\r
-        {\r
-            $this->page_data->assign("tutorial",$this->returnSee($t));\r
-        } else\r
-        {\r
-            $this->page_data->assign("tutorial",false);\r
-        }\r
-        if ($element->docblock)\r
-        {\r
-            $docblock = $this->prepareDocBlock($element, false);\r
-            $this->page_data->assign("sdesc",$docblock['sdesc']);\r
-            $this->page_data->assign("desc",$docblock['desc']);\r
-            $this->page_data->assign("tags",$docblock['tags']);\r
-            $this->page_data->assign("api_tags",$docblock['api_tags']);\r
-            $this->page_data->assign("info_tags",$docblock['info_tags']);\r
-            $this->page_data->assign("utags",$docblock['utags']);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Converts global variables for template output\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * {@internal\r
-     * In addition to using {@link prepareDocBlock()}, this method also\r
-     * uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}\r
-     * @param parserGlobal\r
-     * @uses postProcess() on global_value template value, makes it displayable\r
-     * @param array any additional template variables should be in this array\r
-     */\r
-    function convertGlobal(&$element, $addition = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-        $value = $this->getGlobalValue($element->getValue());\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->page_data->append('globals',array_merge(\r
-                                            array('sdesc' => $docblock['sdesc'],\r
-                                                  'desc' => $docblock['desc'],\r
-                                                  'tags' => $docblock['tags'],\r
-                                                  'api_tags' => $docblock['api_tags'],\r
-                                                  'info_tags' => $docblock['info_tags'],\r
-                                                  'utags' => $docblock['utags'],\r
-                                                  'global_name'     => $element->getName(),\r
-                                                  'global_type' => $element->getDataType($this),\r
-                                                  'global_value'    => $value,\r
-                                                  'line_number' => $element->getLineNumber(),\r
-                                                  'global_conflicts'    => $this->getFormattedConflicts($element,"global variables"),\r
-                                                  'id' => $this->getId($element)),\r
-                                            $addition));\r
-    }\r
-\r
-    /**\r
-     * Converts defines for template output\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * {@internal\r
-     * In addition to using {@link prepareDocBlock()}, this method also\r
-     * uses utility functions {@link getGlobalValue(), getFormattedConflicts()}}}\r
-     * @param parserDefine\r
-     * @uses postProcess() on define_value template value, makes it displayable\r
-     * @param array any additional template variables should be in this array\r
-     */\r
-    function convertDefine(&$element, $addition = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->page_data->append('defines',array_merge(\r
-                                            array('sdesc' => $docblock['sdesc'],\r
-                                                  'desc' => $docblock['desc'],\r
-                                                  'tags' => $docblock['tags'],\r
-                                                  'api_tags' => $docblock['api_tags'],\r
-                                                  'info_tags' => $docblock['info_tags'],\r
-                                                  'utags' => $docblock['utags'],\r
-                                                  'define_name'     => $element->getName(),\r
-                                                  'line_number' => $element->getLineNumber(),\r
-                                                  'define_value'    => $this->postProcess($element->getValue()),\r
-                                                  'define_conflicts'    => $this->getFormattedConflicts($element,"defines"),\r
-                                                  'id' => $this->getId($element)),\r
-                                            $addition));\r
-    }\r
-\r
-\r
-    /**\r
-     * Converts includes for template output\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * @see prepareDocBlock()\r
-     * @param parserInclude\r
-     */\r
-    function convertInclude(&$element, $addition = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-        $per = $this->getIncludeValue($element->getValue(), $element->getPath());\r
-\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->page_data->append('includes',array_merge(\r
-                                             array('sdesc' => $docblock['sdesc'],\r
-                                                   'desc' => $docblock['desc'],\r
-                                                   'tags' => $docblock['tags'],\r
-                                                   'api_tags' => $docblock['api_tags'],\r
-                                                   'info_tags' => $docblock['info_tags'],\r
-                                                   'utags' => $docblock['utags'],\r
-                                                   'include_name'     => $element->getName(),\r
-                                                   'line_number' => $element->getLineNumber(),\r
-                                                   'include_value'    => $per),\r
-                                             $addition));\r
-    }\r
-\r
-    /**\r
-     * Converts function for template output\r
-     *\r
-     * This function must be called by a child converter with any extra\r
-     * template variables needed in the parameter $addition\r
-     * @see prepareDocBlock()\r
-     * @param parserFunction\r
-     */\r
-    function convertFunction(&$element, $addition = array())\r
-    {\r
-        $docblock = $this->prepareDocBlock($element);\r
-        $fname = $element->getName();\r
-        $params = $param_i = array();\r
-        if (count($element->docblock->params))\r
-        foreach($element->docblock->params as $param => $val)\r
-        {\r
-            $a = $val->Convert($this);\r
-            $params[] = $param_i[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);\r
-        }\r
-        $returntype = 'void';\r
-        if ($element->docblock->return)\r
-        {\r
-            $a = $element->docblock->return->Convert($this);\r
-            $returntype = $element->docblock->return->converted_returnType;\r
-        }\r
-\r
-        if ($this->hasSourceCode($element->getPath()))\r
-        $addition["slink"] = $this->getSourceAnchor($element->getPath(),$element->getLineNumber(),$element->getLineNumber(),true);\r
-        $this->page_data->append('functions',array_merge(\r
-                                              array('sdesc' => $docblock['sdesc'],\r
-                                                    'desc' => $docblock['desc'],\r
-                                                    'tags' => $docblock['tags'],\r
-                                                    'api_tags' => $docblock['api_tags'],\r
-                                                    'info_tags' => $docblock['info_tags'],\r
-                                                    'utags' => $docblock['utags'],\r
-                                                    'function_name'     => $fname,\r
-                                                    'function_return'    => $returntype,\r
-                                                    'function_conflicts'    => $this->getFormattedConflicts($element,"functions"),\r
-                                                    'ifunction_call'     => $element->getIntricateFunctionCall($this, $param_i),\r
-                                                    'function_call'     => $element->getFunctionCall(),\r
-                                                    'line_number' => $element->getLineNumber(),\r
-                                                    'id' => $this->getId($element),\r
-                                                    'params' => $params),\r
-                                              $addition));\r
-    }\r
-    /**#@-*/\r
-\r
-    /**\r
-     * convert the element's DocBlock for output\r
-     *\r
-     * This function converts all tags and descriptions for output\r
-     * @param mixed any descendant of {@link parserElement}, or {@link parserData}\r
-     * @param array used to translate tagnames into other tags\r
-     * @param boolean set to false for pages and classes, the only elements allowed to specify @package\r
-     * @return array\r
-     *\r
-     * Format:\r
-     * <pre>\r
-     * array('sdesc' => DocBlock summary\r
-     *       'desc' => DocBlock detailed description\r
-     *       'tags' => array('keyword' => tagname, 'data' => tag description)\r
-     *                 known tags\r
-     *       'api_tags' => array('keyword' => tagname, 'data' => tag description)\r
-     *                 known api documentation tags\r
-     *       'info_tags' => array('keyword' => tagname, 'data' => tag description)\r
-     *                 known informational tags\r
-     *     [ 'utags' => array('keyword' => tagname, 'data' => tag description\r
-     *                 unknown tags ]\r
-     *     [ 'vartype' => type from @var/@return tag ]\r
-     *     [ 'var_descrip' => description from @var/@return tag ]\r
-     *      )\r
-     * </pre>\r
-     */\r
-    function prepareDocBlock(&$element, $names = array(),$nopackage = true)\r
-    {\r
-        $tagses = $element->docblock->listTags();\r
-        $tags = $ret = $api_tags = $info_tags = array();\r
-        $api_tags_arr = array("abstract", "access", "deprecated", "example", "filesource",\r
-                             "global", "internal", "name", "return", "see",\r
-                             "property", "property-read", "property-write", "method",\r
-                             "staticvar", "usedby", "uses", "var");\r
-        if (!$nopackage)\r
-        {\r
-            $tags[] = array('keyword' => 'package','data' => $element->docblock->package);\r
-            if (!empty($element->docblock->subpackage)) $tags[] = array('keyword' => 'subpackage','data' => $element->docblock->subpackage);\r
-        }\r
-        if ($element->docblock->var)\r
-        {\r
-            $a = $element->docblock->var->Convert($this);\r
-            $ret['vartype'] = $element->docblock->var->converted_returnType;\r
-            if (!empty($a))\r
-            {\r
-                $tags[] = array('keyword' => 'var', 'data' => $a);\r
-                $ret["var_descrip"] = $a;\r
-            }\r
-        }\r
-        if ($element->docblock->return)\r
-        {\r
-            $a = $element->docblock->return->Convert($this);\r
-            $ret['vartype'] = $element->docblock->return->converted_returnType;\r
-            if (!empty($a))\r
-            {\r
-                $tags[] = $api_tags[] = array('keyword' => 'return', 'data' => $a);\r
-                $ret["var_descrip"] = $a;\r
-            }\r
-        }\r
-        if ($element->docblock->funcglobals)\r
-        foreach($element->docblock->funcglobals as $global => $val)\r
-        {\r
-            if ($a = $this->getGlobalLink($global,$element->docblock->package))\r
-            {\r
-                $global = $a;\r
-            }\r
-            $b = Converter::getLink($val[0]);\r
-            if (is_object($b) && phpDocumentor_get_class($b) == 'classlink')\r
-            {\r
-                $val[0] = $this->returnSee($b);\r
-            }\r
-            $tags[] = $api_tags[] = array('keyword' => 'global','data' => $val[0].' '.$global.': '.$val[1]->Convert($this));\r
-        }\r
-        if ($element->docblock->statics)\r
-        foreach($element->docblock->statics as $static => $val)\r
-        {\r
-            $a = $val->Convert($this);\r
-            $tags[] = $api_tags[] = array('keyword' => 'staticvar','data' => $val->converted_returnType.' '.$static.': '.$a);\r
-        }\r
-        $property_tags = array();\r
-        foreach ( $element->docblock->properties as $prop_name => $val )\r
-        {\r
-            $a = $val->Convert( $this );\r
-            if ( !empty( $a ) )\r
-            {\r
-                $tags[] = $api_tags[] = array( 'keyword' => $val->keyword ,\r
-                                               'data' => $val->converted_returnType  . ' ' . $prop_name . ': ' . $a );\r
-                $prop['prop_name'] = $prop_name;\r
-                $prop['access'] = $val->keyword == 'property-read' ? 'read' :\r
-                                    ( $val->keyword == 'property-write' ? 'write' : 'read/write' );\r
-                $prop['prop_type'] = $val->converted_returnType;\r
-                $prop['sdesc'] = $a;\r
-                $property_tags[ $prop_name ] = $prop;\r
-            }\r
-        }\r
-        ksort( $property_tags, SORT_STRING );\r
-        $property_tags = array_values( $property_tags );\r
-        $info_tags_sorted = array();\r
-        $ret['static'] = false;\r
-        foreach($tagses as $tag)\r
-        {\r
-            if (isset($names[$tag->keyword])) $tag->keyword = $names[$tag->keyword];\r
-            if ($tag->keyword == 'static') {\r
-                $ret['static'] = true;\r
-                continue;\r
-            }\r
-            if ($tag->keyword)\r
-                $tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));\r
-            if (in_array($tag->keyword, $api_tags_arr)) {\r
-                $api_tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));\r
-            } else {\r
-                $info_tags[] = array("keyword" => $tag->keyword,"data" => $tag->Convert($this));\r
-                @list( $className, $desc ) = explode( " ", $tag->Convert($this), 2 );\r
-                $info_tags_sorted[ $tag->keyword ][] = array( 'keyword' => $className, 'data' => $desc );\r
-            }\r
-        }\r
-        $utags = array();\r
-        foreach($element->docblock->unknown_tags as $keyword => $tag)\r
-        {\r
-            foreach($tag as $t)\r
-            $utags[] = array('keyword' => $keyword, 'data' => $t->Convert($this));\r
-        }\r
-        $ret['abstract'] = false;\r
-        $ret['access'] = 'public';\r
-        $see_tags = array();\r
-        foreach($tags as $tag)\r
-        {\r
-            if ($tag['keyword'] == 'access') {\r
-                $ret['access'] = $tag['data'];\r
-            }\r
-            if ($tag['keyword'] == 'abstract') {\r
-                $ret['abstract'] = true;\r
-            }\r
-            if ($tag['keyword'] == 'see' || $tag['keyword'] == 'uses' ||\r
-                  $tag['keyword'] == 'usedby') {\r
-                $see_tags[] = $tag['data'];\r
-            }\r
-        }\r
-        $ret['sdesc'] = $element->docblock->getSDesc($this);\r
-        $ret['desc'] = $element->docblock->getDesc($this);\r
-        $ret['tags'] = $tags;\r
-        $ret['see_tags'] = $see_tags;\r
-        $ret['info_tags_sorted'] = $info_tags_sorted;\r
-        $ret['api_tags'] = $api_tags;\r
-        $ret['info_tags'] = $info_tags;\r
-        $ret['utags'] = $utags;\r
-        $ret['property_tags'] = $property_tags;\r
-        return $ret;\r
-    }\r
-\r
-    /**\r
-     * gets a list of all classes declared on a procedural page represented by\r
-     * $element, a {@link parserData} class\r
-     * @param parserData &$element\r
-     * @return array links to each classes documentation\r
-     *\r
-     * Format:\r
-     * <pre>\r
-     * array('name' => class name,\r
-     *       'sdesc' => summary of the class\r
-     *       'link' => link to the class's documentation)\r
-     * </pre>\r
-     */\r
-    function getClassesOnPage(&$element)\r
-    {\r
-        global $_phpDocumentor_setting;\r
-        $a = $element->getClasses($this);\r
-        $classes = array();\r
-        foreach($a as $package => $clas)\r
-        {\r
-            if (!empty($_phpDocumentor_setting['packageoutput']))\r
-            {\r
-                $packages = explode(',',$_phpDocumentor_setting['packageoutput']);\r
-                if (!in_array($package, $packages)) continue;\r
-            }\r
-            for($i=0; $i<count($clas); $i++)\r
-            {\r
-                if ($this->parseprivate || ! ($clas[$i]->docblock && $clas[$i]->docblock->hasaccess && $clas[$i]->docblock->tags['access'][0]->value == 'private'))\r
-                {\r
-                    $sdesc = '';\r
-                    $r = array();\r
-                    $sdesc = $clas[$i]->docblock->getSDesc($this);\r
-                    if ($clas[$i]->docblock->hasaccess)\r
-                                                                                       $r['access'] = $clas[$i]->docblock->tags['access'][0]->value;\r
-                    else\r
-                                                                                       $r['access'] = 'public';\r
-                                                                               if (isset ($clas[$i]->docblock->tags['abstract']))\r
-                                                                                       $r['abstract'] = TRUE;\r
-                                                                               else\r
-                                                                                       $r['abstract'] = FALSE;\r
-                    $r['name'] = $clas[$i]->getName();\r
-                    $r['sdesc'] = $sdesc;\r
-                    $r['link'] = $this->getClassLink($clas[$i]->getName(),$package,$clas[$i]->getPath());\r
-                    $classes[] = $r;\r
-                }\r
-            }\r
-        }\r
-        return $classes;\r
-    }\r
-\r
-    /**\r
-     * returns an array containing the class inheritance tree from the root\r
-     * object to the class.\r
-     *\r
-     * This method must be overridden, or phpDocumentor will halt with a fatal\r
-     * error\r
-     * @return string Converter-specific class tree for an individual class\r
-     * @param parserClass    class variable\r
-     * @abstract\r
-     */\r
-\r
-    function generateFormattedClassTree($class)\r
-    {\r
-        addErrorDie(PDERROR_CONVERTER_OVR_GFCT,phpDocumentor_get_class($this));\r
-    }\r
-\r
-    /**\r
-     * returns an array containing the class inheritance tree from the root\r
-     * object to the class.\r
-     *\r
-     * This method must be overridden, or phpDocumentor will halt with a fatal\r
-     * error\r
-     * @return string Converter-specific class tree for an individual class\r
-     * @param parserClass    class variable\r
-     * @abstract\r
-     */\r
-\r
-    function getFormattedImplements($el)\r
-    {\r
-        $ret = array();\r
-        foreach ($el->getImplements() as $interface)\r
-        {\r
-            $link = $this->getLink($interface);\r
-            if ($link && is_object($link)) {\r
-                $ret[] = $this->returnSee($link);\r
-            } else {\r
-                if (class_exists('ReflectionClass')) {\r
-                    if (interface_exists($interface)) {\r
-                        $inter = new ReflectionClass($interface);\r
-                        if ($inter->isInternal()) {\r
-                            $ret[] = $interface . ' (internal interface)';\r
-                        } else {\r
-                            $ret[] = $interface;\r
-                        }\r
-                    }\r
-                } else {\r
-                    $ret[] = $interface;\r
-                }\r
-            }\r
-        }\r
-        return $ret;\r
-    }\r
-\r
-    /**\r
-     * @param mixed {@link parserClass, parserFunction, parserDefine} or\r
-     * {@link parserGlobal}\r
-     * @param string type to display.  either 'class','function','define'\r
-     *               or 'global variable'\r
-     * @return array links to conflicting elements, or empty array\r
-     * @uses parserClass::getConflicts()\r
-     * @uses parserFunction::getConflicts()\r
-     * @uses parserDefine::getConflicts()\r
-     * @uses parserGlobal::getConflicts()\r
-     */\r
-    function getFormattedConflicts(&$element,$type)\r
-    {\r
-        $conflicts = $element->getConflicts($this);\r
-        $r = array();\r
-        if (!$conflicts) return false;\r
-        foreach($conflicts as $package => $class)\r
-        {\r
-            $r[] = $class->getLink($this,$class->docblock->package);\r
-        }\r
-        if (!empty($r)) $r = array('conflicttype' => $type, 'conflicts' => $r);\r
-        return $r;\r
-    }\r
-\r
-    /**\r
-     * Get a list of methods in child classes that override this method\r
-     * @return array empty array or array(array('link'=>link to method,\r
-     * 'sdesc'=>short description of the method),...)\r
-     * @uses parserMethod::getOverridingMethods()\r
-     * @param parserMethod\r
-     */\r
-    function getFormattedDescMethods(&$element)\r
-    {\r
-        $meths = $element->getOverridingMethods($this);\r
-        $r = array();\r
-        for($i=0; $i<count($meths); $i++)\r
-        {\r
-            $ms = array();\r
-            $ms['link'] = $meths[$i]->getLink($this);\r
-            $ms['sdesc'] = $meths[$i]->docblock->getSDesc($this);\r
-            $r[] = $ms;\r
-        }\r
-        return $r;\r
-    }\r
-\r
-    /**\r
-     * Get a list of vars in child classes that override this var\r
-     * @return array empty array or array('link'=>link to var,\r
-     * 'sdesc'=>short description of the method\r
-     * @uses parserVar::getOverridingVars()\r
-     * @param parserVar\r
-     */\r
-    function getFormattedDescVars(&$element)\r
-    {\r
-        $vars = $element->getOverridingVars($this);\r
-        $r = array();\r
-        for($i=0; $i<count($vars); $i++)\r
-        {\r
-            $vs = array();\r
-            $vs['link'] = $vars[$i]->getLink($this);\r
-            $vs['sdesc'] = $vars[$i]->docblock->getSDesc($this);\r
-            $r[] = $vs;\r
-        }\r
-        return $r;\r
-    }\r
-\r
-    /**\r
-     * Get the method this method overrides, if any\r
-     * @return array|false array('link'=>link to overridden method,\r
-     * 'sdesc'=>short description\r
-     * @see parserMethod::getOverrides()\r
-     * @param parserMethod\r
-     */\r
-    function getFormattedOverrides(&$element)\r
-    {\r
-        $ovr = $element->getOverrides($this);\r
-        if (!$ovr) return false;\r
-        $sdesc = $ovr->docblock->getSDesc($this);\r
-        $name = method_exists($ovr, 'getFunctionCall') ? $ovr->getFunctionCall() : $ovr->getName();\r
-        $link = ($link = $ovr->getLink($this)) ? $link : $ovr->getClass() . '::' . $name;\r
-        return array('link' => $link,'sdesc' => $sdesc);\r
-    }\r
-\r
-    /**\r
-     * Get the method this method(s) implemented from an interface, if any\r
-     * @return array|false array('link'=>link to implemented method,\r
-     * 'sdesc'=>short description\r
-     * @uses parserMethod::getImplements()\r
-     * @param parserMethod\r
-     */\r
-    function getFormattedMethodImplements(&$element)\r
-    {\r
-        $ovr = $element->getImplements($this);\r
-        if (!$ovr) return false;\r
-        $ret = array();\r
-        foreach ($ovr as $impl) {\r
-            $sdesc = $impl->docblock->getSDesc($this);\r
-            $name = $impl->getName();\r
-            $link = ($link = $impl->getLink($this)) ? $link : $impl->getClass() . '::' . $name;\r
-            $ret[] = array('link' => $link,'sdesc' => $sdesc);\r
-        }\r
-        return $ret;\r
-    }\r
-\r
-    /**\r
-     * returns a list of child classes\r
-     *\r
-     * @param parserClass class variable\r
-     * @uses parserClass::getChildClassList()\r
-     */\r
-\r
-    function generateChildClassList($class)\r
-    {\r
-        $kids = $class->getChildClassList($this);\r
-        $list = array();\r
-        if (count($kids))\r
-        {\r
-            for($i=0; $i<count($kids); $i++)\r
-            {\r
-                $lt['link'] = $kids[$i]->getLink($this);\r
-                $lt['sdesc'] = $kids[$i]->docblock->getSDesc($this);\r
-\r
-                                                               if ($kids[$i]->docblock->hasaccess)\r
-                                                                       $lt['access'] = $kids[$i]->docblock->tags['access'][0]->value;\r
-                                                               else\r
-                                                                       $lt['access'] = 'public';\r
-\r
-                                                               $lt['abstract'] = isset ($kids[$i]->docblock->tags['abstract'][0]);\r
-\r
-                $list[] = $lt;\r
-            }\r
-        } else return false;\r
-        return $list;\r
-    }\r
-\r
-    /**\r
-     * Return template-enabled list of inherited variables\r
-     *\r
-     * uses parserVar helper function getInheritedVars and generates a\r
-     * template-enabled list using getClassLink()\r
-     * @param parserVar $child class var\r
-     * @see getClassLink(), parserVar::getInheritedVars()\r
-     * @return array Format:\r
-     * <pre>\r
-     * array(\r
-     *   array('parent_class' => link to parent class's documentation,\r
-     *         'ivars' =>\r
-     *            array(\r
-     *              array('name' => inherited variable name,\r
-     *                    'link' => link to inherited variable's documentation,\r
-     *                    'default' => default value of inherited variable,\r
-     *                    'sdesc' => summary of inherited variable),\r
-     *              ...),\r
-     *   ...)\r
-     * </pre>\r
-     */\r
-\r
-    function getFormattedInheritedVars($child)\r
-    {\r
-        $package = $child->docblock->package;\r
-        $subpackage = $child->docblock->subpackage;\r
-        $ivars = $child->getInheritedVars($this);\r
-        $results = array();\r
-        if (!count($ivars)) return $results;\r
-        foreach($ivars as $parent => $vars)\r
-        {\r
-            $file = $vars['file'];\r
-            $vars = $vars['vars'];\r
-            $par = $this->classes->getClass($parent,$file);\r
-            if ($par) {\r
-                $package = $par->docblock->package;\r
-            }\r
-            usort($vars,array($this,"sortVar"));\r
-            $result['parent_class'] = $this->getClassLink($parent, $package);\r
-            if (!$result['parent_class']) {\r
-                $result['parent_class'] = $parent . ' (Internal Class)';\r
-            }\r
-            foreach($vars as $var)\r
-            {\r
-                $info = array();\r
-\r
-                if ($var->docblock->hasaccess) {\r
-                    $info['access'] = $var->docblock->tags['access'][0]->value;\r
-                } else {\r
-                    $info['access'] = 'public';\r
-                }\r
-\r
-                $info['abstract'] = isset ($var->docblock->tags['abstract'][0]);\r
-\r
-                $info['name'] = $var->getName();\r
-                $info['link'] = $var->getLink($this);\r
-                if (!$info['link']) {\r
-                    $info['link'] = $info['name'];\r
-                }\r
-                $info['default'] = $this->postProcess($var->getValue());\r
-                if ($var->docblock)\r
-                $info['sdesc'] = $var->docblock->getSDesc($this);\r
-                $result["ivars"][] = $info;\r
-            }\r
-            $results[] = $result;\r
-            $result = array();\r
-        }\r
-        return $results;\r
-    }\r
-\r
-    /**\r
-     * Return template-enabled list of inherited methods\r
-     *\r
-     * uses parserMethod helper function getInheritedMethods and generates a\r
-     * template-enabled list using getClassLink()\r
-     * @param parserMethod $child class method\r
-     * @see getClassLink(), parserMethod::getInheritedMethods()\r
-     * @return array Format:\r
-     * <pre>\r
-     * array(\r
-     *   array('parent_class' => link to parent class's documentation,\r
-     *         'ivars' =>\r
-     *            array(\r
-     *              array('name' => inherited variable name,\r
-     *                    'link' => link to inherited variable's documentation,\r
-     *                    'function_call' => {@link parserMethod::getIntricateFunctionCall()}\r
-     *                                       returned array,\r
-     *                    'sdesc' => summary of inherited variable),\r
-     *              ...),\r
-     *   ...)\r
-     * </pre>\r
-     */\r
-\r
-    function getFormattedInheritedMethods($child)\r
-    {\r
-        $package = $child->docblock->package;\r
-        $subpackage = $child->docblock->subpackage;\r
-        $imethods = $child->getInheritedMethods($this);\r
-        $results = array();\r
-        if (!count($imethods)) return $results;\r
-        foreach($imethods as $parent => $methods)\r
-        {\r
-            $file = $methods['file'];\r
-            $methods = $methods['methods'];\r
-            $par = $this->classes->getClass($parent,$file);\r
-            if ($par) {\r
-                $package = $par->docblock->package;\r
-            }\r
-            usort($methods,array($this,"sortMethod"));\r
-            $result['parent_class'] = $this->getClassLink($parent,$package);\r
-            if (!$result['parent_class']) {\r
-                $result['parent_class'] = $parent . ' (Internal Class)';\r
-            }\r
-            foreach($methods as $method)\r
-            {\r
-                $info = array();\r
-\r
-                if ($method->docblock->hasaccess) {\r
-                    $info['access'] = $method->docblock->tags['access'][0]->value;\r
-                } else {\r
-                    $info['access'] = 'public';\r
-                }\r
-                $info['abstract'] = isset ($method->docblock->tags['abstract'][0]);\r
-\r
-                if ($method->isConstructor) $info['constructor'] = 1;\r
-                $returntype = 'void';\r
-                if ($method->isConstructor) {\r
-                    $returntype = $method->getClass();\r
-                }\r
-                if ($method->docblock->return) {\r
-                    $a = $method->docblock->return->Convert($this);\r
-                    $returntype = $method->docblock->return->converted_returnType;\r
-                }\r
-                $info['function_return'] = $returntype;\r
-                $info['static'] = isset ($method->docblock->tags['static'][0]);\r
-                $info['link'] = $method->getLink($this);\r
-                if (!$info['link']) {\r
-                    $info['link'] = $method->getFunctionCall();\r
-                }\r
-                $info['name'] = $method->getName();\r
-                if ($method->docblock)\r
-                $info['sdesc'] = $method->docblock->getSDesc($this);\r
-                $params = array();\r
-                if (count($method->docblock->params))\r
-                foreach($method->docblock->params as $param => $val)\r
-                {\r
-                    $a = $val->Convert($this);\r
-                    $params[$param] = array("var" => $param,"datatype" => $val->converted_returnType,"data" => $a);\r
-                }\r
-\r
-                $info['function_call'] = $method->getIntricateFunctionCall($this,$params);\r
-                $result["imethods"][] = $info;\r
-            }\r
-            $results[] = $result;\r
-            $result = array();\r
-        }\r
-        return $results;\r
-    }\r
-\r
-    /**\r
-     * Return template-enabled list of inherited class constants\r
-     *\r
-     * uses parserConst helper function getInheritedConsts and generates a\r
-     * template-enabled list using getClassLink()\r
-     * @param parserConst $child class constant\r
-     * @see getClassLink(), parserMethod::getInheritedConsts()\r
-     * @return array Format:\r
-     * <pre>\r
-     * array(\r
-     *   array('parent_class' => link to parent class's documentation,\r
-     *         'ivars' =>\r
-     *            array(\r
-     *              array('name' => inherited constant name,\r
-     *                    'link' => link to inherited constant's documentation,\r
-     *                    'value' => constant value,\r
-     *                    'sdesc' => summary of inherited constant),\r
-     *              ...),\r
-     *   ...)\r
-     * </pre>\r
-     */\r
-\r
-    function getFormattedInheritedConsts($child)\r
-    {\r
-        $package = $child->docblock->package;\r
-        $subpackage = $child->docblock->subpackage;\r
-        $ivars = $child->getInheritedConsts($this);\r
-        $results = array();\r
-        if (!count($ivars)) return $results;\r
-        foreach($ivars as $parent => $vars)\r
-        {\r
-            $file = $vars['file'];\r
-            $vars = $vars['consts'];\r
-            $par = $this->classes->getClass($parent,$file);\r
-            if ($par) {\r
-                $package = $par->docblock->package;\r
-            }\r
-            usort($vars,array($this,"sortVar"));\r
-            $result['parent_class'] = $this->getClassLink($parent,$package);\r
-            if (!$result['parent_class']) {\r
-                $result['parent_class'] = $parent . ' (Internal Class)';\r
-            }\r
-            foreach($vars as $var)\r
-            {\r
-                $info = array();\r
-\r
-                if ($var->docblock->hasaccess) {\r
-                       $info['access'] = $var->docblock->tags['access'][0]->value;\r
-                } else {\r
-                       $info['access'] = 'public';\r
-                }\r
-                $info['name'] = $var->getName();\r
-                $info['link'] = $var->getLink($this);\r
-                if (!$info['link']) {\r
-                    $info['link'] = $info['name'] . ' = ' . $var->getValue();\r
-                }\r
-                $info['value'] = $this->postProcess($var->getValue());\r
-                if ($var->docblock)\r
-                $info['sdesc'] = $var->docblock->getSDesc($this);\r
-                $result["iconsts"][] = $info;\r
-            }\r
-            $results[] = $result;\r
-            $result = array();\r
-        }\r
-        return $results;\r
-    }\r
-\r
-    /**\r
-     * Return a Smarty template object to operate with\r
-     *\r
-     * This returns a Smarty template with pre-initialized variables for use.\r
-     * If the method "SmartyInit()" exists, it is called.\r
-     * @return Smarty\r
-     */\r
-    function &newSmarty()\r
-    {\r
-        $templ = new Smarty;\r
-        $templ->use_sub_dirs = false;\r
-        $templ->template_dir = realpath($this->smarty_dir . PATH_DELIMITER . 'templates');\r
-        $templatename = get_class($this) . $this->templateName;\r
-        if (!file_exists($this->targetDir . DIRECTORY_SEPARATOR . md5($templatename))) {\r
-            // we'll delete this on finishing conversion\r
-            $this->_compiledDir[$this->targetDir . DIRECTORY_SEPARATOR . md5($templatename)] = 1;\r
-            mkdir($this->targetDir . DIRECTORY_SEPARATOR . md5($templatename),0775);\r
-        }\r
-        $templ->compile_dir = realpath($this->targetDir . PATH_DELIMITER . md5($templatename));\r
-        $templ->config_dir = realpath($this->smarty_dir . PATH_DELIMITER . 'configs');\r
-        $templ->assign("date",date("r",time()));\r
-        $templ->assign("maintitle",$this->title);\r
-        $templ->assign("package",$this->package);\r
-        $templ->assign("phpdocversion",PHPDOCUMENTOR_VER);\r
-        $templ->assign("phpdocwebsite",PHPDOCUMENTOR_WEBSITE);\r
-        $templ->assign("subpackage",$this->subpackage);\r
-        if (method_exists($this,'SmartyInit')) return $this->SmartyInit($templ);\r
-        return $templ;\r
-    }\r
-\r
-    /**\r
-     * Finish up parsing/cleanup directories\r
-     */\r
-    function cleanup()\r
-    {\r
-        foreach ($this->_compiledDir as $dir => $one) {\r
-            $this->_rmdir($dir);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Completely remove a directory and its contents\r
-     *\r
-     * @param string $directory\r
-     */\r
-    function _rmdir($directory)\r
-    {\r
-        $handle = @opendir($directory);\r
-        if ($handle) {\r
-            while (false !== ($file = readdir($handle))) {\r
-                if ($file == '.' || $file == '..') {\r
-                    continue;\r
-                }\r
-                if (is_dir($directory . DIRECTORY_SEPARATOR . $file)) {\r
-                    $this->_rmdir($directory . DIRECTORY_SEPARATOR . $file);\r
-                }\r
-                @unlink($directory . DIRECTORY_SEPARATOR . $file);\r
-            }\r
-            closedir($handle);\r
-            @rmdir($directory);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * do all necessary output\r
-     * @see Converter\r
-     * @abstract\r
-     */\r
-    function Output($title)\r
-    {\r
-        phpDocumentor_out("WARNING: Generic Converter::Output was used, no output will be generated");\r
-    }\r
-\r
-    /**\r
-     * Set the template directory with a different template base directory\r
-     * @tutorial phpDocumentor.howto.pkg#using.command-line.templatebase\r
-     * @param string template base directory\r
-     * @param string template name\r
-     */\r
-    function setTemplateBase($base, $dir)\r
-    {\r
-        // remove trailing /'s from the base path, if any\r
-        $base = str_replace('\\','/',$base);\r
-        while ($base{strlen($base) - 1} == '/') $base = substr($base,0,strlen($base) - 1);\r
-        $this->templateName = substr($dir,0,strlen($dir) - 1);\r
-        $this->templateDir =  $base . "/Converters/" . $this->outputformat . "/" . $this->name . "/templates/" . $dir;\r
-        if (!is_dir($this->templateDir))\r
-        {\r
-            addErrorDie(PDERROR_TEMPLATEDIR_DOESNT_EXIST, $this->templateDir);\r
-        }\r
-\r
-        $this->smarty_dir = $this->templateDir;\r
-        if (file_exists($this->templateDir . PATH_DELIMITER . 'options.ini'))\r
-        {\r
-            // retrieve template options, allow array creation\r
-            $this->template_options = phpDocumentor_parse_ini_file($this->templateDir . PATH_DELIMITER . 'options.ini',true);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * sets the template directory based on the {@link $outputformat} and {@link $name}\r
-     * Also sets {@link $templateName} to the $dir parameter\r
-     * @param string subdirectory\r
-     */\r
-    function setTemplateDir($dir)\r
-    {\r
-        if ('@DATA-DIR@' != '@'.'DATA-DIR@') {\r
-            $templateBase = str_replace('\\', '/', '@DATA-DIR@/PhpDocumentor/phpDocumentor');\r
-        } else {\r
-            $templateBase = str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) . '/phpDocumentor';\r
-        }\r
-        $this->setTemplateBase($templateBase, $dir);\r
-    }\r
-\r
-    /**\r
-     * Get the absolute path to the converter's base directory\r
-     * @return string\r
-     */\r
-    function getConverterDir()\r
-    {\r
-        if ('@DATA-DIR@' != '@' . 'DATA-DIR@') {\r
-            return str_replace('\\', '/', "@DATA-DIR@/PhpDocumentor/phpDocumentor/Converters/") . $this->outputformat . "/" . $this->name;\r
-        } else {\r
-            return str_replace('\\','/',$GLOBALS['_phpDocumentor_install_dir']) ."/phpDocumentor/Converters/" . $this->outputformat . "/" . $this->name;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Parse a global variable's default value for class initialization.\r
-     *\r
-     * If a global variable's default value is "new class" as in:\r
-     * <code>\r
-     * $globalvar = new Parser\r
-     * </code>\r
-     * This method will document it not as "new Parser" but instead as\r
-     * "new {@link Parser}".    For examples, see {@link phpdoc.inc}.\r
-     * Many global variables are classes, and phpDocumentor links to their\r
-     * documentation\r
-     * @return string default global variable value with link to class if\r
-     *                it's "new Class"\r
-     * @param string default value of a global variable.\r
-     */\r
-    function getGlobalValue($value)\r
-    {\r
-        if (strpos($value,'new') === 0)\r
-        {\r
-            preg_match('/new([^(]*)((?:.|\r|\n)*)/',$value,$newval);\r
-            if (isset($newval[1]))\r
-            {\r
-                $a = Converter::getLink(trim($newval[1]));\r
-                if (!isset($newval[2])) $newval[2] = '';\r
-                if ($a && phpDocumentor_get_class($a) == 'classlink') $value = 'new '.$this->returnSee($a) .\r
-                    $this->postProcess($newval[2]);\r
-            }\r
-            return $value;\r
-        }\r
-        return $this->postProcess($value);\r
-    }\r
-\r
-    /**\r
-     * Parse an include's file to see if it is a file documented in this project\r
-     *\r
-     * Although not very smart yet, this method will try to look for the\r
-     * included file file.ext:\r
-     *\r
-     * <code>\r
-     * include ("file.ext");\r
-     * </code>\r
-     *\r
-     * If it finds it, it will return a link to the file's documentation.  As of\r
-     * 1.2.0rc1, phpDocumentor is smarty enough to find these cases:\r
-     * <ul>\r
-     *  <li>absolute path to file</li>\r
-     *  <li>./file.ext or ../file.ext</li>\r
-     *  <li>relpath/to/file.ext if relpath is a subdirectory of the base parse\r
-     *      directory</li>\r
-     * </ul>\r
-     * For examples, see {@link Setup.inc.php} includes.\r
-     * Every include auto-links to the documentation for the file that is included\r
-     * @return string included file with link to docs for file, if found\r
-     * @param string file included by include statement.\r
-     * @param string path of file that has the include statement\r
-     */\r
-    function getIncludeValue($value, $ipath)\r
-    {\r
-        preg_match('/"([^"\']*\.[^"\']*)"/',$value,$match);\r
-        if (!isset($match[1]))\r
-        preg_match('/\'([^"\']*\.[^"\']*)\'/',$value,$match);\r
-        if (isset($match[1]))\r
-        {\r
-            $fancy_per = $this->proceduralpages->pathMatchesParsedFile($match[1],$ipath);\r
-            if ($fancy_per)\r
-            {\r
-                $link = $this->addLink($fancy_per);\r
-                if (is_object($link) && phpDocumentor_get_class($link) == 'pagelink' &&\r
-                    isset($this->all_packages[$link->package]))\r
-                {\r
-                    $value = $this->returnSee($link,$value);\r
-                }\r
-            } else\r
-            {\r
-                $per = Converter::getLink($match[1]);\r
-                if (is_object($per) && phpDocumentor_get_class($per) == 'pagelink')\r
-                $value = $this->returnSee($per);\r
-            }\r
-        }\r
-        return $value;\r
-    }\r
-\r
-    /**\r
-     * Recursively creates all subdirectories that don't exist in the $dir path\r
-     * @param string $dir\r
-     */\r
-    function createParentDir($dir)\r
-    {\r
-        if (empty($dir)) return;\r
-        $tmp = explode(SMART_PATH_DELIMITER,$dir);\r
-        array_pop($tmp);\r
-        $parent = implode(SMART_PATH_DELIMITER,$tmp);\r
-        if ($parent != '' && !file_exists($parent))\r
-        {\r
-            $test = @mkdir($parent,0775);\r
-            if (!$test)\r
-            {\r
-                $this->createParentDir($parent);\r
-                $test = @mkdir($parent,0775);\r
-                phpDocumentor_out("Creating Parent Directory $parent\n");\r
-            } else\r
-            {\r
-                phpDocumentor_out("Creating Parent Directory $parent\n");\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the output directory for generated documentation\r
-     * \r
-     * As of 1.3.0RC6, this also sets the compiled templates directory inside\r
-     * the target directory\r
-     * @param string $dir the output directory\r
-     */\r
-    function setTargetDir($dir)\r
-    {\r
-        if (strlen($dir) > 0)\r
-        {\r
-            $this->targetDir = $dir;\r
-            // if directory does exist create it, this should have more error checking in the future\r
-            if (!file_exists($dir))\r
-            {\r
-                $tmp = str_replace(array("/","\\"),SMART_PATH_DELIMITER,$dir);\r
-                if (substr($tmp,-1) == SMART_PATH_DELIMITER)\r
-                {\r
-                    $tmp = substr($tmp,0,(strlen($tmp)-1));\r
-                }\r
-                $this->createParentDir($tmp);\r
-                phpDocumentor_out("Creating Directory $dir\n");\r
-                mkdir($dir,0775);\r
-            } elseif (!is_dir($dir))\r
-            {\r
-                echo "Output path: '$dir' is not a directory\n";\r
-                die();\r
-            }\r
-        } else {\r
-            echo "a target directory must be specified\n try phpdoc -h\n";\r
-            die();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Writes a file to target dir\r
-     * @param string\r
-     * @param string\r
-     * @param boolean true if the data is binary and not text\r
-     */\r
-    function writeFile($file,$data,$binary = false)\r
-    {\r
-        if (!file_exists($this->targetDir))\r
-        {\r
-            mkdir($this->targetDir,0775);\r
-        }\r
-        $string = '';\r
-        if ($binary) $string = 'binary file ';\r
-        phpDocumentor_out("    Writing $string".$this->targetDir . PATH_DELIMITER . $file . "\n");\r
-        flush();\r
-        $write = 'w';\r
-        if ($binary) $write = 'wb';\r
-        $fp = fopen($this->targetDir . PATH_DELIMITER . $file,$write);\r
-        set_file_buffer( $fp, 0 );\r
-        fwrite($fp,$data,strlen($data));\r
-        fclose($fp);\r
-    }\r
-\r
-    /**\r
-     * Copies a file from the template directory to the target directory\r
-     * thanks to Robert Hoffmann for this fix\r
-     * @param string\r
-     */\r
-    function copyFile($file, $subdir = '')\r
-    {\r
-        if (!file_exists($this->targetDir))\r
-        {\r
-            mkdir($this->targetDir,0775);\r
-        }\r
-        copy($this->templateDir . $subdir  . PATH_DELIMITER . $file, $this->targetDir . PATH_DELIMITER . $file);\r
-    }\r
-\r
-    /**\r
-     * Return parserStringWithInlineTags::Convert() cache state\r
-     * @see parserStringWithInlineTags::Convert()\r
-     * @abstract\r
-     */\r
-    function getState()\r
-    {\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Compare parserStringWithInlineTags::Convert() cache state to $state\r
-     * @param mixed\r
-     * @see parserStringWithInlineTags::Convert()\r
-     * @abstract\r
-     */\r
-    function checkState($state)\r
-    {\r
-        return true;\r
-    }\r
-\r
-}\r
-\r
-/**\r
- * @access private\r
- * @see Converter::getSortedClassTreeFromClass()\r
- */\r
-function rootcmp($a, $b)\r
-{\r
-    return strnatcasecmp($a['class'],$b['class']);\r
-}\r
-\r
-/**\r
- * @access private\r
- * @global string used to make the first tutorials converted the default package tutorials\r
- */\r
-function tutorialcmp($a, $b)\r
-{\r
-    global $phpDocumentor_DefaultPackageName;\r
-    if ($a == $phpDocumentor_DefaultPackageName) return -1;\r
-    if ($b == $phpDocumentor_DefaultPackageName) return 1;\r
-    return strnatcasecmp($a, $b);\r
-}\r
-\r
-/**\r
- * smart htmlentities, doesn't entity the allowed tags list\r
- * Since version 1.1, this function uses htmlspecialchars instead of\r
- * htmlentities, for international support\r
- * This function has been replaced by functionality in {@link ParserDescCleanup.inc}\r
- * @param string $s\r
- * @return string browser-displayable page\r
- * @deprecated As of v1.2, No longer needed, as valid tags are parsed out of the source,\r
- *   and everything else is {@link Converter::postProcess()} handled\r
- */\r
-function adv_htmlentities($s)\r
-{\r
-    return;\r
-    global $phpDocumentor___html,$_phpDocumentor_html_allowed;\r
-    $result = htmlspecialchars($s);\r
-    $entities = array_flip(get_html_translation_table(HTML_SPECIALCHARS));\r
-    $result = strtr($result,$phpDocumentor___html);\r
-    $matches = array();\r
-    preg_match_all('/(&lt;img.*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    preg_match_all('/(&lt;font.*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    preg_match_all('/(&lt;ol.*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    preg_match_all('/(&lt;ul.*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    preg_match_all('/(&lt;li.*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    preg_match_all('/(&lt;a .*&gt;)/U',$result,$matches);\r
-    for($i=0;$i<count($matches[1]);$i++)\r
-    {\r
-        $result = str_replace($matches[1][$i],strtr($matches[1][$i],array_flip(get_html_translation_table(HTML_SPECIALCHARS))),$result);\r
-    }\r
-    return $result;\r
-}\r
-\r
-/**\r
- * Used solely for setting up the @uses list\r
- * @package ignore\r
- * @ignore\r
- */\r
-class __dummyConverter extends Converter\r
-{\r
-    function setTemplateDir(){}\r
-    function setTargetDir(){}\r
-    function getPageName(&$element)\r
-    {\r
-        if (phpDocumentor_get_class($element) == 'parserpage') return '_'.$element->getName();\r
-        return '_'.$element->parent->getName();\r
-    }\r
-}\r
-?>\r