@Override
 public void setValueExpression(String name, ValueExpression binding) {
   if ("expanded".equals(name)) {
     super.setValueExpression("value", binding);
   } else {
     super.setValueExpression(name, binding);
   }
 }
 public void setEventPhase(FacesEvent event) {
   if (event instanceof ItemChangeEvent) {
     AbstractPanelMenuItem actItm = (AbstractPanelMenuItem) ((ItemChangeEvent) event).getNewItem();
     if (isImmediate() || (actItm != null && actItm.isImmediate())) {
       event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
     } else if (actItm != null && actItm.isBypassUpdates()) {
       event.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
     } else {
       event.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
     }
   }
 }
  @Override
  public void processDecodes(FacesContext context) {
    super.processDecodes(context);

    // TODO nick - is component immediate==true always?
    executeValidate(context);
  }
  @Override
  public void queueEvent(FacesEvent event) {
    if ((event instanceof ItemChangeEvent) && (event.getComponent() == this)) {
      setEventPhase(event);
    }

    super.queueEvent(event);
  }
  public boolean hasActiveItem(UIComponent component, String activeItem) {
    if (activeItem == null) {
      return false;
    }
    if (component instanceof AbstractPanelMenuItem) {
      AbstractPanelMenuItem item = (AbstractPanelMenuItem) component;
      if (activeItem.equals(item.getName())) {
        return true;
      }
    }

    if (component instanceof AbstractPanelMenuGroup) {
      AbstractPanelMenuGroup group = (AbstractPanelMenuGroup) component;
      if (!group.getPanelMenu().isBubbleSelection()) {
        return false;
      }
    }

    if (component.getChildCount() > 0) {
      for (UIComponent child : component.getChildren()) {
        if (!child.isRendered()) {
          continue;
        }

        if (!(child instanceof AbstractPanelMenuItem)) {
          continue;
        }

        if (hasActiveItem(child, activeItem)) {
          return true;
        }
      }
    }

    return false;
  }