public void Init( int?streamOfProviderIfApplicable, EnumMethodEnum enumMethodEnum, String enumMethodUsedName, EPType typeInfo, IList <ExprNode> parameters, ExprValidationContext validationContext) { var eventTypeColl = EPTypeHelper.GetEventTypeMultiValued(typeInfo); var eventTypeBean = EPTypeHelper.GetEventTypeSingleValued(typeInfo); var collectionComponentType = EPTypeHelper.GetClassMultiValued(typeInfo); _enumMethodEnum = enumMethodEnum; _enumMethodUsedName = enumMethodUsedName; _streamCountIncoming = validationContext.StreamTypeService.EventTypes.Length; if (eventTypeColl == null && collectionComponentType == null && eventTypeBean == null) { throw new ExprValidationException( "Invalid input for built-in enumeration method '" + enumMethodUsedName + "', expecting collection of event-type or scalar values as input, received " + EPTypeHelper.ToTypeDescriptive(typeInfo)); } // compile parameter abstract for validation against available footprints var footprintProvided = DotMethodUtil.GetProvidedFootprint(parameters); // validate parameters DotMethodInputTypeMatcher inputTypeMatcher = new ProxyDotMethodInputTypeMatcher { ProcMatches = fp => { if (fp.Input == DotMethodFPInputEnum.EVENTCOLL && eventTypeBean == null && eventTypeColl == null) { return(false); } if (fp.Input == DotMethodFPInputEnum.SCALAR_ANY && collectionComponentType == null) { return(false); } return(true); } }; var footprint = DotMethodUtil.ValidateParametersDetermineFootprint( enumMethodEnum.GetFootprints(), DotMethodTypeEnum.ENUM, enumMethodUsedName, footprintProvided, inputTypeMatcher); // validate input criteria met for this footprint if (footprint.Input != DotMethodFPInputEnum.ANY) { var message = "Invalid input for built-in enumeration method '" + enumMethodUsedName + "' and " + footprint.Parameters.Length + "-parameter footprint, expecting collection of "; var received = " as input, received " + EPTypeHelper.ToTypeDescriptive(typeInfo); if (footprint.Input == DotMethodFPInputEnum.EVENTCOLL && eventTypeColl == null) { throw new ExprValidationException(message + "events" + received); } if (footprint.Input.IsScalar() && collectionComponentType == null) { throw new ExprValidationException(message + "values (typically scalar values)" + received); } if (footprint.Input == DotMethodFPInputEnum.SCALAR_NUMERIC && !collectionComponentType.IsNumeric()) { throw new ExprValidationException(message + "numeric values" + received); } } // manage context of this lambda-expression in regards to outer lambda-expression that may call this one. ExpressionResultCacheForEnumerationMethod enumerationMethodCache = validationContext.ExprEvaluatorContext.ExpressionResultCacheService.AllocateEnumerationMethod; enumerationMethodCache.PushStack(this); var bodiesAndParameters = new List <ExprDotEvalParam>(); var count = 0; var inputEventType = eventTypeBean ?? eventTypeColl; foreach (var node in parameters) { var bodyAndParameter = GetBodyAndParameter( enumMethodUsedName, count++, node, inputEventType, collectionComponentType, validationContext, bodiesAndParameters, footprint); bodiesAndParameters.Add(bodyAndParameter); } _enumEval = GetEnumEval( validationContext.EngineImportService, validationContext.EventAdapterService, validationContext.StreamTypeService, validationContext.StatementId, enumMethodUsedName, bodiesAndParameters, inputEventType, collectionComponentType, _streamCountIncoming, validationContext.IsDisablePropertyExpressionEventCollCache); _enumEvalNumRequiredEvents = _enumEval.StreamNumSize; // determine the stream ids of event properties asked for in the Evaluator(s) var streamsRequired = new HashSet <int>(); var visitor = new ExprNodeIdentifierCollectVisitor(); foreach (var desc in bodiesAndParameters) { desc.Body.Accept(visitor); foreach (var ident in visitor.ExprProperties) { streamsRequired.Add(ident.StreamId); } } if (streamOfProviderIfApplicable != null) { streamsRequired.Add(streamOfProviderIfApplicable.Value); } // We turn on caching if the stack is not empty (we are an inner lambda) and the dependency does not include the stream. var isInner = !enumerationMethodCache.PopLambda(); if (isInner) { // If none of the properties that the current lambda uses comes from the ultimate Parent(s) or subsequent streams, then cache. var parents = enumerationMethodCache.GetStack(); var found = false; foreach (var req in streamsRequired) { var first = (ExprDotEvalEnumMethodBase)parents.First; var parentIncoming = first._streamCountIncoming - 1; var selfAdded = _streamCountIncoming; // the one we use ourselfs if (req > parentIncoming && req < selfAdded) { found = true; } } _cache = !found; } }