private static CodeGen AddIDynamicObject(TypeGen newType, Slot dictSlot)
            {
                Slot classSlot = newType.AddStaticField(typeof(DynamicType), FieldAttributes.Private, "$class");

                newType.myType.AddInterfaceImplementation(typeof(ISuperDynamicObject));
                /* GetDynamicType */

                CodeGen gdtCg = newType.DefineMethodOverride(typeof(IDynamicObject).GetMethod("GetDynamicType"));

                CodeGen cg = newType.DefineUserHiddenMethod(MethodAttributes.FamORAssem | MethodAttributes.Static,
                    "$$GetOrMakeDynamicType", typeof(DynamicType), new Type[0]);
                DoLazyInitCheck(cg, classSlot,
                    delegate() {
                        // if not null, just return the value.
                        classSlot.EmitGet(cg);
                        cg.EmitReturn();
                    },
                    delegate() {
                        // initialization code

                        // CompiledType GetTypeForType(Type t)
                        cg.EmitType(newType.myType);
                        cg.EmitCall(typeof(CompiledType), "GetTypeForType");
                        cg.Emit(OpCodes.Dup);
                        classSlot.EmitSet(cg);

                        cg.EmitReturn();
                    });

                cg.Finish();
                CodeGen ret = cg;

                // just a call to the helper method
                gdtCg.EmitThis();
                gdtCg.EmitCall(typeof(object), "GetType");
                gdtCg.EmitType(newType.myType);
                Label differ = gdtCg.DefineLabel();
                gdtCg.Emit(OpCodes.Bne_Un, differ);

                gdtCg.EmitCall(cg.MethodInfo);
                gdtCg.EmitReturn();

                gdtCg.MarkLabel(differ);

                gdtCg.EmitThis();
                gdtCg.EmitCall(typeof(object), "GetType");
                gdtCg.EmitCall(typeof(Ops), "GetDynamicTypeFromType");
                gdtCg.EmitReturn();

                gdtCg.Finish();

                /* GetDict */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("GetDict"));
                DoLazyInitCheck(cg, dictSlot,
                    delegate() {
                        // if not null, just return the value.
                        dictSlot.EmitGet(cg);
                        cg.EmitReturn();
                    },
                    delegate() {
                        // initialization code - dictSlot = new CustomOldClassDict()
                        cg.EmitNew(typeof(CustomOldClassDict).GetConstructor(new Type[0]));
                        cg.Emit(OpCodes.Dup);
                        dictSlot.EmitSet(cg);

                        cg.EmitReturn();
                    });
                cg.Finish();

                /* SetDict */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDict"));
                cg.EmitString("SetDict");
                cg.EmitInt(0);
                cg.Emit(OpCodes.Newarr, typeof(object));
                cg.EmitCall(typeof(Ops), "NotImplementedError");
                cg.Emit(OpCodes.Throw);

                /* SetDynamicType */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDynamicType"));
                cg.EmitString("SetDynamicType");
                cg.EmitInt(0);
                cg.Emit(OpCodes.Newarr, typeof(object));
                cg.EmitCall(typeof(Ops), "NotImplementedError");
                cg.Emit(OpCodes.Throw);

                return ret;
            }
        internal static CodeGen GenerateModuleInitialize(CompilerContext context, GlobalSuite gs, TypeGen tg, bool staticTypes, CustomModuleInit customInit)
        {
            CodeGen ncg = tg.DefineMethodOverride(typeof(CompiledModule).GetMethod("Initialize", BindingFlags.Public | BindingFlags.Instance));
            ncg.Context = context;
            ncg.EmitSetTraceBackUpdateStatus(false);

            ncg.Names = CodeGen.CreateStaticFieldNamespace(tg);

            if (context.TrueDivision) {
                ncg.ModuleSlot.EmitGet(ncg);
                ncg.EmitInt(1);
                ncg.EmitCall(typeof(ICallerContext), "set_TrueDivision");
            }

            // Add __doc__ and __name__
            ncg.Names.CreateGlobalSlot(SymbolTable.Doc);
            ncg.Names.CreateGlobalSlot(SymbolTable.Name);

            string doc = gs.Documentation;
            ncg.EmitStringOrNull(doc);
            ncg.EmitSet(SymbolTable.Doc);

            if (customInit != null) customInit(ncg);

            if (staticTypes) {
                UserTypeGenerator.DoStaticCompilation(gs, ncg);
            } else {
                gs.Emit(ncg);
            }

            ncg.EmitPosition(Location.None, Location.None);
            ncg.EmitReturn();
            ncg.Finish();

            FinishCustomDict(tg, ncg.Names);

            return ncg;
        }