docs: def add(self, origin, rel, target, attrs=None, index=None):
          '''
          Add one relationship to the extent
  
          origin - origin of the relationship (similar to an RDF subject)
          rel - type IRI of the relationship (similar to an RDF predicate)
          target - target of the relationship (similar to an RDF object), a boolean, floating point or unicode object
          attrs - optional attribute mapping of relationship metadata, i.e. {attrname1: attrval1, attrname2: attrval2}
          index - optional position for the relationship to be inserted
          '''
          #FIXME: return an ID (IRI) for the resulting relationship?
  
          if not origin: 
              raise ValueError('Relationship origin cannot be null')
          if not rel: 
              raise ValueError('Relationship ID cannot be null')
  
          # convert attribute class to the expected type
          if type(attrs) != type(self._attr_cls):
              attrs = self._attr_cls(attrs or {})
  
          #No, could be an I instance, fails assertion
          #assert isinstance(origin, str) and isinstance(origin, str) and isinstance(origin, str) and isinstance(origin, dict), (origin, rel, target, attrs)
  
          item = (origin, rel, target, attrs)
          if index is not None:
              rid = index
              self._relationships.insert(index, item)
          else:
              rid = self.size()
              self._relationships.append(item)
          return rid