protected void processSpecialPages(
      long userId, WikiNode node, Element rootElement, List<String> specialNamespaces)
      throws PortalException {

    ProgressTracker progressTracker = ProgressTrackerThreadLocal.getProgressTracker();

    List<Element> pageElements = rootElement.elements("page");

    for (int i = 0; i < pageElements.size(); i++) {
      Element pageElement = pageElements.get(i);

      String title = pageElement.elementText("title");

      if (!title.startsWith("Category:")) {
        if (isSpecialMediaWikiPage(title, specialNamespaces)) {
          rootElement.remove(pageElement);
        }

        continue;
      }

      String categoryName = title.substring("Category:".length());

      categoryName = normalize(categoryName, 75);

      Element revisionElement = pageElement.element("revision");

      String description = revisionElement.elementText("text");

      description = normalizeDescription(description);

      try {
        AssetTag assetTag = null;

        try {
          assetTag = AssetTagLocalServiceUtil.getTag(node.getCompanyId(), categoryName);
        } catch (NoSuchTagException nste) {
          ServiceContext serviceContext = new ServiceContext();

          serviceContext.setAddGroupPermissions(true);
          serviceContext.setAddGuestPermissions(true);
          serviceContext.setScopeGroupId(node.getGroupId());

          assetTag = AssetTagLocalServiceUtil.addTag(userId, categoryName, null, serviceContext);
        }

        if (Validator.isNotNull(description)) {
          AssetTagPropertyLocalServiceUtil.addTagProperty(
              userId, assetTag.getTagId(), "description", description);
        }
      } catch (SystemException se) {
        _log.error(se, se);
      }

      if ((i % 5) == 0) {
        progressTracker.setPercent((i * 10) / pageElements.size());
      }
    }
  }
  protected void processRegularPages(
      long userId,
      WikiNode node,
      Element rootElement,
      List<String> specialNamespaces,
      Map<String, String> usersMap,
      InputStream imagesInputStream,
      Map<String, String[]> options) {

    boolean importLatestVersion =
        MapUtil.getBoolean(options, WikiImporterKeys.OPTIONS_IMPORT_LATEST_VERSION);
    boolean strictImportMode =
        MapUtil.getBoolean(options, WikiImporterKeys.OPTIONS_STRICT_IMPORT_MODE);

    ProgressTracker progressTracker = ProgressTrackerThreadLocal.getProgressTracker();

    int count = 0;

    int percentage = 10;

    int maxPercentage = 50;

    if (imagesInputStream == null) {
      maxPercentage = 99;
    }

    List<Element> pageElements = rootElement.elements("page");

    for (int i = 0; i < pageElements.size(); i++) {
      Element pageElement = pageElements.get(i);

      String title = pageElement.elementText("title");

      title = normalizeTitle(title);

      percentage =
          Math.min(10 + (i * (maxPercentage - percentage)) / pageElements.size(), maxPercentage);

      progressTracker.setPercent(percentage);

      if (isSpecialMediaWikiPage(title, specialNamespaces)) {
        continue;
      }

      List<Element> revisionElements = pageElement.elements("revision");

      if (importLatestVersion) {
        Element lastRevisionElement = revisionElements.get(revisionElements.size() - 1);

        revisionElements = new ArrayList<Element>();

        revisionElements.add(lastRevisionElement);
      }

      for (Element revisionElement : revisionElements) {
        Element contributorElement = revisionElement.element("contributor");

        String author = contributorElement.elementText("username");

        String content = revisionElement.elementText("text");
        String summary = revisionElement.elementText("comment");

        try {
          importPage(userId, author, node, title, content, summary, usersMap, strictImportMode);
        } catch (Exception e) {
          if (_log.isWarnEnabled()) {
            _log.warn("Page with title " + title + " could not be imported", e);
          }
        }
      }

      count++;
    }

    if (_log.isInfoEnabled()) {
      _log.info("Imported " + count + " pages into " + node.getName());
    }
  }
  protected void processImages(long userId, WikiNode node, InputStream imagesInputStream)
      throws Exception {

    if (imagesInputStream == null) {
      return;
    }

    ProgressTracker progressTracker = ProgressTrackerThreadLocal.getProgressTracker();

    int count = 0;

    ZipReader zipReader = ZipReaderFactoryUtil.getZipReader(imagesInputStream);

    List<String> entries = zipReader.getEntries();

    int total = entries.size();

    if (total > 0) {
      try {
        WikiPageLocalServiceUtil.getPage(node.getNodeId(), SHARED_IMAGES_TITLE);
      } catch (NoSuchPageException nspe) {
        ServiceContext serviceContext = new ServiceContext();

        serviceContext.setAddGroupPermissions(true);
        serviceContext.setAddGuestPermissions(true);

        WikiPageLocalServiceUtil.addPage(
            userId,
            node.getNodeId(),
            SHARED_IMAGES_TITLE,
            SHARED_IMAGES_CONTENT,
            null,
            true,
            serviceContext);
      }
    }

    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
        new ArrayList<ObjectValuePair<String, InputStream>>();

    try {
      int percentage = 50;

      for (int i = 0; i < entries.size(); i++) {
        String entry = entries.get(i);

        String key = entry;

        InputStream inputStream = zipReader.getEntryAsInputStream(entry);

        String[] paths = StringUtil.split(key, CharPool.SLASH);

        if (!isValidImage(paths, inputStream)) {
          if (_log.isInfoEnabled()) {
            _log.info("Ignoring " + key);
          }

          continue;
        }

        String fileName = StringUtil.toLowerCase(paths[paths.length - 1]);

        ObjectValuePair<String, InputStream> inputStreamOVP =
            new ObjectValuePair<String, InputStream>(fileName, inputStream);

        inputStreamOVPs.add(inputStreamOVP);

        count++;

        if ((i % 5) == 0) {
          WikiPageLocalServiceUtil.addPageAttachments(
              userId, node.getNodeId(), SHARED_IMAGES_TITLE, inputStreamOVPs);

          inputStreamOVPs.clear();

          percentage = Math.min(50 + (i * 50) / total, 99);

          progressTracker.setPercent(percentage);
        }
      }

      if (!inputStreamOVPs.isEmpty()) {
        WikiPageLocalServiceUtil.addPageAttachments(
            userId, node.getNodeId(), SHARED_IMAGES_TITLE, inputStreamOVPs);
      }
    } finally {
      for (ObjectValuePair<String, InputStream> inputStreamOVP : inputStreamOVPs) {

        InputStream inputStream = inputStreamOVP.getValue();

        StreamUtil.cleanUp(inputStream);
      }
    }

    zipReader.close();

    if (_log.isInfoEnabled()) {
      _log.info("Imported " + count + " images into " + node.getName());
    }
  }