/** @return Returns a list of pages or returns null if has not any page. */
  public List<PageModel> next() {
    ExoContainer container = PortalContainer.getInstance();
    PageService pageService = (PageService) container.getComponentInstance(PageService.class);
    QueryResult<PageContext> result =
        pageService.findPages(
            currentIndex,
            pageSize + 1,
            SiteType.valueOf(ownerType.toUpperCase()),
            ownerId,
            name,
            title);

    int size = result.getSize();
    hasNext = size > pageSize;

    //
    if (size > 0) {
      int hsize = hasNext ? pageSize : size;
      List<PageModel> holder = new ArrayList<PageModel>(hsize);

      Iterator<PageContext> iterator = result.iterator();
      while (holder.size() < hsize) {
        holder.add(new PageModel(iterator.next()));
      }

      currentIndex += holder.size();
      return holder;
    } else {
      return null;
    }
  }
  public boolean hasNext() {
    if (hasNext && currentIndex == 0) {
      ExoContainer container = PortalContainer.getInstance();
      PageService pageService = (PageService) container.getComponentInstance(PageService.class);
      QueryResult<PageContext> result =
          pageService.findPages(
              0, 1, SiteType.valueOf(ownerType.toUpperCase()), ownerId, name, title);

      hasNext = result.getSize() > 0;
    }

    //
    return hasNext;
  }
  /**
   * Analyze a request and split this request's URI to get useful information then keep it in
   * following properties of PortalRequestContext :<br>
   * 1. <code>requestURI</code> : The decoded URI of this request <br>
   * 2. <code>portalOwner</code> : The portal name ( "classic" for instance )<br>
   * 3. <code>portalURI</code> : The URI to current portal ( "/portal/public/classic/ for instance )
   * <br>
   * 4. <code>nodePath</code> : The path that is used to reflect to a navigation node
   */
  public PortalRequestContext(
      WebuiApplication app,
      ControllerContext controllerContext,
      String requestSiteType,
      String requestSiteName,
      String requestPath,
      Locale requestLocale)
      throws Exception {
    super(app);

    //
    this.urlFactory = (URLFactoryService) PortalContainer.getComponent(URLFactoryService.class);
    this.controllerContext = controllerContext;

    //
    request_ = controllerContext.getRequest();
    response_ = controllerContext.getResponse();
    response_.setBufferSize(1024 * 100);
    setSessionId(request_.getSession().getId());

    // The encoding needs to be set before reading any of the parameters since the parameters's
    // encoding
    // is set at the first access.

    // TODO use the encoding from the locale-config.xml file
    response_.setContentType("text/html; charset=UTF-8");
    try {
      request_.setCharacterEncoding("UTF-8");
    } catch (UnsupportedEncodingException e) {
      log.error("Encoding not supported", e);
    }

    // Query parameters from the request will be set in the servlet container url encoding and not
    // necessarly in utf-8 format. So we need to directly parse the parameters from the query
    // string.
    parameterMap = new HashMap<String, String[]>();
    parameterMap.putAll(request_.getParameterMap());
    String queryString = request_.getQueryString();
    if (queryString != null) {
      // The QueryStringParser currently only likes & and not &amp;
      queryString = queryString.replace("&amp;", "&");
      Map<String, String[]> queryParams =
          QueryStringParser.getInstance().parseQueryString(queryString);
      parameterMap.putAll(queryParams);
    }

    ajaxRequest_ = "true".equals(request_.getParameter("ajaxRequest"));
    String cache = request_.getParameter(CACHE_LEVEL);
    if (cache != null) {
      cacheLevel_ = cache;
    }

    requestURI_ = request_.getRequestURI();
    /*
          String decodedURI = URLDecoder.decode(requestURI_, "UTF-8");

          // req.getPathInfo will already have the encoding set from the server.
          // We need to use the UTF-8 value since this is how we store the portal name.
          // Reconstructing the getPathInfo from the non server decoded values.
          String servletPath = URLDecoder.decode(request_.getServletPath(), "UTF-8");
          String contextPath = URLDecoder.decode(request_.getContextPath(), "UTF-8");
          String pathInfo = "/";
          if (requestURI_.length() > servletPath.length() + contextPath.length())
             pathInfo = decodedURI.substring(servletPath.length() + contextPath.length());

          int colonIndex = pathInfo.indexOf("/", 1);
          if (colonIndex < 0)
          {
             colonIndex = pathInfo.length();
          }
          portalOwner_ = pathInfo.substring(1, colonIndex);
          nodePath_ = pathInfo.substring(colonIndex, pathInfo.length());
    */
    //
    this.siteKey = new SiteKey(SiteType.valueOf(requestSiteType.toUpperCase()), requestSiteName);
    this.nodePath_ = requestPath;
    this.requestLocale = requestLocale;

    //
    NodeURL url = createURL(NodeURL.TYPE);
    url.setResource(new NavigationResource(siteKey, ""));
    portalURI = url.toString();

    //
    urlBuilder = new PortalURLBuilder(this, createURL(ComponentURL.TYPE));
  }