/**
   * @param independentExpressions
   * @param dependentExpressions
   * @param makeDep
   * @return
   * @throws TeiidComponentException
   * @throws QueryMetadataException
   * @since 4.3
   */
  private PlanNode getDependentCriteriaNode(
      String id,
      List<Expression> independentExpressions,
      List<Expression> dependentExpressions,
      PlanNode indNode,
      QueryMetadataInterface metadata,
      DependentCostAnalysis dca,
      Boolean bound,
      MakeDep makeDep)
      throws QueryMetadataException, TeiidComponentException {

    Float cardinality = null;

    List<DependentSetCriteria.AttributeComparison> expressions =
        new ArrayList<DependentSetCriteria.AttributeComparison>(dependentExpressions.size());

    for (int i = 0; i < dependentExpressions.size(); i++) {
      Expression depExpr = dependentExpressions.get(i);
      Expression indExpr = independentExpressions.get(i);

      DependentSetCriteria.AttributeComparison comp =
          new DependentSetCriteria.AttributeComparison();
      if (dca != null && dca.expectedNdv[i] != null) {
        if (dca.expectedNdv[i] > 4 * dca.maxNdv[i]) {
          continue; // not necessary to use
        }
        comp.ndv = dca.expectedNdv[i];
        comp.maxNdv = dca.maxNdv[i];
      } else {
        Collection<ElementSymbol> elems = ElementCollectorVisitor.getElements(indExpr, true);
        if (cardinality == null) {
          cardinality = NewCalculateCostUtil.computeCostForTree(indNode, metadata);
        }
        comp.ndv = NewCalculateCostUtil.getNDVEstimate(indNode, metadata, cardinality, elems, true);
        if (bound) {
          if (dca != null) {
            comp.maxNdv = Math.max(comp.ndv * 4, dca.expectedCardinality * 2);
          } else {
            comp.maxNdv = Math.max(UNKNOWN_INDEPENDENT_CARDINALITY, comp.ndv * 4);
          }
        }
      }
      comp.ind = indExpr;
      comp.dep = SymbolMap.getExpression(depExpr);
      expressions.add(comp);
    }

    PlanNode result = createDependentSetNode(id, expressions);
    if (makeDep != null) {
      DependentSetCriteria dsc = (DependentSetCriteria) result.getProperty(Info.SELECT_CRITERIA);
      dsc.setMakeDepOptions(makeDep);
    }
    return result;
  }