code: func (l *State) SyncChanges() error {
  	l.Lock()
  	defer l.Unlock()
  
  	// We will do node-level info syncing at the end, since it will get
  	// updated by a service or check sync anyway, given how the register
  	// API works.
  
  	// Sync the services
  	// (logging happens in the helper methods)
  	for id, s := range l.services {
  		var err error
  		switch {
  		case s.Deleted:
  			err = l.deleteService(id)
  		case !s.InSync:
  			err = l.syncService(id)
  		default:
  			l.logger.Printf("[DEBUG] agent: Service %q in sync", id)
  		}
  		if err != nil {
  			return err
  		}
  	}
  
  	// Sync the checks
  	// (logging happens in the helper methods)
  	for id, c := range l.checks {
  		var err error
  		switch {
  		case c.Deleted:
  			err = l.deleteCheck(id)
  		case !c.InSync:
  			if c.DeferCheck != nil {
  				c.DeferCheck.Stop()
  				c.DeferCheck = nil
  			}
  			err = l.syncCheck(id)
  		default:
  			l.logger.Printf("[DEBUG] agent: Check %q in sync", id)
  		}
  		if err != nil {
  			return err
  		}
  	}
  
  	// Now sync the node level info if we need to, and didn't do any of
  	// the other sync operations.
  	if l.nodeInfoInSync {
  		l.logger.Printf("[DEBUG] agent: Node info in sync")
  		return nil
  	}
  	return l.syncNodeInfo()
  }
docs: // SyncChanges pushes checks, services and node info data which has been
  // marked out of sync or deleted to the server.