public MemoryVisitor(CodeContractAwareHostEnvironment host, PdbReader pdbReader, ContractProvider contractProvider, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation)
 {
     _host = host;
     _pdbReader = pdbReader;
     _contractProvider = contractProvider;
     _memoryContractsInformation = memoryContractsInformation;
     _errorReportItems = new List<ErrorReportItem>();
     _pointsToInformation = pointsToInformation;
 }
        private static MemoryContractsInformation ExtractMemoryContractsFromModule(CodeContractAwareHostEnvironment host, IModule module)
        {
            var memoryContractsInformation = new MemoryContractsInformation();

            if (_visitedModules.Contains(module))
            {
                return memoryContractsInformation;
            }

            _visitedModules.Add(module);

            if (module != null && module != Dummy.Module && module != Dummy.Assembly)
            {
                PdbReader pdbReader = null;
                string pdbFile = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile))
                    {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);

                var extractor = new MemoryContractsExtractor();

                extractor.Visit(module);

                memoryContractsInformation.MethodsTmpTypes = extractor.MethodsTmpTypes;
                memoryContractsInformation.MethodsTmpContracts = extractor.MethodsTmpContracts;
                memoryContractsInformation.MethodsTmpContractsWithConds = extractor.MethodsTmpContractsWithConds;
                memoryContractsInformation.MethodsRsdTypes = extractor.MethodsRsdTypes;
                memoryContractsInformation.MethodsRsdContracts = extractor.MethodsRsdContracts;
                memoryContractsInformation.MethodsRsdContractsWithConds = extractor.MethodsRsdContractsWithConds;
                memoryContractsInformation.MethodsRsdExprs = extractor.MethodsRsdExprs;

                //merge the contracts of the referenced assemblies
                foreach (var assemblyReference in module.AssemblyReferences)
                {
                    //skip assemblies that we know don't have memory contracts
                    if (!new List<string>() { "mscorlib", "Contracts", "System", "Microsoft" }.Exists(s => assemblyReference.Name.Value.StartsWith(s)))
                    {
                        var referencedAssembly = host.LoadAssembly(assemblyReference.AssemblyIdentity);

                        var referencedModuleMemoryContractsInformation = ExtractMemoryContractsFromModule(host, referencedAssembly);

                        if (referencedModuleMemoryContractsInformation.MethodsTmpTypes != null)
                        {
                            foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsTmpTypes.Keys)
                            {
                                memoryContractsInformation.MethodsTmpTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsTmpTypes[methodName];
                            }
                        }

                        if (referencedModuleMemoryContractsInformation.MethodsRsdTypes != null)
                        {
                            foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsRsdTypes.Keys)
                            {
                                memoryContractsInformation.MethodsRsdTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsRsdTypes[methodName];
                            }
                        }
                    }
                }
            }

            return memoryContractsInformation;
        }
        private static List<ErrorReportItem> RewriteAssembly(CodeContractAwareHostEnvironment host, string assemblyFullPath, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation)
        {
            var module = host.LoadUnitFrom(assemblyFullPath) as IModule;

            PdbReader pdbReader = null;
            string pdbFile = Path.ChangeExtension(module.Location, "pdb");
            if (File.Exists(pdbFile))
            {
                using (var pdbStream = File.OpenRead(pdbFile))
                {
                    pdbReader = new PdbReader(pdbStream, host);
                }
            }

            if (module != null && module != Dummy.Module && module != Dummy.Assembly)
            {
                var mutableModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);

                using (pdbReader)
                {
                    var contractProvider = Microsoft.Cci.MutableContracts.ContractHelper.ExtractContracts(host, mutableModule, pdbReader, pdbReader);

                    var mutator = new MemoryVisitor(host, pdbReader, contractProvider, memoryContractsInformation, pointsToInformation);

                    mutator.Visit(mutableModule);

                    Microsoft.Cci.MutableContracts.ContractHelper.InjectContractCalls(host, mutableModule, contractProvider, pdbReader);

                    Stream peStream = File.Create(Path.ChangeExtension(mutableModule.Location, ".mod.dll"));

                    if (pdbReader == null)
                    {
                        PeWriter.WritePeToStream(mutableModule, host, peStream);
                    }
                    else
                    {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(pdbFile, ".mod.pdb"), pdbReader))
                        {
                            PeWriter.WritePeToStream(mutableModule, host, peStream, pdbReader, pdbReader, pdbWriter);
                        }
                    }

                    peStream.Close();

                    return mutator.ErrorReportItems;
                }
            }

            return null;
        }