public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            // define stop
            var stopCallbacks = new List <StopCallback>();

            // determine context
            var contextName = _statementSpec.OptionalContextName;

            // Create view factories and parent view based on a filter specification
            // Since only for non-joins we get the existing stream's lock and try to reuse it's views
            var filterStreamSpec = (FilterStreamSpecCompiled)_statementSpec.StreamSpecs[0];
            InstrumentationAgent instrumentationAgentCreateWindowInsert = null;

            if (InstrumentationHelper.ENABLED)
            {
                var eventTypeName = filterStreamSpec.FilterSpec.FilterForEventType.Name;
                instrumentationAgentCreateWindowInsert = new ProxyInstrumentationAgent()
                {
                    ProcIndicateQ = () => InstrumentationHelper.Get().QFilterActivationNamedWindowInsert(eventTypeName),
                    ProcIndicateA = () => InstrumentationHelper.Get().AFilterActivationNamedWindowInsert(),
                };
            }
            var activator = services.ViewableActivatorFactory.CreateFilterProxy(services, filterStreamSpec.FilterSpec, statementContext.Annotations, false, instrumentationAgentCreateWindowInsert, false, 0);

            // create data window view factories
            var unmaterializedViewChain = services.ViewService.CreateFactories(0, filterStreamSpec.FilterSpec.ResultEventType, filterStreamSpec.ViewSpecs, filterStreamSpec.Options, statementContext, false, -1);

            // verify data window
            VerifyDataWindowViewFactoryChain(unmaterializedViewChain.FactoryChain);

            // get processor for variant-streams and versioned typed
            var windowName = _statementSpec.CreateWindowDesc.WindowName;
            var optionalRevisionProcessor = statementContext.ValueAddEventService.GetValueAddProcessor(windowName);

            // add named window processor (one per named window for all agent instances)
            var isPrioritized = services.EngineSettingsService.EngineSettings.ExecutionConfig.IsPrioritized;
            var isEnableSubqueryIndexShare = HintEnum.ENABLE_WINDOW_SUBQUERY_INDEXSHARE.GetHint(_statementSpec.Annotations) != null;

            if (!isEnableSubqueryIndexShare && unmaterializedViewChain.FactoryChain[0] is VirtualDWViewFactory)
            {
                isEnableSubqueryIndexShare = true;      // index share is always enabled for virtual data window (otherwise it wouldn't make sense)
            }
            var isBatchingDataWindow     = DetermineBatchingDataWindow(unmaterializedViewChain.FactoryChain);
            var virtualDataWindowFactory = DetermineVirtualDataWindow(unmaterializedViewChain.FactoryChain);
            var optionalUniqueKeyProps   = ViewServiceHelper.GetUniqueCandidateProperties(unmaterializedViewChain.FactoryChain, _statementSpec.Annotations);
            var processor = services.NamedWindowMgmtService.AddProcessor(
                windowName, contextName, filterStreamSpec.FilterSpec.ResultEventType,
                statementContext.StatementResultService, optionalRevisionProcessor, statementContext.Expression,
                statementContext.StatementName, isPrioritized, isEnableSubqueryIndexShare, isBatchingDataWindow,
                virtualDataWindowFactory != null, optionalUniqueKeyProps,
                _statementSpec.CreateWindowDesc.AsEventTypeName,
                statementContext, services.NamedWindowDispatchService);

            Viewable finalViewable;
            EPStatementStopMethod    stopStatementMethod;
            EPStatementDestroyMethod destroyStatementMethod;

            try {
                // add stop callback
                stopCallbacks.Add(new ProxyStopCallback(() =>
                {
                    services.NamedWindowMgmtService.RemoveProcessor(windowName);
                    if (virtualDataWindowFactory != null)
                    {
                        virtualDataWindowFactory.DestroyNamedWindow();
                    }
                }));

                // Add a wildcard to the select clause as subscribers received the window contents
                _statementSpec.SelectClauseSpec.SetSelectExprList(new SelectClauseElementWildcard());
                _statementSpec.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH;

                // obtain result set processor factory
                StreamTypeService typeService   = new StreamTypeServiceImpl(new EventType[] { processor.NamedWindowType }, new string[] { windowName }, new bool[] { true }, services.EngineURI, false);
                var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype(
                    _statementSpec, statementContext, typeService, null, new bool[0], true, null, null, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, false, false);

                // obtain factory for output limiting
                var outputViewFactory = OutputProcessViewFactoryFactory.Make(
                    _statementSpec,
                    services.InternalEventRouter,
                    statementContext,
                    resultSetProcessorPrototype.ResultSetProcessorFactory.ResultEventType, null,
                    services.TableService,
                    resultSetProcessorPrototype.ResultSetProcessorFactory.ResultSetProcessorType,
                    services.ResultSetProcessorHelperFactory,
                    services.StatementVariableRefService);

                // create context factory
                // Factory for statement-context instances
                var contextFactory = new StatementAgentInstanceFactoryCreateWindow(statementContext, _statementSpec, services, activator, unmaterializedViewChain, resultSetProcessorPrototype, outputViewFactory, isRecoveringStatement);
                statementContext.StatementAgentInstanceFactory = contextFactory;

                // With context - delegate instantiation to context
                EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);
                if (_statementSpec.OptionalContextName != null)
                {
                    var mergeView = new ContextMergeView(processor.NamedWindowType);
                    finalViewable = mergeView;

                    var statement = new ContextManagedStatementCreateWindowDesc(_statementSpec, statementContext, mergeView, contextFactory);
                    services.ContextManagementService.AddStatement(contextName, statement, isRecoveringResilient);
                    stopStatementMethod = new ProxyEPStatementStopMethod(() =>
                    {
                        services.ContextManagementService.StoppedStatement(contextName, statementContext.StatementName, statementContext.StatementId, statementContext.Expression, statementContext.ExceptionHandlingService);
                        stopMethod.Stop();
                    });

                    destroyStatementMethod = new ProxyEPStatementDestroyMethod(() =>
                                                                               services.ContextManagementService.DestroyedStatement(contextName, statementContext.StatementName, statementContext.StatementId));
                }
                // Without context - start here
                else
                {
                    var agentInstanceContext = GetDefaultAgentInstanceContext(statementContext);
                    StatementAgentInstanceFactoryCreateWindowResult resultOfStart;
                    try {
                        resultOfStart = (StatementAgentInstanceFactoryCreateWindowResult)contextFactory.NewContext(agentInstanceContext, isRecoveringResilient);
                    }
                    catch (Exception) {
                        services.NamedWindowMgmtService.RemoveProcessor(windowName);
                        throw;
                    }
                    finalViewable = resultOfStart.FinalView;
                    var stopCallback = services.EpStatementFactory.MakeStopMethod(resultOfStart);
                    stopStatementMethod = new ProxyEPStatementStopMethod(() =>
                    {
                        stopCallback.Stop();
                        stopMethod.Stop();
                    });
                    destroyStatementMethod = null;

                    if (statementContext.StatementExtensionServicesContext != null && statementContext.StatementExtensionServicesContext.StmtResources != null)
                    {
                        var holder = statementContext.StatementExtensionServicesContext.ExtractStatementResourceHolder(resultOfStart);
                        statementContext.StatementExtensionServicesContext.StmtResources.Unpartitioned = holder;
                        statementContext.StatementExtensionServicesContext.PostProcessStart(resultOfStart, isRecoveringResilient);
                    }
                }
            }
            catch (ExprValidationException) {
                services.NamedWindowMgmtService.RemoveProcessor(windowName);
                throw;
            }
            catch (Exception) {
                services.NamedWindowMgmtService.RemoveProcessor(windowName);
                throw;
            }

            services.StatementVariableRefService.AddReferences(statementContext.StatementName, windowName);

            return(new EPStatementStartResult(finalViewable, stopStatementMethod, destroyStatementMethod));
        }
        public override EPStatementStartResult StartInternal(
            EPServicesContext services,
            StatementContext statementContext,
            bool isNewStatement,
            bool isRecoveringStatement,
            bool isRecoveringResilient)
        {
            var statementSpec = base.StatementSpec;

            // define stop and destroy
            var stopCallbacks    = new List <StopCallback>();
            var destroyCallbacks = new EPStatementDestroyCallbackList();

            // determine context
            var contextName = statementSpec.OptionalContextName;

            if (contextName != null)
            {
                throw new ExprValidationException("Update IStream is not supported in conjunction with a context");
            }

            // First we create streams for subselects, if there are any
            var subSelectStreamDesc =
                EPStatementStartMethodHelperSubselect.CreateSubSelectActivation(
                    services, statementSpec, statementContext, destroyCallbacks);

            var    streamSpec = statementSpec.StreamSpecs[0];
            var    updateSpec = statementSpec.UpdateSpec;
            string triggereventTypeName;

            if (streamSpec is FilterStreamSpecCompiled)
            {
                var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec;
                triggereventTypeName = filterStreamSpec.FilterSpec.FilterForEventTypeName;
            }
            else if (streamSpec is NamedWindowConsumerStreamSpec)
            {
                var namedSpec = (NamedWindowConsumerStreamSpec)streamSpec;
                triggereventTypeName = namedSpec.WindowName;
            }
            else if (streamSpec is TableQueryStreamSpec)
            {
                throw new ExprValidationException("Tables cannot be used in an update-istream statement");
            }
            else
            {
                throw new ExprValidationException("Unknown stream specification streamEventType: " + streamSpec);
            }

            // determine a stream name
            var streamName = triggereventTypeName;

            if (updateSpec.OptionalStreamName != null)
            {
                streamName = updateSpec.OptionalStreamName;
            }

            var streamEventType = services.EventAdapterService.GetEventTypeByName(triggereventTypeName);
            var typeService     = new StreamTypeServiceImpl(
                new EventType[] { streamEventType },
                new string[] { streamName },
                new bool[] { true },
                services.EngineURI, false);

            // determine subscriber result types
            var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false);

            statementContext.StatementResultService.SetSelectClause(
                new Type[] { streamEventType.UnderlyingType },
                new string[] { "*" },
                false, null, evaluatorContextStmt);

            // Materialize sub-select views
            var subSelectStrategyCollection =
                EPStatementStartMethodHelperSubselect.PlanSubSelect(
                    services, statementContext, IsQueryPlanLogging(services), subSelectStreamDesc, new string[]
            {
                streamName
            }, new EventType[]
            {
                streamEventType
            }, new string[]
            {
                triggereventTypeName
            }, statementSpec.DeclaredExpressions, null);

            var validationContext = new ExprValidationContext(
                statementContext.Container,
                typeService,
                statementContext.EngineImportService,
                statementContext.StatementExtensionServicesContext,
                null,
                statementContext.SchedulingService,
                statementContext.VariableService,
                statementContext.TableService, evaluatorContextStmt,
                statementContext.EventAdapterService,
                statementContext.StatementName,
                statementContext.StatementId,
                statementContext.Annotations,
                statementContext.ContextDescriptor,
                statementContext.ScriptingService,
                false, false, false, false, null,
                false);

            foreach (var assignment in updateSpec.Assignments)
            {
                var validated = ExprNodeUtility.GetValidatedAssignment(assignment, validationContext);
                assignment.Expression = validated;
                EPStatementStartMethodHelperValidate.ValidateNoAggregations(
                    validated, "Aggregation functions may not be used within an update-clause");
            }
            if (updateSpec.OptionalWhereClause != null)
            {
                var validated = ExprNodeUtility.GetValidatedSubtree(
                    ExprNodeOrigin.WHERE, updateSpec.OptionalWhereClause, validationContext);
                updateSpec.OptionalWhereClause = validated;
                EPStatementStartMethodHelperValidate.ValidateNoAggregations(
                    validated, "Aggregation functions may not be used within an update-clause");
            }

            // preprocessing view
            var onExprView = new InternalRoutePreprocessView(streamEventType, statementContext.StatementResultService);

            // validation
            var routerDesc =
                services.InternalEventRouter.GetValidatePreprocessing(
                    onExprView.EventType, updateSpec, statementContext.Annotations);

            // create context factory
            var contextFactory = new StatementAgentInstanceFactoryUpdate(
                statementContext, services, streamEventType, updateSpec, onExprView, routerDesc,
                subSelectStrategyCollection);

            statementContext.StatementAgentInstanceFactory = contextFactory;

            // perform start of hook-up to start
            Viewable finalViewable;
            EPStatementStopMethod stopStatementMethod;
            IDictionary <ExprSubselectNode, SubSelectStrategyHolder> subselectStrategyInstances;

            // With context - delegate instantiation to context
            var stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks);

            if (statementSpec.OptionalContextName != null)
            {
                // use statement-wide agent-instance-specific subselects
                var aiRegistryExpr = statementContext.StatementAgentInstanceRegistry.AgentInstanceExprService;
                subselectStrategyInstances = new Dictionary <ExprSubselectNode, SubSelectStrategyHolder>();
                foreach (var node in subSelectStrategyCollection.Subqueries.Keys)
                {
                    var specificService = aiRegistryExpr.AllocateSubselect(node);
                    node.Strategy = specificService;
                    subselectStrategyInstances.Put(
                        node, new SubSelectStrategyHolder(null, null, null, null, null, null, null));
                }

                var mergeView = new ContextMergeView(onExprView.EventType);
                finalViewable = mergeView;

                var statement = new ContextManagedStatementOnTriggerDesc(
                    statementSpec, statementContext, mergeView, contextFactory);
                services.ContextManagementService.AddStatement(
                    statementSpec.OptionalContextName, statement, isRecoveringResilient);
                stopStatementMethod = new ProxyEPStatementStopMethod
                {
                    ProcStop = () =>
                    {
                        services.ContextManagementService.StoppedStatement(
                            contextName, statementContext.StatementName, statementContext.StatementId,
                            statementContext.Expression, statementContext.ExceptionHandlingService);
                        stopMethod.Stop();
                    }
                };

                destroyCallbacks.AddCallback(
                    new EPStatementDestroyCallbackContext(
                        services.ContextManagementService, statementSpec.OptionalContextName,
                        statementContext.StatementName, statementContext.StatementId));
            }
            else
            {
                // Without context - start here
                var agentInstanceContext = GetDefaultAgentInstanceContext(statementContext);
                var resultOfStart        =
                    (StatementAgentInstanceFactoryUpdateResult)
                    contextFactory.NewContext(agentInstanceContext, isRecoveringResilient);
                finalViewable = resultOfStart.FinalView;
                var stopCallback = services.EpStatementFactory.MakeStopMethod(resultOfStart);
                stopStatementMethod = new ProxyEPStatementStopMethod
                {
                    ProcStop = () =>
                    {
                        stopCallback.Stop();
                        stopMethod.Stop();
                    }
                };
                subselectStrategyInstances = resultOfStart.SubselectStrategies;

                if (statementContext.StatementExtensionServicesContext != null &&
                    statementContext.StatementExtensionServicesContext.StmtResources != null)
                {
                    var holder =
                        statementContext.StatementExtensionServicesContext.ExtractStatementResourceHolder(resultOfStart);
                    statementContext.StatementExtensionServicesContext.StmtResources.Unpartitioned = holder;
                    statementContext.StatementExtensionServicesContext.PostProcessStart(
                        resultOfStart, isRecoveringResilient);
                }
            }

            // assign subquery nodes
            EPStatementStartMethodHelperAssignExpr.AssignSubqueryStrategies(
                subSelectStrategyCollection, subselectStrategyInstances);

            return(new EPStatementStartResult(finalViewable, stopStatementMethod, destroyCallbacks));
        }