Modify a relationship from RELS-EXT for this object.  As the Fedora API-M does not contain
        a native "modifyRelationship", this method purges an existing one, then adds a new one,
        pivoting on the predicate.
        Calls :meth:`API_M.purgeRelationship`, :meth:`API_M.addRelationship`

        Example usage::

            predicate = 'info:fedora/fedora-system:def/relations-external#isMemberOfCollection'
            old_object = 'info:fedora/foo:456'
            new_object = 'info:fedora/foo:789'

            object.modify_relationship(predicate, old_object, new_object)

        :param rel_uri: URI for the existing relationship
        :param old_object: previous target object for relationship; can be
                        :class:`DigitalObject` or string; if string begins with info:fedora/ it
                        will be treated as a resource, otherwise it will be treated as a literal
        :param new_object: new target object for relationship; can be
                        :class:`DigitalObject` or string; if string begins with info:fedora/ it
                        will be treated as a resource, otherwise it will be treated as a literal
        :rtype: boolean

def modify_relationship(self, rel_uri, old_object, new_object):
        """
        Modify a relationship from RELS-EXT for this object.  As the Fedora API-M does not contain
        a native "modifyRelationship", this method purges an existing one, then adds a new one,
        pivoting on the predicate.
        Calls :meth:`API_M.purgeRelationship`, :meth:`API_M.addRelationship`

        Example usage::

            predicate = 'info:fedora/fedora-system:def/relations-external#isMemberOfCollection'
            old_object = 'info:fedora/foo:456'
            new_object = 'info:fedora/foo:789'

            object.modify_relationship(predicate, old_object, new_object)

        :param rel_uri: URI for the existing relationship
        :param old_object: previous target object for relationship; can be
                        :class:`DigitalObject` or string; if string begins with info:fedora/ it
                        will be treated as a resource, otherwise it will be treated as a literal
        :param new_object: new target object for relationship; can be
                        :class:`DigitalObject` or string; if string begins with info:fedora/ it
                        will be treated as a resource, otherwise it will be treated as a literal
        :rtype: boolean
        """

        if isinstance(rel_uri, URIRef):
            rel_uri = force_text(rel_uri)

        # old_object
        obj_old_is_literal = True
        if isinstance(old_object, DigitalObject):
            old_object = old_object.uri
            obj_old_is_literal = False
        elif (isinstance(old_object, str) or isinstance(old_object, six.string_types)) \
          and old_object.startswith('info:fedora/'):
            obj_old_is_literal = False

        # new_object
        obj_new_is_literal = True
        if isinstance(new_object, DigitalObject):
            new_object = new_object.uri
            obj_new_is_literal = False
        elif (isinstance(new_object, str) or isinstance(new_object, six.string_types)) \
          and new_object.startswith('info:fedora/'):
            obj_new_is_literal = False

        # this call will change RELS-EXT, possibly creating it if it's
        # missing. remove any cached info we have for that datastream.
        if 'RELS-EXT' in self.dscache:
            del self.dscache['RELS-EXT']
        self._ds_list = None

        # attempt purge
        if self.api.purgeRelationship(self.pid, self.uri, rel_uri, old_object,
                                      obj_old_is_literal) is not True:
            return False
        # attempt add
        elif self.api.addRelationship(self.pid, self.uri, rel_uri, new_object,
                                      obj_new_is_literal) is not True:
            # if addRelationship fails, rollback to old_object
            self.api.addRelationship(self.pid, self.uri, rel_uri, old_object,
                                     obj_old_is_literal)
            return False
        else:
            return True