code: func sendHttp(apiKey string, m HttpMessage, c httpClient, b backoffProvider) (*HttpResponse, error) {
  	// TODO(silvano): check this with responses for topic/notification group
  	gcmResp := &HttpResponse{}
  	var multicastId int
  	targets, err := messageTargetAsStringsArray(m)
  	if err != nil {
  		return gcmResp, fmt.Errorf("error extracting target from message: %v", err)
  	}
  	// make a copy of the targets to keep track of results during retries
  	localTo := make([]string, len(targets))
  	copy(localTo, targets)
  	resultsState := &multicastResultsState{}
  	for b.sendAnother() {
  		gcmResp, err = c.send(apiKey, m)
  		if err != nil {
  			return gcmResp, fmt.Errorf("error sending request to GCM HTTP server: %v", err)
  		}
  		if len(gcmResp.Results) > 0 {
  			doRetry, toRetry, err := checkResults(gcmResp.Results, localTo, *resultsState)
  			multicastId = gcmResp.MulticastId
  			if err != nil {
  				return gcmResp, fmt.Errorf("error checking GCM results: %v", err)
  			}
  			if doRetry {
  				retryAfter, err := time.ParseDuration(c.getRetryAfter())
  				if err != nil {
  					b.setMin(retryAfter)
  				}
  				localTo = make([]string, len(toRetry))
  				copy(localTo, toRetry)
  				if m.RegistrationIds != nil {
  					m.RegistrationIds = toRetry
  				}
  				b.wait()
  				continue
  			} else {
  				break
  			}
  		} else {
  			break
  		}
  	}
  	// if it was multicast, reconstruct response in case there have been retries
  	if len(targets) > 1 {
  		gcmResp = buildRespForMulticast(targets, *resultsState, multicastId)
  	}
  	return gcmResp, nil
  }
docs: // sendHttp sends an http message using exponential backoff, handling multicast replies.