private void buildStateModel() {
    stateModel = new DynamicMenuModel();
    DefaultMenuItem homeItem = new DefaultMenuItem();
    homeItem.setAjax(false);
    homeItem.setValue("home");
    homeItem.setId(
        FacesContext.getCurrentInstance().getViewRoot().createUniqueId() + "_state_home");
    homeItem.setImmediate(true);
    homeItem.setCommand("#{stateController.clearStateAndGoHome}");
    stateModel.addElement(homeItem);
    for (StateItem stateItem : stateItens) {
      DefaultMenuItem item = new DefaultMenuItem();
      item.setAjax(stateItem.isAjax());
      item.setGlobal(stateItem.isGlobal());
      item.setResetValues(stateItem.isResetValues());
      item.setTitle(stateItem.getTitle());
      item.setImmediate(stateItem.isImmediate());
      item.setValue(getItemValue(stateItem.getValue()));
      if (stateItem.getOncomplete() != null && !"".equals(stateItem.getOncomplete())) {
        item.setOncomplete(stateItem.getOncomplete());
      }
      item.setId(FacesContext.getCurrentInstance().getViewRoot().createUniqueId() + "_state");
      if (stateItem.getOutcome() != null && !"".equals(stateItem.getOutcome())) {
        item.setIncludeViewParams(true);
        StringBuilder url = new StringBuilder(stateItem.getOutcome());
        if (stateItem.isAddEntityIdParam()) {
          url.append("?id=").append(((BaseEntity) stateItem.getEntity()).getId());
        }
        if (url.toString().contains("?")) {
          url.append("&pullState=true");
        } else {
          url.append("?pullState=true"); // tell statePusher to not call preRenderView event
        }
        url.append("&itemIndex=").append(stateItens.indexOf(stateItem));
        item.setUrl(url.toString());
      } else { // if has not outcome set command, note that they are muttually exclusive:
               // http://stackoverflow.com/questions/16437336/using-both-setactionexpression-and-seturl-on-menuitem-object-is-not-working
        item.setCommand("#{stateController.pullStateItem(" + stateItens.indexOf(stateItem) + ")}");
      }
      if (!"".equals(stateItem.getUpdate())) {
        item.setUpdate(stateItem.getUpdate());
      }

      if (stateItens.indexOf(stateItem) == stateItens.size() - 1) {
        item.setDisabled(true);
        item.setStyleClass("ui-state-disabled");
      }
      stateModel.addElement(item);
    }
  }
  /**
   * action called by backButton
   *
   * @return outcome to redirect
   */
  public String goBack() {
    stateItens.removeLast();
    if (stateItens.isEmpty()) {
      try {
        // if stateItens is empty go to index
        FacesContext.getCurrentInstance()
            .getExternalContext()
            .redirect(
                FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath());
        return null;
      } catch (IOException ex) {
        Logger.getLogger(StateController.class.getName()).log(Level.SEVERE, null, ex);
      }
    }

    // update data in the managed bean
    StateItem item = stateItens.peekLast();
    statePullEvent.fire(new StatePullEvent(item));
    buildStateModel();
    invokeCallback(item);
    return item.getOutcome();
  }