private boolean visitRule(RenderingRule rule, boolean loadOutput) {
    RenderingRuleProperty[] properties = rule.getProperties();
    for (int i = 0; i < properties.length; i++) {
      RenderingRuleProperty rp = properties[i];
      if (rp.isInputProperty()) {
        boolean match;
        if (rp.isFloat()) {
          match = rp.accept(rule.getFloatProp(i), fvalues[rp.getId()], this);
        } else {
          match = rp.accept(rule.getIntProp(i), values[rp.getId()], this);
        }
        if (!match) {
          return false;
        }
      } else if (rp == storage.PROPS.R_DISABLE) {
        // quick disable return even without load output
        values[rp.getId()] = rule.getIntProp(i);
      }
    }
    if (!loadOutput) {
      return true;
    }
    // accept it
    for (int i = 0; i < properties.length; i++) {
      RenderingRuleProperty rp = properties[i];
      if (rp.isOutputProperty()) {
        searchResult = true;
        if (rp.isFloat()) {
          fvalues[rp.getId()] = rule.getFloatProp(i);
          values[rp.getId()] = rule.getIntProp(i);
        } else {
          values[rp.getId()] = rule.getIntProp(i);
        }
      }
    }

    for (RenderingRule rr : rule.getIfElseChildren()) {
      boolean match = visitRule(rr, loadOutput);
      if (match) {
        break;
      }
    }

    for (RenderingRule rr : rule.getIfChildren()) {
      visitRule(rr, loadOutput);
    }
    return true;
  }
 public void setBooleanFilter(RenderingRuleProperty p, boolean filter) {
   assert p.isInputProperty();
   values[p.getId()] =
       filter ? RenderingRuleProperty.TRUE_VALUE : RenderingRuleProperty.FALSE_VALUE;
 }
 public void setIntFilter(RenderingRuleProperty p, int filter) {
   assert p.isInputProperty();
   values[p.getId()] = filter;
 }
 public void setStringFilter(RenderingRuleProperty p, String filter) {
   assert p.isInputProperty();
   values[p.getId()] = storage.getDictionaryValue(filter);
 }