protected virtual void WriteUserDefinedTypes(ModuleDefinition module, Func <bool> shouldCancel)
        {
            Mono.Collections.Generic.Collection <TypeDefinition> moduleTypes;

            if (!UserDefinedTypes.TryGetValue(module, out moduleTypes))
            {
                throw new Exception("Module types not found.");
            }

            ProjectItemWriterFactory writerFactory =
                new ProjectItemWriterFactory(this.assembly, moduleTypes, this.projectFileManager, this.filePathsService, this.language.VSCodeFileExtension, this.targetDir);

#if !NET35
            CancellationTokenSource cts = new CancellationTokenSource();

            ParallelOptions parallelOptions = new ParallelOptions()
            {
                CancellationToken = cts.Token, MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            try
            {
                Parallel.ForEach(
                    moduleTypes,
                    parallelOptions,
                    (TypeDefinition type) =>
                {
                    try
                    {
                        if (shouldCancel())
                        {
                            cts.Cancel();
                            return;
                        }

                        IProjectItemFileWriter itemWriter = writerFactory.GetProjectItemWriter(type);

                        bool shouldBeXamlPartial = Utilities.ShouldBePartial(type) || this.projectFileManager.XamlFullNameToRelativePathMap.ContainsKey(type.FullName);

                        if (shouldBeXamlPartial)
                        {
                            string typeName = type.FullName;
                            if (this.xamlGeneratedFields.ContainsKey(typeName))
                            {
                                this.xamlGeneratedFields[typeName].Add("_contentLoaded");                                         // Always present, not bound to any XAML element
                            }
                            else
                            {
                                this.xamlGeneratedFields.Add(typeName, new HashSet <string>(new string[1] {
                                    "_contentLoaded"
                                }));                                                                                                                                     // Always present, not bound to any XAML element
                            }
                        }

                        List <WritingInfo> writingInfos;
                        string theCodeString;
                        bool exceptionsWhileDecompiling = WriteTypeToFile(type, itemWriter, this.xamlGeneratedFields, shouldBeXamlPartial,
                                                                          language, out writingInfos, out theCodeString);
                        bool exceptionsWhileWriting = HasExceptionsWhileWriting(writingInfos);

                        lock (writeTypesLock)
                        {
                            itemWriter.GenerateProjectItems();

                            Dictionary <MemberIdentifier, CodeSpan> mapping = null;
                            if (this.fileGeneratedNotifier != null)
                            {
                                /// Create the mapping only when it's needed for the internal API.
                                mapping = GenerateMemberMapping(this.assemblyPath, theCodeString, writingInfos);
                            }

                            IUniqueMemberIdentifier uniqueMemberIdentifier = new UniqueMemberIdentifier(module.FilePath, type.MetadataToken.ToInt32());
                            IFileGeneratedInfo args = new TypeGeneratedInfo(itemWriter.FullSourceFilePath, exceptionsWhileDecompiling, exceptionsWhileWriting, uniqueMemberIdentifier, mapping);
                            this.OnProjectFileCreated(args);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.OnTypeWritingFailure(type.FullName, ex);

                        if (this.projectNotifier != null)
                        {
                            this.projectNotifier.OnTypeWritingFailure(type.FullName, ex);
                        }
                    }
                });
            }
            catch (OperationCanceledException e)
            {
            }
#else
            for (int typeIndex = 0; typeIndex < moduleTypes.Count; typeIndex++)
            {
                if (shouldCancel())
                {
                    return;
                }
                TypeDefinition type = moduleTypes[typeIndex];
                try
                {
                    IProjectItemFileWriter itemWriter = writerFactory.GetProjectItemWriter(type);
                    bool shouldBeXamlPartial          = Utilities.ShouldBePartial(type) || this.projectFileManager.XamlFullNameToRelativePathMap.ContainsKey(type.FullName);
                    if (shouldBeXamlPartial)
                    {
                        string typeName = type.FullName;
                        if (xamlGeneratedFields.ContainsKey(typeName))
                        {
                            xamlGeneratedFields[typeName].Add("_contentLoaded");                            //Always present, not bound to any XAML element
                        }
                        else
                        {
                            xamlGeneratedFields.Add(typeName, new HashSet <string>(new string[1] {
                                "_contentLoaded"
                            }));                                                                                                                   //Always present, not bound to any XAML element
                        }
                    }
                    List <WritingInfo> writingInfos;
                    string             typeCode;
                    bool exceptionsWhileDecompiling = WriteTypeToFile(type, itemWriter, xamlGeneratedFields, shouldBeXamlPartial,
                                                                      language, out writingInfos, out typeCode);
                    bool exceptionsWhileWriting = HasExceptionsWhileWriting(writingInfos);
                    itemWriter.GenerateProjectItems();
                    Dictionary <MemberIdentifier, CodeSpan> mapping = GenerateMemberMapping(this.assemblyPath, typeCode, writingInfos);

                    IUniqueMemberIdentifier uniqueMemberIdentifier = new UniqueMemberIdentifier(module.FilePath, type.MetadataToken.ToInt32());
                    IFileGeneratedInfo      args = new TypeGeneratedInfo(itemWriter.FullSourceFilePath, exceptionsWhileDecompiling, exceptionsWhileWriting, uniqueMemberIdentifier, mapping);
                    this.OnProjectFileCreated(args);
                }
                catch (Exception ex)
                {
                    if (TypeWritingFailure != null)
                    {
                        TypeWritingFailure(this, type.FullName, ex);
                    }
                }
            }
#endif
        }
        public bool WriteTypeToFile(TypeDefinition type, IProjectItemFileWriter itemWriter, Dictionary <string, ICollection <string> > membersToSkip, bool shouldBePartial,
                                    ILanguage language, out List <WritingInfo> writingInfos, out string theCodeString)
        {
            theCodeString = string.Empty;
            writingInfos  = null;
            StringWriter theWriter = new StringWriter();

            bool showCompilerGeneratedMembers = Utilities.IsVbInternalTypeWithoutRootNamespace(type) ||
                                                Utilities.IsVbInternalTypeWithRootNamespace(type);

            IFormatter      formatter = GetFormatter(theWriter);
            IWriterSettings settings  = new WriterSettings(writeExceptionsAsComments: true,
                                                           writeFullyQualifiedNames: decompilationPreferences.WriteFullNames,
                                                           writeDocumentation: decompilationPreferences.WriteDocumentation,
                                                           showCompilerGeneratedMembers: showCompilerGeneratedMembers,
                                                           writeLargeNumbersInHex: decompilationPreferences.WriteLargeNumbersInHex);
            ILanguageWriter writer = language.GetWriter(formatter, this.exceptionFormater, settings);

            IWriterContextService writerContextService = this.GetWriterContextService();

            writer.ExceptionThrown += OnExceptionThrown;
            writerContextService.ExceptionThrown += OnExceptionThrown;

            bool exceptionOccurred = false;

            try
            {
                if (!(writer is INamespaceLanguageWriter))
                {
                    writingInfos = writer.Write(type, writerContextService);
                }
                else
                {
                    if (shouldBePartial)
                    {
                        writingInfos = (writer as INamespaceLanguageWriter).WritePartialTypeAndNamespaces(type, writerContextService, membersToSkip);
                    }
                    else
                    {
                        writingInfos = (writer as INamespaceLanguageWriter).WriteTypeAndNamespaces(type, writerContextService);
                    }
                }

                this.RecordGeneratedFileData(type, itemWriter.FullSourceFilePath, theWriter, formatter, writerContextService, writingInfos);

                MemoryStream sourceFileStream = new MemoryStream(Encoding.UTF8.GetBytes(theWriter.ToString()));
                itemWriter.CreateProjectSourceFile(sourceFileStream);
                sourceFileStream.Close();
                theWriter.Close();
            }
            catch (Exception e)
            {
                exceptionOccurred = true;

                string[] exceptionMessageLines     = exceptionFormater.Format(e, type.FullName, itemWriter.FullSourceFilePath);
                string   exceptionMessage          = string.Join(Environment.NewLine, exceptionMessageLines);
                string   commentedExceptionMessage = language.CommentLines(exceptionMessage);
                itemWriter.CreateProjectSourceFile(new MemoryStream(Encoding.UTF8.GetBytes(commentedExceptionMessage)));

                OnExceptionThrown(this, e);
            }

            theCodeString = theWriter.ToString();

            writer.ExceptionThrown -= OnExceptionThrown;
            writerContextService.ExceptionThrown -= OnExceptionThrown;

            return(exceptionOccurred || writerContextService.ExceptionsWhileDecompiling.Any());
        }
        public bool WriteTypeToFile(TypeDefinition type, IProjectItemFileWriter itemWriter, Dictionary<string, ICollection<string>> membersToSkip, bool shouldBePartial,
            ILanguage language, out List<WritingInfo> writingInfos, out string theCodeString)
        {
			theCodeString = string.Empty;
			writingInfos = null;
            StringWriter theWriter = new StringWriter();

			IFormatter formatter = GetFormatter(theWriter);
            ILanguageWriter writer = language.GetWriter(formatter, this.exceptionFormater, true);

            IWriterContextService writerContextService = this.GetWriterContextService();

            bool exceptionOccurred = false;

            try
            {
				bool showCompilerGeneratedMembers = Utilities.IsVbInternalTypeWithoutRootNamespace(type) ||
													Utilities.IsVbInternalTypeWithRootNamespace(type);

                if (!(writer is INamespaceLanguageWriter))
                {
					writingInfos = writer.Write(type, writerContextService, decompilationPreferences.WriteDocumentation, showCompilerGeneratedMembers);
                }
                else
                {

                    if (shouldBePartial)
                    {
						writingInfos = (writer as INamespaceLanguageWriter).WritePartialTypeAndNamespaces(type, writerContextService, showCompilerGeneratedMembers,
							decompilationPreferences.WriteFullNames, decompilationPreferences.WriteDocumentation, membersToSkip);
                    }
                    else
                    {
						writingInfos = (writer as INamespaceLanguageWriter).WriteTypeAndNamespaces(type, writerContextService, decompilationPreferences.WriteDocumentation, showCompilerGeneratedMembers, decompilationPreferences.WriteFullNames);
                    }
                }

                RecordGeneratedFileData(type, itemWriter.FullSourceFilePath, theWriter, formatter, writerContextService, writingInfos);

                MemoryStream sourceFileStream = new MemoryStream(Encoding.UTF8.GetBytes(theWriter.ToString()));
                itemWriter.CreateProjectSourceFile(sourceFileStream);
                sourceFileStream.Close();
                theWriter.Close();
            }
            catch (Exception e)
            {
                exceptionOccurred = true;

                string[] exceptionMessageLines = exceptionFormater.Format(e, type.FullName, itemWriter.FullSourceFilePath);
                string exceptionMessage = string.Join(Environment.NewLine, exceptionMessageLines);
                string commentedExceptionMessage = language.CommentLines(exceptionMessage);
                itemWriter.CreateProjectSourceFile(new MemoryStream(Encoding.UTF8.GetBytes(commentedExceptionMessage)));
            }

			theCodeString = theWriter.ToString();
            return exceptionOccurred || writerContextService.ExceptionsWhileDecompiling.Any();
        }