public static function makeRFC2396Valid($url)
  {
    // parse the url into parts
    $parsed_url=@parse_url($url);
    // check parsed url
    if($parsed_url===false){
      // unable to parse url
      return null;
    }
    // when no scheme present, parse_url may go haywire
    if(!isset($parsed_url['scheme'])){
      // if its any kind of relative url. we are not interested and we should return null
      
      // check if its only a fragment (starting with #)
      if(preg_match('/^#/',$url)){
        // yep, fragment
        return null;
      }
      
      // check if it starts with a path (/some/path)
      if(preg_match('#^/[^/]#',$url)){
        // starts with / (but not //)
        return null;
      }
      
      // check if starts with //
      if(preg_match('#^//[^/]#',$url)){
        // okay it starts with // (but not ///), so turn it into http://
        $parsed_url=@parse_url('http:'.$url);
      }else{
        // okay, it doesnt have a scheme, but lets add one as it possibly could be an url
        $parsed_url=@parse_url('http://'.$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='http://';
    if(isset($parsed_url['scheme'])){
      $scheme=$parsed_url['scheme'].'://';
    }
    $hostname=$parsed_url['host'];
    // todo: If the URL uses an internationalized domain name (IDN) it should be converted to the ASCII Punycode representation.
    $port='';
    if(isset($parsed_url['port'])){
      $port=':'.$parsed_url['port'];
    }
    $path='/';
    if(isset($parsed_url['path'])){
      // actually path should always exist
      $path=$parsed_url['path'];
    }
    $query='';
    if(isset($parsed_url['query'])){
      $query='?'.$parsed_url['query'];
    }
    $fragment='';
    if(isset($parsed_url['fragment'])){
      $fragment='#'.$parsed_url['fragment'];
    }
    return $scheme.$hostname.$port.$path.$query.$fragment;
  }