protected override void ProcessAssembly(AssemblyDefinition assemblyDef)
        {
            if (_frameworkProfile == null) {
                _frameworkProfile = assemblyDef.GuessAssemblyProfile();
            }
            if (_frameworkProfile != null) {
                _assemblyResolver.AddSearchDirectory(_frameworkProfile.ReferencesDirectory);
            }
            var typesDependenciesCollector = new CollectTypesDependenciesProcessor(_frameworkProfile);
            typesDependenciesCollector.Process(assemblyDef);

            var goodAssemblyNames = assemblyDef.Modules.SelectMany(asmDef => asmDef.AssemblyReferences);
            if(_removeNonRetargetable) {
                goodAssemblyNames = goodAssemblyNames.Where(asmRef => asmRef.IsRetargetable);
            }
            if (_frameworkProfile != null) {
                goodAssemblyNames = goodAssemblyNames.Concat(_frameworkProfile.GetFrameworkAssemblies());
            }

            var goodModules = new HashSet<ModuleDefinition>(CecilEqualityComparer.Default);
            goodModules.AddRange(assemblyDef.Modules);
            goodModules.AddRange(goodAssemblyNames.Select(_assemblyResolver.TryResolve).Where(asmDef => asmDef != null).SelectMany(asmDef => asmDef.Modules));

            var allTypesDependencies = typesDependenciesCollector.AllTypesDependencies;
            var typeDependenciesToRemove = new Queue<TypeReferenceAndDependencies>(allTypesDependencies.Where(
                kv => {
                    var typeRef = kv.Key;
                    var typeDef = typeRef.TryResolve();
                    return typeDef == null || !goodModules.Contains(typeDef.Module);
                }).Select(kv => (TypeReferenceAndDependencies)kv));

            var removedDependencies = new HashSet<TypeDependency>();
            while (typeDependenciesToRemove.Any()) {
                var typeDependencies = typeDependenciesToRemove.Dequeue();
                var typeRef = typeDependencies.Type;
                var dependencies = typeDependencies.DependingMembers;
                Trace.WriteLine(string.Format("Removing dependencies on type {0}:", typeRef), "RemoveExternalTypesUsage");
                Trace.Indent();
                foreach (var dependency in dependencies) {
                    if (!removedDependencies.Contains(dependency)) {
                        dependency.Break();
                        removedDependencies.Add(dependency);

                        var baseClassDependency = dependency as BaseClassDependency;
                        if (baseClassDependency != null) {
                            var removedClass = baseClassDependency.DerivedClass;
                            if (allTypesDependencies.ContainsKey(removedClass)) {
                                var removedClassDependencies = allTypesDependencies[removedClass];
                                typeDependenciesToRemove.Enqueue(new TypeReferenceAndDependencies(removedClass, removedClassDependencies));
                            }
                        }
                    }
                }
                Trace.Unindent();
            }

            base.ProcessAssembly(assemblyDef);
        }
        protected override void ProcessAssembly(AssemblyDefinition assemblyDef)
        {
            base.ProcessAssembly(assemblyDef);

            var typesDependenciesCollector = new CollectTypesDependenciesProcessor();

            typesDependenciesCollector.Process(assemblyDef);
            _typesDependencies = typesDependenciesCollector.AllTypesDependencies;

            var allTypesDependencies     = typesDependenciesCollector.AllTypesDependencies;
            var typeDependenciesToRemove = new Queue <TypeReferenceAndDependencies>(allTypesDependencies.Where(kv => _typesToRemove.Contains(kv.Key)).Select(kv => (TypeReferenceAndDependencies)kv));

            var removedDependencies = new HashSet <TypeDependency>();

            while (typeDependenciesToRemove.Any())
            {
                var typeDependencies = typeDependenciesToRemove.Dequeue();
                var typeRef          = typeDependencies.Type;
                var dependencies     = typeDependencies.DependingMembers;
                Trace.WriteLine(string.Format("Removing dependencies on type {0}:", typeRef), "IntersectSkeletons");
                Trace.Indent();
                foreach (var dependency in dependencies)
                {
                    if (!removedDependencies.Contains(dependency))
                    {
                        dependency.Break();
                        removedDependencies.Add(dependency);

                        var baseClassDependency = dependency as BaseClassDependency;
                        if (baseClassDependency != null)
                        {
                            var removedClass = baseClassDependency.DerivedClass;
                            if (allTypesDependencies.ContainsKey(removedClass))
                            {
                                var removedClassDependencies = allTypesDependencies[removedClass];
                                typeDependenciesToRemove.Enqueue(new TypeReferenceAndDependencies(removedClass, removedClassDependencies));
                            }
                        }
                    }
                }

                var typeDef = typeRef.TryResolve();;
                Trace.WriteLine(string.Format("Removing type {0}, because it doesn't exist in one of the assemblies.", typeRef), "IntersectSkeletons");
                if (typeDef.IsNested)
                {
                    typeDef.DeclaringType.NestedTypes.Remove(typeDef);
                }
                else
                {
                    typeDef.Module.Types.Remove(typeDef);
                }
            }
        }
        protected override void ProcessAssembly(AssemblyDefinition assemblyDef)
        {
            if (_frameworkProfile == null)
            {
                _frameworkProfile = assemblyDef.GuessAssemblyProfile();
            }
            if (_frameworkProfile != null)
            {
                _assemblyResolver.AddSearchDirectory(_frameworkProfile.ReferencesDirectory);
            }
            var typesDependenciesCollector = new CollectTypesDependenciesProcessor(_frameworkProfile);

            typesDependenciesCollector.Process(assemblyDef);

            var goodAssemblyNames = assemblyDef.Modules.SelectMany(asmDef => asmDef.AssemblyReferences);

            if (_removeNonRetargetable)
            {
                goodAssemblyNames = goodAssemblyNames.Where(asmRef => asmRef.IsRetargetable);
            }
            if (_frameworkProfile != null)
            {
                goodAssemblyNames = goodAssemblyNames.Concat(_frameworkProfile.GetFrameworkAssemblies());
            }

            var goodModules = new HashSet <ModuleDefinition>(CecilEqualityComparer.Default);

            goodModules.AddRange(assemblyDef.Modules);
            goodModules.AddRange(goodAssemblyNames.Select(_assemblyResolver.TryResolve).Where(asmDef => asmDef != null).SelectMany(asmDef => asmDef.Modules));

            var allTypesDependencies     = typesDependenciesCollector.AllTypesDependencies;
            var typeDependenciesToRemove = new Queue <TypeReferenceAndDependencies>(allTypesDependencies.Where(
                                                                                        kv => {
                var typeRef = kv.Key;
                var typeDef = typeRef.TryResolve();
                return(typeDef == null || !goodModules.Contains(typeDef.Module));
            }).Select(kv => (TypeReferenceAndDependencies)kv));

            var removedDependencies = new HashSet <TypeDependency>();

            while (typeDependenciesToRemove.Any())
            {
                var typeDependencies = typeDependenciesToRemove.Dequeue();
                var typeRef          = typeDependencies.Type;
                var dependencies     = typeDependencies.DependingMembers;
                Trace.WriteLine(string.Format("Removing dependencies on type {0}:", typeRef), "RemoveExternalTypesUsage");
                Trace.Indent();
                foreach (var dependency in dependencies)
                {
                    if (!removedDependencies.Contains(dependency))
                    {
                        dependency.Break();
                        removedDependencies.Add(dependency);

                        var baseClassDependency = dependency as BaseClassDependency;
                        if (baseClassDependency != null)
                        {
                            var removedClass = baseClassDependency.DerivedClass;
                            if (allTypesDependencies.ContainsKey(removedClass))
                            {
                                var removedClassDependencies = allTypesDependencies[removedClass];
                                typeDependenciesToRemove.Enqueue(new TypeReferenceAndDependencies(removedClass, removedClassDependencies));
                            }
                        }
                    }
                }
                Trace.Unindent();
            }

            base.ProcessAssembly(assemblyDef);
        }