private void updateRelativeLinks(XWikiDocument document, DocumentReference oldDocumentReference)
      throws XWikiException {
    // We support only the syntaxes for which there is an available renderer.
    if (!this.contextComponentManagerProvider
        .get()
        .hasComponent(BlockRenderer.class, document.getSyntax().toIdString())) {
      this.logger.warn(
          "We can't update the relative links from [{}]"
              + " because there is no renderer available for its syntax [{}].",
          document.getDocumentReference(),
          document.getSyntax());
      return;
    }

    DocumentReference newDocumentReference = document.getDocumentReference();

    XDOM xdom = document.getXDOM();
    List<Block> blocks = linkedResourceHelper.getBlocks(xdom);

    boolean modified = false;
    for (Block block : blocks) {
      ResourceReference resourceReference = linkedResourceHelper.getResourceReference(block);
      if (resourceReference == null) {
        // Skip invalid blocks.
        continue;
      }

      ResourceType resourceType = resourceReference.getType();

      // TODO: support ATTACHMENT as well.
      if (!ResourceType.DOCUMENT.equals(resourceType) && !ResourceType.SPACE.equals(resourceType)) {
        // We are currently only interested in Document or Space references.
        continue;
      }

      // current link, use the old document's reference to fill in blanks.
      EntityReference oldLinkReference =
          this.resourceReferenceResolver.resolve(resourceReference, null, oldDocumentReference);
      // new link, use the new document's reference to fill in blanks.
      EntityReference newLinkReference =
          this.resourceReferenceResolver.resolve(resourceReference, null, newDocumentReference);

      // If the new and old link references don`t match, then we must update the relative link.
      if (!newLinkReference.equals(oldLinkReference)) {
        modified = true;

        // Serialize the old (original) link relative to the new document's location, in compact
        // form.
        String serializedLinkReference =
            this.compactEntityReferenceSerializer.serialize(oldLinkReference, newDocumentReference);

        // Update the reference in the XDOM.
        linkedResourceHelper.setResourceReferenceString(block, serializedLinkReference);
      }
    }

    if (modified) {
      document.setContent(xdom);
      saveDocumentPreservingContentAuthor(document, "Updated the relative links.", true);
      this.logger.info("Updated the relative links from [{}].", document.getDocumentReference());
    } else {
      this.logger.info("No relative links to update in [{}].", document.getDocumentReference());
    }
  }
  private boolean renameLink(
      Block block,
      DocumentReference currentDocumentReference,
      DocumentReference oldTarget,
      DocumentReference newTarget)
      throws InvalidArgumentException {
    boolean modified = false;

    ResourceReference resourceReference = linkedResourceHelper.getResourceReference(block);
    if (resourceReference == null) {
      // Skip invalid blocks.
      throw new InvalidArgumentException();
    }

    ResourceType resourceType = resourceReference.getType();

    // TODO: support ATTACHMENT as well.
    if (!ResourceType.DOCUMENT.equals(resourceType) && !ResourceType.SPACE.equals(resourceType)) {
      // We are currently only interested in Document or Space references.
      throw new InvalidArgumentException();
    }

    // Resolve the resource reference.
    EntityReference linkEntityReference =
        resourceReferenceResolver.resolve(resourceReference, null, currentDocumentReference);
    // Resolve the document of the reference.
    DocumentReference linkTargetDocumentReference =
        defaultReferenceDocumentReferenceResolver.resolve(linkEntityReference);
    EntityReference newTargetReference = newTarget;
    ResourceType newResourceType = resourceType;

    // If the link was resolved to a space...
    if (EntityType.SPACE.equals(linkEntityReference.getType())) {
      if (XWiki.DEFAULT_SPACE_HOMEPAGE.equals(newTarget.getName())) {
        // If the new document reference is also a space (non-terminal doc), be careful to keep it
        // serialized as a space still (i.e. without ".WebHome") and not serialize it as a doc by
        // mistake
        // (i.e. with ".WebHome").
        newTargetReference = newTarget.getLastSpaceReference();
      } else {
        // If the new target is a non-terminal document, we can not use a "space:" resource type to
        // access
        // it anymore. To fix it, we need to change the resource type of the link reference "doc:".
        newResourceType = ResourceType.DOCUMENT;
      }
    }

    // If the link targets the old (renamed) document reference, we must update it.
    if (linkTargetDocumentReference.equals(oldTarget)) {
      modified = true;
      String newReferenceString =
          this.compactEntityReferenceSerializer.serialize(
              newTargetReference, currentDocumentReference);

      // Update the reference in the XDOM.
      linkedResourceHelper.setResourceReferenceString(block, newReferenceString);
      linkedResourceHelper.setResourceType(block, newResourceType);
    }

    return modified;
  }