public static function buildURLFromLink($link, PHPCrawlerUrlPartsDescriptor $BaseUrl)
  { 
    $url_parts = $BaseUrl->toArray();
    
    // Dedoce HTML-entities
    $link = PHPCrawlerEncodingUtils::decodeHtmlEntities($link);
    
    // Remove anchor ("#..."), but ONLY at the end, not if # is at the beginning !
    $link = preg_replace("/^(.{1,})#.{0,}$/", "\\1", $link);

    // Cases
    
    // Strange link like "//foo.htm" -> make it to "http://foo.html"
    if (substr($link, 0, 2) == "//")
    {
      $link = "http:".$link;
    }
   
    // 1. relative link starts with "/" --> doc_root
    // "/index.html" -> "http://www.foo.com/index.html"    
    elseif (substr($link,0,1)=="/")
    {
      $link = $url_parts["protocol"].$url_parts["host"].":".$url_parts["port"].$link;
    }
     
     // 2. "./foo.htm" -> "foo.htm"
     elseif (substr($link,0,2)=="./")
     {
       $link=$url_parts["protocol"].$url_parts["host"].":".$url_parts["port"].$url_parts["path"].substr($link, 2);
     }
     
     // 3. Link is an absolute Link with a given protocol and host (f.e. "http://..." or "android-app://...)
     // DO NOTHING
     elseif (preg_match("#^[a-z0-9-]{1,}(:\/\/)# i", $link))
     {
       $link = $link;
     }
     
     // 4. Link is stuff like "javascript: ..." or something
     elseif (preg_match("/^[a-zA-Z]{0,}:[^\/]{0,1}/", $link))
     {
       $link = "";
     }
    
     // 5. "../../foo.html" -> remove the last path from our actual path
     // and remove "../" from link at the same time until there are
     // no more "../" at the beginning of the link
     elseif (substr($link, 0, 3)=="../")
     {
       $new_path = $url_parts["path"];
       
       while (substr($link, 0, 3) == "../")
       {
         $new_path = preg_replace('/\/[^\/]{0,}\/$/',"/", $new_path);
         $link  = substr($link, 3);
       }
       
       $link = $url_parts["protocol"].$url_parts["host"].":".$url_parts["port"].$new_path.$link;
     }
     
     // 6. link starts with #
     // -> leads to the same site as we are on, trash
     elseif (substr($link,0,1) == "#")
     {
       $link="";
     }
     
     // 7. link starts with "?"
     elseif (substr($link,0,1)=="?")
     {
       $link = $url_parts["protocol"].$url_parts["host"].":".$url_parts["port"].$url_parts["path"].$url_parts["file"].$link;
     }
    
     // 7. thats it, else the abs_path is simply PATH.LINK ...
     else
     { 
       $link = $url_parts["protocol"].$url_parts["host"].":".$url_parts["port"].$url_parts["path"].$link;
     }
     
     if ($link == "") return null;

     // Now, at least, replace all HTMLENTITIES with normal text.
     // I.E.: HTML-Code of the link is: <a href="index.php?x=1&amp;y=2">
     // -> Link has to be "index.php?x=1&y=2"
     //$link = PHPCrawlerEncodingUtils::decodeHtmlEntities($link);

     // Replace linebreaks in the link with "" (happens if a link in the sourcecode
     // linebreaks)
     $link = str_replace(array("\n", "\r"), "", $link);
     
     // "Normalize" URL
     $link = self::normalizeUrl($link);
      
     return $link;
  }