code: func (it *unionIterator) Next(descend bool) bool {
  	if len(*it.items) == 0 {
  		return false
  	}
  
  	// Get the next key from the union
  	least := heap.Pop(it.items).(NodeIterator)
  
  	// Skip over other nodes as long as they're identical, or, if we're not descending, as
  	// long as they have the same prefix as the current node.
  	for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) {
  		skipped := heap.Pop(it.items).(NodeIterator)
  		// Skip the whole subtree if the nodes have hashes; otherwise just skip this node
  		if skipped.Next(skipped.Hash() == common.Hash{}) {
  			it.count++
  			// If there are more elements, push the iterator back on the heap
  			heap.Push(it.items, skipped)
  		}
  	}
  	if least.Next(descend) {
  		it.count++
  		heap.Push(it.items, least)
  	}
  	return len(*it.items) > 0
  }
docs: // Next returns the next node in the union of tries being iterated over.
  //
  // It does this by maintaining a heap of iterators, sorted by the iteration
  // order of their next elements, with one entry for each source trie. Each
  // time Next() is called, it takes the least element from the heap to return,
  // advancing any other iterators that also point to that same element. These
  // iterators are called with descend=false, since we know that any nodes under
  // these nodes will also be duplicates, found in the currently selected iterator.
  // Whenever an iterator is advanced, it is pushed back into the heap if it still
  // has elements remaining.
  //
  // In the case that descend=false - eg, we're asked to ignore all subnodes of the
  // current node - we also advance any iterators in the heap that have the current
  // path as a prefix.