Adds a link to the document.

        Calling code should use this method to add links instead of
        modifying ``links`` directly.

        This method adds a link to the given ``target`` to the document with
        the given ``rel``. If one or more links are already present for that
        link relationship type, the new link will be added to the existing
        links for that link relationship type.

        If ``target`` is a string, a link is added with ``target`` as its
        ``href`` property and other properties from the keyword arguments.

        If ``target`` is a ``Link`` object, it is added to the document and the
        keyword arguments are ignored.

        If ``target`` is a ``Document`` object, ``target``'s ``self`` link is
        added to this document and the keyword arguments are ignored.

        If ``target`` is a ``Builder`` object, ``target``'s ``self`` link is
        added to this document and the keyword arguments are ignored.

        Arguments:

        - ``rel``: a string specifying the link relationship type of the link.
          It should be a well-known link relation name from the IANA registry
          (http://www.iana.org/assignments/link-relations/link-relations.xml),
          a full URI, or a CURIE.
        - ``target``: the destination of the link.
        - ``wrap``: Defaults to False, but if True, specifies that the link
          object should be initally wrapped in a JSON array even if it is the
          first link for the given ``rel``.

def add_link(self, rel, target, wrap=False, **kwargs):
        """Adds a link to the document.

        Calling code should use this method to add links instead of
        modifying ``links`` directly.

        This method adds a link to the given ``target`` to the document with
        the given ``rel``. If one or more links are already present for that
        link relationship type, the new link will be added to the existing
        links for that link relationship type.

        If ``target`` is a string, a link is added with ``target`` as its
        ``href`` property and other properties from the keyword arguments.

        If ``target`` is a ``Link`` object, it is added to the document and the
        keyword arguments are ignored.

        If ``target`` is a ``Document`` object, ``target``'s ``self`` link is
        added to this document and the keyword arguments are ignored.

        If ``target`` is a ``Builder`` object, ``target``'s ``self`` link is
        added to this document and the keyword arguments are ignored.

        Arguments:

        - ``rel``: a string specifying the link relationship type of the link.
          It should be a well-known link relation name from the IANA registry
          (http://www.iana.org/assignments/link-relations/link-relations.xml),
          a full URI, or a CURIE.
        - ``target``: the destination of the link.
        - ``wrap``: Defaults to False, but if True, specifies that the link
          object should be initally wrapped in a JSON array even if it is the
          first link for the given ``rel``.

        """
        if hasattr(target, 'as_link'):
            link = target.as_link()
        else:
            link = self.link(target, **kwargs)

        links = self.o.setdefault(LINKS_KEY, {})

        new_link = link.as_object()
        collected_links = CanonicalRels(links, self.curies, self.base_uri)
        if rel not in collected_links:
            if wrap:
                links[rel] = [new_link]
            else:
                links[rel] = new_link
            return

        original_rel = collected_links.original_key(rel)

        current_links = links[original_rel]
        if isinstance(current_links, list):
            current_links.append(new_link)
        else:
            links[original_rel] = [current_links, new_link]