/**
   * Reads the resources available for processing based on the path parameters.
   *
   * <p>
   *
   * @return the resources available for processing based on the path parameters.
   */
  @SuppressWarnings("unchecked")
  private List<CmsResource> getResources() {

    List<CmsResource> result = new LinkedList<CmsResource>();
    CmsObject cms = this.getCms();
    CmsResourceFilter filter = CmsResourceFilter.ALL;
    try {
      for (String path : this.m_paths) {
        List<CmsResource> resources = cms.readResources(path, filter, true);
        // filter out any resource that is no XML content:
        for (CmsResource resource : resources) {
          if (resource.isFile()) {
            if (CmsResourceTypeXmlContent.isXmlContent(resource)) {
              result.add(resource);
            } else if (CmsResourceTypeXmlPage.isXmlPage(resource)) {
              result.add(resource);
            }
          }
        }
      }
    } catch (CmsException e) {
      LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_LANGUAGECOPY_READRESOURCES_0), e);
      result = Collections.emptyList();
    }

    return result;
  }
  /**
   * Creates a list of new resources of the specified folder and filters the unwanted resources.
   *
   * <p>If the parameter categoryFolders is an empty list, all new resources are returned, otherwise
   * only those resources which are in a subfolder specified by the list.
   *
   * <p>
   *
   * @param cms the CmsObject
   * @param startFolder the root folder
   * @param startDate the start date in milliseconds
   * @param endDate the end date in milliseconds
   * @param selectedCategories list with selected categories/folders
   * @param openedCategories list with opened categories/folders
   * @return list of new resources
   */
  private static List<CmsResource> getNewResourceList(
      CmsObject cms,
      String startFolder,
      long startDate,
      long endDate,
      List<String> selectedCategories,
      List<String> openedCategories) {

    List<CmsResource> searchResult = null;
    List<CmsResource> foundResources = null;
    Set<CmsUUID> addedResources = null;

    if (LOG.isDebugEnabled()) {

      StringBuffer buf = new StringBuffer();
      for (int i = 0, n = selectedCategories.size(); i < n; i++) {
        buf.append(selectedCategories.get(i));

        if (i < (n - 1)) {
          buf.append(", ");
        }
      }

      LOG.debug("################ INPUT VALUES FOR NEW DOCUMENTS SEARCH");
      LOG.debug("startDate : " + startDate + " " + new java.util.Date(startDate).toString());
      LOG.debug("endDate : " + endDate + " " + new java.util.Date(endDate).toString());
      LOG.debug("startFolder : " + startFolder);
      LOG.debug("categories : " + buf.toString());
    }

    try {

      // get all resources in the site root which are in the time range
      CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION;
      filter = filter.addRequireLastModifiedAfter(startDate);
      filter = filter.addRequireLastModifiedBefore(endDate);
      foundResources = cms.readResources(startFolder, filter);
    } catch (CmsException e) {

      if (LOG.isErrorEnabled()) {
        LOG.error(
            "Error reading resources in time range "
                + new java.util.Date(startDate).toString()
                + " - "
                + new java.util.Date(endDate).toString()
                + " below folder "
                + startFolder,
            e);
      }
      foundResources = Collections.emptyList();
    }

    if (selectedCategories.size() == 0) {

      // return all found resources with filtered links
      searchResult = filterLinkedResources(foundResources);
    } else {

      addedResources = new HashSet<CmsUUID>();
      searchResult = new ArrayList<CmsResource>();
      long currentTime = System.currentTimeMillis();

      for (int i = 0, n = foundResources.size(); i < n; i++) {

        // analyze each resource if it has to be included in the search result

        CmsResource resource = foundResources.get(i);

        // filter those documents that are folders or outside the release and expire window
        if (resource.isFolder()
            || (resource.getDateReleased() > currentTime)
            || (resource.getDateExpired() < currentTime)) {
          // skip folders and resources outside time range
          continue;
        }

        String resourceName = cms.getRequestContext().removeSiteRoot(resource.getRootPath());
        String parentFolder = CmsResource.getParentFolder(resourceName);
        boolean addToResult = false;

        if (!selectedCategories.contains(parentFolder) && openedCategories.contains(parentFolder)) {

          // skip resources that are inside an opened, but un-selected category/folder
          continue;
        }

        // check if the parent folder of the resource is one of the selected categories/folders
        addToResult = selectedCategories.contains(parentFolder);

        if (!addToResult) {

          // check if the resource is inside a collapsed sub-tree
          // of a selected category

          int openedCategoryCount = 0;

          while (!"/".equals(parentFolder)) {

            if (openedCategories.contains(parentFolder)) {
              openedCategoryCount++;
            }

            if (selectedCategories.contains(parentFolder) && (openedCategoryCount == 0)) {

              // we found a selected parent category,
              // and it's sub-tree is collapsed
              addToResult = true;
              break;
            }

            parentFolder = CmsResource.getParentFolder(parentFolder);
          }
        }

        if (!addToResult) {

          // continue with the next resource
          continue;
        }

        if (CmsDocumentFactory.isIgnoredDocument(resourceName, true)) {
          // this resource is ignored, skip it before checking the resource id
          continue;
        }

        // check if the resource is a sibling that has already been added to the search result
        CmsUUID resourceId = resource.getResourceId();
        if (!addedResources.contains(resourceId)) {

          // add resource to the result
          addedResources.add(resourceId);
          searchResult.add(resource);
        }
      }
    }

    return searchResult;
  }