public void Merge()
        {
            if (_mergedAssemblies.Count == 0 && _mergedModules.Count == 0)
            {
                return;
            }

            CollectMainReferences();

            // Relocate main assembly.
            {
                var relocator = new SignatureRelocator(this, null);
                relocator.Build(_assembly.Module);
            }

            // Merge modules.
            foreach (var mergedModule in _mergedModules)
            {
                MergeModule(mergedModule);
            }

            // Merge assemblies.
            foreach (var mergedAssembly in _mergedAssemblies)
            {
                MergeAssembly(mergedAssembly);
            }

            AddMainReferences();

            CreateStartupMethods();

            UnloadMergedModules();
        }
        private void MergeAssembly(MergeAssemblyState state)
        {
            var relocator = new SignatureRelocator(this, state.Modules[0]);

            // Resources
            foreach (var resource in state.Resources)
            {
                var mergedResource = _assembly.Resources.Add();
                resource.CopyTo(mergedResource);
                relocator.Build(mergedResource);
            }

            MergeModuleReferences(state);

            // Modules
            foreach (var moduleState in state.Modules)
            {
                MergeModule(moduleState);
            }
        }
        private void MergeModule(MergeModuleState state)
        {
            var module       = _assembly.Module;
            var mergedModule = state.Module;
            var relocator    = new SignatureRelocator(this, state);

            // Types
            foreach (var type in state.Types)
            {
                var mergedType = module.Types.Add();
                type.CopyTo(mergedType);
                relocator.Build(mergedType);

                bool isGlobal = mergedType.IsGlobal();

                var typeRef = mergedType.ToReference(mergedType.Module);

                string newName;
                if (state.RenamedTypeNames.TryGetValue(typeRef, out newName))
                {
                    mergedType.Name = newName;
                }

                if (isGlobal)
                {
                    MergeGlobalType(mergedType);
                }
            }

            // Assembly references
            foreach (var assemblyRef in mergedModule.AssemblyReferences)
            {
                if (_assembly.Name == assemblyRef.Name)
                {
                    continue;
                }

                if (_mergedAssemblyByName.ContainsKey(assemblyRef.Name))
                {
                    continue;
                }

                if (!_assemblyRefs.Contains(assemblyRef))
                {
                    _assemblyRefs.Add(assemblyRef);
                }
            }

            // Exproted types
            foreach (var exportedType in mergedModule.ExportedTypes)
            {
                var enclosingExportedType = (TypeReference)exportedType.GetOutermostType();
                if (!_exportedTypeToOwner.ContainsKey(enclosingExportedType))
                {
                    continue;
                }

                if (!_exportedTypes.Contains(exportedType))
                {
                    _exportedTypes.Add(exportedType);
                }
            }
        }