docs: protected List<CmsPublishedResource> addMovedLinkSources(
          CmsObject cms,
          List<CmsPublishedResource> publishedResources) {
  
          long timer = System.currentTimeMillis();
          if (LOG.isDebugEnabled()) {
              LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUB_EXPORT_START_MOVED_SOURCES_0));
          }
          publishedResources = new ArrayList<CmsPublishedResource>(publishedResources);
          Set<String> pubResources = new HashSet<String>(publishedResources.size());
          // this is needed since the CmsPublishedResource#equals(Object) method just compares ids and not paths
          // and with moved files you have 2 entries with the same id and different paths...
          for (CmsPublishedResource pubRes : publishedResources) {
              pubResources.add(pubRes.getRootPath());
          }
          boolean modified = true;
          // until no more resources are added
          while (modified) {
              modified = false;
              Iterator<CmsPublishedResource> itPrePubRes = new ArrayList<CmsPublishedResource>(
                  publishedResources).iterator();
              while (itPrePubRes.hasNext()) {
                  CmsPublishedResource res = itPrePubRes.next();
                  if (res.getMovedState() != CmsPublishedResource.STATE_MOVED_DESTINATION) {
                      // handle only resources that are destination of move operations
                      continue;
                  }
                  List<CmsRelation> relations = null;
                  try {
                      // get all link sources to this resource
                      relations = cms.getRelationsForResource(
                          cms.getRequestContext().removeSiteRoot(res.getRootPath()),
                          CmsRelationFilter.SOURCES);
                  } catch (CmsException e) {
                      // should never happen
                      if (LOG.isErrorEnabled()) {
                          LOG.error(e.getLocalizedMessage(), e);
                      }
                  }
                  if ((relations == null) || relations.isEmpty()) {
                      // continue with next resource if no link sources found
                      continue;
                  }
                  Iterator<CmsRelation> itRelations = relations.iterator();
                  while (itRelations.hasNext()) {
                      CmsRelation relation = itRelations.next();
                      CmsPublishedResource source = null;
                      try {
                          // get the link source
                          source = new CmsPublishedResource(relation.getSource(cms, CmsResourceFilter.ALL));
                      } catch (CmsException e) {
                          // should never happen
                          if (LOG.isWarnEnabled()) {
                              LOG.warn(e.getLocalizedMessage());
                          }
                      }
                      if ((source == null) || pubResources.contains(source.getRootPath())) {
                          // continue if the link source could not been retrieved or if the list already contains it
                          continue;
                      }
                      // add it, and set the modified flag to give it another round
                      modified = true;
                      pubResources.add(source.getRootPath());
                      publishedResources.add(source);
                  }
              }
          }
          if (LOG.isDebugEnabled()) {
              LOG.debug(
                  Messages.get().getBundle().key(
                      Messages.LOG_SCRUB_EXPORT_FINISH_MOVED_SOURCES_1,
                      (System.currentTimeMillis() - timer) + ""));
          }
          return publishedResources;
      }