public void InstanceCodegen(
            CodegenInstanceAux instance,
            CodegenClassScope classScope,
            CodegenCtor factoryCtor,
            IList<CodegenTypedParam> factoryMembers)
        {
            instance.Properties.AddProperty(
                typeof(AggregationService),
                "AggregationService",
                GetType(),
                classScope,
                node => node.GetterBlock.BlockReturn(MEMBER_AGGREGATIONSVC));
            instance.Methods.AddMethod(
                typeof(ExprEvaluatorContext),
                "GetAgentInstanceContext",
                EmptyList<CodegenNamedParam>.Instance,
                GetType(),
                classScope,
                node => node.Block.ReturnMethodOrBlock(MEMBER_AGENTINSTANCECONTEXT));
            instance.Properties.AddProperty(
                typeof(bool),
                "IsSelectRStream",
                typeof(ResultSetProcessorRowForAll),
                classScope,
                node => node.GetterBlock.BlockReturn(Constant(IsSelectRStream)));

            var rollupDesc = classScope.AddDefaultFieldUnshared(
                true,
                typeof(AggregationGroupByRollupDesc),
                GroupByRollupDesc.Codegen(classScope.NamespaceScope.InitMethod, classScope));

            instance.Properties.AddProperty(
                typeof(AggregationGroupByRollupDesc),
                "GroupByRollupDesc",
                typeof(ResultSetProcessorRowPerGroupRollup),
                classScope,
                node => node.GetterBlock.BlockReturn(rollupDesc));

            GenerateGroupKeySingle = ResultSetProcessorGroupedUtil.GenerateGroupKeySingleCodegen(GroupKeyNodeExpressions, MultiKeyClassRef, classScope, instance);
            ResultSetProcessorRowPerGroupRollupImpl.RemovedAggregationGroupKeyCodegen(classScope, instance);
            ResultSetProcessorRowPerGroupRollupImpl.GenerateOutputBatchedMapUnsortedCodegen(this, instance, classScope);
            ResultSetProcessorRowPerGroupRollupImpl.GenerateOutputBatchedCodegen(this, instance, classScope);

            // generate having clauses
            var havingForges = PerLevelForges.OptionalHavingForges;
            if (havingForges != null) {
                factoryMembers.Add(
                    new CodegenTypedParam(typeof(HavingClauseEvaluator[]), NAME_HAVINGEVALUATOR_ARRAYNONMEMBER));
                factoryCtor.Block.AssignRef(
                    NAME_HAVINGEVALUATOR_ARRAYNONMEMBER,
                    NewArrayByLength(typeof(HavingClauseEvaluator), Constant(havingForges.Length)));
                for (var i = 0; i < havingForges.Length; i++) {
                    var evaluateHaving = new CodegenExpressionLambda(factoryCtor.Block)
                        .WithParams(PARAMS)
                        .WithBody(block => block.BlockReturn(
                            CodegenLegoMethodExpression.CodegenBooleanExpressionReturnTrueFalse(
                                havingForges[i],
                                classScope,
                                factoryCtor,
                                REF_EPS,
                                ResultSetProcessorCodegenNames.REF_ISNEWDATA,
                                REF_EXPREVALCONTEXT)));

                    var impl = NewInstance<ProxyHavingClauseEvaluator>(evaluateHaving);

                    //var evaluateHaving = CodegenMethod.MakeMethod(typeof(bool), GetType(), classScope)
                    //    .AddParam(PARAMS);
                    //impl.AddMethod("EvaluateHaving", evaluateHaving);

                    factoryCtor.Block.AssignArrayElement(NAME_HAVINGEVALUATOR_ARRAYNONMEMBER, Constant(i), impl);
                }
            }
        }