private void LoadTypes(TypeDeclarationCollection types, MergeModuleState state)
 {
     foreach (var type in types)
     {
         LoadType(type, state);
     }
 }
            private bool BuildTypeRef(TypeReference typeRef, ref ModuleReference moduleRef, ref string name)
            {
                MergeModuleState moduleState = null;

                if (_moduleState != null)
                {
                    MergeAssemblyState assemblyState;
                    if (!_merge._mergedAssemblyByName.TryGetValue(_moduleState.Module.Assembly.Name, out assemblyState))
                    {
                        return(false);
                    }

                    if (!assemblyState.ModuleByName.TryGetValue(moduleRef.Name, out moduleState))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!_merge._mergedModuleByName.TryGetValue(moduleRef.Name, out moduleState))
                    {
                        return(false);
                    }
                }

                string newName;

                if (moduleState.RenamedTypeNames.TryGetValue(typeRef, out newName))
                {
                    name = newName;
                }

                moduleRef = null;
                return(true);
            }
        private MergeModuleState LoadModule(Module module, MergeDuplicateBehavior duplicateBehavior)
        {
            var state = new MergeModuleState();

            state.Module            = module;
            state.DuplicateBehavior = duplicateBehavior;

            LoadTypes(module.Types, state);

            return(state);
        }
        private void LoadGlobalType(TypeDeclaration type, MergeModuleState state)
        {
            if (!type.HasMembers())
            {
                return;
            }

            TypeReference typeRef;

            do
            {
                string newName = _random.NextString(12);
                typeRef = new TypeReference(newName);
            }while (_typeRefs.Contains(typeRef));

            _typeRefs.Add(typeRef);
            state.Types.Add(type);
            state.RenamedTypeNames.Add(type.ToReference(), typeRef.Name);
        }
 internal SignatureRelocator(AssemblyMerge merge, MergeModuleState moduleState)
 {
     _merge       = merge;
     _moduleState = moduleState;
 }
        private void LoadType(TypeDeclaration type, MergeModuleState state)
        {
            if (type.IsGlobal())
            {
                LoadGlobalType(type, state);
                return;
            }

            var typeRef = type.ToReference();

            // Check existing type.
            if (!_typeRefs.Contains(typeRef))
            {
                // Type does not exists.
                _typeRefs.Add(typeRef);
                state.Types.Add(type);
                return;
            }

            // Check exported type.
            Signature exportedTypeOwner;

            if (_exportedTypeToOwner.TryGetValue(typeRef, out exportedTypeOwner))
            {
                // Type exists as exported type.
                switch (exportedTypeOwner.SignatureType)
                {
                case SignatureType.Module:
                {
                    var moduleRef = (ModuleReference)exportedTypeOwner;
                    if (state.Module.Name == moduleRef.Name)
                    {
                        _exportedTypeToOwner.Remove(typeRef);
                        state.Types.Add(type);
                        return;
                    }
                }
                break;

                case SignatureType.Assembly:
                {
                    var assemblyRef = (AssemblyReference)exportedTypeOwner;
                    if (state.Module.Assembly.Name == assemblyRef.Name)
                    {
                        _exportedTypeToOwner.Remove(typeRef);
                        state.Types.Add(type);
                        return;
                    }
                }
                break;

                default:
                    throw new InvalidOperationException();
                }
            }

            // Type is duplicate.
            switch (state.DuplicateBehavior)
            {
            case MergeDuplicateBehavior.Rename:
            {
                int index = 1;

                var newTypeRef = typeRef;
                do
                {
                    string newName = typeRef.Name + (++index).ToString();
                    newTypeRef = new TypeReference(newName, typeRef.Namespace);
                }while (_typeRefs.Contains(newTypeRef));

                _typeRefs.Add(newTypeRef);
                state.Types.Add(type);
                state.RenamedTypeNames.Add(typeRef, newTypeRef.Name);
            }
                return;

            case MergeDuplicateBehavior.Skip:
                return;

            case MergeDuplicateBehavior.Throw:
                throw new AssemblyDefenderException(string.Format(SR.MergeDuplicatedType, type.FullName, type.Module.ToString()));

            default:
                throw new InvalidOperationException();
            }
        }
        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);
                }
            }
        }