/**
   * This method is used to pass an algorithm decorator factory that is used for tracing (for
   * example). See {@link #checkedRules(Object, Object[], IRuntimeEnv)} for full documentation
   *
   * @param target target object
   * @param params parameters of a test
   * @param env environment
   * @param decoratorFactory a decorator factory that will decorate an objects that are used to
   *     calculate a rule
   * @return iterator over <b>rule indexes</b> - integer iterator.
   * @see #checkedRules(Object, Object[], IRuntimeEnv)
   */
  protected final IIntIterator checkedRules(
      Object target,
      Object[] params,
      IRuntimeEnv env,
      DefaultAlgorithmDecoratorFactory decoratorFactory) {

    // Select rules set using indexed mode
    //
    //        ICondition[] conditions = table.getConditionRows();

    IIntIterator iterator = null;
    int conditionNumber = info.fromCondition;

    if (indexRoot == null) {
      iterator = info.makeRuleIterator();
    } else {

      ARuleIndex index = indexRoot;

      for (; conditionNumber <= info.toCondition; conditionNumber++) {
        index = decoratorFactory.create(index, table.getCondition(conditionNumber));

        Object testValue =
            evaluateTestValue(table.getCondition(conditionNumber), target, params, env);

        DecisionTableRuleNode node = index.findNode(testValue);

        if (!node.hasIndex()) {
          iterator = node.getRulesIterator();
          conditionNumber += 1;
          break;
        }

        index = node.getNextIndex();
      }
    }

    for (; conditionNumber <= info.toCondition; conditionNumber++) {

      ICondition condition = table.getCondition(conditionNumber);
      IConditionEvaluator evaluator = evaluators[conditionNumber];

      IIntSelector sel = evaluator.getSelector(condition, target, params, env);
      sel = decoratorFactory.create(sel, condition);

      iterator = iterator.select(sel);
    }

    return iterator;
  }
 /**
  * Clears condition's param values.
  *
  * <p>Memory optimization: clear condition values because this values will be used in index(only
  * if it condition is not used).
  */
 public void removeParamValuesForIndexedConditions() {
   for (int i = info.fromRule; i <= info.toCondition; i++) {
     if (evaluators[i].isIndexed()) {
       if (!isDependecyOnConditionExists(table.getCondition(i))) {
         table.getCondition(i).clearParamValues();
       }
     } else {
       final IConditionEvaluator evaluator = evaluators[i];
       evaluators[i] = new ConditionEvaluatorDecoratorAsNotIndexed(evaluator);
       break;
     }
   }
   // we do not need dependencies after clearing conditions
   dependencies = null;
 }
 public DecisionTableOptimizedAlgorithm(
     IConditionEvaluator[] evaluators, DecisionTable table, IndexInfo info, ARuleIndex indexRoot) {
   this.evaluators = evaluators;
   this.table = table;
   this.info = info;
   this.indexRoot = indexRoot;
   this.dependencies = new RulesBindingDependencies();
   table.updateDependency(dependencies);
 }