public static function googleCanonicalize($url)
  {
  
    // First, remove tab (0x09), CR (0x0d), and LF (0x0a) characters from the URL. Do not remove escape sequences for these characters (e.g. '%0a').
    $url=preg_replace('#[\x09\x0d\x0a]#', '', $url);
    
    $url=self::makeRFC2396Valid(trim($url));
    if(is_null($url)){
      // unable to parse url
      return null;
    }
    
    // Next, repeatedly percent-unescape the URL until it has no more percent-escapes.
    $url=self::percentUnEscape($url);
    // fixme: unescaped %23 are not handled correctly
    
    // parse the url into parts
    $parsed_url=parse_url($url);
    // check parsed url
    if($parsed_url===false){
      // unable to parse url
      return null;
    }
    if(!isset($parsed_url['host'])){
      // without host, we cannot do anything
      return null;
    }
    // now create our url parts:
    $scheme=$parsed_url['scheme'].'://';
    $hostname=$parsed_url['host'];
    $hostname=strtolower($hostname);
    $hostname=preg_replace('#(\.+)?(.*?)(\.+)?$#', '$2', $hostname);
    // todo: handle ip address conversions
    // is it IPv4 in decimal?
    if(preg_match('/^[0-9]+$/',$hostname)){
      // ok its a number
      // lets see if its in the 32bit range
      $ip4_hex=base_convert($hostname, 10, 16);
      if(strlen($ip4_hex)<=8){
        // ok, hex representation is less than 9 chars, so thats max FFFFFFFF
        // convert to decimal dotted
        // first make sure its 8 chars hex
        $ip4_hex=str_pad($ip4_hex , 8, "0", STR_PAD_LEFT);
        $ip4_dec_arr=array();
        foreach(str_split($ip4_hex,2) as $octet){
          $ip4_dec_arr[]=base_convert($octet, 16, 10);
        }
        $hostname=implode('.', $ip4_dec_arr);
      }
    }
    $port='';
    if(isset($parsed_url['port'])){
      $port=':'.$parsed_url['port'];
    }
    // The sequences "/../" and "/./" in the path should be resolved by replacing "/./" with "/", and removing "/../" along with the preceding path component.
    $path=preg_replace('#/\.(/|$)#', '/', $parsed_url['path']);
    $path=preg_replace('#/[^/]+/\.\.(/|$)#', '/', $path);
    // Replace runs of consecutive slashes with a single slash character
    $path=preg_replace('#/+#', '/', $path);
    $query='';
    if(isset($parsed_url['query'])){
      $query='?'.$parsed_url['query'];
    }
    // fixme: empty queries (only the questionmark) are not handled correctly, the questionmark is lost
    return self::googlePercentEscape($scheme.$hostname.$port.$path.$query);
  }