public EntitiesILPostProcessorProfileMarker CreateChildMarker(string sectionName)
        {
            var newMarker = new EntitiesILPostProcessorProfileMarker(m_AssemblyName, sectionName);

            newMarker.m_IsChild = true;
            m_ChildMarkers.Add(newMarker);
            return(newMarker);
        }
        public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
        {
            if (!WillProcess(compiledAssembly))
            {
                return(null);
            }

            using (var marker = new EntitiesILPostProcessorProfileMarker(compiledAssembly.Name))
            {
                bool madeAnyChange = false;
                Defines = compiledAssembly.Defines;
                var assemblyDefinition = AssemblyDefinitionFor(compiledAssembly);
                var postProcessors     = FindAllEntitiesILPostProcessors();

                TypeDefinition[] componentSystemTypes;
                using (marker.CreateChildMarker("GetAllComponentTypes"))
                    componentSystemTypes = assemblyDefinition.MainModule.GetAllTypes().Where(TypeDefinitionExtensions.IsComponentSystem).ToArray();

                using (marker.CreateChildMarker("InjectOnCreateForCompiler"))
                {
                    foreach (var systemType in componentSystemTypes)
                    {
                        InjectOnCreateForCompiler(systemType);
                        madeAnyChange = true;
                    }
                }

                var diagnostics = new List <DiagnosticMessage>();
                foreach (var postProcessor in postProcessors)
                {
                    postProcessor.Defines = Defines;
                    using (marker.CreateChildMarker(postProcessor.GetType().Name))
                    {
                        diagnostics.AddRange(postProcessor.PostProcess(assemblyDefinition, componentSystemTypes, out var madeChange));
                        madeAnyChange |= madeChange;
                    }
                }

                var unmanagedComponentSystemTypes = assemblyDefinition.MainModule.GetAllTypes().Where((x) => x.TypeImplements(typeof(ISystemBase))).ToArray();
                foreach (var postProcessor in postProcessors)
                {
                    diagnostics.AddRange(postProcessor.PostProcessUnmanaged(assemblyDefinition, unmanagedComponentSystemTypes, out var madeChange));
                    madeAnyChange |= madeChange;
                }

                // Hack to remove Entities => Entities circular references
                var selfName = assemblyDefinition.Name.FullName;
                foreach (var referenceName in assemblyDefinition.MainModule.AssemblyReferences)
                {
                    if (referenceName.FullName == selfName)
                    {
                        assemblyDefinition.MainModule.AssemblyReferences.Remove(referenceName);
                        break;
                    }
                }

                if (!madeAnyChange || diagnostics.Any(d => d.DiagnosticType == DiagnosticType.Error))
                {
                    return(new ILPostProcessResult(null, diagnostics));
                }

                using (marker.CreateChildMarker("WriteAssembly"))
                {
                    var pe  = new MemoryStream();
                    var pdb = new MemoryStream();
                    var writerParameters = new WriterParameters
                    {
                        SymbolWriterProvider = new PortablePdbWriterProvider(), SymbolStream = pdb, WriteSymbols = true
                    };

                    assemblyDefinition.Write(pe, writerParameters);
                    return(new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), diagnostics));
                }
            }
        }