code: func DiffTreeContext(ctx context.Context, fromTree, toTree noder.Noder,
  	hashEqual noder.Equal) (Changes, error) {
  	ret := NewChanges()
  
  	ii, err := newDoubleIter(fromTree, toTree, hashEqual)
  	if err != nil {
  		return nil, err
  	}
  
  	for {
  		select {
  		case <-ctx.Done():
  			return nil, ErrCanceled
  		default:
  		}
  
  		from := ii.from.current
  		to := ii.to.current
  
  		switch r := ii.remaining(); r {
  		case noMoreNoders:
  			return ret, nil
  		case onlyFromRemains:
  			if err = ret.AddRecursiveDelete(from); err != nil {
  				return nil, err
  			}
  			if err = ii.nextFrom(); err != nil {
  				return nil, err
  			}
  		case onlyToRemains:
  			if err = ret.AddRecursiveInsert(to); err != nil {
  				return nil, err
  			}
  			if err = ii.nextTo(); err != nil {
  				return nil, err
  			}
  		case bothHaveNodes:
  			if err = diffNodes(&ret, ii); err != nil {
  				return nil, err
  			}
  		default:
  			panic(fmt.Sprintf("unknown remaining value: %d", r))
  		}
  	}
  }
docs: // DiffTree calculates the list of changes between two merkletries.  It
  // uses the provided hashEqual callback to compare noders.
  // Error will be returned if context expires
  // Provided context must be non nil