code: func (d *dynProviderState) ApplyChanges(changes *plan.Changes) error {
  	log.Debugf("Processing chages: %+v", changes)
  
  	if d.DryRun {
  		log.Infof("Will NOT delete these records: %+v", changes.Delete)
  		log.Infof("Will NOT create these records: %+v", changes.Create)
  		log.Infof("Will NOT update these records: %+v", merge(changes.UpdateOld, changes.UpdateNew))
  		return nil
  	}
  
  	client, err := d.login()
  	if err != nil {
  		return err
  	}
  	defer client.Logout()
  
  	var errs []error
  
  	needsCommit := false
  
  	for _, ep := range changes.Delete {
  		err := d.deleteRecord(client, ep)
  		if err != nil {
  			errs = append(errs, err)
  		} else {
  			needsCommit = true
  		}
  	}
  
  	for _, ep := range changes.Create {
  		err := d.createRecord(client, ep)
  		if err != nil {
  			errs = append(errs, err)
  		} else {
  			needsCommit = true
  		}
  	}
  
  	updates := merge(changes.UpdateOld, changes.UpdateNew)
  	log.Debugf("Updates after merging: %+v", updates)
  	for _, ep := range updates {
  		err := d.replaceRecord(client, ep)
  		if err != nil {
  			errs = append(errs, err)
  		} else {
  			needsCommit = true
  		}
  	}
  
  	switch len(errs) {
  	case 0:
  	case 1:
  		return errs[0]
  	default:
  		return fmt.Errorf("Multiple errors committing: %+v", errs)
  	}
  
  	if needsCommit {
  		return d.commit(client)
  	}
  
  	return nil
  }
docs: // this method does C + 2*Z requests: C=total number of changes, Z = number of
  // affected zones (1 login + 1 commit)