static function discover($uri, $fetcher,
                      $extra_ns_map = null, $timeout = 20)
    {
        $result = new Auth_Yadis_DiscoveryResult($uri);

        $headers = array("Accept: " . Auth_Yadis_CONTENT_TYPE .
                         ', text/html; q=0.3, application/xhtml+xml; q=0.5');

        if ($fetcher === null) {
            $fetcher = Auth_Yadis_Yadis::getHTTPFetcher($timeout);
        }

        $response = $fetcher->get($uri, $headers);

        if (!$response || ($response->status != 200 and
                           $response->status != 206)) {
            $result->fail();
            return $result;
        }

        $result->normalized_uri = $response->final_url;
        $result->content_type = Auth_Yadis_Yadis::_getHeader(
                                       $response->headers,
                                       array('content-type'));

        if ($result->content_type &&
            (Auth_Yadis_Yadis::_getContentType($result->content_type) ==
             Auth_Yadis_CONTENT_TYPE)) {
            $result->xrds_uri = $result->normalized_uri;
        } else {
            $yadis_location = Auth_Yadis_Yadis::_getHeader(
                                                 $response->headers,
                                                 array(Auth_Yadis_HEADER_NAME));

            if (!$yadis_location) {
                $parser = new Auth_Yadis_ParseHTML();
                $yadis_location = $parser->getHTTPEquiv($response->body);
            }

            if ($yadis_location) {
                $result->xrds_uri = $yadis_location;

                $response = $fetcher->get($yadis_location);

                if ((!$response) || ($response->status != 200 and
                                     $response->status != 206)) {
                    $result->fail();
                    return $result;
                }

                $result->content_type = Auth_Yadis_Yadis::_getHeader(
                                                         $response->headers,
                                                         array('content-type'));
            }
        }

        $result->response_text = $response->body;
        return $result;
    }