protected function _loadRootCats()
    {
        if ($this->_aCatLvlCache === null) {
            $this->_aCatLvlCache = [];

            $sCatView = getViewName('oxcategories');
            $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();

            // Load all root cat's == all trees
            $sSQL = "select oxid from $sCatView where oxparentid = 'oxrootid'";
            $oRs = $oDb->select($sSQL);
            if ($oRs != false && $oRs->count() > 0) {
                while (!$oRs->EOF) {
                    // now load each tree
                    $sSQL = "SELECT s.oxid, s.oxtitle,
                             s.oxparentid, count( * ) AS LEVEL FROM $sCatView v,
                             $sCatView s WHERE s.oxrootid = '" . $oRs->fields[0] . "' and
                             v.oxrootid='" . $oRs->fields[0] . "' and s.oxleft BETWEEN
                             v.oxleft AND v.oxright AND s.oxhidden = '0' GROUP BY s.oxleft order by level";

                    $oRs2 = $oDb->select($sSQL);
                    if ($oRs2 != false && $oRs2->count() > 0) {
                        while (!$oRs2->EOF) {
                            // store it
                            $oCat = new stdClass();
                            $oCat->_sOXID = $oRs2->fields[0];
                            $oCat->oxtitle = $oRs2->fields[1];
                            $oCat->oxparentid = $oRs2->fields[2];
                            $oCat->ilevel = $oRs2->fields[3];
                            $this->_aCatLvlCache[$oCat->_sOXID] = $oCat;

                            $oRs2->fetchRow();
                        }
                    }
                    $oRs->fetchRow();
                }
            }
        }

        return $this->_aCatLvlCache;
    }