code: func Crawl(url string, depth int, fetcher Fetcher) {
  	if depth <= 0 {
  		fmt.Printf("<- Done with %v, depth 0.\n", url)
  		return
  	}
  
  	fetched.Lock()
  	if _, ok := fetched.m[url]; ok {
  		fetched.Unlock()
  		fmt.Printf("<- Done with %v, already fetched.\n", url)
  		return
  	}
  	// We mark the url to be loading to avoid others reloading it at the same time.
  	fetched.m[url] = loading
  	fetched.Unlock()
  
  	// We load it concurrently.
  	body, urls, err := fetcher.Fetch(url)
  
  	// And update the status in a synced zone.
  	fetched.Lock()
  	fetched.m[url] = err
  	fetched.Unlock()
  
  	if err != nil {
  		fmt.Printf("<- Error on %v: %v\n", url, err)
  		return
  	}
  	fmt.Printf("Found: %s %q\n", url, body)
  	done := make(chan bool)
  	for i, u := range urls {
  		fmt.Printf("-> Crawling child %v/%v of %v : %v.\n", i, len(urls), url, u)
  		go func(url string) {
  			Crawl(url, depth-1, fetcher)
  			done <- true
  		}(u)
  	}
  	for i, u := range urls {
  		fmt.Printf("<- [%v] %v/%v Waiting for child %v.\n", url, i, len(urls), u)
  		<-done
  	}
  	fmt.Printf("<- Done with %v\n", url)
  }
docs: // Crawl uses fetcher to recursively crawl
  // pages starting with url, to a maximum of depth.