@Override
  public Object getBackCopy(PropertyContext propertyContext) {
    final XFormsSelect1Control cloned = (XFormsSelect1Control) super.getBackCopy(propertyContext);

    // If we have an itemset, make sure the computed value is used as basis for comparison
    if (itemsetProperty != null)
      cloned.itemsetProperty =
          new ConstantControlProperty<Itemset>(itemsetProperty.getValue(propertyContext));

    return cloned;
  }
 private boolean mustSendItemsetUpdate(
     PropertyContext propertyContext, XFormsSelect1Control otherSelect1Control) {
   if (getSelectionControl().hasStaticItemset()) {
     // There is no need to send an update:
     //
     // 1. Items are static...
     // 2. ...and they have been outputted statically in the HTML page, directly or in repeat
     // template
     return false;
   } else if (isStaticReadonly()) {
     // There is no need to send an update for static readonly controls
     return false;
   } else {
     // There is a possible change
     if (XFormsSingleNodeControl.isRelevant(otherSelect1Control) != isRelevant()) {
       // Relevance changed
       // Here we decide to send an update only if we become relevant, as the client will know that
       // the
       // new state of the control is non-relevant and can handle the itemset on the client as it
       // wants.
       return isRelevant();
     } else if (!XFormsSingleNodeControl.isRelevant(this)) {
       // We were and are non-relevant, no update
       return false;
     } else {
       // If the itemsets changed, then we need to send an update
       // NOTE: This also covers the case where the control was and is non-relevant
       return !Itemset.compareItemsets(
           otherSelect1Control.getItemset(propertyContext), getItemset(propertyContext));
     }
   }
 }
  protected void handleControlStart(
      String uri,
      String localname,
      String qName,
      Attributes attributes,
      String staticId,
      String effectiveId,
      XFormsControl control)
      throws SAXException {
    // Get items, dynamic or static, if possible
    final XFormsSelect1Control xformsSelect1Control = (XFormsSelect1Control) control;

    // Get items if:
    // 1. The itemset is static
    // 2. The control exists and is relevant
    final Itemset itemset =
        XFormsSelect1Control.getInitialItemset(
            pipelineContext, containingDocument, xformsSelect1Control, getPrefixedId());

    outputContent(
        uri,
        localname,
        attributes,
        effectiveId,
        xformsSelect1Control,
        itemset,
        isMultiple,
        isFull,
        false);
  }
  /**
   * Get itemset for a selection control given either directly or by id. If the control is null or
   * non-relevant, lookup by id takes place and the control must have a static itemset or otherwise
   * null is returned.
   *
   * @param pipelineContext current pipeline context
   * @param containingDocument current containing document
   * @param control control from which to obtain itemset (may be null if control has a static
   *     itemset)
   * @param prefixedId prefixed id of control from which to obtain itemset (if control is null)
   * @return itemset or null if it is not possible to obtain it
   */
  public static Itemset getInitialItemset(
      PipelineContext pipelineContext,
      XFormsContainingDocument containingDocument,
      XFormsSelect1Control control,
      String prefixedId) {

    if (control != null && control.isRelevant()) {
      // Control is there and relevant so just ask it (this will include static itemsets evaluation
      // as well)
      return control.getItemset(pipelineContext);
    } else if (isStaticItemset(containingDocument, prefixedId)) {
      // Control is not there or is not relevant, so use static itemsets
      // NOTE: This way we output static itemsets during initialization as well, even for
      // non-relevant controls
      return ((SelectionControl) containingDocument.getStaticState().getControlAnalysis(prefixedId))
          .evaluateStaticItemset();
    } else {
      // Not possible so return null
      return null;
    }
  }