[TASK] Rename and deprecate config.minifyJS / config.minifyCSS
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_menu.php
old mode 100755 (executable)
new mode 100644 (file)
index a0ea2ae..bb5ef4b
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * The main class, tslib_menu, is also extended by other external PHP scripts such as the GMENU_LAYERS and GMENU_FOLDOUT scripts which creates pop-up menus.
  * Notice that extension classes (like "tslib_tmenu") must have their suffix (here "tmenu") listed in $this->tmpl->menuclasses - otherwise they cannot be instantiated.
  *
- * $Id$
- * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
+ * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
  * XHTML compliant
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
- */
-/**
- * [CLASS/FUNCTION INDEX of SCRIPT]
- *
- *
- *
- *  143: class tslib_menu
- *  187:     function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber)
- *  313:     function makeMenu()
- *  822:     function includeMakeMenu($conf,$altSortField)
- *  838:     function filterMenuPages(&$data,$banUidArray,$spacer)
- *  894:     function procesItemStates($splitCount)
- * 1082:     function link($key,$altTarget='',$typeOverride='')
- * 1142:     function subMenu($uid)
- * 1184:     function isNext($uid, $MPvar='')
- * 1205:     function isActive($uid, $MPvar='')
- * 1226:     function isCurrent($uid, $MPvar='')
- * 1241:     function isSubMenu($uid)
- * 1266:     function isItemState($kind,$key)
- * 1303:     function accessKey($title)
- * 1329:     function userProcess($mConfKey,$passVar)
- * 1344:     function setATagParts()
- * 1357:     function getPageTitle($title,$nav_title)
- * 1369:     function getMPvar($key)
- * 1384:     function getDoktypeExcludeWhere()
- *
- *
- * 1416: class tslib_tmenu extends tslib_menu
- * 1425:     function generate()
- * 1441:     function writeMenu()
- * 1582:     function getBeforeAfter($pref)
- * 1612:     function addJScolorShiftFunction()
- * 1634:     function extProc_init()
- * 1645:     function extProc_RO($key)
- * 1656:     function extProc_beforeLinking($key)
- * 1668:     function extProc_afterLinking($key)
- * 1685:     function extProc_beforeAllWrap($item,$key)
- * 1696:     function extProc_finish()
- *
- *
- * 1732: class tslib_gmenu extends tslib_menu
- * 1741:     function generate()
- * 1779:     function makeGifs($conf, $resKey)
- * 1984:     function findLargestDims($conf,$items,$Hobjs,$Wobjs,$minDim,$maxDim)
- * 2056:     function writeMenu()
- * 2173:     function extProc_init()
- * 2184:     function extProc_RO($key)
- * 2195:     function extProc_beforeLinking($key)
- * 2208:     function extProc_afterLinking($key)
- * 2225:     function extProc_beforeAllWrap($item,$key)
- * 2236:     function extProc_finish()
- *
- *
- * 2270: class tslib_imgmenu extends tslib_menu
- * 2279:     function generate()
- * 2297:     function makeImageMap($conf)
- * 2480:     function writeMenu()
- *
- *
- * 2523: class tslib_jsmenu extends tslib_menu
- * 2530:     function generate()
- * 2538:     function writeMenu()
- * 2599:     function generate_level($levels,$count,$pid,$menuItemArray='',$MP_array=array())
- *
- * TOTAL FUNCTIONS: 44
- * (This index is automatically created/updated by the extension "extdeveval")
- *
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  */
 
 
  * $menu->makeMenu();
  * $content.=$menu->writeMenu();
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
  * @see tslib_cObj::HMENU()
@@ -144,20 +76,38 @@ class tslib_menu {
        var $menuNumber = 1;                            // tells you which menu-number this is. This is important when getting data from the setup
        var $entryLevel = 0;                            // 0 = rootFolder
        var $spacerIDList = '199';                      // The doktype-number that defines a spacer
-       var $doktypeExcludeList = '5,6';                        // doktypes that define which should not be included in a menu
+       var $doktypeExcludeList = '6';                  // doktypes that define which should not be included in a menu
        var $alwaysActivePIDlist=array();
        var $imgNamePrefix = 'img';
        var $imgNameNotRandom=0;
        var $debug = 0;
-       var $parent_cObj ='';                           // Loaded with the parent cObj-object when a new HMENU is made
+
+       /**
+        * Loaded with the parent cObj-object when a new HMENU is made
+        *
+        * @var tslib_cObj
+        */
+       var $parent_cObj;
        var $GMENU_fixKey='gmenu';
        var $MP_array=array();                          // accumulation of mount point data
 
                // internal
        var $conf = Array();                            // HMENU configuration
        var $mconf = Array();                           // xMENU configuration (TMENU, GMENU etc)
-       var $tmpl;              // template-object
-       var $sys_page;  // sys_page-object
+
+       /**
+        * template-object
+        *
+        * @var t3lib_TStemplate
+        */
+       var $tmpl;
+
+       /**
+        * sys_page-object, pagefunctions
+        *
+        * @var t3lib_pageSelect
+        */
+       var $sys_page;
        var $id;                                                        // The base page-id of the menu.
        var $nextActive;                                        // Holds the page uid of the NEXT page in the root line from the page pointed to by entryLevel; Used to expand the menu automatically if in a certain root line.
        var $menuArr;   // The array of menuItems which is built
@@ -172,6 +122,7 @@ class tslib_menu {
        var $WMsubmenuObjSuffixes;
        var $WMextraScript;
        var $alternativeMenuTempArray='';               // Can be set to contain menu item arrays for sub-levels.
+       var $nameAttribute = 'name';                    // Will be 'id' in XHTML-mode
 
        /**
         * The initialization of the object. This just sets some internal variables.
@@ -182,7 +133,7 @@ class tslib_menu {
         * @param       array           The TypoScript configuration for the HMENU cObject
         * @param       integer         Menu number; 1,2,3. Should probably be '1'
         * @param       string          Submenu Object suffix. This offers submenus a way to use alternative configuration for specific positions in the menu; By default "1 = TMENU" would use "1." for the TMENU configuration, but if this string is set to eg. "a" then "1a." would be used for configuration instead (while "1 = " is still used for the overall object definition of "TMENU")
-        * @return      boolean         Returns true on success
+        * @return      boolean         Returns TRUE on success
         * @see tslib_cObj::HMENU()
         */
        function start(&$tmpl,&$sys_page,$id,$conf,$menuNumber,$objSuffix='')   {
@@ -193,13 +144,29 @@ class tslib_menu {
                $this->mconf = $conf[$this->menuNumber.$objSuffix.'.'];
                $this->debug=$GLOBALS['TSFE']->debug;
 
+                       // In XHTML there is no "name" attribute anymore
+               switch ($GLOBALS['TSFE']->xhtmlDoctype) {
+                       case 'xhtml_strict':
+                       case 'xhtml_11':
+                       case 'xhtml_2':
+                       case 'html5':
+                               $this->nameAttribute = 'id';
+                               break;
+                       default:
+                               $this->nameAttribute = 'name';
+                               break;
+               }
+
                        // Sets the internal vars. $tmpl MUST be the template-object. $sys_page MUST be the sys_page object
                if ($this->conf[$this->menuNumber.$objSuffix] && is_object($tmpl) && is_object($sys_page))      {
-                       $this->tmpl = &$tmpl;
-                       $this->sys_page = &$sys_page;
+                       $this->tmpl = $tmpl;
+                       $this->sys_page = $sys_page;
 
                                // alwaysActivePIDlist initialized:
-                       if (trim($this->conf['alwaysActivePIDlist']))   {
+                       if (trim($this->conf['alwaysActivePIDlist']) || isset($this->conf['alwaysActivePIDlist.'])) {
+                               if (isset($this->conf['alwaysActivePIDlist.'])) {
+                                       $this->conf['alwaysActivePIDlist'] = $this->parent_cObj->stdWrap($this->conf['alwaysActivePIDlist'], $this->conf['alwaysActivePIDlist.']);
+                               }
                                $this->alwaysActivePIDlist = t3lib_div::intExplode(',', $this->conf['alwaysActivePIDlist']);
                        }
 
@@ -207,15 +174,13 @@ class tslib_menu {
                        if($this->conf['excludeDoktypes']) {
                                $this->doktypeExcludeList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['excludeDoktypes']);
                        }
-                       if($this->conf['includeNotInMenu']) {
-                               $exclDoktypeArr = t3lib_div::trimExplode(',',$this->doktypeExcludeList,1);
-                               $exclDoktypeArr = t3lib_div::removeArrayEntryByValue($exclDoktypeArr,'5');
-                               $this->doktypeExcludeList = implode(',',$exclDoktypeArr);
-                       }
-
                                // EntryLevel
-                       $this->entryLevel = tslib_cObj::getKey ($conf['entryLevel'],$this->tmpl->rootLine);
-
+                       $this->entryLevel = tslib_cObj::getKey (
+                               isset($conf['entryLevel.'])
+                               ? $this->parent_cObj->stdWrap($conf['entryLevel'], $conf['entryLevel.'])
+                               : $conf['entryLevel'],
+                               $this->tmpl->rootLine
+                       );
                                // Set parent page: If $id not stated with start() then the base-id will be found from rootLine[$this->entryLevel]
                        if ($id)        {       // Called as the next level in a menu. It is assumed that $this->MP_array is set from parent menu.
                                $this->id = intval($id);
@@ -239,7 +204,7 @@ class tslib_menu {
                                }
                        }
 
-                               // Return false if no page ID was set (thus no menu of subpages can be made).
+                               // Return FALSE if no page ID was set (thus no menu of subpages can be made).
                        if ($this->id<=0)       {
                                return FALSE;
                        }
@@ -272,15 +237,38 @@ class tslib_menu {
                                }
                        }
 
+                       // Set $directoryLevel so the following evalution of the nextActive will not return
+                       // an invalid value if .special=directory was set
+                       $directoryLevel = 0;
+                       if ($this->conf['special'] == 'directory')      {
+                               $value = isset($this->conf['special.']['value.'])
+                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.'])
+                                       : $this->conf['special.']['value'];
+                               if ($value=='') {
+                                       $value=$GLOBALS['TSFE']->page['uid'];
+                               }
+                               $directoryLevel = intval($GLOBALS['TSFE']->tmpl->getRootlineLevel($value));
+                       }
+
                                // Setting "nextActive": This is the page uid + MPvar of the NEXT page in rootline. Used to expand the menu if we are in the right branch of the tree
-                               // Notice: The automatic expansion of a menu is designed to work only when no "special" modes are used.
-                       if (is_array($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]))       {
+                               // Notice: The automatic expansion of a menu is designed to work only when no "special" modes (except "directory") are used.
+                       $startLevel = $directoryLevel ? $directoryLevel : $this->entryLevel;
+                       $currentLevel = $startLevel + $this->menuNumber;
+                       if (is_array($this->tmpl->rootLine[$currentLevel])) {
                                $nextMParray = $this->MP_array;
-                               if ($this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MOUNT_OL'])    {       // In overlay mode, add next level MPvars as well:
-                                       $nextMParray[] = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['_MP_PARAM'];
+                               if (!count($nextMParray) && !$this->tmpl->rootLine[$currentLevel]['_MOUNT_OL'] && $currentLevel > 0) {
+                                               // Make sure to slide-down any mount point information (_MP_PARAM) to children records in the rootline
+                                               // otherwise automatic expansion will not work
+                                       $parentRecord = $this->tmpl->rootLine[$currentLevel - 1];
+                                       if (isset($parentRecord['_MP_PARAM'])) {
+                                               $nextMParray[] = $parentRecord['_MP_PARAM'];
+                                       }
+                               }
+
+                               if ($this->tmpl->rootLine[$currentLevel]['_MOUNT_OL']) {        // In overlay mode, add next level MPvars as well:
+                                       $nextMParray[] = $this->tmpl->rootLine[$currentLevel]['_MP_PARAM'];
                                }
-                               $this->nextActive = $this->tmpl->rootLine[$this->entryLevel+$this->menuNumber]['uid'].
-                                                                               (count($nextMParray)?':'.implode(',',$nextMParray):'');
+                               $this->nextActive = $this->tmpl->rootLine[$currentLevel]['uid'] . (count($nextMParray) ? ':' . implode(',', $nextMParray) : '');
                        } else {
                                $this->nextActive = '';
                        }
@@ -321,7 +309,9 @@ class tslib_menu {
                        $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
                        $altSortField = $altSortFieldValue ? $altSortFieldValue : 'sorting';
                        if ($this->menuNumber==1 && $this->conf['special'])     {               // ... only for the FIRST level of a HMENU
-                               $value = $this->conf['special.']['value'];
+                               $value = isset($this->conf['special.']['value.'])
+                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.'])
+                                       : $this->conf['special.']['value'];
 
                                switch($this->conf['special'])  {
                                        case 'userdefined':
@@ -358,12 +348,19 @@ class tslib_menu {
                                                        } else {
                                                                $iState = $GLOBALS['TSFE']->sys_language_uid==$sUid ? 'ACT' : 'NO';
                                                        }
+
+                                                       if ($this->conf['addQueryString'])      {
+                                                               $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'],array('L'=>$sUid),TRUE);
+                                                       } else {
+                                                               $getVars = '&L='.$sUid;
+                                                       }
+
                                                                // Adding menu item:
                                                        $temp[] = array_merge(
                                                                array_merge($currentPageWithNoOverlay, $lRecs),
                                                                array(
                                                                        'ITEM_STATE' => $iState,
-                                                                       '_ADD_GETVARS' => '&L='.$sUid,
+                                                                       '_ADD_GETVARS' => $getVars,
                                                                        '_SAFE' => TRUE
                                                                )
                                                        );
@@ -391,23 +388,26 @@ class tslib_menu {
                                                        }
 
                                                                // Get sub-pages:
-                                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
+                                                       $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
                                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
+                                                               $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
 
-                                                                       // Keep mount point?
-                                                               $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
-                                                               if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
-                                                                       $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);           // Using "getPage" is OK since we need the check for enableFields AND for type 2 of mount pids we DO require a doktype < 200!
-                                                                       if (count($mp_row))     {
-                                                                               $row = $mp_row;
-                                                                               $row['_MP_PARAM'] = $mount_info['MPvar'];
-                                                                       } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
-                                                               }
-
-                                                                       // Add external MP params, then the row:
                                                                if (is_array($row))     {
-                                                                       if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
-                                                                       $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
+                                                                               // Keep mount point?
+                                                                       $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
+                                                                       if (is_array($mount_info) && $mount_info['overlay'])    {       // There is a valid mount point.
+                                                                               $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);           // Using "getPage" is OK since we need the check for enableFields AND for type 2 of mount pids we DO require a doktype < 200!
+                                                                               if (count($mp_row))     {
+                                                                                       $row = $mp_row;
+                                                                                       $row['_MP_PARAM'] = $mount_info['MPvar'];
+                                                                               } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
+                                                                       }
+
+                                                                               // Add external MP params, then the row:
+                                                                       if (is_array($row))     {
+                                                                               if ($MP)        $row['_MP_PARAM'] = $MP.($row['_MP_PARAM'] ? ','.$row['_MP_PARAM'] : '');
+                                                                               $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
+                                                                       }
                                                                }
                                                        }
                                                }
@@ -435,12 +435,16 @@ class tslib_menu {
                                                                        if ($mount_info['overlay'])     {       // Overlays should already have their full MPvars calculated:
                                                                                $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
                                                                                if ($MP) unset($row['_MP_PARAM']);
-                                                       }
-
+                                                                       }
                                                                } else unset($row);     // If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
                                                        } else {
                                                                $row = $loadDB->results['pages'][$val['id']];
-                                               }
+                                                       }
+
+                                                               //Add versioning overlay for current page (to respect workspaces)
+                                                       if (is_array($row)) {
+                                                               $this->sys_page->versionOL('pages', $row, TRUE);
+                                                       }
 
                                                                // Add external MP params, then the row:
                                                        if (is_array($row))     {
@@ -454,12 +458,12 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                $items=t3lib_div::intExplode(',',$value);
-                                               if (t3lib_div::testInt($this->conf['special.']['depth']))       {
-                                                       $depth = t3lib_div::intInRange($this->conf['special.']['depth'],1,20);          // Tree depth
+                                               if (t3lib_utility_Math::canBeInterpretedAsInteger($this->conf['special.']['depth']))    {
+                                                       $depth = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['depth'],1,20);                // Tree depth
                                                } else {
                                                        $depth=20;
                                                }
-                                               $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
+                                               $limit = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['limit'],0,100);       // max number of items
                                                $maxAge = intval(tslib_cObj::calc($this->conf['special.']['maxAge']));
                                                if (!$limit)    $limit=10;
                                                $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
@@ -467,7 +471,7 @@ class tslib_menu {
                                                $id_list_arr = Array();
 
                                                foreach($items as $id)  {
-                                                       $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
+                                                       $bA = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['beginAtLevel'],0,100);
                                                        $id_list_arr[] = tslib_cObj::getTreeList(-1*$id,$depth-1+$bA,$bA-1);
                                                }
                                                $id_list = implode(',',$id_list_arr);
@@ -491,18 +495,21 @@ class tslib_menu {
                                                        break;
                                                }
                                                        // Get
-                                               $extraWhere = ' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
+                                               $extraWhere = ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
 
                                                if ($this->conf['special.']['excludeNoSearchPages']) {
                                                        $extraWhere.= ' AND pages.no_search=0';
                                                }
                                                if ($maxAge>0)  {
-                                                       $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_EXEC_TIME']-$maxAge);
+                                                       $extraWhere.=' AND '.$sortField.'>'.($GLOBALS['SIM_ACCESS_TIME']-$maxAge);
                                                }
 
-                                               $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
+                                               $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>$sortField.'>=0'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
                                                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                                       $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                       $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
+                                                       if (is_array($row))     {
+                                                               $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                       }
                                                }
                                        break;
                                        case 'keywords':
@@ -511,13 +518,15 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
-                                                       $kw = $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']);
-                                               } else {
-                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
+                                                       $kw = isset($this->conf['special.']['setKeywords.'])
+                                                               ? $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.'])
+                                                               : $this->conf['special.']['setKeywords'];
+                                               } else {
+                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
 
                                                        $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
                                                        $kw = trim(tslib_cObj::keywords($value_rec[$kfieldSrc]));               // keywords.
-                                               }
+                                               }
 
                                                $mode = $this->conf['special.']['mode'];        // *'auto', 'manual', 'tstamp'
                                                switch($mode)   {
@@ -540,18 +549,23 @@ class tslib_menu {
                                                }
 
                                                        // depth, limit, extra where
-                                               if (t3lib_div::testInt($this->conf['special.']['depth']))       {
-                                                       $depth = t3lib_div::intInRange($this->conf['special.']['depth'],0,20);          // Tree depth
+                                               if (t3lib_utility_Math::canBeInterpretedAsInteger($this->conf['special.']['depth']))    {
+                                                       $depth = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['depth'],0,20);                // Tree depth
                                                } else {
                                                        $depth=20;
                                                }
-                                               $limit = t3lib_div::intInRange($this->conf['special.']['limit'],0,100); // max number of items
-                                               $extraWhere = ' AND pages.uid!='.$value.' AND pages.nav_hide=0'.$this->getDoktypeExcludeWhere();
+                                               $limit = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['limit'],0,100);       // max number of items
+                                               $extraWhere = ' AND pages.uid!='.$value.($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0').$this->getDoktypeExcludeWhere();
                                                if ($this->conf['special.']['excludeNoSearchPages']) {
                                                        $extraWhere.= ' AND pages.no_search=0';
                                                }
                                                        // start point
-                                               $eLevel = tslib_cObj::getKey (intval($this->conf['special.']['entryLevel']),$this->tmpl->rootLine);
+                                               $eLevel = tslib_cObj::getKey(
+                                                       isset($this->conf['special.']['entryLevel.'])
+                                                               ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.'])
+                                                               : $this->conf['special.']['entryLevel'],
+                                                       $this->tmpl->rootLine
+                                               );
                                                $startUid = intval($this->tmpl->rootLine[$eLevel]['uid']);
 
                                                        // which field is for keywords
@@ -562,7 +576,7 @@ class tslib_menu {
 
                                                        // If there are keywords and the startuid is present.
                                                if ($kw && $startUid)   {
-                                                       $bA = t3lib_div::intInRange($this->conf['special.']['beginAtLevel'],0,100);
+                                                       $bA = t3lib_utility_Math::forceIntegerInRange($this->conf['special.']['beginAtLevel'],0,100);
                                                        $id_list=tslib_cObj::getTreeList(-1*$startUid,$depth-1+$bA,$bA-1);
 
                                                        $kwArr = explode(',',$kw);
@@ -572,16 +586,24 @@ class tslib_menu {
                                                                        $keyWordsWhereArr[] = $kfield.' LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($word, 'pages').'%\'';
                                                                }
                                                        }
-                                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
+                                                       $res = $this->parent_cObj->exec_getQuery('pages',Array('pidInList'=>'0', 'uidInList'=>$id_list, 'where'=>'('.implode(' OR ',$keyWordsWhereArr).')'.$extraWhere, 'orderBy'=>($altSortFieldValue ? $altSortFieldValue : $sortField.' desc'),'max'=>$limit));
                                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                                               $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                               $GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
+                                                               if (is_array($row))     {
+                                                                       $temp[$row['uid']]=$this->sys_page->getPageOverlay($row);
+                                                               }
                                                        }
                                                }
                                        break;
                                        case 'rootline':
-                                               $begin_end = explode('|',$this->conf['special.']['range']);
-                                               if (!t3lib_div::testInt($begin_end[0])) {intval($begin_end[0]);}
-                                               if (!t3lib_div::testInt($begin_end[1])) {$begin_end[1]=-1;}
+                                               $range = isset($this->conf['special.']['range.'])
+                                                       ? $this->parent_cObj->stdWrap($this->conf['special.']['range'], $this->conf['special.']['range.'])
+                                                       : $this->conf['special.']['range'];
+                                               $begin_end = explode('|', $range);
+                                               $begin_end[0] = intval($begin_end[0]);
+                                               if (!t3lib_utility_Math::canBeInterpretedAsInteger($begin_end[1])) {
+                                                       $begin_end[1] = -1;
+                                               }
 
                                                $beginKey = tslib_cObj::getKey ($begin_end[0],$this->tmpl->rootLine);
                                                $endKey = tslib_cObj::getKey ($begin_end[1],$this->tmpl->rootLine);
@@ -607,7 +629,12 @@ class tslib_menu {
                                                                // For normal mount points, set the variable for next level.
                                                        if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL'])  {
                                                                $rl_MParray[] = $v_rl['_MP_PARAM'];
+                                                       }
                                                }
+                                                       // Reverse order of elements (e.g. "1,2,3,4" gets "4,3,2,1"):
+                                               if (isset($this->conf['special.']['reverseOrder']) && $this->conf['special.']['reverseOrder']) {
+                                                       $temp = array_reverse($temp);
+                                                       $rl_MParray = array_reverse($rl_MParray);
                                                }
                                        break;
                                        case 'browse':
@@ -616,69 +643,67 @@ class tslib_menu {
                                                        $value=$GLOBALS['TSFE']->page['uid'];
                                                }
                                                if ($value!=$this->tmpl->rootLine[0]['uid'])    {       // Will not work out of rootline
-                                                       $recArr=array();
-                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
-                                                       if ($value_rec['pid'])  {       // 'up' page cannot be outside rootline
-                                                               $recArr['up']=$this->sys_page->getPage($value_rec['pid']);      // The page record of 'up'.
-                                                       }
-                                                       if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) {       // If the 'up' item was NOT level 0 in rootline...
-                                                               $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']);        // The page record of "index".
-                                                       }
-
-                                                               // prev / next is found
-                                                       $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField);
-                                                       $lastKey=0;
-                                                       $nextActive=0;
-                                                       reset($prevnext_menu);
-                                                       while(list($k_b,$v_b)=each($prevnext_menu))     {
-                                                               if ($nextActive)        {
-                                                                       $recArr['next']=$v_b;
-                                                                       $nextActive=0;
+                                                       $recArr=array();
+                                                       $value_rec=$this->sys_page->getPage($value);    // The page record of the 'value'.
+                                                       if ($value_rec['pid'])  {       // 'up' page cannot be outside rootline
+                                                               $recArr['up']=$this->sys_page->getPage($value_rec['pid']);      // The page record of 'up'.
+                                                       }
+                                                       if ($recArr['up']['pid'] && $value_rec['pid']!=$this->tmpl->rootLine[0]['uid']) {       // If the 'up' item was NOT level 0 in rootline...
+                                                               $recArr['index']=$this->sys_page->getPage($recArr['up']['pid']);        // The page record of "index".
+                                                       }
+
+                                                               // prev / next is found
+                                                       $prevnext_menu = $this->sys_page->getMenu($value_rec['pid'],'*',$altSortField);
+                                                       $lastKey=0;
+                                                       $nextActive=0;
+                                                       foreach ($prevnext_menu as $k_b => $v_b) {
+                                                               if ($nextActive)        {
+                                                                       $recArr['next']=$v_b;
+                                                                       $nextActive=0;
                                                                }
-                                                               if ($v_b['uid']==$value)        {
-                                                                       if ($lastKey)   {
-                                                                               $recArr['prev']=$prevnext_menu[$lastKey];
-                                                                       }
-                                                                       $nextActive=1;
+                                                               if ($v_b['uid']==$value)        {
+                                                                       if ($lastKey)   {
+                                                                               $recArr['prev']=$prevnext_menu[$lastKey];
+                                                                       }
+                                                                       $nextActive=1;
                                                                }
-                                                               $lastKey=$k_b;
-                                                       }
-                                                       reset($prevnext_menu);
+                                                               $lastKey=$k_b;
+                                                       }
+                                                       reset($prevnext_menu);
                                                        $recArr['first']=pos($prevnext_menu);
                                                        end($prevnext_menu);
                                                        $recArr['last']=pos($prevnext_menu);
 
-                                                               // prevsection / nextsection is found
+                                                               // prevsection / nextsection is found
                                                        if (is_array($recArr['index'])) {       // You can only do this, if there is a valid page two levels up!
-                                                               $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField);
-                                                               $lastKey=0;
-                                                               $nextActive=0;
-                                                               reset($prevnextsection_menu);
-                                                               while(list($k_b,$v_b)=each($prevnextsection_menu))      {
-                                                                       if ($nextActive)        {
+                                                               $prevnextsection_menu = $this->sys_page->getMenu($recArr['index']['uid'],'*',$altSortField);
+                                                               $lastKey=0;
+                                                               $nextActive=0;
+                                                               foreach ($prevnextsection_menu as $k_b => $v_b) {
+                                                                       if ($nextActive)        {
                                                                                $sectionRec_temp = $this->sys_page->getMenu($v_b['uid'],'*',$altSortField);
                                                                                if (count($sectionRec_temp))    {
                                                                                        reset($sectionRec_temp);
-                                                                                       $recArr['nextsection']=pos($sectionRec_temp);
+                                                                                       $recArr['nextsection']=pos($sectionRec_temp);
                                                                                        end ($sectionRec_temp);
-                                                                                       $recArr['nextsection_last']=pos($sectionRec_temp);
-                                                                                       $nextActive=0;
+                                                                                       $recArr['nextsection_last']=pos($sectionRec_temp);
+                                                                                       $nextActive=0;
                                                                                }
                                                                        }
-                                                                       if ($v_b['uid']==$value_rec['pid'])     {
-                                                                               if ($lastKey)   {
+                                                                       if ($v_b['uid']==$value_rec['pid'])     {
+                                                                               if ($lastKey)   {
                                                                                        $sectionRec_temp = $this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'],'*',$altSortField);
                                                                                        if (count($sectionRec_temp))    {
                                                                                                reset($sectionRec_temp);
-                                                                                               $recArr['prevsection']=pos($sectionRec_temp);
+                                                                                               $recArr['prevsection']=pos($sectionRec_temp);
                                                                                                end ($sectionRec_temp);
-                                                                                               $recArr['prevsection_last']=pos($sectionRec_temp);
+                                                                                               $recArr['prevsection_last']=pos($sectionRec_temp);
                                                                                        }
-                                                                               }
-                                                                               $nextActive=1;
+                                                                               }
+                                                                               $nextActive=1;
                                                                        }
-                                                                       $lastKey=$k_b;
-                                                               }
+                                                                       $lastKey=$k_b;
+                                                               }
                                                        }
                                                        if ($this->conf['special.']['items.']['prevnextToSection'])     {
                                                                if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last']))        {
@@ -689,27 +714,27 @@ class tslib_menu {
                                                                }
                                                        }
 
-                                                       $items = explode('|',$this->conf['special.']['items']);
+                                                       $items = explode('|',$this->conf['special.']['items']);
                                                        $c=0;
-                                                       while(list($k_b,$v_b)=each($items))     {
-                                                               $v_b=strtolower(trim($v_b));
+                                                       foreach ($items as $k_b => $v_b) {
+                                                               $v_b=strtolower(trim($v_b));
                                                                if (intval($this->conf['special.'][$v_b.'.']['uid']))   {
                                                                        $recArr[$v_b] = $this->sys_page->getPage(intval($this->conf['special.'][$v_b.'.']['uid']));     // fetches the page in case of a hardcoded pid in template
                                                                }
-                                                               if (is_array($recArr[$v_b]))    {
-                                                                       $temp[$c]=$recArr[$v_b];
+                                                               if (is_array($recArr[$v_b]))    {
+                                                                       $temp[$c]=$recArr[$v_b];
                                                                        if ($this->conf['special.'][$v_b.'.']['target'])        {
                                                                                $temp[$c]['target']=$this->conf['special.'][$v_b.'.']['target'];
                                                                        }
-                                                                       if (is_array($this->conf['special.'][$v_b.'.']['fields.']))     {
-                                                                               reset($this->conf['special.'][$v_b.'.']['fields.']);
-                                                                               while(list($fk,$val)=each($this->conf['special.'][$v_b.'.']['fields.']))        {
+                                                                       $tmpSpecialFields = $this->conf['special.'][$v_b.'.']['fields.'];
+                                                                       if (is_array($tmpSpecialFields)) {
+                                                                               foreach ($tmpSpecialFields as $fk => $val) {
                                                                                        $temp[$c][$fk]=$val;
                                                                                }
                                                                        }
                                                                        $c++;
                                                                }
-                                                       }
+                                                       }
                                                }
                                        break;
                                }
@@ -731,26 +756,31 @@ class tslib_menu {
                                                unset($selectSetup['andWhere']);
                                        break;
                                        case 'header':
-                                               $selectSetup['andWhere']='header_layout!=100 AND header!=""';
+                                               $selectSetup['andWhere'] .= ' AND header_layout!=100 AND header!=""';
                                        break;
                                }
                                $basePageRow=$this->sys_page->getPage($this->id);
                                if (is_array($basePageRow))     {
-                                       $res = $GLOBALS['TSFE']->cObj->exec_getQuery('tt_content',      $selectSetup);
+                                       $res = $this->parent_cObj->exec_getQuery('tt_content',  $selectSetup);
                                        while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))      {
-                                               $temp[$row['uid']]=$basePageRow;
-                                               $temp[$row['uid']]['title']=$row['header'];
-                                               $temp[$row['uid']]['subtitle']=$row['subheader'];
-                                               $temp[$row['uid']]['starttime']=$row['starttime'];
-                                               $temp[$row['uid']]['endtime']=$row['endtime'];
-                                               $temp[$row['uid']]['fe_group']=$row['fe_group'];
-                                               $temp[$row['uid']]['media']=$row['media'];
-
-                                               $temp[$row['uid']]['header_layout']=$row['header_layout'];
-                                               $temp[$row['uid']]['bodytext']=$row['bodytext'];
-                                               $temp[$row['uid']]['image']=$row['image'];
-
-                                               $temp[$row['uid']]['sectionIndex_uid']=$row['uid'];
+                                               $GLOBALS['TSFE']->sys_page->versionOL('tt_content',$row);
+
+                                               if (is_array($row))     {
+                                                       $temp[$row['uid']] = $basePageRow;
+                                                       $temp[$row['uid']]['title'] = $row['header'];
+                                                       $temp[$row['uid']]['nav_title'] = $row['header'];
+                                                       $temp[$row['uid']]['subtitle'] = $row['subheader'];
+                                                       $temp[$row['uid']]['starttime'] = $row['starttime'];
+                                                       $temp[$row['uid']]['endtime'] = $row['endtime'];
+                                                       $temp[$row['uid']]['fe_group'] = $row['fe_group'];
+                                                       $temp[$row['uid']]['media'] = $row['media'];
+
+                                                       $temp[$row['uid']]['header_layout'] = $row['header_layout'];
+                                                       $temp[$row['uid']]['bodytext'] = $row['bodytext'];
+                                                       $temp[$row['uid']]['image'] = $row['image'];
+
+                                                       $temp[$row['uid']]['sectionIndex_uid'] = $row['uid'];
+                                               }
                                        }
                                }
                        } else {        // Default:
@@ -763,10 +793,7 @@ class tslib_menu {
                        $maxItems = intval($this->mconf['maxItems'] ? $this->mconf['maxItems'] : $this->conf['maxItems']);
                        $begin = tslib_cObj::calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
 
-                       $banUidArray=array();
-                       if (trim($this->conf['excludeUidList']))        {
-                               $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
-                       }
+                       $banUidArray = $this->getBannedUids();
 
                                // Fill in the menuArr with elements that should go into the menu:
                        $this->menuArr = Array();
@@ -795,21 +822,29 @@ class tslib_menu {
                                        $c++;
                                }
                        }
-                               // Setting number of menu items
-                       $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
                                //      Passing the menuArr through a user defined function:
                        if ($this->mconf['itemArrayProcFunc'])  {
                                if (!is_array($this->parentMenuArr)) {$this->parentMenuArr=array();}
                                $this->menuArr = $this->userProcess('itemArrayProcFunc',$this->menuArr);
                        }
+                               // Setting number of menu items
+                       $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
+
                        $this->hash = md5(serialize($this->menuArr).serialize($this->mconf).serialize($this->tmpl->rootLine).serialize($this->MP_array));
 
-                       $serData = $this->sys_page->getHash($this->hash, 60*60*24);
+                               // Get the cache timeout:
+                       if ($this->conf['cache_period']) {
+                               $cacheTimeout = $this->conf['cache_period'];
+                       } else {
+                               $cacheTimeout = $GLOBALS['TSFE']->get_cache_timeout();
+                       }
+
+                       $serData = $this->sys_page->getHash($this->hash);
                        if (!$serData)  {
                                $this->generate();
-                               $this->sys_page->storeHash($this->hash, serialize($this->result),'MENUDATA');
+                               $this->sys_page->storeHash($this->hash, serialize($this->result), 'MENUDATA', $cacheTimeout);
                        } else {
-                               $this->result=unserialize($serData);
+                               $this->result = unserialize($serData);
                        }
 
                                // End showAccessRestrictedPages
@@ -821,39 +856,37 @@ class tslib_menu {
        }
 
        /**
-        * Includes the PHP script defined for the HMENU special type "userdefined".
-        * This script is supposed to populate the array $menuItemsArray with a set of page records comprising the menu.
-        * The "userdefined" type is depreciated since "userfunction" has arrived since and is a better choice for many reasons (like using classes/functions for rendering the menu)
-        *
-        * @param       array           TypoScript parameters for "special.". In particular the property "file" is reserved and specifies the file to include. Seems like any other property can be used freely by the script.
-        * @param       string          The sorting field. Can be used from the script in the $incFile.
-        * @return      array           An array with the menu items
-        * @access private
-        */
-       function includeMakeMenu($conf,$altSortField)   {
-               $incFile = $GLOBALS['TSFE']->tmpl->getFileName($conf['file']);
-               if ($incFile && $GLOBALS['TSFE']->checkFileInclude($incFile))   {
-                       include($incFile);
-               }
-               return is_array($menuItemsArray) ? $menuItemsArray : array();
-       }
-
-       /**
         * Checks if a page is OK to include in the final menu item array. Pages can be excluded if the doktype is wrong, if they are hidden in navigation, have a uid in the list of banned uids etc.
         *
         * @param       array           Array of menu items
         * @param       array           Array of page uids which are to be excluded
         * @param       boolean         If set, then the page is a spacer.
-        * @return      boolean         Returns true if the page can be safely included.
+        * @return      boolean         Returns TRUE if the page can be safely included.
         */
        function filterMenuPages(&$data,$banUidArray,$spacer)   {
 
+               $includePage = TRUE;
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/tslib/class.tslib_menu.php']['filterMenuPages'] as $classRef) {
+                               $hookObject = t3lib_div::getUserObj($classRef);
+
+                               if (!($hookObject instanceof tslib_menu_filterMenuPagesHook)) {
+                                       throw new UnexpectedValueException('$hookObject must implement interface tslib_menu_filterMenuPagesHook', 1269877402);
+                               }
+
+                               $includePage = $includePage && $hookObject->processFilter($data, $banUidArray, $spacer, $this);
+                       }
+               }
+               if (!$includePage) {
+                       return FALSE;
+               }
+
                if ($data['_SAFE'])     return TRUE;
 
                $uid = $data['uid'];
                if ($this->mconf['SPC'] || !$spacer)    {       // If the spacer-function is not enabled, spacers will not enter the $menuArr
                        if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']))     {               // Page may not be 'not_in_menu' or 'Backend User Section'
-                               if (!$data['nav_hide']) {       // Not hidden in navigation
+                               if (!$data['nav_hide'] || $this->conf['includeNotInMenu'])      {       // Not hidden in navigation
                                        if (!t3lib_div::inArray($banUidArray,$uid))     {       // not in banned uid's
 
                                                        // Checks if the default language version can be shown:
@@ -869,14 +902,14 @@ class tslib_menu {
                                                                }
                                                        }
 
-                                                               // Continue if token is true:
+                                                               // Continue if token is TRUE:
                                                        if ($tok)       {
 
                                                                        // Checking if "&L" should be modified so links to non-accessible pages will not happen.
                                                                if ($this->conf['protectLvar']) {
-                                                                       $Lvar = intval(t3lib_div::_GP('L'));
-                                                                       if (($this->conf['protectLvar']=='all' || t3lib_div::hideIfNotTranslated($data['l18n_cfg'])) && $Lvar!=$GLOBALS['TSFE']->sys_language_uid)      {       // page cannot be access in locaization and Lvar is different than sys_language uid - this means we must check!
-                                                                               $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $Lvar);
+                                                                       $languageUid = intval($GLOBALS['TSFE']->config['config']['sys_language_uid']);
+                                                                       if ($languageUid && ($this->conf['protectLvar']=='all' || t3lib_div::hideIfNotTranslated($data['l18n_cfg'])))   {
+                                                                               $olRec = $GLOBALS['TSFE']->sys_page->getPageOverlay($data['uid'], $languageUid);
                                                                                if (!count($olRec))     {
                                                                                                // If no pages_language_overlay record then page can NOT be accessed in the language pointed to by "&L" and therefore we protect the link by setting "&L=0"
                                                                                        $data['_ADD_GETVARS'].= '&L=0';
@@ -915,11 +948,10 @@ class tslib_menu {
                }
 
                        // Prepare IFSUB settings, overriding normal settings
-                       // IFSUB is true if there exist submenu items to the current item
+                       // IFSUB is TRUE if there exist submenu items to the current item
                if ($this->mconf['IFSUB'])      {
                        $IFSUBinit = 0; // Flag: If $IFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('IFSUB',$key))   {
                                        if (!$IFSUBinit)        {       // if this is the first IFSUB element, we must generate IFSUB.
                                                $IFSUBconf = $this->tmpl->splitConfArray($this->mconf['IFSUB.'],$splitCount);
@@ -938,8 +970,7 @@ class tslib_menu {
                        // Prepare active settings, overriding normal settings
                if ($this->mconf['ACT'])        {
                        $ACTinit = 0;   // Flag: If $ACT is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('ACT',$key))     {
                                        if (!$ACTinit)  {       // if this is the first 'active', we must generate ACT.
                                                $ACTconf = $this->tmpl->splitConfArray($this->mconf['ACT.'],$splitCount);
@@ -957,11 +988,10 @@ class tslib_menu {
                        }
                }
                        // Prepare ACT (active)/IFSUB settings, overriding normal settings
-                       // ACTIFSUB is true if there exist submenu items to the current item and the current item is active
+                       // ACTIFSUB is TRUE if there exist submenu items to the current item and the current item is active
                if ($this->mconf['ACTIFSUB'])   {
                        $ACTIFSUBinit = 0;      // Flag: If $ACTIFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('ACTIFSUB',$key))        {
                                        if (!$ACTIFSUBinit)     {       // if this is the first 'active', we must generate ACTIFSUB.
                                                $ACTIFSUBconf = $this->tmpl->splitConfArray($this->mconf['ACTIFSUB.'],$splitCount);
@@ -979,11 +1009,10 @@ class tslib_menu {
                        }
                }
                        // Prepare CUR (current) settings, overriding normal settings
-                       // CUR is true if the current page equals the item here!
+                       // CUR is TRUE if the current page equals the item here!
                if ($this->mconf['CUR'])        {
                        $CURinit = 0;   // Flag: If $CUR is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('CUR',$key))     {
                                        if (!$CURinit)  {       // if this is the first 'current', we must generate CUR. Basically this control is just inherited from the other implementations as current would only exist one time and thats it (unless you use special-features of HMENU)
                                                $CURconf = $this->tmpl->splitConfArray($this->mconf['CUR.'],$splitCount);
@@ -1000,11 +1029,10 @@ class tslib_menu {
                        }
                }
                        // Prepare CUR (current)/IFSUB settings, overriding normal settings
-                       // CURIFSUB is true if there exist submenu items to the current item and the current page equals the item here!
+                       // CURIFSUB is TRUE if there exist submenu items to the current item and the current page equals the item here!
                if ($this->mconf['CURIFSUB'])   {
                        $CURIFSUBinit = 0;      // Flag: If $CURIFSUB is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {
+                       foreach ($NOconf as $key => $val) {
                                if ($this->isItemState('CURIFSUB',$key))        {
                                        if (!$CURIFSUBinit)     {       // if this is the first 'current', we must generate CURIFSUB.
                                                $CURIFSUBconf = $this->tmpl->splitConfArray($this->mconf['CURIFSUB.'],$splitCount);
@@ -1024,8 +1052,7 @@ class tslib_menu {
                        // Prepare active settings, overriding normal settings
                if ($this->mconf['USR'])        {
                        $USRinit = 0;   // Flag: If $USR is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USR',$key))     {
                                        if (!$USRinit)  {       // if this is the first active, we must generate USR.
                                                $USRconf = $this->tmpl->splitConfArray($this->mconf['USR.'],$splitCount);
@@ -1045,8 +1072,7 @@ class tslib_menu {
                        // Prepare spacer settings, overriding normal settings
                if ($this->mconf['SPC'])        {
                        $SPCinit = 0;   // Flag: If $SPC is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find spacers
+                       foreach ($NOconf as $key => $val) {     // Find spacers
                                if ($this->isItemState('SPC',$key))     {
                                        if (!$SPCinit)  {       // if this is the first spacer, we must generate SPC.
                                                $SPCconf = $this->tmpl->splitConfArray($this->mconf['SPC.'],$splitCount);
@@ -1059,8 +1085,7 @@ class tslib_menu {
                        // Prepare Userdefined settings
                if ($this->mconf['USERDEF1'])   {
                        $USERDEF1init = 0;      // Flag: If $USERDEF1 is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USERDEF1',$key))        {
                                        if (!$USERDEF1init)     {       // if this is the first active, we must generate USERDEF1.
                                                $USERDEF1conf = $this->tmpl->splitConfArray($this->mconf['USERDEF1.'],$splitCount);
@@ -1080,8 +1105,7 @@ class tslib_menu {
                        // Prepare Userdefined settings
                if ($this->mconf['USERDEF2'])   {
                        $USERDEF2init = 0;      // Flag: If $USERDEF2 is generated
-                       reset($NOconf);
-                       while (list($key,$val)=each($NOconf))   {       // Find active
+                       foreach ($NOconf as $key => $val) {     // Find active
                                if ($this->isItemState('USERDEF2',$key))        {
                                        if (!$USERDEF2init)     {       // if this is the first active, we must generate USERDEF2.
                                                $USERDEF2conf = $this->tmpl->splitConfArray($this->mconf['USERDEF2.'],$splitCount);
@@ -1135,9 +1159,40 @@ class tslib_menu {
                        // Creating link:
                if ($this->mconf['collapse'] && $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)))    {
                        $thePage = $this->sys_page->getPage($this->menuArr[$key]['pid']);
-                       $LD = $this->tmpl->linkData($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+                       $LD = $this->menuTypoLink($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
                } else {
-                       $LD = $this->tmpl->linkData($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+                       $LD = $this->menuTypoLink($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+               }
+
+                       // Override URL if using "External URL" as doktype with a valid e-mail address:
+               if ($this->menuArr[$key]['doktype'] == t3lib_pageSelect::DOKTYPE_LINK && $this->menuArr[$key]['urltype'] == 3 && t3lib_div::validEmail($this->menuArr[$key]['url'])) {
+                               // Create mailto-link using tslib_cObj::typolink (concerning spamProtectEmailAddresses):
+                       $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array('parameter' => $this->menuArr[$key]['url']));
+                       $LD['target'] = '';
+               }
+
+                       // Override url if current page is a shortcut
+               if ($this->menuArr[$key]['doktype'] == t3lib_pageSelect::DOKTYPE_SHORTCUT
+                       && $this->menuArr[$key]['shortcut_mode'] != t3lib_pageSelect::SHORTCUT_MODE_RANDOM_SUBPAGE) {
+
+                       $shortcut = NULL;
+                       try {
+                               $shortcut = $GLOBALS['TSFE']->getPageShortcut(
+                                       $this->menuArr[$key]['shortcut'],
+                                       $this->menuArr[$key]['shortcut_mode'],
+                                       $this->menuArr[$key]['uid']
+                               );
+                       } catch (Exception $ex) {
+                               // shortcut configuration is wrong and Exception is thrown
+                               // this will be catched with the next is_array() check
+                       }
+
+                       if (!is_array($shortcut)) {
+                               return FALSE;
+                       }
+
+                               // Only setting url, not target
+                       $LD['totalURL'] = $this->parent_cObj->typoLink_URL(array('parameter' => $shortcut['uid']));
                }
 
                        // Manipulation in case of access restricted pages:
@@ -1159,6 +1214,28 @@ class tslib_menu {
                        $GLOBALS['TSFE']->setJS('openPic');
                }
 
+                       // look for type and popup
+                       // following settings are valid in field target:
+                       // 230                                                          will add type=230 to the link
+                       // 230 500x600                                          will add type=230 to the link and open in popup window with 500x600 pixels
+                       // 230 _blank                                           will add type=230 to the link and open with target "_blank"
+                       // 230x450:resizable=0,location=1       will open in popup window with 500x600 pixels with settings "resizable=0,location=1"
+               $matches = array();
+               $targetIsType = $LD['target'] && (string) intval($LD['target']) == trim($LD['target']) ? intval($LD['target']) : FALSE;
+               if (preg_match('/([0-9]+[\s])?(([0-9]+)x([0-9]+))?(:.+)?/s', $LD['target'], $matches) || $targetIsType) {
+                               // has type?
+                       if(intval($matches[1]) || $targetIsType) {
+                               $LD['totalURL'] .= '&type=' . ($targetIsType ?  $targetIsType : intval($matches[1]));
+                               $LD['target'] = $targetIsType ?  '' : trim(substr($LD['target'], strlen($matches[1]) + 1));
+                       }
+                               // open in popup window?
+                       if ($matches[3] && $matches[4]) {
+                               $JSparamWH = 'width=' . $matches[3] . ',height=' . $matches[4] . ($matches[5] ? ',' . substr($matches[5], 1) : '');
+                               $onClick = 'vHWin=window.open(\'' . $LD['totalURL'] . '\',\'FEopenLink\',\'' . $JSparamWH . '\');vHWin.focus();return false;';
+                               $LD['target'] = '';
+                       }
+               }
+
                        // out:
                $list = array();
                $list['HREF'] = strlen($LD['totalURL']) ? $LD['totalURL'] : $GLOBALS['TSFE']->baseUrl;  // Added this check: What it does is to enter the baseUrl (if set, which it should for "realurl" based sites) as URL if the calculated value is empty. The problem is that no link is generated with a blank URL and blank URLs might appear when the realurl encoding is used and a link to the frontpage is generated.
@@ -1171,22 +1248,22 @@ class tslib_menu {
        /**
         * Will change $LD (passed by reference) if the page is access restricted
         *
-        * @param       array   $LD, the array from the linkData() function
-        * @param       array   Page array
-        * @param       string  Main target value
-        * @param       string  Type number override if any
-        * @return      void    ($LD passed by reference might be changed.)
+        * @param       array           $LD, the array from the linkData() function
+        * @param       array           Page array
+        * @param       string          Main target value
+        * @param       string          Type number override if any
+        * @return      void            ($LD passed by reference might be changed.)
         */
        function changeLinksForAccessRestrictedPages(&$LD, $page, $mainTarget, $typeOverride)   {
 
                        // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
-               if ($this->mconf['showAccessRestrictedPages'] && $this->mconf['showAccessRestrictedPages']!=='NONE' && !$GLOBALS['TSFE']->checkPageGroupAccess($page))          {
+               if ($this->mconf['showAccessRestrictedPages'] && $this->mconf['showAccessRestrictedPages']!=='NONE' && !$GLOBALS['TSFE']->checkPageGroupAccess($page))  {
                        $thePage = $this->sys_page->getPage($this->mconf['showAccessRestrictedPages']);
 
                        $addParams = $this->mconf['showAccessRestrictedPages.']['addParams'];
                        $addParams = str_replace('###RETURN_URL###',rawurlencode($LD['totalURL']),$addParams);
                        $addParams = str_replace('###PAGE_ID###',$page['uid'],$addParams);
-                       $LD = $this->tmpl->linkData($thePage,$mainTarget,'','','', $addParams, $typeOverride);
+                       $LD = $this->menuTypoLink($thePage,$mainTarget,'','','', $addParams, $typeOverride);
                }
        }
 
@@ -1210,6 +1287,11 @@ class tslib_menu {
                $cls = strtolower($this->conf[($this->menuNumber+1).$objSuffix]);
                $subLevelClass = ($cls && t3lib_div::inList($this->tmpl->menuclasses,$cls)) ? $cls : '';
 
+                       // stdWrap for expAll
+               if (isset($this->mconf['expAll.'])) {
+                       $this->mconf['expAll'] = $this->parent_cObj->stdWrap($this->mconf['expAll'], $this->mconf['expAll.']);
+               }
+
                if ($subLevelClass && ($this->mconf['expAll'] || $this->isNext($uid, $this->getMPvar($this->I['key'])) || is_array($altArray)) && !$this->mconf['sectionIndex'])        {
                        $submenu = t3lib_div::makeInstance('tslib_'.$subLevelClass);
                        $submenu->entryLevel = $this->entryLevel+1;
@@ -1220,6 +1302,7 @@ class tslib_menu {
                        }
 
                                // especially scripts that build the submenu needs the parent data
+                       $submenu->parent_cObj = $this->parent_cObj;
                        $submenu->parentMenuArr = $this->menuArr;
 
                                // Setting alternativeMenuTempArray (will be effective only if an array)
@@ -1229,17 +1312,25 @@ class tslib_menu {
 
                        if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber+1, $objSuffix))  {
                                $submenu->makeMenu();
-                               return $submenu->writeMenu();
+                                       // Memorize the current menu item count
+                               $tempCountMenuObj = $GLOBALS['TSFE']->register['count_MENUOBJ'];
+                                       // Reset the menu item count for the submenu
+                               $GLOBALS['TSFE']->register['count_MENUOBJ'] = 0;
+                               $content = $submenu->writeMenu();
+                                       // Restore the item count now that the submenu has been handled
+                               $GLOBALS['TSFE']->register['count_MENUOBJ'] = $tempCountMenuObj;
+                               $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
+                               return $content;
                        }
                }
        }
 
        /**
-        * Returns true if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn)
+        * Returns TRUE if the page with UID $uid is the NEXT page in root line (which means a submenu should be drawn)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page with $uid is active
+        * @return      boolean         TRUE if page with $uid is active
         * @access private
         * @see subMenu()
         */
@@ -1257,11 +1348,11 @@ class tslib_menu {
        }
 
        /**
-        * Returns true if the page with UID $uid is active (in the current rootline)
+        * Returns TRUE if the page with UID $uid is active (in the current rootline)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page with $uid is active
+        * @return      boolean         TRUE if page with $uid is active
         * @access private
         */
        function isActive($uid, $MPvar='')      {
@@ -1278,26 +1369,26 @@ class tslib_menu {
        }
 
        /**
-        * Returns true if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id)
+        * Returns TRUE if the page with UID $uid is the CURRENT page (equals $GLOBALS['TSFE']->id)
         *
         * @param       integer         Page uid to evaluate.
         * @param       string          MPvar for the current position of item.
-        * @return      boolean         True if page $uid = $GLOBALS['TSFE']->id
+        * @return      boolean         TRUE if page $uid = $GLOBALS['TSFE']->id
         * @access private
         */
        function isCurrent($uid, $MPvar='')     {
                $testUid = $uid.($MPvar?':'.$MPvar:'');
                if ($uid && !strcmp(end($this->rL_uidRegister),'ITEM:'.$testUid))       {
                        return TRUE;
-       }
+               }
        }
 
        /**
-        * Returns true if there is a submenu with items for the page id, $uid
+        * Returns TRUE if there is a submenu with items for the page id, $uid
         * Used by the item states "IFSUB", "ACTIFSUB" and "CURIFSUB" to check if there is a submenu
         *
         * @param       integer         Page uid for which to search for a submenu
-        * @return      boolean         Returns true if there was a submenu with items found
+        * @return      boolean         Returns TRUE if there was a submenu with items found
         * @access private
         */
        function isSubMenu($uid)        {
@@ -1308,9 +1399,9 @@ class tslib_menu {
                        $uid = $mount_info['mount_pid'];
                }
 
-               $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide');
+               $recs = $this->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide,shortcut,shortcut_mode');
                foreach($recs as $theRec)       {
-                       if (!t3lib_div::inList($this->doktypeExcludeList,$theRec['doktype']) && !$theRec['nav_hide'])   {       // If a menu item seems to be another type than 'Not in menu', then return true (there were items!)
+                       if (!t3lib_div::inList($this->doktypeExcludeList,$theRec['doktype']) && (!$theRec['nav_hide'] || $this->conf['includeNotInMenu']))      {       // If a menu item seems to be another type than 'Not in menu', then return TRUE (there were items!)
                                return TRUE;
                        }
                }
@@ -1321,7 +1412,7 @@ class tslib_menu {
         *
         * @param       string          The item state to evaluate (SPC, IFSUB, ACT etc... but no xxxRO states of course)
         * @param       integer         Key pointing to menu item from ->menuArr
-        * @return      boolean         True (integer!=0) if match, otherwise false (=0, zero)
+        * @return      boolean         True (integer!=0) if match, otherwise FALSE (=0, zero)
         * @access private
         * @see procesItemStates()
         */
@@ -1359,7 +1450,7 @@ class tslib_menu {
        }
 
        /**
-        * Creates an access-key for a GMENU menu item based on the menu item titles first letter
+        * Creates an access-key for a TMENU/GMENU menu item based on the menu item titles first letter
         *
         * @param       string          Menu item title.
         * @return      array           Returns an array with keys "code" ("accesskey" attribute for the img-tag) and "alt" (text-addition to the "alt" attribute) if an access key was defined. Otherwise array was empty
@@ -1369,13 +1460,15 @@ class tslib_menu {
                        // The global array ACCESSKEY is used to globally control if letters are already used!!
                $result = Array();
 
+               $title = trim(strip_tags($title));
                $titleLen = strlen($title);
                for ($a=0;$a<$titleLen;$a++)    {
-                       $key = strtoupper(trim(substr($title,$a,1)));
-                       if (preg_match('/[a-zA-Z]/', $key) && !isset($GLOBALS['TSFE']->accessKey[$key]))        {
-                               $GLOBALS['TSFE']->accessKey[$key]=1;
+                       $key = strtoupper(substr($title,$a,1));
+                       if (preg_match('/[A-Z]/', $key) && !isset($GLOBALS['TSFE']->accessKey[$key]))   {
+                               $GLOBALS['TSFE']->accessKey[$key] = 1;
                                $result['code'] = ' accesskey="'.$key.'"';
                                $result['alt'] = ' (ALT+'.$key.')';
+                               $result['key'] = $key;
                                break;
                        }
                }
@@ -1394,8 +1487,8 @@ class tslib_menu {
        function userProcess($mConfKey,$passVar)        {
                if ($this->mconf[$mConfKey])    {
                        $funcConf = $this->mconf[$mConfKey.'.'];
-                       $funcConf['parentObj']=&$this;
-                       $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
+                       $funcConf['parentObj'] = $this;
+                       $passVar = $this->parent_cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
                }
                return $passVar;
        }
@@ -1407,7 +1500,7 @@ class tslib_menu {
         * @access private
         */
        function setATagParts() {
-               $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).$this->I['val']['ATagParams'].$this->I['addATagParams'].$this->I['accessKey']['code'].'>';
+               $this->I['A1'] = '<a '.t3lib_div::implodeAttributes($this->I['linkHREF'],1).' '.$this->I['val']['ATagParams'].$this->I['accessKey']['code'].'>';
                $this->I['A2'] = '</a>';
        }
 
@@ -1450,6 +1543,61 @@ class tslib_menu {
                return $this->doktypeExcludeList ? ' AND pages.doktype NOT IN ('.$this->doktypeExcludeList.')' : '';
        }
 
+       /**
+        * Returns an array of banned UIDs (from excludeUidList)
+        *
+        * @return      array           Array of banned UIDs
+        * @access private
+        */
+       function getBannedUids() {
+               $banUidArray = array();
+
+               if (trim($this->conf['excludeUidList'])) {
+                       $banUidList = str_replace('current', $GLOBALS['TSFE']->page['uid'], $this->conf['excludeUidList']);
+                       $banUidArray = t3lib_div::intExplode(',', $banUidList);
+               }
+
+               return $banUidArray;
+       }
+
+       /**
+        * Calls typolink to create menu item links.
+        *
+        * @param       array           $page   Page record (uid points where to link to)
+        * @param       string          $oTarget        Target frame/window
+        * @param       boolean         $no_cache       TRUE if caching should be disabled
+        * @param       string          $script Alternative script name
+        * @param       array           $overrideArray  Array to override values in $page
+        * @param       string          $addParams      Parameters to add to URL
+        * @param       array           $typeOverride   "type" value
+        * @return      array           See linkData
+        */
+       function menuTypoLink($page, $oTarget, $no_cache, $script, $overrideArray = '', $addParams = '', $typeOverride = '') {
+               $conf = array(
+                       'parameter' => is_array($overrideArray) && $overrideArray['uid'] ? $overrideArray['uid'] : $page['uid'],
+               );
+               if ($typeOverride && t3lib_utility_Math::canBeInterpretedAsInteger($typeOverride)) {
+                       $conf['parameter'] .= ',' . $typeOverride;
+               }
+               if ($addParams) {
+                       $conf['additionalParams'] = $addParams;
+               }
+               if ($no_cache) {
+                       $conf['no_cache'] = TRUE;
+               }
+               if ($oTarget) {
+                       $conf['target'] = $oTarget;
+               }
+               if ($page['sectionIndex_uid']) {
+                       $conf['section'] = $page['sectionIndex_uid'];
+               }
+
+               $this->parent_cObj->typoLink('|', $conf);
+               $LD = $this->parent_cObj->lastTypoLinkLD;
+               $LD['totalURL'] = $this->parent_cObj->lastTypoLinkUrl;
+               return $LD;
+       }
+
 }
 
 
@@ -1473,10 +1621,9 @@ class tslib_menu {
 /**
  * Extension class creating text based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=387&cHash=73a3116ab8
  */
 class tslib_tmenu extends tslib_menu {
 
@@ -1492,7 +1639,10 @@ class tslib_tmenu extends tslib_menu {
                if ($splitCount)        {
                        list($NOconf) = $this->procesItemStates($splitCount);
                }
-               if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+               if ($this->mconf['debugItemConf']) {
+                       echo '<h3>$NOconf:</h3>';
+                       debug($NOconf);
+               }
                $this->result = $NOconf;
        }
 
@@ -1505,36 +1655,50 @@ class tslib_tmenu extends tslib_menu {
         */
        function writeMenu()    {
                if (is_array($this->result) && count($this->result))    {
-                       $this->WMcObj =t3lib_div::makeInstance('tslib_cObj');   // Create new tslib_cObj for our use
-                       $this->WMresult='';
+                       $this->WMcObj = t3lib_div::makeInstance('tslib_cObj');  // Create new tslib_cObj for our use
+                       $this->WMresult = '';
                        $this->INPfixMD5 = substr(md5(microtime().'tmenu'),0,4);
                        $this->WMmenuItems = count($this->result);
 
                        $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix'=>$this->mconf['submenuObjSuffixes']),$this->WMmenuItems);
 
                        $this->extProc_init();
-                       reset($this->result);
-                       while (list($key,$val)=each($this->result))     {
+                       foreach ($this->result as $key => $val) {
                                $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
                                $GLOBALS['TSFE']->register['count_MENUOBJ']++;
 
-                               $this->I=array();
                                $this->WMcObj->start($this->menuArr[$key],'pages');             // Initialize the cObj with the page record of the menu item
+
+                               $this->I = array();
                                $this->I['key'] = $key;
-                               $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$key;
+                               $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key;
                                $this->I['val'] = $val;
-                               $this->I['title'] = $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']),$this->I['val']['stdWrap.']);
+                               $this->I['title'] = isset($this->I['val']['stdWrap.'])
+                                       ? $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']), $this->I['val']['stdWrap.'])
+                                       : $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']);
                                $this->I['uid'] = $this->menuArr[$key]['uid'];
                                $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
                                $this->I['pid'] = $this->menuArr[$key]['pid'];
                                $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
 
+                                       // Set access key
+                               if ($this->mconf['accessKey'])  {
+                                       $this->I['accessKey'] = $this->accessKey($this->I['title']);
+                               } else {
+                                       $this->I['accessKey'] = Array();
+                               }
+
                                        // Make link tag
-                               $this->I['val']['ATagParams'] = $this->I['val']['ATagParams'] ? ' '.$this->I['val']['ATagParams'] : '';
-                               $this->I['linkHREF'] =  $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
+                               $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
+                               if(isset($this->I['val']['additionalParams.'])) {
+                                       $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
+                               }
+                               $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
 
                                        // Title attribute of links:
-                               $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']);
+                               $titleAttrValue = isset($this->I['val']['ATagTitle.'])
+                                       ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt']
+                                       : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt'];
                                if (strlen($titleAttrValue))    {
                                        $this->I['linkHREF']['title'] = $titleAttrValue;
                                }
@@ -1576,6 +1740,11 @@ class tslib_tmenu extends tslib_menu {
                                        // Calling extra processing function
                                $this->extProc_beforeLinking($key);
 
+                                       // stdWrap for doNotLinkIt
+                               if (isset($this->I['val']['doNotLinkIt.'])) {
+                                       $this->I['val']['doNotLinkIt'] = $this->WMcObj->stdWrap($this->I['val']['doNotLinkIt'], $this->I['val']['doNotLinkIt.']);
+                               }
+
                                        // Compile link tag
                                if (!$this->I['val']['doNotLinkIt']) {$this->I['val']['doNotLinkIt']=0;}
                                if (!$this->I['spacer'] && $this->I['val']['doNotLinkIt']!=1)   {
@@ -1585,7 +1754,7 @@ class tslib_tmenu extends tslib_menu {
                                        $this->I['A2'] = '';
                                }
 
-                                       // ATAGBeforeWrap processing:
+                                       // ATagBeforeWrap processing:
                                if ($this->I['val']['ATagBeforeWrap'])  {
                                        $wrapPartsBefore = explode('|',$this->I['val']['linkWrap']);
                                        $wrapPartsAfter = array('','');
@@ -1594,13 +1763,22 @@ class tslib_tmenu extends tslib_menu {
                                        $wrapPartsAfter = explode('|',$this->I['val']['linkWrap']);
                                }
                                if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) {
-                                       $wrapPartsStdWrap = explode($this->I['val']['stdWrap2']?$this->I['val']['stdWrap2']:'|',$this->WMcObj->stdWrap('|',$this->I['val']['stdWrap2.']));
+                                       $stdWrap2 = isset($this->I['val']['stdWrap2.'])
+                                               ? $this->WMcObj->stdWrap('|', $this->I['val']['stdWrap2.'])
+                                               : '|';
+                                       $wrapPartsStdWrap = explode($this->I['val']['stdWrap2'] ? $this->I['val']['stdWrap2'] : '|', $stdWrap2);
                                } else {$wrapPartsStdWrap = array('','');}
 
                                        // Make before, middle and after parts
                                $this->I['parts'] = array();
                                $this->I['parts']['before']=$this->getBeforeAfter('before');
                                $this->I['parts']['stdWrap2_begin']=$wrapPartsStdWrap[0];
+
+                                       // stdWrap for doNotShowLink
+                               if (isset($this->I['val']['doNotShowLink.'])) {
+                                       $this->I['val']['doNotShowLink'] = $this->WMcObj->stdWrap($this->I['val']['doNotShowLink'], $this->I['val']['doNotShowLink.']);
+                               }
+
                                if (!$this->I['val']['doNotShowLink']) {
                                        $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0];
                                        $this->I['parts']['ATag_begin'] = $this->I['A1'];
@@ -1623,14 +1801,16 @@ class tslib_tmenu extends tslib_menu {
                                $this->I['theItem']= $this->extProc_beforeAllWrap($this->I['theItem'],$key);
 
                                        // allWrap:
-                               $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
+                               $allWrap = isset($this->I['val']['allWrap.'])
+                                       ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.'])
+                                       : $this->I['val']['allWrap'];
                                $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
 
                                if ($this->I['val']['subst_elementUid'])        $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
 
                                        // allStdWrap:
                                if (is_array($this->I['val']['allStdWrap.']))   {
-                                       $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
+                                       $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
                                }
 
                                        // Calling extra processing function
@@ -1645,7 +1825,6 @@ class tslib_tmenu extends tslib_menu {
         *
         * @param       string          Can be "before" or "after" and determines which kind of image to create (basically this is the prefix of the TypoScript properties that are read from the ->I['val'] array
         * @return      string          The resulting HTML of the image, if any.
-        * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=388&cHash=a7486044cd
         */
        function getBeforeAfter($pref)  {
                $res = '';
@@ -1656,18 +1835,35 @@ class tslib_tmenu extends tslib_menu {
                                $imgROInfo[3] = t3lib_div::png_to_gif_by_imagemagick($imgROInfo[3]);
                                if ($imgROInfo) {
                                        $theName = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'].$pref;
-                                       $name = ' name="'.$theName.'"';
-                                       $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; ';
-                                       $GLOBALS['TSFE']->JSImgCode.= chr(10).$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; ';
+                                       $name = ' '.$this->nameAttribute.'="'.$theName.'"';
+                                       $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_n=new Image(); '.$theName.'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'"; ';
+                                       $GLOBALS['TSFE']->JSImgCode.= LF.$theName.'_h=new Image(); '.$theName.'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$imgROInfo[3].'"; ';
                                }
                        }
                        $GLOBALS['TSFE']->imagesOnPage[]=$imgInfo[3];
-                       $res='<img src="'.$GLOBALS['TSFE']->absRefPrefix.$imgInfo[3].'" width="'.$imgInfo[0].'" height="'.$imgInfo[1].'"'.$name.($this->I['val'][$pref.'ImgTagParams']?" ".$this->I['val'][$pref.'ImgTagParams']:'').' border="0"';
-                       if (!strstr($res,'alt="'))      $res.=' alt=""';        // Adding alt attribute if not set.
+                       $res='<img' .
+                               ' src="' . $GLOBALS['TSFE']->absRefPrefix . $imgInfo[3] . '"' .
+                               ' width="' . $imgInfo[0] . '"' .
+                               ' height="' . $imgInfo[1] . '"' .
+                               $name .
+                               ($this->I['val'][$pref.'ImgTagParams'] ? ' ' . $this->I['val'][$pref.'ImgTagParams'] : '') .
+                               tslib_cObj::getBorderAttr(' border="0"');
+                       if (!strstr($res,'alt="')) {
+                               $res .= ' alt=""'; // Adding alt attribute if not set.
+                       }
                        $res.=' />';
-                       if ($this->I['val'][$pref.'ImgLink'])   {$res=$this->I['A1'].$res.$this->I['A2'];}
+                       if ($this->I['val'][$pref.'ImgLink']) {
+                               $res=$this->I['A1'].$res.$this->I['A2'];
+                       }
+               }
+               $processedPref = isset($this->I['val'][$pref . '.'])
+                       ? $this->WMcObj->stdWrap($this->I['val'][$pref], $this->I['val'][$pref . '.'])
+                       : $this->I['val'][$pref];
+               if (isset($this->I['val'][$pref . 'Wrap'])) {
+                       return $this->tmpl->wrap($res . $processedPref, $this->I['val'][$pref . 'Wrap']);
+               } else {
+                       return $res . $processedPref;
                }
-               return $this->tmpl->wrap($res.$this->WMcObj->stdWrap($this->I['val'][$pref],$this->I['val'][$pref.'.']), $this->I['val'][$pref.'Wrap']);
        }
 
        /**
@@ -1684,9 +1880,9 @@ class tslib_tmenu extends tslib_menu {
                                        document.getElementById(id).style.background = color;
                                        return true;
                                } else if (document.layers && document.layers[id]) {
-                               document.layers[id].bgColor = color;
+                                       document.layers[id].bgColor = color;
                                        return true;
-                           }
+                               }
                        }
                ';
        }
@@ -1738,7 +1934,10 @@ class tslib_tmenu extends tslib_menu {
                if (!$this->I['spacer'])        {
                        $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
                }
-               $this->WMresult.= $this->I['val']['wrapItemAndSub'] ? $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrapItemAndSub']) : $this->I['theItem'];
+               $part = isset($this->I['val']['wrapItemAndSub.'])
+                       ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.'])
+                       : $this->I['val']['wrapItemAndSub'];
+               $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem'];
        }
 
        /**
@@ -1762,6 +1961,10 @@ class tslib_tmenu extends tslib_menu {
         * @see writeMenu(), tslib_tmenu_layers::extProc_finish()
         */
        function extProc_finish()       {
+                       // stdWrap:
+               if (is_array($this->mconf['stdWrap.'])) {
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
+               }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
 }
@@ -1792,10 +1995,9 @@ class tslib_tmenu extends tslib_menu {
 /**
  * Extension class creating graphic based menus (PNG or GIF files)
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=384&cHash=93a7644cba
  */
 class tslib_gmenu extends tslib_menu {
 
@@ -1820,13 +2022,19 @@ class tslib_gmenu extends tslib_menu {
                        $tempcnt_HMENU_MENUOBJ = $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'];
                        $tempcnt_MENUOBJ = $GLOBALS['TSFE']->register['count_MENUOBJ'];
 
-                       if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+                       if ($this->mconf['debugItemConf']) {
+                               echo '<h3>$NOconf:</h3>';
+                               debug($NOconf);
+                       }
                        if ($ROconf)    {               // RollOver
                                        //start recount for rollover with initial values
                                $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']= $temp_HMENU_MENUOBJ;
                                $GLOBALS['TSFE']->register['count_MENUOBJ']= $temp_MENUOBJ;
                                $this->makeGifs($ROconf,'RO');
-                               if ($this->mconf['debugItemConf'])      {echo '<h3>$ROconf:</h3>';      debug($ROconf); }
+                               if ($this->mconf['debugItemConf']) {
+                                       echo '<h3>$ROconf:</h3>';
+                                       debug($ROconf);
+                               }
                        }
                                // use count from NO obj
                        $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ'] = $tempcnt_HMENU_MENUOBJ;
@@ -1881,8 +2089,7 @@ class tslib_gmenu extends tslib_menu {
                $c=0;
                $maxFlag=0;
                $distributeAccu=array('H'=>0,'W'=>0);
-               reset($conf);
-               while (list($key,$val)=each($conf))     {
+               foreach ($conf as $key => $val) {
                        $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
                        $GLOBALS['TSFE']->register['count_MENUOBJ']++;
 
@@ -1890,8 +2097,7 @@ class tslib_gmenu extends tslib_menu {
                                $Lobjs = $this->mconf['removeObjectsOfDummy'];
                                if ($Lobjs)     {
                                        $Lobjs = t3lib_div::intExplode(',',$Lobjs);
-                                       reset($Lobjs);
-                                       while(list(,$remItem)=each($Lobjs))     {
+                                       foreach ($Lobjs as $remItem) {
                                                unset($val[$remItem]);
                                                unset($val[$remItem.'.']);
                                        }
@@ -1899,8 +2105,14 @@ class tslib_gmenu extends tslib_menu {
 
                                $flag =0;
                                $tempXY = explode(',',$val['XY']);
-                               if ($Wcounter<$minDim[0])       {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
-                               if ($Hcounter<$minDim[1])       {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
+                               if ($Wcounter<$minDim[0]) {
+                                       $tempXY[0] = $minDim[0] - $Wcounter;
+                                       $flag = 1;
+                               }
+                               if ($Hcounter<$minDim[1]) {
+                                       $tempXY[1] = $minDim[1] - $Hcounter;
+                                       $flag = 1;
+                               }
                                $val['XY'] = implode(',',$tempXY);
                                if (!$flag){break;}
                        }
@@ -1951,8 +2163,14 @@ class tslib_gmenu extends tslib_menu {
                                        // If max dimensions are specified
                                if ($maxDim)    {
                                        $tempXY = explode(',',$val['XY']);
-                                       if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0])     {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
-                                       if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1])     {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
+                                       if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
+                                               $tempXY[0] == $maxDim[0] - $Wcounter;
+                                               $maxFlag = 1;
+                                       }
+                                       if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
+                                               $tempXY[1] = $maxDim[1] - $Hcounter;
+                                               $maxFlag = 1;
+                                       }
                                        if ($maxFlag)   {
                                                $val['XY'] = implode(',',$tempXY);
                                                $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
@@ -1966,8 +2184,7 @@ class tslib_gmenu extends tslib_menu {
 
                                // displace
                                if ($Hobjs)     {
-                                       reset($Hobjs);
-                                       while(list(,$index)=each($Hobjs))       {
+                                       foreach ($Hobjs as $index) {
                                                if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.'])       {
                                                        $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
                                                        $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(0,-$Hcounter)));
@@ -1976,8 +2193,7 @@ class tslib_gmenu extends tslib_menu {
                                }
 
                                if ($Wobjs)     {
-                                       reset($Wobjs);
-                                       while(list(,$index)=each($Wobjs))       {
+                                       foreach ($Wobjs as $index) {
                                                if ($gifCreator->setup[$index] && $gifCreator->setup[$index.'.'])       {
                                                        $oldOffset = explode(',',$gifCreator->setup[$index.'.']['offset']);
                                                        $gifCreator->setup[$index.'.']['offset'] = implode(',',$gifCreator->applyOffset($oldOffset,Array(-$Wcounter,0)));
@@ -2001,12 +2217,14 @@ class tslib_gmenu extends tslib_menu {
                                $gifFileName = $gifCreator->fileName('menu/');
                        }
 
+                       $this->result[$resKey][$key] = $conf[$key];
+
                                // Generation of image file:
-                       if (@file_exists($gifFileName)) {               // File exists
+                       if (file_exists($gifFileName))  {               // File exists
                                $info = @getimagesize($gifFileName);
                                $this->result[$resKey][$key]['output_w']=intval($info[0]);
                                $this->result[$resKey][$key]['output_h']=intval($info[1]);
-                               $this->result[$resKey][$key]['output_file']=$gifFileName;
+                               $this->result[$resKey][$key]['output_file'] = $gifFileName;
                        } elseif ($isGD) {              // file is generated
                                $gifCreator->make();
                                $this->result[$resKey][$key]['output_w']=$gifCreator->w;
@@ -2015,22 +2233,13 @@ class tslib_gmenu extends tslib_menu {
                                $gifCreator->output($this->result[$resKey][$key]['output_file']);
                                $gifCreator->destroy();
                        }
+
                        $this->result[$resKey][$key]['output_file'] = t3lib_div::png_to_gif_by_imagemagick($this->result[$resKey][$key]['output_file']);
-                       $this->result[$resKey][$key]['noLink']=$conf[$key]['noLink'];
-                       $this->result[$resKey][$key]['altTarget']=$conf[$key]['altTarget'];
-                       $this->result[$resKey][$key]['imgParams']=$conf[$key]['imgParams'];
-                       $this->result[$resKey][$key]['ATagTitle'] = $conf[$key]['ATagTitle'];
-                       $this->result[$resKey][$key]['ATagTitle.'] = $conf[$key]['ATagTitle.'];
-                       $this->result[$resKey][$key]['wrap'] = $conf[$key]['wrap'];
-                       $this->result[$resKey][$key]['allWrap'] = $conf[$key]['allWrap'];
-                       $this->result[$resKey][$key]['allWrap.'] = $conf[$key]['allWrap.'];
-                       $this->result[$resKey][$key]['subst_elementUid'] = $conf[$key]['subst_elementUid'];
-                       $this->result[$resKey][$key]['allStdWrap.'] = $conf[$key]['allStdWrap.'];
 
                        $Hcounter+=$this->result[$resKey][$key]['output_h'];            // counter is increased
                        $Wcounter+=$this->result[$resKey][$key]['output_w'];            // counter is increased
 
-                       if ($maxFlag){break;}
+                       if ($maxFlag)   break;
                }
        }
 
@@ -2061,15 +2270,13 @@ class tslib_gmenu extends tslib_menu {
                $Wcounter = 0;
                $c=0;
                $maxFlag=0;
-               reset($conf);
-               while (list($key,$val)=each($conf))     {
+               foreach ($conf as $key => $val) {
                        // SAME CODE AS makeGifs()! BEGIN
                        if ($items==($c+1) && $minDim)  {
                                $Lobjs = $this->mconf['removeObjectsOfDummy'];
                                if ($Lobjs)     {
                                        $Lobjs = t3lib_div::intExplode(',',$Lobjs);
-                                       reset($Lobjs);
-                                       while(list(,$remItem)=each($Lobjs))     {
+                                       foreach ($Lobjs as $remItem) {
                                                unset($val[$remItem]);
                                                unset($val[$remItem.'.']);
                                        }
@@ -2077,8 +2284,14 @@ class tslib_gmenu extends tslib_menu {
 
                                $flag =0;
                                $tempXY = explode(',',$val['XY']);
-                               if ($Wcounter<$minDim[0])       {$tempXY[0]=$minDim[0]-$Wcounter; $flag=1;}
-                               if ($Hcounter<$minDim[1])       {$tempXY[1]=$minDim[1]-$Hcounter; $flag=1;}
+                               if ($Wcounter < $minDim[0]) {
+                                       $tempXY[0] = $minDim[0] - $Wcounter;
+                                       $flag = 1;
+                               }
+                               if ($Hcounter < $minDim[1]) {
+                                       $tempXY[1] = $minDim[1] - $Hcounter;
+                                       $flag = 1;
+                               }
                                $val['XY'] = implode(',',$tempXY);
                                if (!$flag){break;}
                        }
@@ -2089,8 +2302,14 @@ class tslib_gmenu extends tslib_menu {
                        $gifCreator->start($val,$this->menuArr[$key]);
                        if ($maxDim)    {
                                $tempXY = explode(',',$val['XY']);
-                               if ($maxDim[0] && $Wcounter+$gifCreator->XY[0]>=$maxDim[0])     {$tempXY[0]==$maxDim[0]-$Wcounter; $maxFlag=1;}
-                               if ($maxDim[1] && $Hcounter+$gifCreator->XY[1]>=$maxDim[1])     {$tempXY[1]=$maxDim[1]-$Hcounter; $maxFlag=1;}
+                               if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
+                                       $tempXY[0] == $maxDim[0] - $Wcounter;
+                                       $maxFlag = 1;
+                               }
+                               if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
+                                       $tempXY[1] = $maxDim[1] - $Hcounter;
+                                       $maxFlag = 1;
+                               }
                                if ($maxFlag)   {
                                        $val['XY'] = implode(',',$tempXY);
                                        $gifCreator = t3lib_div::makeInstance('tslib_gifBuilder');
@@ -2124,7 +2343,7 @@ class tslib_gmenu extends tslib_menu {
        function writeMenu()    {
                if (is_array($this->menuArr) && is_array($this->result) && count($this->result) && is_array($this->result['NO']))       {
                        $this->WMcObj = t3lib_div::makeInstance('tslib_cObj');  // Create new tslib_cObj for our use
-                       $this->WMresult='';
+                       $this->WMresult = '';
                        $this->INPfixMD5 = substr(md5(microtime().$this->GMENU_fixKey),0,4);
                        $this->WMmenuItems = count($this->result['NO']);
 
@@ -2135,9 +2354,9 @@ class tslib_gmenu extends tslib_menu {
                                if ($this->result['NO'][$key]['output_file'])   {
                                        $this->WMcObj->start($this->menuArr[$key],'pages');             // Initialize the cObj with the page record of the menu item
 
-                                       $this->I =array();
+                                       $this->I = array();
                                        $this->I['key'] = $key;
-                                       $this->I['INPfix']= $this->imgNameNotRandom?'':'_'.$this->INPfixMD5.'_'.$key;
+                                       $this->I['INPfix']= ($this->imgNameNotRandom ? '' : '_'.$this->INPfixMD5).'_'.$key;
                                        $this->I['val'] = $this->result['NO'][$key];
                                        $this->I['title'] = $this->getPageTitle($this->menuArr[$key]['title'],$this->menuArr[$key]['nav_title']);
                                        $this->I['uid'] = $this->menuArr[$key]['uid'];
@@ -2146,12 +2365,26 @@ class tslib_gmenu extends tslib_menu {
                                        $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
                                        if (!$this->I['uid'] && !$this->menuArr[$key]['_OVERRIDE_HREF']) {$this->I['spacer']=1;}
                                        $this->I['noLink'] = ($this->I['spacer'] || $this->I['val']['noLink'] || !count($this->menuArr[$key]));         // !count($this->menuArr[$key]) means that this item is a dummyItem
-                                       $this->I['name']='';
+                                       $this->I['name'] = '';
 
-                                               // Get link.
+                                               // Set access key
+                                       if ($this->mconf['accessKey'])  {
+                                               $this->I['accessKey'] = $this->accessKey($this->I['title']);
+                                       } else {
+                                               $this->I['accessKey'] = array();
+                                       }
+
+                                               // Make link tag
+                                       $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
+                                       if (isset($this->I['val']['additionalParams.'])) {
+                                               $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
+                                       }
                                        $this->I['linkHREF'] = $this->link($key,$this->I['val']['altTarget'],$this->mconf['forceTypeValue']);
+
                                                // Title attribute of links:
-                                       $titleAttrValue = $this->WMcObj->stdWrap($this->I['val']['ATagTitle'],$this->I['val']['ATagTitle.']);
+                                       $titleAttrValue = isset($this->I['val']['ATagTitle.'])
+                                               ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt']
+                                               : $this->I['val']['ATagTitle'].$this->I['accessKey']['alt'];
                                        if (strlen($titleAttrValue))    {
                                                $this->I['linkHREF']['title'] = $titleAttrValue;
                                        }
@@ -2163,24 +2396,18 @@ class tslib_gmenu extends tslib_menu {
                                                // Set rollover
                                        if ($this->result['RO'][$key] && !$this->I['noLink'])   {
                                                $this->I['theName'] = $this->imgNamePrefix.$this->I['uid'].$this->I['INPfix'];
-                                               $this->I['name'] = ' name="'.$this->I["theName"].'"';
+                                               $this->I['name'] = ' '.$this->nameAttribute.'="'.$this->I["theName"].'"';
                                                $this->I['linkHREF']['onMouseover']=$this->WMfreezePrefix.'over(\''.$this->I['theName'].'\');';
                                                $this->I['linkHREF']['onMouseout']=$this->WMfreezePrefix.'out(\''.$this->I['theName'].'\');';
-                                               $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; ';
-                                               $GLOBALS['TSFE']->JSImgCode.= chr(10).$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; ';
+                                               $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_n=new Image(); '.$this->I['theName'].'_n.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'"; ';
+                                               $GLOBALS['TSFE']->JSImgCode.= LF.$this->I['theName'].'_h=new Image(); '.$this->I['theName'].'_h.src = "'.$GLOBALS['TSFE']->absRefPrefix.$this->result['RO'][$key]['output_file'].'"; ';
                                                $GLOBALS['TSFE']->imagesOnPage[]=$this->result['RO'][$key]['output_file'];
                                                $GLOBALS['TSFE']->setJS('mouseOver');
                                                $this->extProc_RO($key);
                                        }
-                                               // Set access key
-                                       if ($this->mconf['accessKey'])  {
-                                               $this->I['accessKey'] = $this->accessKey($this->I['title']);
-                                       } else {
-                                               $this->I['accessKey']=Array();
-                                       }
 
                                                // Set altText
-                                       $this->I['altText'] = $this->mconf['disableAltText'] ? '' : $this->I['title'].$this->I['accessKey']['alt'];
+                                       $this->I['altText'] = $this->I['title'].$this->I['accessKey']['alt'];
 
                                                // Calling extra processing function
                                        $this->extProc_beforeLinking($key);
@@ -2192,7 +2419,7 @@ class tslib_gmenu extends tslib_menu {
                                                $this->I['A1'] = '';
                                                $this->I['A2'] = '';
                                        }
-                                       $this->I['IMG'] = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'" width="'.$this->I['val']['output_w'].'" height="'.$this->I['val']['output_h'].'" border="0" alt="'.htmlspecialchars($this->I['altText']).'"'.$this->I['name'].($this->I['val']['imgParams']?' '.$this->I['val']['imgParams']:'').' />';
+                                       $this->I['IMG'] = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$this->I['val']['output_file'].'" width="'.$this->I['val']['output_w'].'" height="'.$this->I['val']['output_h'].'" '.tslib_cObj::getBorderAttr('border="0"').($this->mconf['disableAltText'] ? '' : ' alt="'.htmlspecialchars($this->I['altText']).'"').$this->I['name'].($this->I['val']['imgParams']?' '.$this->I['val']['imgParams']:'').' />';
 
                                                // Make before, middle and after parts
                                        $this->I['parts'] = array();
@@ -2214,14 +2441,16 @@ class tslib_gmenu extends tslib_menu {
                                        $this->I['theItem']= $this->tmpl->wrap($this->I['theItem'],$this->I['val']['wrap']);
 
                                                // allWrap:
-                                       $allWrap = $this->WMcObj->stdWrap($this->I['val']['allWrap'],$this->I['val']['allWrap.']);
+                                       $allWrap = isset($this->I['val']['allWrap.'])
+                                               ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.'])
+                                               : $this->I['val']['allWrap'];
                                        $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'],$allWrap);
 
                                        if ($this->I['val']['subst_elementUid'])        $this->I['theItem'] = str_replace('{elementUid}',$this->I['uid'],$this->I['theItem']);
 
                                                // allStdWrap:
                                        if (is_array($this->I['val']['allStdWrap.']))   {
-                                               $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'],$this->I['val']['allStdWrap.']);
+                                               $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
                                        }
 
                                        $GLOBALS['TSFE']->imagesOnPage[]=$this->I['val']['output_file'];
@@ -2277,10 +2506,14 @@ class tslib_gmenu extends tslib_menu {
         * @see writeMenu(), tslib_gmenu_layers::extProc_afterLinking(), tslib_menu::subMenu()
         */
        function extProc_afterLinking($key)     {
-               $this->WMresult.=$this->I['theItem'];
+                       // Add part to the accumulated result + fetch submenus
                if (!$this->I['spacer'])        {
-                       $this->WMresult.= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
+                       $this->I['theItem'].= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
                }
+               $part = isset($this->I['val']['wrapItemAndSub.'])
+                       ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.'])
+                       : $this->I['val']['wrapItemAndSub'];
+               $this->WMresult.= $part ? $this->tmpl->wrap($this->I['theItem'],$part) : $this->I['theItem'];
        }
 
 
@@ -2305,6 +2538,10 @@ class tslib_gmenu extends tslib_menu {
         * @see writeMenu(), tslib_gmenu_layers::extProc_finish()
         */
        function extProc_finish()       {
+                       // stdWrap:
+               if (is_array($this->mconf['stdWrap.'])) {
+                       $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
+               }
                return $this->tmpl->wrap($this->WMresult,$this->mconf['wrap']).$this->WMextraScript;
        }
 }
@@ -2333,10 +2570,9 @@ class tslib_gmenu extends tslib_menu {
 /**
  * ImageMap based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=389&cHash=fcf18c5d9f
  */
 class tslib_imgmenu extends tslib_menu {
 
@@ -2352,7 +2588,10 @@ class tslib_imgmenu extends tslib_menu {
                if ($splitCount)        {
                        list($NOconf) = $this->procesItemStates($splitCount);
                }
-               if ($this->mconf['debugItemConf'])      {echo '<h3>$NOconf:</h3>';      debug($NOconf); }
+               if ($this->mconf['debugItemConf']) {
+                       echo '<h3>$NOconf:</h3>';
+                       debug($NOconf);
+               }
                $this->makeImageMap($NOconf);
        }
 
@@ -2384,9 +2623,8 @@ class tslib_imgmenu extends tslib_menu {
                                $lastOriginal = $gifObjCount;
 
                                        // Now we add graphical objects to the gifbuilder-setup
-                               reset($itemsConf);
                                $waArr = Array();
-                               while (list($key,$val)=each($itemsConf))        {
+                               foreach ($itemsConf as $key => $val) {
                                        if (is_array($val))     {
                                                $gifObjCount++;
                                                $waArr[$key]['free']=$gifObjCount;
@@ -2409,7 +2647,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                        unset($theValArr['text.']);     // if this is not done it seems that imageMaps will be rendered wrong!!
                                                                                // check links
 
-                                                                       $LD = $this->tmpl->linkData($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']);
+                                                                       $LD = $this->menuTypoLink($this->menuArr[$key],$this->mconf['target'],'','',array(),'',$this->mconf['forceTypeValue']);
 
                                                                                // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
                                                                        $this->changeLinksForAccessRestrictedPages($LD, $this->menuArr[$key], $this->mconf['target'], $this->mconf['forceTypeValue']);
@@ -2433,13 +2671,17 @@ class tslib_imgmenu extends tslib_menu {
                                                                        if (is_array($theValArr['imgMap.']['altText.']))        {
                                                                                $cObj =t3lib_div::makeInstance('tslib_cObj');
                                                                                $cObj->start($cObjData,'pages');
-                                                                               $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']);
+                                                                               if(isset($theValArr['imgMap.']['altText.'])) {
+                                                                                       $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']);
+                                                                               }
                                                                                unset($theValArr['imgMap.']['altText.']);
                                                                }
                                                                        if (is_array($theValArr['imgMap.']['titleText.']))      {
                                                                                $cObj =t3lib_div::makeInstance('tslib_cObj');
                                                                                $cObj->start($cObjData,'pages');
-                                                                               $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']);
+                                                                               if(isset($theValArr['imgMap.']['titleText.'])) {
+                                                                                       $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']);
+                                                                               }
                                                                                unset($theValArr['imgMap.']['titleText.']);
                                                                        }
                                                                }
@@ -2447,8 +2689,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                if ($theValue=='IMAGE') {
                                                                        if ($theValArr['file']=='GIFBUILDER')   {
                                                                                $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['file.']);
-                                                                               reset($temp_sKeyArray);
-                                                                               while(list(,$temp_theKey)=each($temp_sKeyArray))        {
+                                                                               foreach ($temp_sKeyArray as $temp_theKey) {
                                                                                        if ($theValArr['mask.'][$temp_theKey]=='TEXT')  {
                                                                                                $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
                                                                                                $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
@@ -2458,8 +2699,7 @@ class tslib_imgmenu extends tslib_menu {
                                                                        }
                                                                        if ($theValArr['mask']=='GIFBUILDER')   {
                                                                                $temp_sKeyArray=t3lib_TStemplate::sortedKeyList($theValArr['mask.']);
-                                                                               reset($temp_sKeyArray);
-                                                                               while(list(,$temp_theKey)=each($temp_sKeyArray))        {
+                                                                               foreach ($temp_sKeyArray as $temp_theKey) {
                                                                                        if ($theValArr['mask.'][$temp_theKey]=='TEXT')  {
                                                                                                $gifCreator->data = $this->menuArr[$key] ? $this->menuArr[$key] : Array();
                                                                                                $theValArr['mask.'][$temp_theKey.'.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey.'.']);
@@ -2493,9 +2733,8 @@ class tslib_imgmenu extends tslib_menu {
                                        // calculations
 
                                $sum=Array(0,0,0,0);
-                               reset($waArr);
-                               while (list($key,$val)=each($waArr))    {
-                                       if ($dConf[$key] =$itemsConf[$key]['distrib'])  {
+                               foreach ($waArr as $key => $val) {
+                                       if (($dConf[$key] = $itemsConf[$key]['distrib'])) {
                                                $textBB = $gifCreator->objBB[$val['textNum']];
                                                $dConf[$key] = str_replace('textX',$textBB[0],$dConf[$key]);
                                                $dConf[$key] = str_replace('textY',$textBB[1],$dConf[$key]);
@@ -2503,8 +2742,7 @@ class tslib_imgmenu extends tslib_menu {
                                        }
                                }
                                $workArea = t3lib_div::intExplode(',',$gifCreator->calcOffset($this->mconf['dWorkArea']));
-                               reset($waArr);
-                               while (list($key,$val)=each($waArr))    {
+                               foreach ($waArr as $key => $val) {
                                        $index = $val['free'];
                                        $gifCreator->setup[$index] = 'WORKAREA';
                                        $workArea[2] = $dConf[$key][2] ? $dConf[$key][2] : $dConf[$key][0];
@@ -2515,16 +2753,19 @@ class tslib_imgmenu extends tslib_menu {
                                        $workArea[1]+=$dConf[$key][1];
                                }
 
-                               if ($this->mconf['debugRenumberedObject'])      {echo '<h3>Renumbered GIFBUILDER object:</h3>'; debug($gifCreator->setup);}
+                               if ($this->mconf['debugRenumberedObject']) {
+                                       echo '<h3>Renumbered GIFBUILDER object:</h3>';
+                                       debug($gifCreator->setup);
+                               }
 
                                $gifCreator->createTempSubDir('menu/');
                                $gifFileName = $gifCreator->fileName('menu/');
 
                                        // Gets the ImageMap from the cache...
                                $imgHash = md5($gifFileName);
-                               $imgMap = $this->sys_page->getHash($imgHash, 0);
+                               $imgMap = $this->sys_page->getHash($imgHash);
 
-                               if ($imgMap && @file_exists($gifFileName))      {               // File exists
+                               if ($imgMap && file_exists($gifFileName))       {               // File exists
                                        $info = @getimagesize($gifFileName);
                                        $w=$info[0];
                                        $h=$info[1];
@@ -2535,7 +2776,7 @@ class tslib_imgmenu extends tslib_menu {
                                        $gifCreator->output($gifFileName);
                                        $gifCreator->destroy();
                                        $imgMap=$gifCreator->map;
-                                       $this->sys_page->storeHash($imgHash, $imgMap, 'MENU IMAGEMAP');
+                                       $this->sys_page->storeHash($imgHash, $imgMap, 'MENUIMAGEMAP');
                                }
                                $imgMap.=$this->mconf['imgMapExtras'];
 
@@ -2547,13 +2788,13 @@ class tslib_imgmenu extends tslib_menu {
 
        /**
         * Returns the HTML for the image map menu.
-        * If ->result is true it will create the HTML for the image map menu.
+        * If ->result is TRUE it will create the HTML for the image map menu.
         *
         * @return      string          The HTML for the menu
         */
        function writeMenu()    {
                if ($this->result)      {
-                       $res = $this->result;
+                       $res = &$this->result;
                        $menuName = 'menu_'.t3lib_div::shortMD5($res['imgMap']);        // shortMD5 260900
                        $result = '<img src="'.$GLOBALS['TSFE']->absRefPrefix.$res['output_file'].'" width="'.$res['output_w'].'" height="'.$res['output_h'].'" usemap="#'.$menuName.'" border="0" '.$this->mconf['params'];
                        if (!strstr($result,'alt="'))   $result.=' alt="Menu Image Map"';       // Adding alt attribute if not set.
@@ -2589,10 +2830,9 @@ class tslib_imgmenu extends tslib_menu {
 /**
  * JavaScript/Selectorbox based menus
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage tslib
- * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=391&cHash=563435abbc
  */
 class tslib_jsmenu extends tslib_menu {
 
@@ -2612,17 +2852,18 @@ class tslib_jsmenu extends tslib_menu {
        function writeMenu()    {
                if ($this->id)  {
                                // Making levels:
-                       $levels = t3lib_div::intInRange($this->mconf['levels'],1,5);
+                       $levels = t3lib_utility_Math::forceIntegerInRange($this->mconf['levels'],1,5);
                        $this->levels = $levels;
-                       $this->JSVarName='eid';
-                       $this->JSMenuName= $this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu';
+                       $uniqueParam = t3lib_div::shortMD5(microtime(), 5);
+                       $this->JSVarName = 'eid' . $uniqueParam;
+                       $this->JSMenuName = ($this->mconf['menuName'] ? $this->mconf['menuName'] : 'JSmenu' . $uniqueParam);
 
                        $JScode="\n var ".$this->JSMenuName." = new JSmenu(".$levels.",'".$this->JSMenuName."Form');";
 
                        for ($a=1;$a<=$levels;$a++)     {
                                $JScode.="\n var ".$this->JSVarName.$a."=0;";
                        }
-                       $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array)."\n";
+                       $JScode.= $this->generate_level($levels,1,$this->id,$this->menuArr,$this->MP_array).LF;
 
                        $GLOBALS['TSFE']->additionalHeaderData['JSMenuCode']='<script type="text/javascript" src="'.$GLOBALS['TSFE']->absRefPrefix.'t3lib/jsfunc.menu.js"></script>';
                        $GLOBALS['TSFE']->JSCode.=$JScode;
@@ -2680,15 +2921,8 @@ class tslib_jsmenu extends tslib_menu {
                        $pid = $mount_info['mount_pid'];
                }
 
-                       // Set "&MP=" var:
-               $MP_var = implode(',',$MP_array);
-               $MP_params = $MP_var ? '&MP='.rawurlencode($MP_var) : '';
-
                        // UIDs to ban:
-               $banUidArray=array();
-               if (trim($this->conf['excludeUidList']))        {
-                       $banUidArray = t3lib_div::intExplode(',', $this->conf['excludeUidList']);
-               }
+               $banUidArray = $this->getBannedUids();
 
                        // Initializing variables:
                $var = $this->JSVarName;
@@ -2696,40 +2930,52 @@ class tslib_jsmenu extends tslib_menu {
                $parent = $count==1 ? 0 : $var.($count-1);
                $prev=0;
                $c=0;
+               $codeLines = '';
 
                $menuItems = is_array($menuItemArray) ? $menuItemArray : $this->sys_page->getMenu($pid);
                foreach($menuItems as $uid => $data)    {
+
+                               // $data['_MP_PARAM'] contains MP param for overlay mount points (MPs with "substitute this page" set)
+                               // if present: add param to copy of MP array (copy used for that submenu branch only)
+                       $MP_array_sub = $MP_array;
+                       if (array_key_exists('_MP_PARAM', $data) && $data['_MP_PARAM']) {
+                               $MP_array_sub[] = $data['_MP_PARAM'];
+                       }
+                               // Set "&MP=" var:
+                       $MP_var = implode(',', $MP_array_sub);
+                       $MP_params = ($MP_var ? '&MP='.rawurlencode($MP_var) : '');
+
                        $spacer = (t3lib_div::inList($this->spacerIDList,$data['doktype'])?1:0);                // if item is a spacer, $spacer is set
                        if ($this->mconf['SPC'] || !$spacer)    {       // If the spacer-function is not enabled, spacers will not enter the $menuArr
-                               if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']) && !$data['nav_hide'] && !t3lib_div::inArray($banUidArray,$uid))     {               // Page may not be 'not_in_menu' or 'Backend User Section' + not in banned uid's
+                               if (!t3lib_div::inList($this->doktypeExcludeList,$data['doktype']) && (!$data['nav_hide'] || $this->conf['includeNotInMenu']) && !t3lib_div::inArray($banUidArray,$uid))        {               // Page may not be 'not_in_menu' or 'Backend User Section' + not in banned uid's
                                        if ($count<$levels)     {
-                                               $addLines = $this->generate_level($levels,$count+1,$data['uid'],'',$MP_array);
+                                               $addLines = $this->generate_level($levels, $count+1, $data['uid'], '', $MP_array_sub);
                                        } else {
                                                $addLines = '';
                                        }
-                                       $title=rawurlencode($data['title']);
+                                       $title=$data['title'];
                                        $url='';
                                        $target='';
                                        if ((!$addLines && !$levelConf['noLink']) || $levelConf['alwaysLink']) {
-                                               $LD = $this->tmpl->linkData($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
+                                               $LD = $this->menuTypoLink($data,$this->mconf['target'],'','',array(),$MP_params,$this->mconf['forceTypeValue']);
 
                                                        // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page:
                                                $this->changeLinksForAccessRestrictedPages($LD, $data, $this->mconf['target'], $this->mconf['forceTypeValue']);
 
-                                               $url = rawurlencode($LD['totalURL']);
-                                               $target = rawurlencode($LD['target']);
+                                               $url = $GLOBALS['TSFE']->baseUrlWrap($LD['totalURL']);
+                                               $target = $LD['target'];
                                        }
-                                       $codeLines.="\n".$var.$count."=".$menuName.".add(".$parent.",".$prev.",0,'".$title."','".$GLOBALS['TSFE']->baseUrlWrap($url)."','".$target."');";
+                                       $codeLines .= LF . $var . $count . '=' . $menuName . '.add(' . $parent . ',' . $prev . ',0,' . t3lib_div::quoteJSvalue($title, TRUE) . ',' . t3lib_div::quoteJSvalue($url, TRUE) . ',' . t3lib_div::quoteJSvalue($target, TRUE) . ');';
                                                // If the active one should be chosen...
-                                       $active = ($levelConf['showActive'] && $data['uid'] == $this->tmpl->rootLine[$count]['uid']);
+                                       $active = ($levelConf['showActive'] && $this->isActive($data['uid'], $MP_var));
                                                // If the first item should be shown
                                        $first = (!$c && $levelConf['showFirst']);
                                                // do it...
                                        if ($active || $first)  {
                                                if ($count==1)  {
-                                                       $codeLines.="\n".$menuName.".openID = ".$var.$count.";";
+                                                       $codeLines.=LF.$menuName.".openID = ".$var.$count.";";
                                                } else {
-                                                       $codeLines.="\n".$menuName.".entry[".$parent."].openID = ".$var.$count.";";
+                                                       $codeLines.=LF.$menuName.".entry[".$parent."].openID = ".$var.$count.";";
                                                }
                                        }
                                                // Add submenu...
@@ -2744,15 +2990,15 @@ class tslib_jsmenu extends tslib_menu {
                        $levelConf['firstLabel'] = $this->mconf['firstLabelGeneral'];
                }
                if ($levelConf['firstLabel'] && $codeLines)     {
-                       $codeLines.="\n".$menuName.".defTopTitle[".$count."] = unescape('".rawurlencode($levelConf['firstLabel'])."');";
+                       $codeLines.= LF.$menuName.'.defTopTitle['.$count.'] = '.t3lib_div::quoteJSvalue($levelConf['firstLabel'], TRUE).';';
                }
                return $codeLines;
        }
 }
 
 
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php'])     {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
 }
 
 ?>
\ No newline at end of file