docs: def add_attribute(self, attrkey, attrvalue, append=False, oldvalue=None):
          """
          Add an attribute to this feature.
  
          Feature attributes are stored as nested dictionaries.
  
          Each feature can only have one ID, so ID attribute mapping is 'string'
          to 'string'. All other attributes can have multiple values, so mapping
          is 'string' to 'dict of strings'.
  
          By default, adding an attribute that already exists will cause the old
          value to be overwritten. If the `append` option is true, the new
          attribute value will not overwrite the old value, but will be appended
          as a second value. (Note: ID attributes can have only 1 value.)
  
          If the `oldvalue` option is set, the new value will replace the old
          value. This is necessary for updating an attribute that has multiple
          values without completely overwriting all old values. (Note: The
          `append` option is ignored when `oldvalue` is set.)
          """
          # Handle ID/Parent relationships
          if attrkey == 'ID':
              if self.children is not None:
                  oldid = self.get_attribute('ID')
                  for child in self.children:
                      child.add_attribute('Parent', attrvalue,
                                          oldvalue=oldid)
              self._attrs[attrkey] = attrvalue
              if self.is_multi:
                  self.multi_rep._attrs[attrkey] = attrvalue
                  for sibling in self.multi_rep.siblings:
                      sibling._attrs[attrkey] = attrvalue
              return
  
          # Handle all other attribute types
          if oldvalue is not None:
              if attrkey in self._attrs:
                  assert oldvalue in self._attrs[attrkey]
                  del self._attrs[attrkey][oldvalue]
          if attrkey not in self._attrs or append is False:
              self._attrs[attrkey] = dict()
          self._attrs[attrkey][attrvalue] = True