public static CollectionExecutor buildCollectionExecutor(CollectionExpression collectionExpression,
                                                             MatchingMetaInfoHolder matchingMetaInfoHolder,
                                                             List<VariableExpressionExecutor>
                                                                     variableExpressionExecutors,
                                                             Map<String, Table> tableMap,
                                                             boolean isFirst,
                                                             ProcessingMode processingMode,
                                                             boolean outputExpectsExpiredEvents,
                                                             SiddhiQueryContext siddhiQueryContext, boolean isCache,
                                                             CacheTable cacheTable) {
        if (collectionExpression instanceof AttributeCollectionExpression) {
            ExpressionExecutor expressionExecutor = null;
            if (isFirst) {
                expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                        tableMap, variableExpressionExecutors, false, 0,
                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
            }
            if (isCache) {
                return new CompareCollectionExecutor(expressionExecutor,
                        matchingMetaInfoHolder.getStoreEventIndex(), ((AttributeCollectionExpression)
                        collectionExpression).getAttribute(), Compare.Operator.EQUAL, new
                        ConstantExpressionExecutor(true, Attribute.Type.BOOL), cacheTable);
            } else {
                return new CompareCollectionExecutor(expressionExecutor, matchingMetaInfoHolder.getStoreEventIndex(), (
                        (AttributeCollectionExpression) collectionExpression).getAttribute(), Compare.Operator.EQUAL,
                        new ConstantExpressionExecutor(true, Attribute.Type.BOOL), null);
            }
        } else if (collectionExpression instanceof CompareCollectionExpression) {
            ExpressionExecutor valueExpressionExecutor = ExpressionParser.parseExpression(
                    ((CompareCollectionExpression) collectionExpression).getValueCollectionExpression().getExpression(),
                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(), tableMap,
                    variableExpressionExecutors, false, 0,
                    processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
            AttributeCollectionExpression attributeCollectionExpression = ((AttributeCollectionExpression)
                    ((CompareCollectionExpression) collectionExpression).getAttributeCollectionExpression());
            ExpressionExecutor expressionExecutor = null;
            if (isFirst) {
                expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                        tableMap, variableExpressionExecutors, false, 0,
                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
            }
            if (isCache) {
                return new CompareCollectionExecutor(expressionExecutor, matchingMetaInfoHolder.
                        getStoreEventIndex(), attributeCollectionExpression.getAttribute(),
                        ((CompareCollectionExpression) collectionExpression).getOperator(), valueExpressionExecutor,
                        cacheTable);
            } else {
                return new CompareCollectionExecutor(expressionExecutor, matchingMetaInfoHolder.getStoreEventIndex(),
                        attributeCollectionExpression.getAttribute(), ((CompareCollectionExpression)
                        collectionExpression).getOperator(), valueExpressionExecutor, null);
            }
        } else if (collectionExpression instanceof NullCollectionExpression) {
            ExpressionExecutor expressionExecutor = null;
            if (isFirst) {
                expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                        tableMap, variableExpressionExecutors, false, 0,
                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
            }
            if (isCache) {
                return new CompareCollectionExecutor(expressionExecutor, matchingMetaInfoHolder.
                        getStoreEventIndex(), ((NullCollectionExpression) collectionExpression).getAttribute(),
                        Compare.Operator.EQUAL, new ConstantExpressionExecutor(null, Attribute.Type.OBJECT),
                        cacheTable);
            } else {
                return new CompareCollectionExecutor(expressionExecutor, matchingMetaInfoHolder.getStoreEventIndex(), (
                        (NullCollectionExpression) collectionExpression).getAttribute(),
                        Compare.Operator.EQUAL, new ConstantExpressionExecutor(null, Attribute.Type.OBJECT), null);
            }
        } else if (collectionExpression instanceof AndMultiPrimaryKeyCollectionExpression) {
            Map<String, ExpressionExecutor> multiPrimaryKeyExpressionExecutors =
                    buildMultiPrimaryKeyExpressionExecutors(collectionExpression,
                            matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
            List<Attribute> attributes = matchingMetaInfoHolder.getStoreDefinition().getAttributeList();
            StringBuilder compositePrimaryKey = new StringBuilder();
            List<ExpressionExecutor> sortedExecutors = new ArrayList<ExpressionExecutor>();
            for (Attribute attribute : attributes) {
                ExpressionExecutor expressionExecutor = multiPrimaryKeyExpressionExecutors.get(attribute.getName());
                if (expressionExecutor != null) {
                    sortedExecutors.add(expressionExecutor);
                    compositePrimaryKey.append(attribute.getName()).append(SiddhiConstants.KEY_DELIMITER);
                }
            }
            if (isCache) {
                return new AndMultiPrimaryKeyCollectionExecutor(compositePrimaryKey.toString(), sortedExecutors,
                        cacheTable);
            } else {
                return new AndMultiPrimaryKeyCollectionExecutor(compositePrimaryKey.toString(), sortedExecutors, null);
            }
        } else if (collectionExpression instanceof AndCollectionExpression) {
            CollectionExpression leftCollectionExpression = ((AndCollectionExpression) collectionExpression)
                    .getLeftCollectionExpression();
            CollectionExpression rightCollectionExpression = ((AndCollectionExpression) collectionExpression)
                    .getRightCollectionExpression();
            ExpressionExecutor expressionExecutor = null;
            CollectionExecutor aCollectionExecutor = null;
            ExhaustiveCollectionExecutor exhaustiveCollectionExecutor = null;
            CollectionExecutor leftCollectionExecutor;
            CollectionExecutor rightCollectionExecutor;
            switch (leftCollectionExpression.getCollectionScope()) {
                case NON:
                    switch (rightCollectionExpression.getCollectionScope()) {

                        case NON:
                            expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                            .getCurrentState(), tableMap, variableExpressionExecutors,
                                    false, 0, processingMode,
                                    outputExpectsExpiredEvents, siddhiQueryContext);
                            return new NonCollectionExecutor(expressionExecutor);
                        case INDEXED_ATTRIBUTE:
                        case INDEXED_RESULT_SET:
                        case PRIMARY_KEY_ATTRIBUTE:
                        case PRIMARY_KEY_RESULT_SET:
                        case PARTIAL_PRIMARY_KEY_RESULT_SET:
                        case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                        case EXHAUSTIVE:
                            expressionExecutor = ExpressionParser.parseExpression(leftCollectionExpression
                                            .getExpression(),
                                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                            .getCurrentState(), tableMap, variableExpressionExecutors,
                                    false, 0, processingMode,
                                    outputExpectsExpiredEvents, siddhiQueryContext);
                            aCollectionExecutor = buildCollectionExecutor(rightCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            return new NonAndCollectionExecutor(expressionExecutor, aCollectionExecutor,
                                    rightCollectionExpression.getCollectionScope());
                    }
                    break;
                case INDEXED_ATTRIBUTE:
                case PRIMARY_KEY_ATTRIBUTE:
                    switch (rightCollectionExpression.getCollectionScope()) {

                        case NON:
                            expressionExecutor = ExpressionParser.parseExpression(rightCollectionExpression
                                            .getExpression(),
                                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                            .getCurrentState(), tableMap, variableExpressionExecutors,
                                    false, 0, processingMode,
                                    outputExpectsExpiredEvents, siddhiQueryContext);
                            aCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            return new NonAndCollectionExecutor(expressionExecutor, aCollectionExecutor,
                                    rightCollectionExpression.getCollectionScope());
                        case INDEXED_ATTRIBUTE:
                        case INDEXED_RESULT_SET:
                        case PRIMARY_KEY_ATTRIBUTE:
                        case PRIMARY_KEY_RESULT_SET:
                        case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                            exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                    .parseExpression(collectionExpression.getExpression(),
                                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                    .getCurrentState(), tableMap, variableExpressionExecutors,
                                            false, 0,
                                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                    matchingMetaInfoHolder.getStoreEventIndex());
                            leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            rightCollectionExecutor = buildCollectionExecutor(rightCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            return new AnyAndCollectionExecutor(leftCollectionExecutor, rightCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                        case PARTIAL_PRIMARY_KEY_RESULT_SET:
                        case EXHAUSTIVE:
                            leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            if (isFirst || leftCollectionExecutor.getDefaultCost() == CollectionExecutor.Cost
                                    .SINGLE_RETURN_INDEX_MATCHING) {
                                exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                        .parseExpression(collectionExpression.getExpression(),
                                                matchingMetaInfoHolder.getMetaStateEvent(),
                                                matchingMetaInfoHolder.getCurrentState(), tableMap,
                                                variableExpressionExecutors, false, 0,
                                                processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                        matchingMetaInfoHolder.getStoreEventIndex());
                            }
                            return new CompareExhaustiveAndCollectionExecutor(leftCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                    }
                    break;
                case INDEXED_RESULT_SET:
                case PRIMARY_KEY_RESULT_SET:
                case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                    switch (rightCollectionExpression.getCollectionScope()) {

                        case NON:
                            expressionExecutor = ExpressionParser.parseExpression(rightCollectionExpression
                                            .getExpression(),
                                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                            .getCurrentState(), tableMap, variableExpressionExecutors,
                                    false, 0, processingMode,
                                    outputExpectsExpiredEvents, siddhiQueryContext);
                            aCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            return new NonAndCollectionExecutor(expressionExecutor, aCollectionExecutor,
                                    rightCollectionExpression.getCollectionScope());

                        case INDEXED_ATTRIBUTE:
                        case PRIMARY_KEY_ATTRIBUTE:
                            exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                    .parseExpression(collectionExpression.getExpression(),
                                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                    .getCurrentState(), tableMap, variableExpressionExecutors,
                                            false, 0,
                                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                    matchingMetaInfoHolder.getStoreEventIndex());
                            leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            rightCollectionExecutor = buildCollectionExecutor(rightCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            return new AnyAndCollectionExecutor(rightCollectionExecutor, leftCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                        case INDEXED_RESULT_SET:
                        case PRIMARY_KEY_RESULT_SET:
                        case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                            exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                    .parseExpression(collectionExpression.getExpression(),
                                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                    .getCurrentState(), tableMap, variableExpressionExecutors,
                                            false, 0,
                                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                    matchingMetaInfoHolder.getStoreEventIndex());
                            leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            rightCollectionExecutor = buildCollectionExecutor(rightCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    false, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                            return new AnyAndCollectionExecutor(leftCollectionExecutor, rightCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                        case PARTIAL_PRIMARY_KEY_RESULT_SET:
                        case EXHAUSTIVE:
                            leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            if (isFirst || leftCollectionExecutor.getDefaultCost() == CollectionExecutor.Cost
                                    .SINGLE_RETURN_INDEX_MATCHING) {
                                exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                        .parseExpression(collectionExpression.getExpression(),
                                                matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                        .getCurrentState(), tableMap,
                                                variableExpressionExecutors, false, 0,
                                                processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                        matchingMetaInfoHolder.getStoreEventIndex());
                            }
                            return new CompareExhaustiveAndCollectionExecutor(leftCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                    }
                    break;
                case PARTIAL_PRIMARY_KEY_RESULT_SET:
                case EXHAUSTIVE:
                    switch (rightCollectionExpression.getCollectionScope()) {

                        case NON:
                            expressionExecutor = ExpressionParser.parseExpression(rightCollectionExpression
                                            .getExpression(),
                                    matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                            .getCurrentState(), tableMap, variableExpressionExecutors,
                                    false, 0,
                                    processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                            aCollectionExecutor = buildCollectionExecutor(leftCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            return new NonAndCollectionExecutor(expressionExecutor, aCollectionExecutor,
                                    rightCollectionExpression.getCollectionScope());

                        case INDEXED_ATTRIBUTE:
                        case INDEXED_RESULT_SET:
                        case PRIMARY_KEY_ATTRIBUTE:
                        case PRIMARY_KEY_RESULT_SET:
                        case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                            rightCollectionExecutor = buildCollectionExecutor(rightCollectionExpression,
                                    matchingMetaInfoHolder, variableExpressionExecutors, tableMap,
                                    isFirst, processingMode, outputExpectsExpiredEvents, siddhiQueryContext, false,
                                    null);
                            if (isFirst || rightCollectionExecutor.getDefaultCost() == CollectionExecutor.Cost
                                    .SINGLE_RETURN_INDEX_MATCHING) {
                                exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser
                                        .parseExpression(collectionExpression.getExpression(),
                                                matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                        .getCurrentState(), tableMap,
                                                variableExpressionExecutors, false, 0,
                                                processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                        matchingMetaInfoHolder.getStoreEventIndex());
                            }
                            return new CompareExhaustiveAndCollectionExecutor(rightCollectionExecutor,
                                    exhaustiveCollectionExecutor);
                        case PARTIAL_PRIMARY_KEY_RESULT_SET:
                        case EXHAUSTIVE:
                            if (isFirst) {
                                expressionExecutor = ExpressionParser.parseExpression(collectionExpression
                                                .getExpression(),
                                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder
                                                .getCurrentState(),
                                        tableMap, variableExpressionExecutors, false, 0,
                                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                            }
                            return new ExhaustiveCollectionExecutor(expressionExecutor, matchingMetaInfoHolder
                                    .getStoreEventIndex());
                    }
                    break;
            }
        } else if (collectionExpression instanceof OrCollectionExpression) {
            CollectionExpression leftCollectionExpression = ((OrCollectionExpression) collectionExpression)
                    .getLeftCollectionExpression();
            CollectionExpression rightCollectionExpression = ((OrCollectionExpression) collectionExpression)
                    .getRightCollectionExpression();
            ExpressionExecutor expressionExecutor = null;
            CollectionExecutor aCollectionExecutor = null;
            CollectionExecutor leftCollectionExecutor;
            CollectionExecutor rightCollectionExecutor;
            if (leftCollectionExpression.getCollectionScope() == CollectionExpression.CollectionScope.NON &&
                    rightCollectionExpression.getCollectionScope() == CollectionExpression.CollectionScope.NON) {
                expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                        tableMap, variableExpressionExecutors, false, 0,
                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                return new NonCollectionExecutor(expressionExecutor);
            } else if ((leftCollectionExpression.getCollectionScope() ==
                    CollectionExpression.CollectionScope.EXHAUSTIVE &&
                    leftCollectionExpression.getCollectionScope() ==
                            CollectionExpression.CollectionScope.PARTIAL_PRIMARY_KEY_RESULT_SET)
                    || (rightCollectionExpression.getCollectionScope() ==
                    CollectionExpression.CollectionScope.EXHAUSTIVE &&
                    rightCollectionExpression.getCollectionScope() ==
                            CollectionExpression.CollectionScope.PARTIAL_PRIMARY_KEY_RESULT_SET)) {
                if (isFirst) {
                    expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                            tableMap, variableExpressionExecutors, false, 0,
                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                }
                return new ExhaustiveCollectionExecutor(expressionExecutor,
                        matchingMetaInfoHolder.getStoreEventIndex());
            } else {
                if (isFirst) {
                    aCollectionExecutor = new ExhaustiveCollectionExecutor(ExpressionParser.parseExpression(
                            collectionExpression.getExpression(),
                            matchingMetaInfoHolder.getMetaStateEvent(),
                            matchingMetaInfoHolder.getCurrentState(),
                            tableMap, variableExpressionExecutors, false,
                            0, processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                            matchingMetaInfoHolder.getStoreEventIndex());
                }
                leftCollectionExecutor = buildCollectionExecutor(leftCollectionExpression, matchingMetaInfoHolder,
                        variableExpressionExecutors, tableMap, isFirst, processingMode,
                        outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                rightCollectionExecutor = buildCollectionExecutor(rightCollectionExpression, matchingMetaInfoHolder,
                        variableExpressionExecutors, tableMap, isFirst, processingMode,
                        outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                return new OrCollectionExecutor(leftCollectionExecutor, rightCollectionExecutor, aCollectionExecutor);
            }
        } else if (collectionExpression instanceof NotCollectionExpression) {
            ExpressionExecutor expressionExecutor = null;
            switch (collectionExpression.getCollectionScope()) {

                case NON:
                    expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                            tableMap, variableExpressionExecutors, false, 0,
                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                    return new NonCollectionExecutor(expressionExecutor);
                case INDEXED_ATTRIBUTE:
                case INDEXED_RESULT_SET:
                case PRIMARY_KEY_ATTRIBUTE:
                case PRIMARY_KEY_RESULT_SET:
                case OPTIMISED_PRIMARY_KEY_OR_INDEXED_RESULT_SET:
                    ExhaustiveCollectionExecutor exhaustiveCollectionExecutor = null;
                    if (isFirst) {
                        exhaustiveCollectionExecutor = new ExhaustiveCollectionExecutor(
                                ExpressionParser.parseExpression(collectionExpression.getExpression(),
                                        matchingMetaInfoHolder.getMetaStateEvent(),
                                        matchingMetaInfoHolder.getCurrentState(), tableMap, variableExpressionExecutors,
                                        false, 0,
                                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext),
                                matchingMetaInfoHolder.getStoreEventIndex());
                    }
                    CollectionExecutor notCollectionExecutor = buildCollectionExecutor(((NotCollectionExpression)
                                    collectionExpression).getCollectionExpression(), matchingMetaInfoHolder,
                            variableExpressionExecutors, tableMap, isFirst, processingMode,
                            outputExpectsExpiredEvents, siddhiQueryContext, false, null);
                    return new NotCollectionExecutor(notCollectionExecutor, exhaustiveCollectionExecutor);

                case PARTIAL_PRIMARY_KEY_RESULT_SET:
                case EXHAUSTIVE:
                    if (isFirst) {
                        expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                                matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                                tableMap, variableExpressionExecutors, false, 0,
                                processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                    }
                    return new ExhaustiveCollectionExecutor(expressionExecutor, matchingMetaInfoHolder
                            .getStoreEventIndex());
            }
        } else { // Basic
            ExpressionExecutor expressionExecutor = null;

            if (collectionExpression.getCollectionScope() == CollectionExpression.CollectionScope.NON) {
                expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                        matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                        tableMap, variableExpressionExecutors, false, 0,
                        processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                return new NonCollectionExecutor(expressionExecutor);
            } else { // EXHAUSTIVE
                if (isFirst) {
                    expressionExecutor = ExpressionParser.parseExpression(collectionExpression.getExpression(),
                            matchingMetaInfoHolder.getMetaStateEvent(), matchingMetaInfoHolder.getCurrentState(),
                            tableMap, variableExpressionExecutors, false, 0,
                            processingMode, outputExpectsExpiredEvents, siddhiQueryContext);
                }
                return new ExhaustiveCollectionExecutor(expressionExecutor,
                        matchingMetaInfoHolder.getStoreEventIndex());
            }
        }
        throw new UnsupportedOperationException(collectionExpression.getClass().getName() + " not supported!");
    }
Parse the given expression and create the appropriate Executor by recursively traversing the expression.

@param expression             Expression to be parsed
@param matchingMetaInfoHolder matchingMetaInfoHolder
@param indexedEventHolder     indexed event holder
@return ExpressionExecutor
modules/siddhi-core/src/main/java/io/siddhi/core/util/parser/CollectionExpressionParser.java