OrganizedOperands organizeOperands(ExecutionContext context) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    // get the list of operands to evaluate, and evaluate operands that can use
    // indexes first.
    List evalOperands = new ArrayList(_operands.length);
    int indexCount = 0;
    // TODO: Check if we can defer the creation of this array list only
    // if there exists an eval operand
    List compositeIterOperands = new ArrayList(_operands.length);
    // Asif: This Map will contain as key the composite filter operand & as
    // value , the set containing independent RuntimeIterators ( which will
    // necessarily be two )
    Map compositeFilterOpsMap = new LinkedHashMap();
    Map iterToOperands = new HashMap();
    CompiledValue operand = null;
    boolean isJunctionNeeded = false;
    boolean indexExistsOnNonJoinOp = false;

    for (final CompiledValue compiledValue : _operands) {
      // Asif : If we are inside this function this itself indicates
      // that there exists at least on operand which can be evaluated
      // as an auxFilterEvaluate. If any operand even if its flag of
      // evalAsFilter happens to be false, but if it is independently
      // evaluable, we should attach it with the auxFilterevaluable
      // operands irrespective of its value ( either true or false.)
      // This is because if it is true or false, it can always be paired
      // up with other filter operands for AND junction. But for
      // OR junction it can get paired with the filterOperands only
      // if it is false. But we do not have to worry about whether
      // the junction is AND or OR because, if the independent operand's
      // value is true & was under an OR junction , it would not have
      // been filterEvaluated. Instead it would have gone for auxIterEvaluate.
      // We are here itself implies, that any independent operand can be
      // either true or false for an AND junction but always false for an
      // OR Junction.
      operand = compiledValue;
      if (!operand.isDependentOnCurrentScope(context)) {
        indexCount++;
        // Asif Ensure that independent operands are always at the start
        evalOperands.add(0, operand);
      } else if (operand instanceof CompiledJunction) {
        if (operand.getPlanInfo(context).evalAsFilter) {
          // Asif Ensure that independent operands are always at the start
          evalOperands.add(indexCount++, operand);
        } else {
          evalOperands.add(operand);
        }
      } else {
        // If the operand happens to be a Like predicate , this is the point
        // where we can expand as now the structures created are all for the current
        // execution. We expand only if the current junction is AND because if its
        // OR we cannot bring Like at level of OR , because like itself is an AND
        // Also cannot expand for NOT LIKE because CCs generated by CompiledLike with AND
        // will be converted to OR by negation
        CompiledValue[] expandedOperands = null;

        if (operand.getType() == LIKE && _operator == OQLLexerTokenTypes.LITERAL_and
            && ((CompiledLike) operand).getOperator() != OQLLexerTokenTypes.TOK_NE) {
          expandedOperands =
              ((CompiledLike) operand).getExpandedOperandsWithIndexInfoSetIfAny(context);
        } else {
          expandedOperands = new CompiledValue[] {operand};
        }

        for (CompiledValue expndOperand : expandedOperands) {
          boolean operandEvalAsFilter = expndOperand.getPlanInfo(context).evalAsFilter;
          isJunctionNeeded = isJunctionNeeded || operandEvalAsFilter;
          Set set = QueryUtils.getCurrentScopeUltimateRuntimeIteratorsIfAny(expndOperand, context);
          if (set.size() != 1) {
            // Asif: A set of size not equal to 1 ( which can mean anything more
            // than 1, will mean a composite condition. For a Composite
            // Condition which is filter evaluable that means necessarily that
            // RHS is dependent on one independent iterator & LHS on the other.
            if (operandEvalAsFilter) {
              Support.Assert(set.size() == 2,
                  " The no of independent iterators should be equal to 2");
              compositeFilterOpsMap.put(expndOperand, set);
            } else {
              compositeIterOperands.add(expndOperand);
            }
          } else {
            Support.Assert(set.size() == 1,
                "The size has to be 1 & cannot be zero as that would mean it is independent");
            RuntimeIterator rIter = (RuntimeIterator) set.iterator().next();
            List operandsList = (List) iterToOperands.get(rIter);
            if (operandsList == null) {
              operandsList = new ArrayList();
              iterToOperands.put(rIter, operandsList);
            }
            if (operandEvalAsFilter && _operator == LITERAL_and) {
              indexExistsOnNonJoinOp = true;
            }
            operandsList.add(expndOperand);
          }
        }
      }
    }
    /*
     * Asif : If there exists a SingleGroupJunction & no other Filter operand , then all remaining
     * eval operands ( even if they are CompiledJunction which are not evaluable as Filter) &
     * composite operands should become part of GroupJunction. If there exists only
     * SingleGroupJunction & at least one Filter operand, then all conditions of GroupJunction which
     * are not filter evaluable should become iter operand of CompiledJunction. If there exists an
     * AllGroupJunction & no Filter operand, then all remaining iter operands of CompiledJunction
     * along with Composite operands should be part of AllGroupJunction. If there exists at least
     * one Filter operand , all remaining operands of AllGroupJunction ( including those
     * GroupJunction not filter evaluable should become part of eval operand of CompiledJunction)
     * The index count will give the idea of number of filter operands
     */
    if (isJunctionNeeded) {
      // There exists at least one condition which must have an index available.
      Filter junction = createJunction(compositeIterOperands, compositeFilterOpsMap, iterToOperands,
          context, indexCount, evalOperands, indexExistsOnNonJoinOp);
      // Asif Ensure that independent operands are always at the start
      evalOperands.add(indexCount++, junction);
    } else {
      // if(compositeIterOperands != null) {
      if (!compositeIterOperands.isEmpty()) {
        evalOperands.addAll(compositeIterOperands);
      }
      for (final Object o : iterToOperands.values()) {
        evalOperands.addAll((List) o);
      }
    }
    OrganizedOperands result = new OrganizedOperands();
    // Group the operands into those that use indexes and those that don't,
    // so we can evaluate all the operands that don't use indexes together in
    // one iteration first get filter operands
    Filter filterOperands = null;
    // there must be at least one filter operand or else we wouldn't be here
    Support.Assert(indexCount > 0);
    if (indexCount == 1) {
      filterOperands = (Filter) evalOperands.get(0);
      result.isSingleFilter = true;
    } else {
      CompiledValue[] newOperands = new CompiledValue[indexCount];
      for (int i = 0; i < indexCount; i++) {
        newOperands[i] = (CompiledValue) evalOperands.get(i);
      }
      filterOperands = new CompiledJunction(newOperands, _operator);
    }
    // get iterating operands
    // INVARIANT: the number of iterating operands when the _operator is
    // LITERAL_or must be zero. This is an invariant on filter evaluation
    CompiledValue iterateOperands = null;
    // int numIterating = _operands.length - indexCount;
    int numIterating = evalOperands.size() - indexCount;
    Support.Assert(_operator == LITERAL_and || numIterating == 0);
    if (numIterating > 0) {
      if (numIterating == 1) {
        iterateOperands = (CompiledValue) evalOperands.get(indexCount);
      } else {
        CompiledValue[] newOperands = new CompiledValue[numIterating];
        for (int i = 0; i < numIterating; i++) {
          newOperands[i] = (CompiledValue) evalOperands.get(i + indexCount);
        }
        iterateOperands = new CompiledJunction(newOperands, _operator);
      }
    }
    result.filterOperand = filterOperands;
    result.iterateOperand = iterateOperands;
    return result;
  }
TODO: Should composite operands be part of iterator operands of CompiledJunction or should it
be part of AllGroupJunction Write a unit Test for this function.

Asif: The iterators which can be considered part of GroupJunction are those which are
exclusively dependent only on the independent iterator of the group. Any iterator which is
ultimately dependent on more than one independent iterators cannot be assumed to be part of the
GroupJunction, even if one of independent iterator belongs to a different scope.

@return New combination of AbstractCompiledValue(s) in form of CompiledJunction.
geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledJunction.java