protected function detectCanonicalPage(array $tsConfig = array())
    {
        #####################
        # Fetch typoscript config
        #####################
        $strictMode = (bool)(int)$tsConfig['strict'];
        $noMpMode   = (bool)(int)$tsConfig['noMP'];
        $linkConf   = !empty($tsConfig['typolink.']) ? $tsConfig['typolink.'] : array();
        $blacklist  = !empty($tsConfig['blacklist.']) ? $tsConfig['blacklist.'] : array();

        $linkParam  = null;
        $linkMpMode = false;

        // Init link configuration
        if ($linkConf === null) {
            $linkConf = array();
        }

        // Fetch chash
        $pageHash = null;
        if (!empty($GLOBALS['TSFE']->cHash)) {
            $pageHash = $GLOBALS['TSFE']->cHash;
        }

        #####################
        # Blacklisting
        #####################
        if (FrontendUtility::checkPageForBlacklist($blacklist)) {
            if ($strictMode) {
                if ($noMpMode && GeneralUtility::isMountpointInRootLine()) {
                    // Mountpoint detected
                    $linkParam = $GLOBALS['TSFE']->id;

                    // Force removing of MP param
                    $linkConf['addQueryString'] = 1;
                    if (!empty($linkConf['addQueryString.']['exclude'])) {
                        $linkConf['addQueryString.']['exclude'] .= ',id,MP,no_cache';
                    } else {
                        $linkConf['addQueryString.']['exclude'] = ',id,MP,no_cache';
                    }

                    // disable mount point linking
                    $linkMpMode = true;
                } else {
                    // force canonical-url to page url (without any parameters)
                    $linkParam = $GLOBALS['TSFE']->id;
                }
            } else {
                // Blacklisted and no strict mode, we don't output canonical tag
                return null;
            }
        }

        #####################
        # No cached pages
        #####################

        if (!empty($GLOBALS['TSFE']->no_cache)) {
            if ($strictMode) {
                // force canonical-url to page url (without any parameters)
                $linkParam = $GLOBALS['TSFE']->id;
            }
        }

        #####################
        # Content from PID
        #####################

        if (!$linkParam && !empty($this->cObj->data['content_from_pid'])) {
            $linkParam = $this->cObj->data['content_from_pid'];
        }

        #####################
        # Mountpoint
        #####################

        if (!$linkParam && $noMpMode && GeneralUtility::isMountpointInRootLine()) {
            // Mountpoint detected
            $linkParam = $GLOBALS['TSFE']->id;

            // Force removing of MP param
            $linkConf['addQueryString'] = 1;
            if (!empty($linkConf['addQueryString.']['exclude'])) {
                $linkConf['addQueryString.']['exclude'] .= ',id,MP,no_cache';
            } else {
                $linkConf['addQueryString.']['exclude'] = ',id,MP,no_cache';
            }

            // disable mount point linking
            $linkMpMode = true;
        }

        #####################
        # Normal page
        #####################

        if (!$linkParam) {
            // Fetch pageUrl
            if ($pageHash !== null) {
                // Virtual plugin page, we have to use anchor or site script
                $linkParam = FrontendUtility::getCurrentUrl();
            } else {
                $linkParam = $GLOBALS['TSFE']->id;
            }
        }

        #####################
        # Fallback
        #####################

        if ($strictMode && empty($linkParam)) {
            $linkParam = $GLOBALS['TSFE']->id;
        }

        return array($linkParam, $linkConf, $linkMpMode);
    }