code: func (u *Untar) Extract() error {
  	// check for detect mode before the main setup, we'll change compression
  	// to the intended type and setup a new reader to re-read the header
  	switch u.Compression {
  	case NONE:
  		u.archive = tar.NewReader(u.source)
  
  	case DETECT:
  		arch, err := DetectArchiveCompression(u.source)
  		if err != nil {
  			return err
  		}
  		u.archive = arch
  
  	default:
  		// Look up the compression handler
  		comp, exists := decompressorTypes[string(u.Compression)]
  		if !exists {
  			return fmt.Errorf("unrecognized decompression type %q", u.Compression)
  		}
  
  		// Create the reader
  		arch, err := comp.NewReader(u.source)
  		if err != nil {
  			return err
  		}
  		defer func() {
  			if cl, ok := arch.(io.ReadCloser); ok {
  				cl.Close()
  			}
  		}()
  		u.archive = tar.NewReader(arch)
  	}
  
  	for {
  		header, err := u.archive.Next()
  		if err == io.EOF {
  			// EOF, ok, break to return
  			break
  		}
  		if err != nil {
  			// See note on logging above.
  			return err
  		}
  
  		err = u.processEntry(header)
  		if err != nil {
  			// See note on logging above.
  			return err
  		}
  	}
  
  	return nil
  }
docs: // Extract unpacks the tar reader that was passed into New(). This is
  // broken out from new to give the caller time to set various
  // settings in the Untar object.