code: func (w *Watcher) Migrate(c *ast.Compiler, txn storage.Transaction) (*Watcher, error) {
  	w.l.Lock()
  	defer w.l.Unlock()
  	if w.closed {
  		return w, errors.New("cannot migrate a closed Watcher")
  	}
  
  	m, err := New(w.ctx, w.store, c, txn)
  	if err != nil {
  		return w, err
  	}
  
  	var handles []*Handle
  	for h := range w.handles {
  		handles = append(handles, h)
  	}
  	w.close(txn, true)
  
  	for _, h := range handles {
  		if err := m.registerHandle(h); err != nil {
  			h.shutDown(newInvalidatedWatchError(err))
  		}
  	}
  
  	return m, nil
  }
docs: // Migrate creates a new Watcher with the same watches as w, but using the new
  // compiler. Like when creating a Watcher with New, the provided compiler must not
  // be modified after being passed to Migrate, or else behavior is undefined.
  //
  // After Migrate returns, the old watcher will be closed, and the new will be ready for
  // use. All Handles from the old watcher will still be active, via the returned Watcher,
  // with the exception of those Handles who's query is no longer valid with the new
  // compiler. Such Handles will be shutdown and a final Event sent along their channel
  // indicating the cause of the error.
  //
  // If an error occurs creating the new Watcher, the state of the old Watcher will not be
  // changed.