static void InjectOnCreateForCompiler(TypeDefinition typeDefinition)
        {
            // Turns out it's not trivial to inject some code that has to be run OnCreate of the system.
            // We cannot just create an OnCreate() method, because there might be a deriving class that also implements it.
            // That child method is probably not calling base.OnCreate(), but even when it is (!!) the c# compiler bakes base.OnCreate()
            // into a direct reference to whatever is the first baseclass to have OnCreate() at the time of compilation.  So if we go
            // and inject an OnCreate() in this class later on,  the child's base.OnCreate() call will actually bypass it.
            //
            // Instead what we do is add OnCreateForCompiler,  hide it from intellisense, give you an error if wanna be that guy that goes
            // and implement it anyway,  and then we inject a OnCreateForCompiler method into each and every ComponentSystem.  The reason we have to emit it in
            // each and every system, and not just the ones where we have something to inject,  is that when we emit these method, we need
            // to also emit base.OnCreateForCompiler().  However, when we are processing an user system type,  we do not know yet if its baseclass
            // also needs an OnCreateForCompiler().   So we play it safe, and assume it does.  So every OnCreateForCompiler() that we emit,
            // will assume its basetype also has an implementation and invoke that.

            if (typeDefinition.Name == nameof(ComponentSystemBase) && typeDefinition.Namespace == "Unity.Entities")
            {
                return;
            }

            var onCreateForCompilerName = EntitiesILHelpers.GetOnCreateForCompilerName();
            var preExistingMethod       = typeDefinition.Methods.FirstOrDefault(m => m.Name == onCreateForCompilerName);

            if (preExistingMethod != null)
            {
                UserError.DC0026($"It's not allowed to implement {onCreateForCompilerName}'", preExistingMethod).Throw();
            }

            EntitiesILHelpers.GetOrMakeOnCreateForCompilerMethodFor(typeDefinition);
        }
        private static MethodDefinition InjectOnCreateForCompiler(TypeDefinition typeDefinition)
        {
            // Turns out it's not trivial to inject some code that has to be run OnCreate of the system.
            // We cannot just create an OnCreate() method, because there might be a deriving class that also implements it.
            // That child method is probably not calling base.OnCreate(), but even when it is (!!) the c# compiler bakes base.OnCreate()
            // into a direct reference to whatever is the first baseclass to have OnCreate() at the time of compilation.  So if we go
            // and inject an OnCreate() in this class later on,  the child's base.OnCreate() call will actually bypass it.
            //
            // Instead what we do is add OnCreateForCompiler,  hide it from intellisense, give you an error if wanna be that guy that goes
            // and implement it anyway,  and then we inject a OnCreateForCompiler method into each and every ComponentSystem.  The reason we have to emit it in
            // each and every system, and not just the ones where we have something to inject,  is that when we emit these method, we need
            // to also emit base.OnCreateForCompiler().  However, when we are processing an user system type,  we do not know yet if its baseclass
            // also needs an OnCreateForCompiler().   So we play it safe, and assume it does.  So every OnCreateForCompiler() that we emit,
            // will assume its basetype also has an implementation and invoke that.

            if (typeDefinition.Name == nameof(ComponentSystemBase) && typeDefinition.Namespace == "Unity.Entities")
            {
                return(null);
            }

            var name = OnCreateForCompilerName;

            var pre_existing_method = typeDefinition.Methods.FirstOrDefault(m => m.Name == name);

            if (pre_existing_method != null)
            {
                UserError.DC0026($"It's not allowed to implement {OnCreateForCompilerName}'", pre_existing_method).Throw();
            }

            var typeSystemVoid = typeDefinition.Module.TypeSystem.Void;
            var newMethod      = new MethodDefinition(name, MethodAttributes.FamORAssem | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeSystemVoid);

            typeDefinition.Methods.Add(newMethod);

            var ilProcessor = newMethod.Body.GetILProcessor();

            ilProcessor.Emit(OpCodes.Ldarg_0);
            ilProcessor.Emit(OpCodes.Call, new MethodReference(name, typeSystemVoid, typeDefinition.BaseType)
            {
                HasThis = true
            });
            ilProcessor.Emit(OpCodes.Ret);
            return(newMethod);
        }