/**
  * 
  * @param string $referenceUrl
  * @param string $requestedUrl
  * @param bool $requestedUrlIsDir
  * @return bool
  */
 protected static function impliesUrl($referenceUrl, $requestedUrl)
 {
     $refUrlParts = AdvancedPathLib::parse_url($referenceUrl);
     $requestedUrlParts = AdvancedPathLib::parse_url($requestedUrl);
     // schemes must match
     if ($refUrlParts['scheme'] != $requestedUrlParts['scheme']) {
         return false;
     }
     // hosts must match (except if reference host is "*")
     // TODO: add ability to provide a partial host (e.g. "*.eyeos.org")
     if (isset($refUrlParts['host'])) {
         if ($refUrlParts['host'] != self::WILD_CHAR) {
             if (!isset($requestedUrlParts['host']) || $refUrlParts['host'] != $requestedUrlParts['host']) {
                 return false;
             }
         }
     }
     // initialize reference URL
     $referenceIsDirectory = false;
     $referenceIsRecursive = false;
     $refCanonicalPath = AdvancedPathLib::getCanonicalPath($refUrlParts['path']);
     //var_dump('$refCanonicalPath: ' . $refCanonicalPath);
     // analyze reference URL (directory? recursive?)
     $length = utf8_strlen($refCanonicalPath);
     $lastChar = $length > 0 ? utf8_substr($refCanonicalPath, -1) : 0;
     $lastCharButOneIdx = $length > 0 ? utf8_substr($refCanonicalPath, -2, 1) : 0;
     if ($lastChar == self::RECURSIVE_CHAR && $lastCharButOneIdx == '/') {
         $referenceIsDirectory = true;
         $referenceIsRecursive = true;
         $refCanonicalPath = utf8_substr($refCanonicalPath, 0, -1);
     } elseif ($lastChar == self::WILD_CHAR && $lastCharButOneIdx == '/') {
         $referenceIsDirectory = true;
         $referenceIsRecursive = utf8_substr($refCanonicalPath, 0, -1);
     }
     // initialize requested URL
     $canonicalPath = AdvancedPathLib::getCanonicalPath($requestedUrlParts['path']);
     //var_dump($canonicalPath . ' ### ' . $refCanonicalPath);
     //var_dump('refIsDir: ' . ($referenceIsDirectory ? 'true' : 'false'));
     //var_dump('refIsRecursive: ' . ($referenceIsRecursive ? 'true' : 'false'));
     // check implication
     $implies = false;
     if ($referenceIsDirectory) {
         if ($referenceIsRecursive) {
             $implies = utf8_strlen($canonicalPath) > utf8_strlen($refCanonicalPath) && ($canonicalPath == $refCanonicalPath || utf8_strpos($canonicalPath, $refCanonicalPath) === 0);
         } else {
             $lastSeparatorIdx = utf8_strrpos($canonicalPath, '/');
             if ($lastSeparatorIdx === false) {
                 $implies = false;
             } else {
                 $implies = utf8_strlen($refCanonicalPath) == $lastSeparatorIdx + 1 && utf8_substr($refCanonicalPath, 0, $lastSeparatorIdx + 1) == utf8_substr($canonicalPath, 0, $lastSeparatorIdx + 1);
             }
         }
     } else {
         $implies = $refCanonicalPath == $canonicalPath;
     }
     //var_dump('$implies= ' . ($implies? 'true' : 'false'));
     return $implies;
 }