code: func (n *node) remove(item Item, minItems int, typ toRemove) Item {
  	var i int
  	var found bool
  	switch typ {
  	case removeMax:
  		if len(n.children) == 0 {
  			return n.items.pop()
  		}
  		i = len(n.items)
  	case removeMin:
  		if len(n.children) == 0 {
  			return n.items.removeAt(0)
  		}
  		i = 0
  	case removeItem:
  		i, found = n.items.find(item)
  		if len(n.children) == 0 {
  			if found {
  				return n.items.removeAt(i)
  			}
  			return nil
  		}
  	default:
  		panic("invalid type")
  	}
  	// If we get to here, we have children.
  	if len(n.children[i].items) <= minItems {
  		return n.growChildAndRemove(i, item, minItems, typ)
  	}
  	child := n.mutableChild(i)
  	// Either we had enough items to begin with, or we've done some
  	// merging/stealing, because we've got enough now and we're ready to return
  	// stuff.
  	if found {
  		// The item exists at index 'i', and the child we've selected can give us a
  		// predecessor, since if we've gotten here it's got > minItems items in it.
  		out := n.items[i]
  		// We use our special-case 'remove' call with typ=maxItem to pull the
  		// predecessor of item i (the rightmost leaf of our immediate left child)
  		// and set it into where we pulled the item from.
  		n.items[i] = child.remove(nil, minItems, removeMax)
  		return out
  	}
  	// Final recursive call.  Once we're here, we know that the item isn't in this
  	// node and that the child is big enough to remove from.
  	return child.remove(item, minItems, typ)
  }
docs: // remove removes an item from the subtree rooted at this node.