private List<NavigatorTarget> processBasePage(
     NavigatorExpression navExpression,
     IPage basePage,
     List<NavigatorTarget> targets,
     UserDetails user) {
   int operatorId = navExpression.getOperatorId();
   if (operatorId < 0) {
     targets.add(new NavigatorTarget(basePage, 0));
   } else {
     if (operatorId == NavigatorExpression.OPERATOR_CHILDREN_ID) {
       IPage children[] = basePage.getChildren();
       for (int i = 0; i < children.length; i++) {
         if (children[i].isShowable() && isUserAllowed(user, children[i])) {
           targets.add(new NavigatorTarget(children[i], 0));
         }
       }
     } else if (operatorId == NavigatorExpression.OPERATOR_PATH_ID) {
       IPage page = basePage;
       int index = targets.size();
       int limit = 0;
       if (page.isShowable() && this.isUserAllowed(user, page)) {
         targets.add(index, new NavigatorTarget(page, 0));
       }
       while (!page.isRoot() && limit < 20) {
         page = page.getParent();
         if (page.isShowable() && this.isUserAllowed(user, page)) {
           targets.add(index, new NavigatorTarget(page, 0));
         }
         limit++;
       }
     } else if (operatorId == NavigatorExpression.OPERATOR_SUBTREE_ID) {
       int depth = navExpression.getOperatorSubtreeLevel();
       if (depth < 0) {
         throw new RuntimeException("Operator level 'SUBTREE' not specified");
       }
       targets = this.putSubTree(basePage, 0, depth, targets, user);
     } else {
       targets = null;
     }
   }
   return targets;
 }
 private List<NavigatorTarget> parseSubSpec(
     NavigatorExpression navExpression,
     IPage page,
     List<NavigatorTarget> targets,
     UserDetails user) {
   int specId = navExpression.getSpecId();
   IPage basePage = null;
   if (specId == NavigatorExpression.SPEC_CURRENT_PAGE_ID) {
     basePage = page;
   } else if (specId == NavigatorExpression.SPEC_PARENT_PAGE_ID) {
     int limit = 0;
     do {
       basePage = page.getParent();
       limit++;
     } while ((!basePage.isShowable() || !this.isUserAllowed(user, basePage)) && limit < 20);
   } else if (specId == NavigatorExpression.SPEC_SUPER_ID) {
     if (navExpression.getSpecSuperLevel() < 0) {
       throw new RuntimeException("Level 'SUPER' not specified : Page " + page.getCode());
     }
     basePage = page;
     for (int i = 1; i <= navExpression.getSpecSuperLevel(); i++) {
       basePage = basePage.getParent();
     }
     int limit = 0;
     while ((!basePage.isShowable() || !this.isUserAllowed(user, basePage)) && limit < 20) {
       basePage = basePage.getParent();
       limit++;
     }
   } else if (specId == NavigatorExpression.SPEC_ABS_ID) {
     basePage = page;
     if (navExpression.getSpecAbsLevel() < 0) {
       throw new RuntimeException("Level 'ABS' not specified : Page " + page.getCode());
     }
     int absLevel = navExpression.getSpecAbsLevel();
     List<IPage> candidates = new ArrayList<IPage>();
     int limit = 0;
     if (basePage.isShowable() && isUserAllowed(user, basePage)) {
       candidates.add(0, basePage);
     }
     while (basePage != basePage.getParent() && limit < 20) {
       basePage = basePage.getParent();
       if (basePage.isShowable() && isUserAllowed(user, basePage)) {
         candidates.add(0, basePage);
       }
       limit++;
     }
     if (absLevel >= candidates.size()) {
       absLevel = candidates.size() - 1;
     }
     basePage = (IPage) candidates.get(absLevel);
   } else if (specId == NavigatorExpression.SPEC_PAGE_ID) {
     if (null == navExpression.getSpecCode()) {
       throw new RuntimeException("Page Code not specified : Page " + page.getCode());
     }
     String code = navExpression.getSpecCode();
     IPage basePageTemp = this.getPageManager().getPage(code);
     if (null == basePageTemp) {
       ApsSystemUtils.getLogger()
           .severe(
               "Invalid Page Specification (null): Code " + code + " - Pagina " + page.getCode());
       return targets;
     }
     if (basePageTemp.isShowable() && this.isUserAllowed(user, basePageTemp)) {
       basePage = basePageTemp;
     }
   }
   if (null == basePage) {
     return targets;
   }
   targets = this.processBasePage(navExpression, basePage, targets, user);
   return targets;
 }