System.Data.SQLite
Check-in [ce3e0bd842]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a bug in NDoc3 that prevented external links from working correctly for the built-in return types and parameter types in the built CHM file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ce3e0bd842f1fb812bd04bfdf9faa0b1bf6d611e
User & Date: mistachkin 2013-09-18 08:14:39
Context
2013-09-18
08:18
Add original NDoc3 source files. check-in: fb8f175216 user: mistachkin tags: trunk
08:14
Fix a bug in NDoc3 that prevented external links from working correctly for the built-in return types and parameter types in the built CHM file. check-in: ce3e0bd842 user: mistachkin tags: trunk
08:11
Add missing comments for the new attribute classes. check-in: b434e4278d user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Doc/buildChm.tcl.

    29     29   proc readFileAsSubSpec { fileName } {
    30     30     set data [readFile $fileName]
    31     31     regsub -all -- {&} $data {\\\&} data
    32     32     regsub -all -- {\\(\d+)} $data {\\\\\1} data
    33     33     return $data
    34     34   }
    35     35   
    36         -set path [file dirname [info script]]
           36  +proc getFileHash { fileName } {
           37  +  if {[catch {
           38  +    exec fossil.exe sha1sum [file nativename $fileName]
           39  +  } result] == 0} then {
           40  +    return [string trim [lindex [split $result " "] 0]]
           41  +  }
           42  +  return ""
           43  +}
           44  +
           45  +#
           46  +# HACK: Copy our local [fixed] copy of the MSDN documenter assembly into the
           47  +#       installed location of NDoc3, if necessary.  Actually copying the file
           48  +#       will require elevated administrator privileges; otherwise, it would
           49  +#       fail.  Any errors encountered while copying the file are reported via
           50  +#       the console; however, they will not halt processing.
           51  +#
           52  +proc copyMsdnDocumenter { sourceDirectory destinationDirectory } {
           53  +  set fileNameOnly NDoc3.Documenter.Msdn.dll
    37     54   
    38         -set nDocPath [file join $env(ProgramFiles) NDoc3]
           55  +  set sourceFileName [file join $sourceDirectory bin $fileNameOnly]
           56  +  set destinationFileName [file join $destinationDirectory bin $fileNameOnly]
    39     57   
    40         -if {![file isdirectory $nDocPath]} then {
    41         -  puts stdout "NDoc3 must be installed to: $nDocPath"
           58  +  set sourceFileHash [getFileHash $sourceFileName]
           59  +  # puts stdout "Hashed \"$sourceFileName\" ==> \"$sourceFileHash\""
           60  +
           61  +  set destinationFileHash [getFileHash $destinationFileName]
           62  +  # puts stdout "Hashed \"$destinationFileName\" ==> \"$destinationFileHash\""
           63  +
           64  +  if {[string length $sourceFileHash] > 0 && \
           65  +      [string length $destinationFileHash] > 0 && \
           66  +      $sourceFileHash ne $destinationFileHash} then {
           67  +    if {[catch {
           68  +      file copy -force $destinationFileName $destinationFileName.bak
           69  +      file copy -force $sourceFileName $destinationFileName
           70  +    } result] == 0} then {
           71  +      puts stdout \
           72  +          "finished copying \"$sourceFileName\" to \"$destinationFileName\""
           73  +    } else {
           74  +      puts stdout $result
           75  +    }
           76  +  } else {
           77  +    puts stdout \
           78  +        "skipped copying \"$sourceFileName\" to \"$destinationFileName\""
           79  +  }
           80  +}
           81  +
           82  +set path [file normalize [file dirname [info script]]]
           83  +
           84  +set nDocExtPath [file join [file dirname $path] Externals NDoc3]
           85  +set nDocInstPath [file join $env(ProgramFiles) NDoc3]
           86  +
           87  +if {![file isdirectory $nDocInstPath]} then {
           88  +  puts stdout "NDoc3 must be installed to: $nDocInstPath"
    42     89     exit 1
    43     90   }
    44     91   
    45     92   set hhcPath [file join $env(ProgramFiles) "HTML Help Workshop"]
    46     93   
    47     94   if {![file isdirectory $hhcPath]} then {
    48     95     puts stdout "HTML Help Workshop must be installed to: $hhcPath"
................................................................................
    93    140     puts stdout "*WARNING* File \"$xmlDocFile\" does not match: $pattern"
    94    141   }
    95    142   
    96    143   #
    97    144   # TODO: If the NDoc version number ever changes, the next line of code will
    98    145   #       probably need to be updated.
    99    146   #
   100         -set outputPath [file join Output ndoc3_msdn_temp]
          147  +set outputPath [file join Output]
          148  +set temporaryPath [file join $outputPath ndoc3_msdn_temp]
   101    149   
   102         -set code [catch {exec [file join $nDocPath bin NDoc3Console.exe] \
          150  +if {[file isdirectory $nDocExtPath]} then {
          151  +  copyMsdnDocumenter $nDocExtPath $nDocInstPath
          152  +}
          153  +
          154  +set code [catch {exec [file join $nDocInstPath bin NDoc3Console.exe] \
   103    155       "-project=[file nativename $projectFile]"} result]
   104    156   
   105    157   puts stdout $result; if {$code != 0} then {exit $code}
   106    158   
   107    159   set fileNames [list SQLite.NET.hhp SQLite.NET.hhc]
   108    160   
   109         -foreach fileName [glob -nocomplain [file join $outputPath *.html]] {
          161  +foreach fileName [glob -nocomplain [file join $temporaryPath *.html]] {
   110    162     lappend fileNames [file tail $fileName]
   111    163   }
   112    164   
   113    165   set patterns(.hhc,1) {<!--This document contains Table of Contents information\
   114    166   for the HtmlHelp compiler\.--><UL>}
   115    167   
   116    168   set patterns(.hhp,1) {Default topic=~System\.Data\.SQLite\.html}
................................................................................
   150    202   set subSpecs(.html,4) {"\1~Overloads.html"}
   151    203   set subSpecs(.html,5) {"\1~Overloads.html"}
   152    204   set subSpecs(.html,6) {"\1~Overloads.html"}
   153    205   set subSpecs(.html,7) {"\1~Overloads.html"}
   154    206   set subSpecs(.html,8) {"\1~Overloads.html"}
   155    207   
   156    208   foreach fileName $fileNames {
   157         -  set fileName [file join $path $outputPath $fileName]
          209  +  set fileName [file join $path $temporaryPath $fileName]
   158    210   
   159    211     #
   160    212     # NOTE: Make sure the file we need actually exists.
   161    213     #
   162    214     if {![file isfile $fileName]} then {
   163    215       puts stdout "Cannot find file: $fileName"
   164    216       exit 1
................................................................................
   200    252     #
   201    253     if {$count > 0} then {
   202    254       writeFile $fileName $data
   203    255     }
   204    256   }
   205    257   
   206    258   set code [catch {exec [file join $hhcPath hhc.exe] \
   207         -    [file nativename [file join $path $outputPath SQLite.NET.hhp]]} result]
          259  +    [file nativename [file join $path $temporaryPath SQLite.NET.hhp]]} result]
   208    260   
   209    261   #
   210    262   # NOTE: For hhc.exe, zero means failure.
   211    263   #
   212    264   puts stdout $result; if {$code == 0} then {exit 1}
   213    265   
   214         -file copy -force [file join $path $outputPath SQLite.NET.chm] \
          266  +file copy -force [file join $path $temporaryPath SQLite.NET.chm] \
   215    267       [file join $path SQLite.NET.chm]
   216    268   
   217    269   puts stdout SUCCESS
   218    270   exit 0

Added Externals/NDoc3/bin/NDoc3.Documenter.Msdn.dll.

cannot compute difference between binary files

Added Externals/NDoc3/src/MsdnDocumenter.cs.

            1  +// MsdnDocumenter.cs - a MSDN-like documenter
            2  +// Copyright (C) 2001  Kral Ferch, Jason Diamond
            3  +//
            4  +// This program is free software; you can redistribute it and/or modify
            5  +// it under the terms of the GNU General Public License as published by
            6  +// the Free Software Foundation; either version 2 of the License, or
            7  +// (at your option) any later version.
            8  +//
            9  +// This program is distributed in the hope that it will be useful,
           10  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
           11  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           12  +// GNU General Public License for more details.
           13  +//
           14  +// You should have received a copy of the GNU General Public License
           15  +// along with this program; if not, write to the Free Software
           16  +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
           17  +
           18  +using System;
           19  +using System.Collections;
           20  +using System.Collections.Generic;
           21  +using System.Collections.Specialized;
           22  +using System.Diagnostics;
           23  +using System.IO;
           24  +using System.Xml;
           25  +using System.Xml.XPath;
           26  +using System.Xml.Xsl;
           27  +using System.Globalization;
           28  +
           29  +using NDoc3.Core;
           30  +using NDoc3.Core.Reflection;
           31  +using NDoc3.Documenter.Msdn.onlinefiles;
           32  +using NDoc3.Documenter.Msdn.onlinetemplates;
           33  +using NDoc3.Xml;
           34  +
           35  +namespace NDoc3.Documenter.Msdn
           36  +{
           37  +	/// <summary>The MsdnDocumenter class.</summary>
           38  +	public class MsdnDocumenter : BaseReflectionDocumenter
           39  +	{
           40  +		private enum WhichType
           41  +		{
           42  +			Class,
           43  +			Interface,
           44  +			Structure,
           45  +			Enumeration,
           46  +			Delegate,
           47  +			Unknown
           48  +		};
           49  +
           50  +		private readonly Dictionary<WhichType, string> lowerCaseTypeNames;
           51  +		private readonly Dictionary<WhichType, string> mixedCaseTypeNames;
           52  +		private List<string> filesToInclude = new List<string>();
           53  +
           54  +		/// <summary>
           55  +		/// Initializes a new instance of the <see cref="MsdnDocumenter" />
           56  +		/// class.
           57  +		/// </summary>
           58  +		public MsdnDocumenter(MsdnDocumenterConfig config)
           59  +			: base(config)
           60  +		{
           61  +			lowerCaseTypeNames = new Dictionary<WhichType, string>();
           62  +			lowerCaseTypeNames.Add(WhichType.Class, "class");
           63  +			lowerCaseTypeNames.Add(WhichType.Interface, "interface");
           64  +			lowerCaseTypeNames.Add(WhichType.Structure, "structure");
           65  +			lowerCaseTypeNames.Add(WhichType.Enumeration, "enumeration");
           66  +			lowerCaseTypeNames.Add(WhichType.Delegate, "delegate");
           67  +
           68  +			mixedCaseTypeNames = new Dictionary<WhichType, string>();
           69  +			mixedCaseTypeNames.Add(WhichType.Class, "Class");
           70  +			mixedCaseTypeNames.Add(WhichType.Interface, "Interface");
           71  +			mixedCaseTypeNames.Add(WhichType.Structure, "Structure");
           72  +			mixedCaseTypeNames.Add(WhichType.Enumeration, "Enumeration");
           73  +			mixedCaseTypeNames.Add(WhichType.Delegate, "Delegate");
           74  +		}
           75  +
           76  +		/// <summary>See <see cref="IDocumenter"/>.</summary>
           77  +		public override string MainOutputFile
           78  +		{
           79  +			get
           80  +			{
           81  +				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0) {
           82  +					return Path.Combine(MyConfig.OutputDirectory,
           83  +						MyConfig.HtmlHelpName + ".chm");
           84  +				}
           85  +				return Path.Combine(MyConfig.OutputDirectory, "index.html");
           86  +			}
           87  +		}
           88  +
           89  +		/// <summary>See <see cref="IDocumenter"/>.</summary>
           90  +		public override string CanBuild(Project project, bool checkInputOnly)
           91  +		{
           92  +			string result = base.CanBuild(project, checkInputOnly);
           93  +			if (result != null) {
           94  +				return result;
           95  +			}
           96  +
           97  +			string AdditionalContentResourceDirectory = MyConfig.AdditionalContentResourceDirectory;
           98  +			if (AdditionalContentResourceDirectory.Length != 0 && !Directory.Exists(AdditionalContentResourceDirectory))
           99  +				return string.Format("The Additional Content Resource Directory {0} could not be found", AdditionalContentResourceDirectory);
          100  +
          101  +			string ExtensibilityStylesheet = MyConfig.ExtensibilityStylesheet;
          102  +			if (ExtensibilityStylesheet.Length != 0 && !File.Exists(ExtensibilityStylesheet))
          103  +				return string.Format("The Extensibility Stylesheet file {0} could not be found", ExtensibilityStylesheet);
          104  +
          105  +			if (checkInputOnly) {
          106  +				return null;
          107  +			}
          108  +
          109  +			string path = Path.Combine(MyConfig.OutputDirectory,
          110  +				MyConfig.HtmlHelpName + ".chm");
          111  +
          112  +			string temp = Path.Combine(MyConfig.OutputDirectory, "~chm.tmp");
          113  +
          114  +			try {
          115  +
          116  +				if (File.Exists(path)) {
          117  +					//if we can move the file, then it is not open...
          118  +					File.Move(path, temp);
          119  +					File.Move(temp, path);
          120  +				}
          121  +			} catch (Exception) {
          122  +				result = "The compiled HTML Help file is probably open.\nPlease close it and try again.";
          123  +			}
          124  +
          125  +			return result;
          126  +		}
          127  +
          128  +		/// <summary>See <see cref="IDocumenter"/>.</summary>
          129  +		public override void Build(Project project)
          130  +		{
          131  +			BuildProjectContext buildContext = new BuildProjectContext(new CultureInfo(MyConfig.LangID),
          132  +				new DirectoryInfo(MyConfig.OutputDirectory), MyConfig.CleanIntermediates);
          133  +
          134  +			try {
          135  +				OnDocBuildingStep(0, "Initializing...");
          136  +
          137  +				buildContext.Initialize();
          138  +
          139  +				OnDocBuildingStep(10, "Merging XML documentation...");
          140  +
          141  +				// Will hold the name of the file name containing the XML doc
          142  +				XmlDocument projectXml = CreateNDocXml(project);
          143  +				buildContext.SetProjectXml(projectXml, MyConfig.MergeAssemblies);
          144  +
          145  +				OnDocBuildingStep(30, "Loading XSLT files...");
          146  +
          147  +				buildContext.stylesheets = StyleSheetCollection.LoadStyleSheets(MyConfig.ExtensibilityStylesheet);
          148  +
          149  +				OnDocBuildingStep(40, "Generating HTML pages...");
          150  +
          151  +				// setup for root page
          152  +				string defaultTopic;
          153  +				string rootPageFileName = null;
          154  +				string rootPageTOCName = null;
          155  +
          156  +				if (!String.IsNullOrEmpty(MyConfig.RootPageFileName)) {
          157  +					rootPageFileName = MyConfig.RootPageFileName;
          158  +					defaultTopic = "default.html";
          159  +
          160  +					rootPageTOCName = "Overview";
          161  +					// what to call the top page in the table of contents?
          162  +					if (!String.IsNullOrEmpty(MyConfig.RootPageTOCName)) {
          163  +						rootPageTOCName = MyConfig.RootPageTOCName;
          164  +					}
          165  +				} else {
          166  +					// TODO (EE): check MergeAssemblies and adjust defaultTopic accordingly
          167  +					XmlNode defaultNamespace;
          168  +					if (MyConfig.MergeAssemblies)
          169  +					{
          170  +						XmlNodeList namespaceNodes = buildContext.SelectNodes("/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace");
          171  +						int[] indexes = SortNodesByAttribute(namespaceNodes, "name");
          172  +
          173  +						defaultNamespace = namespaceNodes[indexes[0]];
          174  +					}
          175  +					else
          176  +					{
          177  +						XmlNodeList assemblyNodes = buildContext.SelectNodes("/ndoc:ndoc/ndoc:assembly");
          178  +						int[] assemblyIndexes = SortNodesByAttribute(assemblyNodes, "name");
          179  +						XmlNode defaultAssemblyNode = assemblyNodes[assemblyIndexes[0]];
          180  +						XmlNodeList namespaceNodes = buildContext.SelectNodes(defaultAssemblyNode, "ndoc:module/ndoc:namespace");
          181  +						int[] indexes = SortNodesByAttribute(namespaceNodes, "name");
          182  +						defaultNamespace = namespaceNodes[indexes[0]];
          183  +					}
          184  +					string defaultNamespaceName = GetNodeName(defaultNamespace);
          185  +					string assemblyName = GetNodeName(buildContext.SelectSingleNode(defaultNamespace, "ancestor::ndoc:assembly"));
          186  +					defaultTopic = buildContext._nameResolver.GetFilenameForNamespace(assemblyName, defaultNamespaceName);
          187  +				}
          188  +				buildContext.htmlHelp = SetupHtmlHelpBuilder(buildContext.WorkingDirectory, defaultTopic);
          189  +
          190  +				using (buildContext.htmlHelp.OpenProjectFile())
          191  +				using (buildContext.htmlHelp.OpenContentsFile(string.Empty, true)) {
          192  +					// Write the embedded css files to the html output directory
          193  +					WriteHtmlContentResources(buildContext);
          194  +
          195  +					GenerateHtmlContentFiles(buildContext, rootPageFileName, rootPageTOCName);
          196  +				}
          197  +
          198  +				HtmlHelp htmlHelp = buildContext.htmlHelp;
          199  +				htmlHelp.WriteEmptyIndexFile();
          200  +
          201  +				if ((MyConfig.OutputTarget & OutputType.Web) > 0) {
          202  +					OnDocBuildingStep(75, "Generating HTML index file...");
          203  +
          204  +					// Write the embedded online templates to the html output directory
          205  +					GenerateHtmlIndexFile(buildContext, defaultTopic);
          206  +				}
          207  +
          208  +				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0) {
          209  +					OnDocBuildingStep(85, "Compiling HTML Help file...");
          210  +					htmlHelp.CompileProject();
          211  +				}
          212  +#if !DEBUG
          213  +				else
          214  +				{
          215  +					//remove .hhc file
          216  +					File.Delete(htmlHelp.GetPathToContentsFile());
          217  +				}
          218  +#endif
          219  +
          220  +				// if we're only building a CHM, copy that to the Outpur dir
          221  +				if ((MyConfig.OutputTarget & OutputType.HtmlHelp) > 0 && (MyConfig.OutputTarget & OutputType.Web) == 0) {
          222  +					buildContext.SaveOutputs("*.chm");
          223  +				} else {
          224  +					// otherwise copy everything to the output dir (cause the help file is all the html, not just one chm)
          225  +					buildContext.SaveOutputs("*.*");
          226  +				}
          227  +
          228  +				OnDocBuildingStep(100, "Done.");
          229  +			} catch(DocumenterException) {
          230  +				throw;
          231  +			} catch (Exception ex) {
          232  +				throw new DocumenterException(ex.Message, ex);
          233  +			} finally {
          234  +				buildContext.Dispose();
          235  +			}
          236  +		}
          237  +
          238  +		private void GenerateHtmlIndexFile(BuildProjectContext ctx, string defaultTopic)
          239  +		{
          240  +			EmbeddedResources.WriteEmbeddedResources(typeof(OnlineFilesLocationHint), ctx.WorkingDirectory);
          241  +
          242  +			using (TemplateWriter indexWriter = new TemplateWriter(
          243  +				Path.Combine(ctx.WorkingDirectory.FullName, "index.html"),
          244  +				EmbeddedResources.GetEmbeddedResourceReader(typeof(OnlineTemplatesLocationHint), "index.html", null))) {
          245  +				indexWriter.CopyToLine("\t\t<title><%TITLE%></title>");
          246  +				indexWriter.WriteLine("\t\t<title>" + MyConfig.HtmlHelpName + "</title>");
          247  +				indexWriter.CopyToLine("\t\t<frame name=\"main\" src=\"<%HOME_PAGE%>\" frameborder=\"1\">");
          248  +				indexWriter.WriteLine("\t\t<frame name=\"main\" src=\"" + defaultTopic + "\" frameborder=\"1\">");
          249  +				indexWriter.CopyToEnd();
          250  +				indexWriter.Close();
          251  +			}
          252  +
          253  +			Trace.WriteLine("transform the HHC contents file into html");
          254  +#if DEBUG
          255  +			int start = Environment.TickCount;
          256  +#endif
          257  +			//transform the HHC contents file into html
          258  +			using (StreamReader contentsFile = new StreamReader(ctx.HtmlHelpContentFilePath.FullName, ctx.CurrentFileEncoding)) {
          259  +				XPathDocument xpathDocument = new XPathDocument(contentsFile);
          260  +				string contentsFilename = Path.Combine(ctx.WorkingDirectory.FullName, "contents.html");
          261  +				using (StreamWriter streamWriter = new StreamWriter(
          262  +					File.Open(contentsFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None), ctx.CurrentFileEncoding)) {
          263  +					XslTransform(ctx, "htmlcontents", xpathDocument, null, streamWriter, contentsFilename);
          264  +				}
          265  +			}
          266  +#if DEBUG
          267  +			Trace.WriteLine(string.Format("{0} msec.", (Environment.TickCount - start)));
          268  +#endif
          269  +		}
          270  +
          271  +		private HtmlHelp SetupHtmlHelpBuilder(DirectoryInfo workingDirectory, string defaultTopic)
          272  +		{
          273  +			HtmlHelp htmlHelp = new HtmlHelp(
          274  +				workingDirectory,
          275  +				MyConfig.HtmlHelpName,
          276  +				defaultTopic,
          277  +				((MyConfig.OutputTarget & OutputType.HtmlHelp) == 0));
          278  +			htmlHelp.IncludeFavorites = MyConfig.IncludeFavorites;
          279  +			htmlHelp.BinaryTOC = MyConfig.BinaryTOC;
          280  +			htmlHelp.LangID = MyConfig.LangID;
          281  +			return htmlHelp;
          282  +		}
          283  +
          284  +		private void GenerateHtmlContentFiles(BuildProjectContext buildContext, string rootPageFileName, string rootPageTOCName)
          285  +		{
          286  +			if (!String.IsNullOrEmpty(MyConfig.CopyrightHref)) {
          287  +				if (!MyConfig.CopyrightHref.StartsWith("http:")) {
          288  +					string copyrightFile = Path.Combine(buildContext.WorkingDirectory.FullName, Path.GetFileName(MyConfig.CopyrightHref));
          289  +					File.Copy(MyConfig.CopyrightHref, copyrightFile, true);
          290  +					File.SetAttributes(copyrightFile, FileAttributes.Archive);
          291  +					buildContext.htmlHelp.AddFileToProject(Path.GetFileName(MyConfig.CopyrightHref));
          292  +				}
          293  +			}
          294  +
          295  +			// add root page if requested
          296  +			if (rootPageFileName != null) {
          297  +				if (!File.Exists(rootPageFileName)) {
          298  +					throw new DocumenterException("Cannot find the documentation's root page file:\n"
          299  +												  + rootPageFileName);
          300  +				}
          301  +
          302  +				// add the file
          303  +				string rootPageOutputName = Path.Combine(buildContext.WorkingDirectory.FullName, "default.html");
          304  +				if (Path.GetFullPath(rootPageFileName) != Path.GetFullPath(rootPageOutputName)) {
          305  +					File.Copy(rootPageFileName, rootPageOutputName, true);
          306  +					File.SetAttributes(rootPageOutputName, FileAttributes.Archive);
          307  +				}
          308  +				buildContext.htmlHelp.AddFileToProject(Path.GetFileName(rootPageOutputName));
          309  +				buildContext.htmlHelp.AddFileToContents(rootPageTOCName,
          310  +										   Path.GetFileName(rootPageOutputName));
          311  +
          312  +				// depending on peer setting, make root page the container
          313  +				if (MyConfig.RootPageContainsNamespaces)
          314  +					buildContext.htmlHelp.OpenBookInContents();
          315  +			}
          316  +
          317  +			MakeHtmlForAssemblies(buildContext, MyConfig.MergeAssemblies);
          318  +			foreach (string filename in filesToInclude) {
          319  +				buildContext.htmlHelp.AddFileToProject(filename);
          320  +			}
          321  +
          322  +			// close root book if applicable
          323  +			if (rootPageFileName != null) {
          324  +				if (MyConfig.RootPageContainsNamespaces)
          325  +					buildContext.htmlHelp.CloseBookInContents();
          326  +			}
          327  +		}
          328  +
          329  +		private XmlDocument CreateNDocXml(Project project)
          330  +		{
          331  +			string tempFileName = null;
          332  +			try {
          333  +				// determine temp file name
          334  +				tempFileName = Path.GetTempFileName();
          335  +				// Let the Documenter base class do it's thing.
          336  +				MakeXmlFile(project, new FileInfo(tempFileName));
          337  +
          338  +				// Load the XML documentation into DOM and XPATH doc.
          339  +				using (FileStream tempFile = File.Open(tempFileName, FileMode.Open, FileAccess.Read)) {
          340  +
          341  +					XmlDocument xml = new XmlDocument();
          342  +					xml.Load(tempFile);
          343  +					return xml;
          344  +				}
          345  +			} finally {
          346  +				if (tempFileName != null && File.Exists(tempFileName)) {
          347  +#if DEBUG
          348  +					File.Copy(tempFileName, MyConfig.OutputDirectory.TrimEnd('\\', '/') + "\\ndoc.xml", true);
          349  +#endif
          350  +					File.Delete(tempFileName);
          351  +				}
          352  +			}
          353  +		}
          354  +
          355  +		private void WriteHtmlContentResources(BuildProjectContext buildContext)
          356  +		{
          357  +			EmbeddedResources.WriteEmbeddedResources(
          358  +				GetType().Module.Assembly,
          359  +				GetType().Namespace + ".css",
          360  +				buildContext.WorkingDirectory);
          361  +
          362  +			// Write the embedded icons to the html output directory
          363  +			EmbeddedResources.WriteEmbeddedResources(
          364  +				GetType().Module.Assembly,
          365  +				GetType().Namespace + ".images",
          366  +				buildContext.WorkingDirectory);
          367  +
          368  +			// Write the embedded scripts to the html output directory
          369  +			EmbeddedResources.WriteEmbeddedResources(
          370  +				GetType().Module.Assembly,
          371  +				GetType().Namespace + ".scripts",
          372  +				buildContext.WorkingDirectory);
          373  +
          374  +			if (((string)MyConfig.AdditionalContentResourceDirectory).Length > 0)
          375  +				buildContext.CopyToWorkingDirectory(new DirectoryInfo(MyConfig.AdditionalContentResourceDirectory));
          376  +
          377  +			// Write the external files (FilesToInclude) to the html output directory
          378  +
          379  +			foreach (string srcFilePattern in MyConfig.FilesToInclude.Split('|')) {
          380  +				if (string.IsNullOrEmpty(srcFilePattern))
          381  +					continue;
          382  +
          383  +				string path = Path.GetDirectoryName(srcFilePattern);
          384  +				string pattern = Path.GetFileName(srcFilePattern);
          385  +
          386  +				// Path.GetDirectoryName can return null in some cases.
          387  +				// Treat this as an empty string.
          388  +				if (path == null)
          389  +					path = string.Empty;
          390  +
          391  +				// Make sure we have a fully-qualified path name
          392  +				if (!Path.IsPathRooted(path))
          393  +					path = Path.Combine(Environment.CurrentDirectory, path);
          394  +
          395  +				// Directory.GetFiles does not accept null or empty string
          396  +				// for the searchPattern parameter. When no pattern was
          397  +				// specified, assume all files (*) are wanted.
          398  +				if (string.IsNullOrEmpty(pattern))
          399  +					pattern = "*";
          400  +
          401  +				foreach (string srcFile in Directory.GetFiles(path, pattern)) {
          402  +					string dstFile = Path.Combine(buildContext.WorkingDirectory.FullName, Path.GetFileName(srcFile));
          403  +					File.Copy(srcFile, dstFile, true);
          404  +					File.SetAttributes(dstFile, FileAttributes.Archive);
          405  +					filesToInclude.Add(dstFile);
          406  +				}
          407  +			}
          408  +		}
          409  +
          410  +		private static void XslTransform(BuildProjectContext buildContext, string stylesheetName, IXPathNavigable xpathNavigable, XsltArgumentList arguments, TextWriter writer, string targetFilename)
          411  +		{
          412  +			StyleSheet stylesheet = buildContext.stylesheets[stylesheetName];
          413  +			try {
          414  +				stylesheet.Transform(xpathNavigable, arguments, writer);
          415  +			} catch (XsltException ex) {
          416  +				throw new DocumenterException(string.Format("XSLT error while writing file {0} using stylesheet {1}({2}:{3}) : {4}", targetFilename, stylesheetName, ex.LineNumber, ex.LinePosition, ex.Message));
          417  +			}
          418  +		}
          419  +
          420  +		private MsdnDocumenterConfig MyConfig
          421  +		{
          422  +			get
          423  +			{
          424  +				return (MsdnDocumenterConfig)Config;
          425  +			}
          426  +		}
          427  +
          428  +		private static WhichType GetWhichType(XmlNode typeNode)
          429  +		{
          430  +			WhichType whichType;
          431  +
          432  +			switch (typeNode.Name) {
          433  +				case "class":
          434  +					whichType = WhichType.Class;
          435  +					break;
          436  +				case "interface":
          437  +					whichType = WhichType.Interface;
          438  +					break;
          439  +				case "structure":
          440  +					whichType = WhichType.Structure;
          441  +					break;
          442  +				case "enumeration":
          443  +					whichType = WhichType.Enumeration;
          444  +					break;
          445  +				case "delegate":
          446  +					whichType = WhichType.Delegate;
          447  +					break;
          448  +				default:
          449  +					whichType = WhichType.Unknown;
          450  +					break;
          451  +			}
          452  +
          453  +			return whichType;
          454  +		}
          455  +
          456  +		private void MakeHtmlForAssemblies(BuildProjectContext ctx, bool mergeAssemblies)
          457  +		{
          458  +#if DEBUG
          459  +			int start = Environment.TickCount;
          460  +#endif
          461  +
          462  +			MakeHtmlForAssembliesSorted(ctx, mergeAssemblies);
          463  +
          464  +#if DEBUG
          465  +			Trace.WriteLine("Making Html: " + ((Environment.TickCount - start) / 1000.0) + " sec.");
          466  +#endif
          467  +		}
          468  +
          469  +		private void MakeHtmlForAssembliesSorted(BuildProjectContext ctx, bool mergeAssemblies)
          470  +		{
          471  +			const string defaultNamespace = null;
          472  +
          473  +			XmlNodeList assemblyNodes = ctx.SelectNodes("/ndoc:ndoc/ndoc:assembly");
          474  +
          475  +			List<string> assemblyNames = new List<string>();
          476  +			foreach(XmlNode node in assemblyNodes) assemblyNames.Add(GetNodeName(node));
          477  +			assemblyNames.Sort();
          478  +
          479  +			if (mergeAssemblies)
          480  +            {
          481  +                // sort namespaces alphabetically except for defaultNamespace, which is always first
          482  +				string[] namespaces = SortNamespaces(ctx, assemblyNames, defaultNamespace);
          483  +				MakeHtmlForNamespaces(ctx, null, namespaces);                
          484  +            }
          485  +            else
          486  +            {
          487  +                foreach (string currentAssemblyName in assemblyNames)
          488  +                {
          489  +                    MakeHtmlForAssembly(ctx, currentAssemblyName);
          490  +
          491  +					ctx.htmlHelp.OpenBookInContents();
          492  +                    string[] namespaces = SortNamespaces(ctx, new List<string>( new[] { currentAssemblyName }) , defaultNamespace);
          493  +					MakeHtmlForNamespaces(ctx, currentAssemblyName, namespaces);
          494  +					ctx.htmlHelp.CloseBookInContents();
          495  +                }
          496  +            }
          497  +        }
          498  +
          499  +		private void MakeHtmlForAssembly(BuildProjectContext ctx, string assemblyName)
          500  +		{
          501  +			BuildAssemblyContext actx = new BuildAssemblyContext(ctx, assemblyName);
          502  +			string fileName = ctx._nameResolver.GetFilenameForAssembly(assemblyName);
          503  +
          504  +			XsltArgumentList arguments = new XsltArgumentList();
          505  +			arguments.AddParam("assembly-name", String.Empty, assemblyName);
          506  +			TransformAndWriteResult(actx, "assembly", arguments, fileName);
          507  +
          508  +			ctx.htmlHelp.AddFileToContents(assemblyName + " Assembly", fileName, HtmlHelpIcon.Page);
          509  +		}
          510  +
          511  +		private void MakeHtmlForNamespaces(BuildProjectContext ctx, string currentAssembly, IList<string> namespaces)
          512  +		{
          513  +			int nNodes = namespaces.Count;
          514  +
          515  +			bool heirTOC = (MyConfig.NamespaceTOCStyle == TOCStyle.Hierarchical);
          516  +			int level = 0;
          517  +
          518  +			string[] last = new string[0];
          519  +
          520  +			BuildAssemblyContext generatorContext = null;
          521  +			for (int i = 0; i < nNodes; i++) {
          522  +				OnDocBuildingProgress(i * 100 / nNodes); // TODO (EE): fix calc for !MergeAssemblies mode
          523  +
          524  +				string currentNamespace = namespaces[i];
          525  +				// determine assembly containing this namespace
          526  +				XmlNodeList namespaceNodes = (currentAssembly==null) 
          527  +					? ctx.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace[@name='{0}']", currentNamespace))
          528  +					: ctx.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace[@name='{1}']", currentAssembly, currentNamespace));
          529  +
          530  +				string assemblyName = GetNodeName(ctx.SelectSingleNode(namespaceNodes[0], "ancestor::ndoc:assembly"));
          531  +				generatorContext = new BuildAssemblyContext(ctx, assemblyName);
          532  +
          533  +				if (heirTOC) {
          534  +					string[] split = currentNamespace.Split('.');
          535  +
          536  +					for (level = last.Length; level >= 0 &&
          537  +						ArrayEquals(split, 0, last, 0, level) == false; level--) {
          538  +						if (level > last.Length)
          539  +							continue;
          540  +
          541  +						string namespaceName = string.Join(".", last, 0, level);
          542  +						XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, namespaceName);
          543  +						MakeHtmlForTypes(generatorContext, typeNodes);
          544  +						ctx.htmlHelp.CloseBookInContents();
          545  +					}
          546  +
          547  +					if (level < 0)
          548  +						level = 0;
          549  +
          550  +					for (; level < split.Length; level++) {
          551  +						string namespaceName = string.Join(".", split, 0, level + 1);
          552  +
          553  +						if (!namespaces.Contains(namespaceName))
          554  +//						if (Array.BinarySearch(namespaces, namespaceName) < 0)
          555  +							MakeHtmlForNamespace(generatorContext, split[level], namespaceName, false);
          556  +						else
          557  +							MakeHtmlForNamespace(generatorContext, split[level], namespaceName, true);
          558  +
          559  +						ctx.htmlHelp.OpenBookInContents();
          560  +					}
          561  +
          562  +					last = split;
          563  +				} else {
          564  +					MakeHtmlForNamespace(generatorContext, currentNamespace, currentNamespace, true);
          565  +					using (ctx.htmlHelp.OpenBookInContents()) {
          566  +						XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, currentNamespace);
          567  +						MakeHtmlForTypes(generatorContext, typeNodes);
          568  +					}
          569  +				}
          570  +			}
          571  +
          572  +
          573  +			if (heirTOC && last.Length > 0) {
          574  +				for (; level >= 1; level--) {
          575  +					string ns = string.Join(".", last, 0, level);
          576  +					XmlNodeList typeNodes = GetTypeNodes(ctx, currentAssembly, ns);
          577  +					MakeHtmlForTypes(generatorContext, typeNodes);
          578  +					ctx.htmlHelp.CloseBookInContents();
          579  +				}
          580  +			}
          581  +
          582  +			OnDocBuildingProgress(100);
          583  +		}
          584  +
          585  +		private static XmlNodeList GetTypeNodes(BuildProjectContext ctx, string assembly, string namespaceName)
          586  +		{
          587  +			string xpath = (assembly == null)
          588  +			               	? string.Format(
          589  +			               	  	"/ndoc:ndoc/ndoc:assembly/ndoc:module/ndoc:namespace[@name='{0}']/*[local-name()!='documentation' and local-name()!='typeHierarchy']",
          590  +			               	  	namespaceName)
          591  +			               	: string.Format(
          592  +			               	  	"/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace[@name='{1}']/*[local-name()!='documentation' and local-name()!='typeHierarchy']",
          593  +								assembly,
          594  +			               	  	namespaceName);
          595  +			XmlNodeList typeNodes = ctx.SelectNodes(xpath);
          596  +			return typeNodes;			
          597  +		}
          598  +
          599  +		private static bool ArrayEquals(string[] array1, int from1, string[] array2, int from2, int count)
          600  +		{
          601  +			for (int i = 0; i < count; i++) {
          602  +				if (array1[from1 + i] != array2[from2 + i])
          603  +					return false;
          604  +			}
          605  +
          606  +			return true;
          607  +		}
          608  +
          609  +		private static void GetNamespacesFromAssembly(BuildProjectContext buildContext, string assemblyName, NameValueCollection namespaceAssemblies)
          610  +		{
          611  +			XmlNodeList namespaceNodes = buildContext.SelectNodes(string.Format("/ndoc:ndoc/ndoc:assembly[@name='{0}']/ndoc:module/ndoc:namespace", assemblyName));
          612  +			foreach (XmlNode namespaceNode in namespaceNodes) {
          613  +				string namespaceName = GetNodeName(namespaceNode);
          614  +				namespaceAssemblies.Add(namespaceName, assemblyName);
          615  +			}
          616  +		}
          617  +
          618  +		/// <summary>
          619  +		/// Add the namespace elements to the output
          620  +		/// </summary>
          621  +		/// <remarks>
          622  +		/// The namespace 
          623  +		/// </remarks>
          624  +		/// <param name="ctx"></param>
          625  +		/// <param name="namespacePart">If nested, the namespace part will be the current
          626  +		/// namespace element being documented</param>
          627  +		/// <param name="namespaceName">The full namespace name being documented</param>
          628  +		/// <param name="addDocumentation">If true, the namespace will be documented, if false
          629  +		/// the node in the TOC will not link to a page</param>
          630  +		private void MakeHtmlForNamespace(BuildAssemblyContext ctx, string namespacePart, string namespaceName,
          631  +			bool addDocumentation)
          632  +		{
          633  +			//			// handle duplicate namespace documentation
          634  +			//			if (ctx.documentedNamespaces.Contains(namespaceName)) 
          635  +			//				return;
          636  +			//			ctx.documentedNamespaces.Add(namespaceName);
          637  +
          638  +			if (addDocumentation) {
          639  +				string currentAssemblyName = (ctx.MergeAssemblies) ? string.Empty : ctx.CurrentAssemblyName;
          640  +
          641  +				string namespaceFilename = ctx._nameResolver.GetFilenameForNamespace(currentAssemblyName, namespaceName);
          642  +
          643  +				ctx.htmlHelp.AddFileToContents(namespacePart, namespaceFilename);
          644  +
          645  +				XsltArgumentList arguments = new XsltArgumentList();
          646  +				arguments.AddParam("merge-assemblies", String.Empty, ctx.MergeAssemblies);
          647  +				arguments.AddParam("namespace", String.Empty, namespaceName);
          648  +				TransformAndWriteResult(ctx, "namespace", arguments, namespaceFilename);
          649  +
          650  +				string namespaceHierarchyFilename = ctx._nameResolver.GetFilenameForNamespaceHierarchy(currentAssemblyName, namespaceName);
          651  +				arguments = new XsltArgumentList();
          652  +				arguments.AddParam("merge-assemblies", String.Empty, ctx.MergeAssemblies);
          653  +				arguments.AddParam("namespace", String.Empty, namespaceName);
          654  +				TransformAndWriteResult(ctx, "namespacehierarchy", arguments, namespaceHierarchyFilename);
          655  +			} else {
          656  +				ctx.htmlHelp.AddFileToContents(namespacePart);
          657  +			}
          658  +		}
          659  +
          660  +		private void MakeHtmlForTypes(BuildProjectContext projectCtx, XmlNodeList typeNodes)
          661  +		{
          662  +			int[] indexes = SortNodesByAttribute(typeNodes, "id");
          663  +			int nNodes = typeNodes.Count;
          664  +
          665  +			for (int i = 0; i < nNodes; i++) {
          666  +				XmlNode typeNode = typeNodes[indexes[i]];
          667  +				WhichType whichType = GetWhichType(typeNode);
          668  +
          669  +				string assemblyName = XmlUtils.GetNodeName(projectCtx.SelectSingleNode(typeNode, "ancestor::ndoc:assembly"));
          670  +				BuildAssemblyContext ctx = new BuildAssemblyContext(projectCtx, assemblyName); // TODO (EE): initialize w/ assembly name
          671  +
          672  +				switch (whichType) {
          673  +					case WhichType.Class:
          674  +						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
          675  +						break;
          676  +					case WhichType.Interface:
          677  +						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
          678  +						break;
          679  +					case WhichType.Structure:
          680  +						MakeHtmlForInterfaceOrClassOrStructure(ctx, whichType, typeNode);
          681  +						break;
          682  +					case WhichType.Enumeration:
          683  +						MakeHtmlForEnumerationOrDelegate(ctx, whichType, typeNode);
          684  +						break;
          685  +					case WhichType.Delegate:
          686  +						MakeHtmlForEnumerationOrDelegate(ctx, whichType, typeNode);
          687  +						break;
          688  +					default:
          689  +						break;
          690  +				}
          691  +			}
          692  +		}
          693  +
          694  +		private void MakeHtmlForEnumerationOrDelegate(BuildAssemblyContext ctx, WhichType whichType, XmlNode typeNode)
          695  +		{
          696  +			string typeName = whichType == WhichType.Delegate ? GetNodeDisplayName(typeNode) : GetNodeName(typeNode);
          697  +			string typeID = GetNodeId(typeNode);
          698  +			string fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, typeID);
          699  +
          700  +			ctx.htmlHelp.AddFileToContents(typeName + " " + mixedCaseTypeNames[whichType], fileName, HtmlHelpIcon.Page);
          701  +
          702  +			XsltArgumentList arguments = new XsltArgumentList();
          703  +			arguments.AddParam("type-id", String.Empty, typeID);
          704  +			TransformAndWriteResult(ctx, "type", arguments, fileName);
          705  +		}
          706  +
          707  +		private void MakeHtmlForInterfaceOrClassOrStructure(BuildAssemblyContext ctx,
          708  +			WhichType whichType,
          709  +			XmlNode typeNode)
          710  +		{
          711  +			string typeName = GetNodeDisplayName(typeNode);
          712  +			string typeID = GetNodeId(typeNode);
          713  +			string fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, typeID);
          714  +
          715  +			ctx.htmlHelp.AddFileToContents(typeName + " " + mixedCaseTypeNames[whichType], fileName);
          716  +
          717  +			bool hasMembers = ctx.SelectNodes(typeNode, "ndoc:constructor|ndoc:field|ndoc:property|ndoc:method|ndoc:operator|ndoc:event").Count > 0;
          718  +
          719  +			if (hasMembers) {
          720  +				ctx.htmlHelp.OpenBookInContents();
          721  +			}
          722  +
          723  +			XsltArgumentList arguments = new XsltArgumentList();
          724  +			arguments.AddParam("type-id", String.Empty, typeID);
          725  +			TransformAndWriteResult(ctx, "type", arguments, fileName);
          726  +
          727  +			if (ctx.SelectNodes(typeNode, "ndoc:derivedBy").Count > 5) {
          728  +				fileName = ctx._nameResolver.GetFilenameForTypeHierarchy(ctx.CurrentAssemblyName, typeID);
          729  +				arguments = new XsltArgumentList();
          730  +				arguments.AddParam("type-id", String.Empty, typeID);
          731  +				TransformAndWriteResult(ctx, "typehierarchy", arguments, fileName);
          732  +			}
          733  +
          734  +			if (hasMembers) {
          735  +				fileName = ctx._nameResolver.GetFilenameForTypeMemberList(ctx.CurrentAssemblyName, typeID);
          736  +				ctx.htmlHelp.AddFileToContents(typeName + " Members",
          737  +					fileName,
          738  +					HtmlHelpIcon.Page);
          739  +
          740  +				arguments = new XsltArgumentList();
          741  +				arguments.AddParam("type-id", String.Empty, typeID);
          742  +				TransformAndWriteResult(ctx, "allmembers", arguments, fileName);
          743  +
          744  +				MakeHtmlForConstructors(ctx, typeNode);
          745  +				MakeHtmlForFields(ctx, typeNode);
          746  +				MakeHtmlForProperties(ctx, typeNode);
          747  +				MakeHtmlForMethods(ctx, typeNode);
          748  +				MakeHtmlForOperators(ctx, typeNode);
          749  +				MakeHtmlForEvents(ctx, typeNode);
          750  +
          751  +				ctx.htmlHelp.CloseBookInContents();
          752  +			}
          753  +		}
          754  +
          755  +		private void MakeHtmlForConstructors(BuildAssemblyContext ctx, XmlNode typeNode)
          756  +		{
          757  +			string constructorID;
          758  +			string fileName;
          759  +
          760  +			string typeName = GetNodeDisplayName(typeNode);
          761  +			string typeID = GetNodeId(typeNode);
          762  +
          763  +			XmlNodeList constructorNodes = ctx.SelectNodes(typeNode, "ndoc:constructor[@contract!='Static']");
          764  +			// If the constructor is overloaded then make an overload page.
          765  +			if (constructorNodes.Count > 1) {
          766  +				fileName = ctx._nameResolver.GetFilenameForConstructorList(ctx.CurrentAssemblyName, typeID);
          767  +				ctx.htmlHelp.AddFileToContents(typeName + " Constructor", fileName);
          768  +
          769  +				ctx.htmlHelp.OpenBookInContents();
          770  +
          771  +				constructorID = constructorNodes[0].Attributes["id"].Value;
          772  +
          773  +				XsltArgumentList arguments = new XsltArgumentList();
          774  +				arguments.AddParam("member-id", String.Empty, constructorID);
          775  +				TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);
          776  +			}
          777  +
          778  +			foreach (XmlNode constructorNode in constructorNodes) {
          779  +				constructorID = constructorNode.Attributes["id"].Value;
          780  +				fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, constructorID);
          781  +
          782  +				if (constructorNodes.Count > 1) {
          783  +					XmlNodeList parameterNodes = ctx.SelectNodes(constructorNode, "ndoc:parameter");
          784  +					ctx.htmlHelp.AddFileToContents(typeName + " Constructor " + GetParamList(parameterNodes), fileName,
          785  +						HtmlHelpIcon.Page);
          786  +				} else {
          787  +					ctx.htmlHelp.AddFileToContents(typeName + " Constructor", fileName, HtmlHelpIcon.Page);
          788  +				}
          789  +
          790  +				XsltArgumentList arguments = new XsltArgumentList();
          791  +				arguments.AddParam("member-id", String.Empty, constructorID);
          792  +				TransformAndWriteResult(ctx, "member", arguments, fileName);
          793  +			}
          794  +
          795  +			if (constructorNodes.Count > 1) {
          796  +				ctx.htmlHelp.CloseBookInContents();
          797  +			}
          798  +
          799  +			XmlNode staticConstructorNode = ctx.SelectSingleNode(typeNode, "ndoc:constructor[@contract='Static']");
          800  +			if (staticConstructorNode != null) {
          801  +				constructorID = staticConstructorNode.Attributes["id"].Value;
          802  +				fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, constructorID);
          803  +
          804  +				ctx.htmlHelp.AddFileToContents(typeName + " Static Constructor", fileName, HtmlHelpIcon.Page);
          805  +
          806  +				XsltArgumentList arguments = new XsltArgumentList();
          807  +				arguments.AddParam("member-id", String.Empty, constructorID);
          808  +				TransformAndWriteResult(ctx, "member", arguments, fileName);
          809  +			}
          810  +		}
          811  +
          812  +		private void MakeHtmlForFields(BuildAssemblyContext ctx, XmlNode typeNode)
          813  +		{
          814  +			XmlNodeList fields = ctx.SelectNodes(typeNode, "ndoc:field[not(@declaringType)]");
          815  +
          816  +			if (fields.Count > 0) {
          817  +				//string typeName = typeNode.Attributes["name"].Value;
          818  +				string typeID = GetNodeId(typeNode);
          819  +				string fileName = ctx._nameResolver.GetFilenameForFieldList(ctx.CurrentAssemblyName, typeID);
          820  +
          821  +				ctx.htmlHelp.AddFileToContents("Fields", fileName);
          822  +
          823  +				XsltArgumentList arguments = new XsltArgumentList();
          824  +				arguments.AddParam("type-id", String.Empty, typeID);
          825  +				arguments.AddParam("member-type", String.Empty, "field");
          826  +				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);
          827  +
          828  +				ctx.htmlHelp.OpenBookInContents();
          829  +
          830  +				int[] indexes = SortNodesByAttribute(fields, "id");
          831  +
          832  +				foreach (int index in indexes) {
          833  +					XmlNode field = fields[index];
          834  +
          835  +					string fieldName = GetNodeName(field);
          836  +					string fieldID = GetNodeId(field);
          837  +					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, fieldID);
          838  +					ctx.htmlHelp.AddFileToContents(fieldName + " Field", fileName, HtmlHelpIcon.Page);
          839  +
          840  +					arguments = new XsltArgumentList();
          841  +					arguments.AddParam("field-id", String.Empty, fieldID);
          842  +					TransformAndWriteResult(ctx, "field", arguments, fileName);
          843  +				}
          844  +
          845  +				ctx.htmlHelp.CloseBookInContents();
          846  +			}
          847  +		}
          848  +
          849  +		private void MakeHtmlForProperties(BuildAssemblyContext ctx, XmlNode typeNode)
          850  +		{
          851  +			XmlNodeList declaredPropertyNodes = ctx.SelectNodes(typeNode, "ndoc:property[not(@declaringType)]");
          852  +
          853  +			if (declaredPropertyNodes.Count > 0) {
          854  +				XmlNode propertyNode;
          855  +				bool bOverloaded = false;
          856  +				int i;
          857  +
          858  +				string typeID = GetNodeId(typeNode);
          859  +				XmlNodeList propertyNodes = ctx.SelectNodes(typeNode, "ndoc:property[not(@declaringType)]");
          860  +				int nNodes = propertyNodes.Count;
          861  +
          862  +				int[] indexes = SortNodesByAttribute(propertyNodes, "id");
          863  +
          864  +				string fileName = ctx._nameResolver.GetFilenameForPropertyList(ctx.CurrentAssemblyName, typeID);
          865  +				ctx.htmlHelp.AddFileToContents("Properties", fileName);
          866  +
          867  +				XsltArgumentList arguments = new XsltArgumentList();
          868  +				arguments.AddParam("type-id", String.Empty, typeID);
          869  +				arguments.AddParam("member-type", String.Empty, "property");
          870  +				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);
          871  +
          872  +				ctx.htmlHelp.OpenBookInContents();
          873  +
          874  +				for (i = 0; i < nNodes; i++) {
          875  +					propertyNode = propertyNodes[indexes[i]];
          876  +
          877  +					string propertyName = propertyNode.Attributes["name"].Value;
          878  +					string propertyID = propertyNode.Attributes["id"].Value;
          879  +
          880  +					// If the method is overloaded then make an overload page.
          881  +					string previousPropertyName = ((i - 1 < 0) || (propertyNodes[indexes[i - 1]].Attributes.Count == 0))
          882  +													? "" : propertyNodes[indexes[i - 1]].Attributes[0].Value;
          883  +					string nextPropertyName = ((i + 1 == nNodes) || (propertyNodes[indexes[i + 1]].Attributes.Count == 0))
          884  +												? "" : propertyNodes[indexes[i + 1]].Attributes[0].Value;
          885  +
          886  +					if ((previousPropertyName != propertyName) && (nextPropertyName == propertyName)) {
          887  +						fileName = ctx._nameResolver.GetFilenameForPropertyOverloads(ctx.CurrentAssemblyName, typeID, propertyName);
          888  +						ctx.htmlHelp.AddFileToContents(propertyName + " Property", fileName);
          889  +
          890  +						arguments = new XsltArgumentList();
          891  +						arguments.AddParam("member-id", String.Empty, propertyID);
          892  +						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);
          893  +
          894  +						ctx.htmlHelp.OpenBookInContents();
          895  +
          896  +						bOverloaded = true;
          897  +					}
          898  +
          899  +					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, propertyID);
          900  +
          901  +					string pageTitle;
          902  +					if (!bOverloaded) {
          903  +						pageTitle = string.Format("{0} Property", propertyName);
          904  +					} else {
          905  +						XmlNodeList parameterNodes = ctx.SelectNodes(propertyNode, "ns:parameter");
          906  +						pageTitle = string.Format("{0} Property {1}", propertyName, GetParamList(parameterNodes));
          907  +					}
          908  +					ctx.htmlHelp.AddFileToContents(pageTitle, fileName, HtmlHelpIcon.Page);
          909  +
          910  +					XsltArgumentList arguments2 = new XsltArgumentList();
          911  +					arguments2.AddParam("property-id", String.Empty, propertyID);
          912  +					TransformAndWriteResult(ctx, "property", arguments2, fileName);
          913  +
          914  +					if ((previousPropertyName == propertyName) && (nextPropertyName != propertyName)) {
          915  +						ctx.htmlHelp.CloseBookInContents();
          916  +						bOverloaded = false;
          917  +					}
          918  +				}
          919  +
          920  +				ctx.htmlHelp.CloseBookInContents();
          921  +			}
          922  +		}
          923  +
          924  +		private static string GetPreviousMethodName(XmlNodeList methodNodes, int[] indexes, int index)
          925  +		{
          926  +			while (--index >= 0) {
          927  +				if (methodNodes[indexes[index]].Attributes["declaringType"] == null)
          928  +					return methodNodes[indexes[index]].Attributes["name"].Value;
          929  +			}
          930  +			return null;
          931  +		}
          932  +
          933  +		private static string GetNextMethodName(XmlNodeList methodNodes, int[] indexes, int index)
          934  +		{
          935  +			while (++index < methodNodes.Count) {
          936  +				if (methodNodes[indexes[index]].Attributes["declaringType"] == null)
          937  +					return methodNodes[indexes[index]].Attributes["name"].Value;
          938  +			}
          939  +			return null;
          940  +		}
          941  +
          942  +		// returns true, if method is neither overload of a method in the same class,
          943  +		// nor overload of a method in the base class.
          944  +		private static bool IsMethodAlone(XmlNodeList methodNodes, int[] indexes, int index)
          945  +		{
          946  +			string name = methodNodes[indexes[index]].Attributes["name"].Value;
          947  +			int lastIndex = methodNodes.Count - 1;
          948  +			if (lastIndex <= 0)
          949  +				return true;
          950  +			bool previousNameDifferent = (index == 0)
          951  +				|| (methodNodes[indexes[index - 1]].Attributes["name"].Value != name);
          952  +			bool nextNameDifferent = (index == lastIndex)
          953  +				|| (methodNodes[indexes[index + 1]].Attributes["name"].Value != name);
          954  +			return (previousNameDifferent && nextNameDifferent);
          955  +		}
          956  +
          957  +		private static bool IsMethodFirstOverload(XmlNodeList methodNodes, int[] indexes, int index)
          958  +		{
          959  +			if ((methodNodes[indexes[index]].Attributes["declaringType"] != null)
          960  +				|| IsMethodAlone(methodNodes, indexes, index))
          961  +				return false;
          962  +
          963  +			string name = methodNodes[indexes[index]].Attributes["name"].Value;
          964  +			string previousName = GetPreviousMethodName(methodNodes, indexes, index);
          965  +			return previousName != name;
          966  +		}
          967  +
          968  +		private static bool IsMethodLastOverload(XmlNodeList methodNodes, int[] indexes, int index)
          969  +		{
          970  +			if ((methodNodes[indexes[index]].Attributes["declaringType"] != null)
          971  +				|| IsMethodAlone(methodNodes, indexes, index))
          972  +				return false;
          973  +
          974  +			string name = methodNodes[indexes[index]].Attributes["name"].Value;
          975  +			string nextName = GetNextMethodName(methodNodes, indexes, index);
          976  +			return nextName != name;
          977  +		}
          978  +
          979  +		private void MakeHtmlForMethods(BuildAssemblyContext ctx, XmlNode typeNode)
          980  +		{
          981  +			XmlNodeList declaredMethodNodes = ctx.SelectNodes(typeNode, "ndoc:method[not(@declaringType)]");
          982  +
          983  +			if (declaredMethodNodes.Count > 0) {
          984  +				bool bOverloaded = false;
          985  +
          986  +				string typeID = GetNodeId(typeNode);
          987  +				XmlNodeList methodNodes = ctx.SelectNodes(typeNode, "ndoc:method");
          988  +				int nNodes = methodNodes.Count;
          989  +
          990  +				int[] indexes = SortNodesByAttribute(methodNodes, "id");
          991  +
          992  +				string fileName = ctx._nameResolver.GetFilenameForMethodList(ctx.CurrentAssemblyName, typeID);
          993  +				ctx.htmlHelp.AddFileToContents("Methods", fileName);
          994  +
          995  +				XsltArgumentList arguments = new XsltArgumentList();
          996  +				arguments.AddParam("type-id", String.Empty, typeID);
          997  +				arguments.AddParam("member-type", String.Empty, "method");
          998  +				TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);
          999  +
         1000  +				ctx.htmlHelp.OpenBookInContents();
         1001  +
         1002  +				for (int i = 0; i < nNodes; i++) {
         1003  +					XmlNode methodNode = methodNodes[indexes[i]];
         1004  +					string methodDisplayName = GetNodeDisplayName(methodNode);
         1005  +					string methodName = GetNodeName(methodNode);
         1006  +					string methodID = GetNodeId(methodNode);
         1007  +
         1008  +					if (IsMethodFirstOverload(methodNodes, indexes, i)) {
         1009  +						bOverloaded = true;
         1010  +
         1011  +						fileName = ctx._nameResolver.GetFilenameForMethodOverloads(ctx.CurrentAssemblyName, typeID, methodName);
         1012  +						ctx.htmlHelp.AddFileToContents(methodDisplayName + " Method", fileName);
         1013  +
         1014  +						arguments = new XsltArgumentList();
         1015  +						arguments.AddParam("member-id", String.Empty, methodID);
         1016  +						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);
         1017  +
         1018  +						ctx.htmlHelp.OpenBookInContents();
         1019  +					}
         1020  +
         1021  +					if (XmlUtils.GetAttributeString(methodNode, "declaringType", false) == null) {
         1022  +						fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, methodID);
         1023  +
         1024  +						string pageTitle;
         1025  +						if (bOverloaded) {
         1026  +							XmlNodeList parameterNodes = ctx.SelectNodes(methodNode, "ndoc:parameter");
         1027  +							pageTitle = methodDisplayName + GetParamList(parameterNodes) + " Method ";
         1028  +						} else {
         1029  +							pageTitle = methodDisplayName + " Method";
         1030  +						}
         1031  +						ctx.htmlHelp.AddFileToContents(pageTitle, fileName,
         1032  +							HtmlHelpIcon.Page);
         1033  +
         1034  +						XsltArgumentList arguments2 = new XsltArgumentList();
         1035  +						arguments2.AddParam("member-id", String.Empty, methodID);
         1036  +						TransformAndWriteResult(ctx, "member", arguments2, fileName);
         1037  +					}
         1038  +
         1039  +					if (bOverloaded && IsMethodLastOverload(methodNodes, indexes, i)) {
         1040  +						bOverloaded = false;
         1041  +						ctx.htmlHelp.CloseBookInContents();
         1042  +					}
         1043  +				}
         1044  +
         1045  +				ctx.htmlHelp.CloseBookInContents();
         1046  +			}
         1047  +		}
         1048  +
         1049  +		private void MakeHtmlForOperators(BuildAssemblyContext ctx, XmlNode typeNode)
         1050  +		{
         1051  +			XmlNodeList opNodes = ctx.SelectNodes(typeNode, "ndoc:operator");
         1052  +
         1053  +			if (opNodes.Count == 0)
         1054  +				return;
         1055  +
         1056  +			string typeID = GetNodeId(typeNode);
         1057  +			string fileName = ctx._nameResolver.GetFilenameForOperatorList(ctx.CurrentAssemblyName, typeID);
         1058  +			bool bOverloaded = false;
         1059  +
         1060  +			bool bHasOperators =
         1061  +				(ctx.SelectSingleNode(typeNode, "ndoc:operator[@name != 'op_Explicit' and @name != 'op_Implicit']") != null);
         1062  +			bool bHasConverters =
         1063  +				(ctx.SelectSingleNode(typeNode, "ndoc:operator[@name  = 'op_Explicit' or  @name  = 'op_Implicit']") != null);
         1064  +			string pageTitle = "";
         1065  +
         1066  +			if (bHasOperators) {
         1067  +				pageTitle = bHasConverters ? "Operators and Type Conversions" : "Operators";
         1068  +			} else {
         1069  +				if (bHasConverters) {
         1070  +					pageTitle = "Type Conversions";
         1071  +				}
         1072  +			}
         1073  +
         1074  +			ctx.htmlHelp.AddFileToContents(pageTitle, fileName);
         1075  +
         1076  +			XsltArgumentList arguments = new XsltArgumentList();
         1077  +			arguments.AddParam("type-id", String.Empty, typeID);
         1078  +			arguments.AddParam("member-type", String.Empty, "operator");
         1079  +			TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);
         1080  +
         1081  +			ctx.htmlHelp.OpenBookInContents();
         1082  +
         1083  +			int[] indexes = SortNodesByAttribute(opNodes, "id");
         1084  +			int nNodes = opNodes.Count;
         1085  +
         1086  +			//operators first
         1087  +			for (int i = 0; i < nNodes; i++) {
         1088  +				XmlNode operatorNode = opNodes[indexes[i]];
         1089  +
         1090  +				string operatorID = GetNodeId(operatorNode);
         1091  +				string opName = GetNodeName(operatorNode);
         1092  +				if ((opName != "op_Implicit") && (opName != "op_Explicit")) {
         1093  +					if (IsMethodFirstOverload(opNodes, indexes, i)) {
         1094  +						bOverloaded = true;
         1095  +
         1096  +						fileName = ctx._nameResolver.GetFilenameForOperatorOverloads(ctx.CurrentAssemblyName, typeID, opName);
         1097  +						ctx.htmlHelp.AddFileToContents(GetOperatorDisplayName(ctx, operatorNode), fileName);
         1098  +
         1099  +						arguments = new XsltArgumentList();
         1100  +						arguments.AddParam("member-id", String.Empty, operatorID);
         1101  +						TransformAndWriteResult(ctx, "memberoverload", arguments, fileName);
         1102  +
         1103  +						ctx.htmlHelp.OpenBookInContents();
         1104  +					}
         1105  +
         1106  +
         1107  +					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, operatorID);
         1108  +					string opPageTitle;
         1109  +					if (bOverloaded) {
         1110  +						XmlNodeList parameterNodes = ctx.SelectNodes(operatorNode, "ns:parameter");
         1111  +						opPageTitle = GetOperatorDisplayName(ctx, operatorNode) + GetParamList(parameterNodes);
         1112  +					} else {
         1113  +						opPageTitle = GetOperatorDisplayName(ctx, operatorNode);
         1114  +					}
         1115  +					ctx.htmlHelp.AddFileToContents(opPageTitle, fileName,
         1116  +												   HtmlHelpIcon.Page);
         1117  +
         1118  +					arguments = new XsltArgumentList();
         1119  +					arguments.AddParam("member-id", String.Empty, operatorID);
         1120  +					TransformAndWriteResult(ctx, "member", arguments, fileName);
         1121  +
         1122  +					if (bOverloaded && IsMethodLastOverload(opNodes, indexes, i)) {
         1123  +						bOverloaded = false;
         1124  +						ctx.htmlHelp.CloseBookInContents();
         1125  +					}
         1126  +				}
         1127  +			}
         1128  +
         1129  +			//type converters
         1130  +			for (int i = 0; i < nNodes; i++) {
         1131  +				XmlNode operatorNode = opNodes[indexes[i]];
         1132  +				string operatorID = GetNodeId(operatorNode);
         1133  +				string opName = GetNodeName(operatorNode);
         1134  +
         1135  +				if ((opName == "op_Implicit") || (opName == "op_Explicit")) {
         1136  +					fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, operatorID);
         1137  +					ctx.htmlHelp.AddFileToContents(GetOperatorDisplayName(ctx, operatorNode), fileName,
         1138  +												   HtmlHelpIcon.Page);
         1139  +
         1140  +					arguments = new XsltArgumentList();
         1141  +					arguments.AddParam("member-id", String.Empty, operatorID);
         1142  +					TransformAndWriteResult(ctx, "member", arguments, fileName);
         1143  +				}
         1144  +			}
         1145  +
         1146  +			ctx.htmlHelp.CloseBookInContents();
         1147  +		}
         1148  +
         1149  +		private static string GetOperatorDisplayName(BuildProjectContext ctx, XmlNode operatorNode)
         1150  +		{
         1151  +			string name = GetNodeName(operatorNode);
         1152  +
         1153  +			switch (name) {
         1154  +				case "op_Decrement":
         1155  +					return "Decrement Operator";
         1156  +				case "op_Increment":
         1157  +					return "Increment Operator";
         1158  +				case "op_UnaryNegation":
         1159  +					return "Unary Negation Operator";
         1160  +				case "op_UnaryPlus":
         1161  +					return "Unary Plus Operator";
         1162  +				case "op_LogicalNot":
         1163  +					return "Logical Not Operator";
         1164  +				case "op_True":
         1165  +					return "True Operator";
         1166  +				case "op_False":
         1167  +					return "False Operator";
         1168  +				case "op_AddressOf":
         1169  +					return "Address Of Operator";
         1170  +				case "op_OnesComplement":
         1171  +					return "Ones Complement Operator";
         1172  +				case "op_PointerDereference":
         1173  +					return "Pointer Dereference Operator";
         1174  +				case "op_Addition":
         1175  +					return "Addition Operator";
         1176  +				case "op_Subtraction":
         1177  +					return "Subtraction Operator";
         1178  +				case "op_Multiply":
         1179  +					return "Multiplication Operator";
         1180  +				case "op_Division":
         1181  +					return "Division Operator";
         1182  +				case "op_Modulus":
         1183  +					return "Modulus Operator";
         1184  +				case "op_ExclusiveOr":
         1185  +					return "Exclusive Or Operator";
         1186  +				case "op_BitwiseAnd":
         1187  +					return "Bitwise And Operator";
         1188  +				case "op_BitwiseOr":
         1189  +					return "Bitwise Or Operator";
         1190  +				case "op_LogicalAnd":
         1191  +					return "LogicalAnd Operator";
         1192  +				case "op_LogicalOr":
         1193  +					return "Logical Or Operator";
         1194  +				case "op_Assign":
         1195  +					return "Assignment Operator";
         1196  +				case "op_LeftShift":
         1197  +					return "Left Shift Operator";
         1198  +				case "op_RightShift":
         1199  +					return "Right Shift Operator";
         1200  +				case "op_SignedRightShift":
         1201  +					return "Signed Right Shift Operator";
         1202  +				case "op_UnsignedRightShift":
         1203  +					return "Unsigned Right Shift Operator";
         1204  +				case "op_Equality":
         1205  +					return "Equality Operator";
         1206  +				case "op_GreaterThan":
         1207  +					return "Greater Than Operator";
         1208  +				case "op_LessThan":
         1209  +					return "Less Than Operator";
         1210  +				case "op_Inequality":
         1211  +					return "Inequality Operator";
         1212  +				case "op_GreaterThanOrEqual":
         1213  +					return "Greater Than Or Equal Operator";
         1214  +				case "op_LessThanOrEqual":
         1215  +					return "Less Than Or Equal Operator";
         1216  +				case "op_UnsignedRightShiftAssignment":
         1217  +					return "Unsigned Right Shift Assignment Operator";
         1218  +				case "op_MemberSelection":
         1219  +					return "Member Selection Operator";
         1220  +				case "op_RightShiftAssignment":
         1221  +					return "Right Shift Assignment Operator";
         1222  +				case "op_MultiplicationAssignment":
         1223  +					return "Multiplication Assignment Operator";
         1224  +				case "op_PointerToMemberSelection":
         1225  +					return "Pointer To Member Selection Operator";
         1226  +				case "op_SubtractionAssignment":
         1227  +					return "Subtraction Assignment Operator";
         1228  +				case "op_ExclusiveOrAssignment":
         1229  +					return "Exclusive Or Assignment Operator";
         1230  +				case "op_LeftShiftAssignment":
         1231  +					return "Left Shift Assignment Operator";
         1232  +				case "op_ModulusAssignment":
         1233  +					return "Modulus Assignment Operator";
         1234  +				case "op_AdditionAssignment":
         1235  +					return "Addition Assignment Operator";
         1236  +				case "op_BitwiseAndAssignment":
         1237  +					return "Bitwise And Assignment Operator";
         1238  +				case "op_BitwiseOrAssignment":
         1239  +					return "Bitwise Or Assignment Operator";
         1240  +				case "op_Comma":
         1241  +					return "Comma Operator";
         1242  +				case "op_DivisionAssignment":
         1243  +					return "Division Assignment Operator";
         1244  +				case "op_Explicit": {
         1245  +						XmlNode parameterNode = ctx.SelectSingleNode(operatorNode, "ndoc:parameter");
         1246  +						string from = GetNodeTypeId(parameterNode);
         1247  +						string to = GetNodeTypeId(ctx.SelectSingleNode(operatorNode, "ndoc:returnType"));
         1248  +						return "Explicit " + StripNamespace(from) + " to " + StripNamespace(to) + " Conversion";
         1249  +					}
         1250  +				case "op_Implicit": {
         1251  +						XmlNode parameterNode = ctx.SelectSingleNode(operatorNode, "ndoc:parameter");
         1252  +						string from = GetNodeTypeId(parameterNode);
         1253  +						string to = GetNodeTypeId(ctx.SelectSingleNode(operatorNode, "ndoc:returnType"));
         1254  +						return "Implicit " + StripNamespace(from) + " to " + StripNamespace(to) + " Conversion";
         1255  +					}
         1256  +				default:
         1257  +					return "ERROR";
         1258  +			}
         1259  +		}
         1260  +
         1261  +		private void MakeHtmlForEvents(BuildAssemblyContext ctx, XmlNode typeNode)
         1262  +		{
         1263  +			XmlNodeList declaredEventNodes = ctx.SelectNodes(typeNode, "ndoc:event[not(@declaringType)]");
         1264  +
         1265  +			if (declaredEventNodes.Count > 0) {
         1266  +				XmlNodeList events = ctx.SelectNodes(typeNode, "ns:event");
         1267  +
         1268  +				if (events.Count > 0) {
         1269  +					//string typeName = (string)typeNode.Attributes["name"].Value;
         1270  +					string typeID = GetNodeId(typeNode);
         1271  +					string fileName = ctx._nameResolver.GetFilenameForEventList(ctx.CurrentAssemblyName, typeID);
         1272  +
         1273  +					ctx.htmlHelp.AddFileToContents("Events", fileName);
         1274  +
         1275  +					XsltArgumentList arguments = new XsltArgumentList();
         1276  +					arguments.AddParam("type-id", String.Empty, typeID);
         1277  +					arguments.AddParam("member-type", String.Empty, "event");
         1278  +					TransformAndWriteResult(ctx, "individualmembers", arguments, fileName);
         1279  +
         1280  +					ctx.htmlHelp.OpenBookInContents();
         1281  +
         1282  +					int[] indexes = SortNodesByAttribute(events, "id");
         1283  +
         1284  +					foreach (int index in indexes) {
         1285  +						XmlNode eventElement = events[index];
         1286  +
         1287  +						if (XmlUtils.GetAttributeString(eventElement, "declaringType", false) == null) {
         1288  +							string eventName = GetNodeName(eventElement);
         1289  +							string eventID = GetNodeId(eventElement);
         1290  +
         1291  +							fileName = ctx._nameResolver.GetFilenameForId(ctx.CurrentAssemblyName, eventID);
         1292  +							ctx.htmlHelp.AddFileToContents(eventName + " Event",
         1293  +								fileName,
         1294  +								HtmlHelpIcon.Page);
         1295  +
         1296  +							arguments = new XsltArgumentList();
         1297  +							arguments.AddParam("event-id", String.Empty, eventID);
         1298  +							TransformAndWriteResult(ctx, "event", arguments, fileName);
         1299  +						}
         1300  +					}
         1301  +
         1302  +					ctx.htmlHelp.CloseBookInContents();
         1303  +				}
         1304  +			}
         1305  +		}
         1306  +
         1307  +		private static string GetParamList(XmlNodeList parameterNodes)
         1308  +		{
         1309  +			ArrayList parameters = new ArrayList();
         1310  +
         1311  +			foreach (XmlNode parameterNode in parameterNodes) {
         1312  +
         1313  +				string parameterTypeName = GetParameterTypeName(parameterNode, "displayName");
         1314  +				
         1315  +				parameters.Add(parameterTypeName);
         1316  +			}
         1317  +
         1318  +			string[] parameterTypeNames = (string[]) parameters.ToArray(typeof (string));
         1319  +			string paramList = "(" + string.Join(",", parameterTypeNames) + ")";
         1320  +
         1321  +			return paramList;
         1322  +		}
         1323  +
         1324  +		private static string GetParameterTypeName(XmlNode root, string typeAttributeName)
         1325  +		{
         1326  +			XmlAttribute typeAtt = root.Attributes[typeAttributeName];
         1327  +			return typeAtt.Value;
         1328  +		}
         1329  +
         1330  +		private static string GetNodeId(XmlNode node)
         1331  +		{
         1332  +			return XmlUtils.GetNodeId(node);
         1333  +		}
         1334  +
         1335  +		private static string GetNodeTypeId(XmlNode node)
         1336  +		{
         1337  +			return XmlUtils.GetNodeTypeId(node);
         1338  +		}
         1339  +
         1340  +		private static string GetNodeName(XmlNode node)
         1341  +		{
         1342  +			return XmlUtils.GetNodeName(node);
         1343  +		}
         1344  +
         1345  +		private static string GetNodeDisplayName(XmlNode node)
         1346  +		{
         1347  +			return XmlUtils.GetNodeDisplayName(node);
         1348  +		}
         1349  +
         1350  +		private static string StripNamespace(string name)
         1351  +		{
         1352  +			string result = name;
         1353  +
         1354  +			int lastDot = name.LastIndexOf('.');
         1355  +
         1356  +			if (lastDot != -1) {
         1357  +				result = name.Substring(lastDot + 1);
         1358  +			}
         1359  +
         1360  +			return result;
         1361  +		}
         1362  +
         1363  +		private static int[] SortNodesByAttribute(XmlNodeList nodes, string attributeName)
         1364  +		{
         1365  +			int length = nodes.Count;
         1366  +			string[] names = new string[length];
         1367  +			int[] indexes = new int[length];
         1368  +			int i = 0;
         1369  +
         1370  +			foreach (XmlNode node in nodes) {
         1371  +				names[i] = node.Attributes[attributeName].Value;
         1372  +				indexes[i] = i++;
         1373  +			}
         1374  +
         1375  +			Array.Sort(names, indexes);
         1376  +
         1377  +			return indexes;
         1378  +		}
         1379  +
         1380  +		private static string[] SortNamespaces(BuildProjectContext ctx, IList<string> assemblyNames, string defaultNamespace)
         1381  +		{
         1382  +			NameValueCollection namespaceAssemblies = new NameValueCollection();
         1383  +			int nNodes = assemblyNames.Count;
         1384  +			for (int i = 0; i < nNodes; i++) {
         1385  +				string assemblyName = assemblyNames[i];
         1386  +				GetNamespacesFromAssembly(ctx, assemblyName, namespaceAssemblies);
         1387  +			}
         1388  +
         1389  +			string[] namespaces = namespaceAssemblies.AllKeys;
         1390  +			if (string.IsNullOrEmpty(defaultNamespace)) {
         1391  +				Array.Sort(namespaces);
         1392  +			} else {
         1393  +				Array.Sort(namespaces, (x, y) =>
         1394  +				{
         1395  +					if (x == y) {
         1396  +						return 0;
         1397  +					} else if (x == null || x == defaultNamespace) {
         1398  +						return -1;
         1399  +					} else if (y == defaultNamespace) {
         1400  +						return 1;
         1401  +					}
         1402  +					return x.CompareTo(y);
         1403  +				});
         1404  +			}
         1405  +			return namespaces;
         1406  +		}
         1407  +
         1408  +		private void TransformAndWriteResult(BuildAssemblyContext ctx,
         1409  +			string transformName,
         1410  +			XsltArgumentList arguments,
         1411  +			string filename)
         1412  +		{
         1413  +			Trace.WriteLine(filename);
         1414  +#if DEBUG
         1415  +			int start = Environment.TickCount;
         1416  +#endif
         1417  +
         1418  +			ExternalHtmlProvider htmlProvider = new ExternalHtmlProvider(MyConfig, filename);
         1419  +
         1420  +			try {
         1421  +
         1422  +				StreamWriter streamWriter;
         1423  +				string fullPath = Path.Combine(ctx.WorkingDirectory.FullName, filename);
         1424  +				using (streamWriter = new StreamWriter(
         1425  +					File.Open(fullPath, FileMode.Create),
         1426  +					ctx.CurrentFileEncoding)) {
         1427  +					string DocLangCode = Enum.GetName(typeof(SdkLanguage), MyConfig.SdkDocLanguage).Replace("_", "-");
         1428  +					
         1429  +					MsdnXsltUtilities utilities = new MsdnXsltUtilities(ctx._nameResolver, ctx.CurrentAssemblyName, MyConfig.SdkDocVersionString, DocLangCode, MyConfig.SdkLinksOnWeb, ctx.CurrentFileEncoding);
         1430  +					ctx._nameResolver.utilities = utilities;
         1431  +
         1432  +					if (arguments.GetParam("assembly-name", string.Empty) == null) {
         1433  +						arguments.AddParam("assembly-name", String.Empty, ctx.CurrentAssemblyName);
         1434  +					}
         1435  +					arguments.AddParam("ndoc-title", String.Empty, MyConfig.Title);
         1436  +					arguments.AddParam("ndoc-vb-syntax", String.Empty, MyConfig.ShowVisualBasic);
         1437  +					arguments.AddParam("ndoc-omit-object-tags", String.Empty, ((MyConfig.OutputTarget & OutputType.HtmlHelp) == 0));
         1438  +					arguments.AddParam("ndoc-document-attributes", String.Empty, MyConfig.DocumentAttributes);
         1439  +					arguments.AddParam("ndoc-documented-attributes", String.Empty, MyConfig.DocumentedAttributes);
         1440  +
         1441  +					arguments.AddParam("ndoc-sdk-doc-base-url", String.Empty, utilities.SdkDocBaseUrl);
         1442  +					arguments.AddParam("ndoc-sdk-doc-file-ext", String.Empty, utilities.SdkDocExt);
         1443  +					arguments.AddParam("ndoc-sdk-doc-language", String.Empty, utilities.SdkDocLanguage);
         1444  +
         1445  +					arguments.AddExtensionObject("urn:NDocUtil", utilities);
         1446  +					arguments.AddExtensionObject("urn:NDocExternalHtml", htmlProvider);
         1447  +
         1448  +					//Use new overload so we don't get obsolete warnings - clean compile :)
         1449  +
         1450  +					XslTransform(ctx, transformName, ctx.GetXPathNavigable(), arguments, streamWriter, fullPath);
         1451  +				}
         1452  +			}
         1453  +			catch(IOException ex)
         1454  +			{
         1455  +				throw new DocumenterException(string.Format("IO error while creating file {0}", filename), ex);
         1456  +			}
         1457  +//			catch (PathTooLongException e) {
         1458  +//				throw new PathTooLongException(e.Message + "\nThe file that NDoc3 was trying to create had the following name:\n" + Path.Combine(ctx.WorkingDirectory.FullName, filename));
         1459  +//			}
         1460  +
         1461  +#if DEBUG
         1462  +			Debug.WriteLine((Environment.TickCount - start) + " msec.");
         1463  +#endif
         1464  +			ctx.htmlHelp.AddFileToProject(filename);
         1465  +		}
         1466  +	}
         1467  +}

Added Externals/NDoc3/src/NameResolver.cs.

            1  +using System;
            2  +using System.Collections.Generic;
            3  +using System.Collections.Specialized;
            4  +using System.Xml;
            5  +using NDoc3.Core;
            6  +using NDoc3.Xml;
            7  +
            8  +namespace NDoc3.Documenter.Msdn {
            9  +	///<summary>
           10  +	///</summary>
           11  +	public class NameResolver {
           12  +		public const string EXT = ".html";
           13  +
           14  +		public MsdnXsltUtilities utilities;
           15  +		private readonly bool mergeAssemblies;
           16  +		private readonly StringDictionary fileNames = new StringDictionary();
           17  +		private readonly StringDictionary elemNames = new StringDictionary();
           18  +
           19  +		private readonly ReferenceTypeDictionary<string, string[]> assemblyReferences = new ReferenceTypeDictionary<string, string[]>();
           20  +
           21  +		///<summary>
           22  +		///</summary>
           23  +		///<param name="documentation"></param>
           24  +		///<param name="mergeAssemblies"></param>
           25  +		public NameResolver(XmlDocument documentation, bool mergeAssemblies) {
           26  +			this.mergeAssemblies = mergeAssemblies;
           27  +			BuildNameTables(documentation, mergeAssemblies);
           28  +		}
           29  +
           30  +		#region Used for Html file generation
           31  +
           32  +		///<summary>
           33  +		///</summary>
           34  +		///<param name="assemblyName"></param>
           35  +		///<param name="typeID"></param>
           36  +		///<returns></returns>
           37  +		public string GetFilenameForFieldList(string assemblyName, string typeID) {
           38  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Fields");
           39  +		}
           40  +
           41  +		///<summary>
           42  +		///</summary>
           43  +		///<param name="assemblyName"></param>
           44  +		///<param name="typeID"></param>
           45  +		///<returns></returns>
           46  +		public string GetFilenameForOperatorList(string assemblyName, string typeID) {
           47  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Operators");
           48  +		}
           49  +
           50  +		///<summary>
           51  +		///</summary>
           52  +		///<param name="assemblyName"></param>
           53  +		///<param name="typeID"></param>
           54  +		///<returns></returns>
           55  +		public string GetFilenameForMethodList(string assemblyName, string typeID) {
           56  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Methods");
           57  +		}
           58  +
           59  +		///<summary>
           60  +		///</summary>
           61  +		///<param name="assemblyName"></param>
           62  +		///<param name="typeID"></param>
           63  +		///<returns></returns>
           64  +		public string GetFilenameForPropertyList(string assemblyName, string typeID) {
           65  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Properties");
           66  +		}
           67  +
           68  +		///<summary>
           69  +		///</summary>
           70  +		///<param name="assemblyName"></param>
           71  +		///<param name="typeID"></param>
           72  +		///<returns></returns>
           73  +		public string GetFilenameForEventList(string assemblyName, string typeID) {
           74  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Events");
           75  +		}
           76  +		#endregion
           77  +
           78  +		// exposed to XSLT
           79  +		///<summary>
           80  +		///</summary>
           81  +		///<param name="currentAssemblyName"></param>
           82  +		///<param name="memberId"></param>
           83  +		///<returns></returns>
           84  +		public string GetDisplayNameForId(string currentAssemblyName, string memberId) {
           85  +			string name = elemNames[currentAssemblyName + memberId];
           86  +			if (name == null) {
           87  +				// search for identifier in referenced assemblies
           88  +				string[] assemblyReference = assemblyReferences[currentAssemblyName];
           89  +				if (assemblyReference != null) {
           90  +					foreach (string assemblyName in assemblyReference) {
           91  +						name = elemNames[assemblyName + memberId];
           92  +						if (name != null)
           93  +							break;
           94  +					}
           95  +				}
           96  +			}
           97  +
           98  +			if (name == null) {
           99  +				name = elemNames[memberId];
          100  +			}
          101  +			return name;
          102  +		}
          103  +
          104  +		// exposed to XSLT
          105  +		///<summary>
          106  +		///</summary>
          107  +		///<param name="currentAssemblyName"></param>
          108  +		///<param name="memberId"></param>
          109  +		///<returns></returns>
          110  +		public string GetFilenameForId(string currentAssemblyName, string memberId) {
          111  +			// lookup current assembly
          112  +			string filename = GetFilenameForIdInternal(currentAssemblyName, memberId);
          113  +			return filename;
          114  +		}
          115  +
          116  +		///<summary>
          117  +		///</summary>
          118  +		///<param name="assemblyName"></param>
          119  +		///<returns></returns>
          120  +		public string GetFilenameForAssembly(string assemblyName) {
          121  +			return GetFilenameForId(assemblyName, null);
          122  +		}
          123  +
          124  +		// exposed to XSLT
          125  +		///<summary>
          126  +		///</summary>
          127  +		///<param name="assemblyName"></param>
          128  +		///<param name="namespaceName"></param>
          129  +		///<returns></returns>
          130  +		public string GetFilenameForNamespaceHierarchy(string assemblyName, string namespaceName) {
          131  +			return GetFilenameForIdSpecial(assemblyName, "N:" + namespaceName, "~Hierarchy");
          132  +		}
          133  +
          134  +		// exposed to XSLT
          135  +		///<summary>
          136  +		///</summary>
          137  +		///<param name="assemblyName"></param>
          138  +		///<param name="namespaceName"></param>
          139  +		///<returns></returns>
          140  +		public string GetFilenameForNamespace(string assemblyName, string namespaceName) {
          141  +			if (mergeAssemblies)
          142  +				assemblyName = string.Empty;
          143  +			if (string.IsNullOrEmpty(namespaceName))
          144  +				namespaceName = "(global)";
          145  +			return GetFilenameForId(assemblyName, "N:" + namespaceName);
          146  +		}
          147  +
          148  +		// exposed to XSLT
          149  +		///<summary>
          150  +		///</summary>
          151  +		///<param name="assemblyName"></param>
          152  +		///<param name="typeID"></param>
          153  +		///<returns></returns>
          154  +		public string GetFilenameForTypeHierarchy(string assemblyName, string typeID) {
          155  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Hierarchy");
          156  +		}
          157  +
          158  +		// exposed to XSLT
          159  +		///<summary>
          160  +		///</summary>
          161  +		///<param name="assemblyName"></param>
          162  +		///<param name="typeID"></param>
          163  +		///<returns></returns>
          164  +		public string GetFilenameForTypeMemberList(string assemblyName, string typeID) {
          165  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Members");
          166  +		}
          167  +
          168  +		// exposed to XSLT
          169  +		///<summary>
          170  +		///</summary>
          171  +		///<param name="assemblyName"></param>
          172  +		///<param name="typeID"></param>
          173  +		///<returns></returns>
          174  +		public string GetFilenameForConstructorList(string assemblyName, string typeID) {
          175  +			return GetFilenameForIdSpecial(assemblyName, typeID, "~Constructors");
          176  +		}
          177  +
          178  +		// exposed to XSLT
          179  +		///<summary>
          180  +		///</summary>
          181  +		///<param name="assemblyName"></param>
          182  +		///<param name="typeID"></param>
          183  +		///<param name="operatorName"></param>
          184  +		///<returns></returns>
          185  +		public string GetFilenameForOperatorOverloads(string assemblyName, string typeID, string operatorName) {
          186  +			return GetFilenameForIdSpecial(assemblyName, typeID, "." + operatorName.Replace('`', '$') + "~Overloads");
          187  +		}
          188  +
          189  +		// exposed to XSLT
          190  +		///<summary>
          191  +		///</summary>
          192  +		///<param name="assemblyName"></param>
          193  +		///<param name="typeID"></param>
          194  +		///<param name="propertyName"></param>
          195  +		///<returns></returns>
          196  +		public string GetFilenameForPropertyOverloads(string assemblyName, string typeID, string propertyName) {
          197  +			string fileName = GetFilenameForIdSpecial(assemblyName, typeID, "." + propertyName.Replace('`', '$') + "~Overloads");
          198  +			return fileName;
          199  +		}
          200  +
          201  +		// exposed to XSLT
          202  +		///<summary>
          203  +		///</summary>
          204  +		///<param name="assemblyName"></param>
          205  +		///<param name="typeID"></param>
          206  +		///<param name="methodName"></param>
          207  +		///<returns></returns>
          208  +		public string GetFilenameForMethodOverloads(string assemblyName, string typeID, string methodName) {
          209  +			string fileName = GetFilenameForIdSpecial(assemblyName, typeID, "." + methodName.Replace('`', '$').Replace("<", "(").Replace(">", ")") + "~Overloads");
          210  +			return fileName;
          211  +		}
          212  +
          213  +		// exposed to XSLT
          214  +		///<summary>
          215  +		///</summary>
          216  +		///<param name="currentAssemblyName"></param>
          217  +		///<param name="typeName"></param>
          218  +		///<returns></returns>
          219  +		public string GetFilenameForTypename(string currentAssemblyName, string typeName) {
          220  +
          221  +			// strip leading type identifier
          222  +			if (typeName.Length > 1 && typeName[1] != ':')
          223  +				typeName = "T:" + typeName;
          224  +			string filename = GetFilenameForId(currentAssemblyName, typeName);
          225  +			return filename;
          226  +		}
          227  +
          228  +		// exposed
          229  +		///<summary>
          230  +		///</summary>
          231  +		///<param name="currentAssemblyName"></param>
          232  +		///<param name="cref"></param>
          233  +		///<param name="overload"></param>
          234  +		///<returns></returns>
          235  +		public string GetFilenameForCRefOverload(string currentAssemblyName, string cref, string overload) {
          236  +			// lookup current assembly
          237  +			string filename = GetFilenameForId(currentAssemblyName, cref);
          238  +			return filename;
          239  +
          240  +			#region Original XSLT Logic
          241  +			/*
          242  +					<!--<xsl:choose>
          243  +						<xsl:when test="starts-with($cref, 'T:')">
          244  +							<xsl:call-template name="get-filename-for-type-name">
          245  +								<xsl:with-param name="type-name" select="substring-after($cref, 'T:')" />
          246  +							</xsl:call-template>
          247  +						</xsl:when>
          248  +						<xsl:when test="starts-with($cref, 'M:')">
          249  +							<xsl:choose>
          250  +								<xsl:when test="contains($cref, '.#c')">
          251  +									<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '.#c'), 'M:'), '[,]', ''), 'Constructor', $overload, '.html')" />
          252  +								</xsl:when>
          253  +								<xsl:when test="contains($cref, '(')">
          254  +									<xsl:choose>
          255  +										<xsl:when test="string-length($overload) &gt; 0">
          256  +											<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'M:'), '[,]', ''), '_overload_', $overload, '.html')" />
          257  +										</xsl:when>
          258  +										<xsl:otherwise>
          259  +											<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'M:'), '[,]', ''), '.html')" />
          260  +										</xsl:otherwise>
          261  +									</xsl:choose>
          262  +								</xsl:when>
          263  +								<xsl:otherwise>
          264  +									<xsl:choose>
          265  +										<xsl:when test="string-length($overload) &gt; 0">
          266  +											<xsl:value-of select="concat(translate(substring-after($cref, 'M:'), '[,]', ''), '_overload_', $overload, '.html')" />
          267  +										</xsl:when>
          268  +										<xsl:otherwise>
          269  +											<xsl:value-of select="concat(translate(substring-after($cref, 'M:'), '[,]', ''), '.html')" />
          270  +										</xsl:otherwise>
          271  +									</xsl:choose>
          272  +								</xsl:otherwise>
          273  +							</xsl:choose>
          274  +						</xsl:when>
          275  +						<xsl:when test="starts-with($cref, 'E:')">
          276  +							<xsl:value-of select="concat(translate(substring-after($cref, 'E:'), '[,]', ''), $overload, '.html')" />
          277  +						</xsl:when>
          278  +						<xsl:when test="starts-with($cref, 'F:')">
          279  +							<xsl:variable name="enum" select="/ndoc/assembly/module/namespace//enumeration[field/@id = $cref]" />
          280  +							<xsl:choose>
          281  +								<xsl:when test="$enum">
          282  +									<xsl:call-template name="get-filename-for-type-name">
          283  +										<xsl:with-param name="type-name" select="substring-after($enum/@id, 'T:')" />
          284  +									</xsl:call-template>
          285  +								</xsl:when>
          286  +								<xsl:otherwise>
          287  +									<xsl:value-of select="concat(translate(substring-after($cref, 'F:'), '[,]', ''), $overload, '.html')" />
          288  +								</xsl:otherwise>
          289  +							</xsl:choose>
          290  +						</xsl:when>
          291  +						<xsl:when test="starts-with($cref, 'P:')">
          292  +							<xsl:choose>
          293  +								<xsl:when test="contains($cref, '(')">
          294  +									<xsl:value-of select="concat(translate(substring-after(substring-before($cref, '('), 'P:'), '[,]', ''), $overload, '.html')" />
          295  +								</xsl:when>
          296  +								<xsl:otherwise>
          297  +									<xsl:value-of select="concat(translate(substring-after($cref, 'P:'), '[,]', ''), $overload, '.html')" />
          298  +								</xsl:otherwise>
          299  +							</xsl:choose>
          300  +						</xsl:when>
          301  +						<xsl:otherwise>
          302  +							<xsl:value-of select="$cref" />
          303  +						</xsl:otherwise>
          304  +					</xsl:choose>-->
          305  +			*/
          306  +			#endregion
          307  +		}
          308  +
          309  +		#region BuildNameTables
          310  +
          311  +		private void BuildNameTables(XmlDocument xmlDocumentation, bool mergeNamespaces) {
          312  +			XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocumentation.NameTable);
          313  +			nsmgr.AddNamespace("ns", "urn:ndoc-schema");
          314  +			XmlNodeList assemblies = xmlDocumentation.SelectNodes("/ns:ndoc/ns:assembly", nsmgr);
          315  +			if(assemblies == null) throw new Exception("No assemblies found");
          316  +			foreach (XmlElement assemblyNode in assemblies) {
          317  +				string assemblyName = GetNodeName(assemblyNode);
          318  +				RegisterAssembly(assemblyName);
          319  +
          320  +				// build list of assemblyReferences
          321  +				XmlNodeList assemblyReferenceNodes = assemblyNode.SelectNodes("ns:assemblyReference", nsmgr);
          322  +				if(assemblyReferenceNodes == null) throw new Exception("No assembly reference nodes found");
          323  +				List<string> assemblyReferenceNames = new List<string>();
          324  +				foreach (XmlNode assemblyReferenceNode in assemblyReferenceNodes) {
          325  +					assemblyReferenceNames.Add(GetNodeName(assemblyReferenceNode));
          326  +				}
          327  +				assemblyReferences.Add(assemblyName, assemblyReferenceNames.ToArray());
          328  +
          329  +				// foreach namespace
          330  +				XmlNodeList namespaces = assemblyNode.SelectNodes("ns:module/ns:namespace", nsmgr);
          331  +				if(namespaces == null) throw new Exception("No namespaces found");
          332  +				foreach (XmlElement namespaceNode in namespaces) {
          333  +					string namespaceName = GetNodeName(namespaceNode);
          334  +					// register namespace
          335  +					RegisterNamespace((mergeNamespaces ? string.Empty : assemblyName), namespaceName);
          336  +
          337  +					XmlNodeList types = namespaceNode.SelectNodes("*[@id]", nsmgr);
          338  +					if(types == null) throw new Exception("No types found");
          339  +					foreach (XmlElement typeNode in types) {
          340  +						string typeId = GetNodeId(typeNode);
          341  +						//TODO The rest should also use displayName ((EE): clarify what above line means - shall we remove 'name' attribute then?)
          342  +						string typeDisplayName = GetNodeDisplayName(typeNode);
          343  +						RegisterType(assemblyName, typeId, typeDisplayName);
          344  +
          345  +						// foreach member
          346  +						XmlNodeList members = typeNode.SelectNodes("*[@id]");
          347  +						if(members == null) throw new Exception("No type members found");
          348  +						foreach (XmlElement memberNode in members) {
          349  +							string memberId = GetNodeId(memberNode);
          350  +							switch (memberNode.Name) {
          351  +								case "constructor": {
          352  +									string overload = XmlUtils.GetAttributeString(memberNode, "overload", false);
          353  +										RegisterConstructor(assemblyName, typeId, memberId, overload);
          354  +									}
          355  +									break;
          356  +								case "field": {
          357  +										bool isEnum = (typeNode.Name == "enumeration");
          358  +										string memberName = GetNodeName(memberNode);
          359  +										RegisterField(assemblyName, typeId, memberId, isEnum, memberName);
          360  +									}
          361  +									break;
          362  +								case "property": {
          363  +										string overload = GetNodeOverload(memberNode);
          364  +										string memberName = GetNodeName(memberNode);
          365  +										RegisterProperty(assemblyName, memberId, memberName, overload);
          366  +									}
          367  +									break;
          368  +								case "method": {
          369  +										string overload = GetNodeOverload(memberNode);
          370  +										string memberDisplayName = GetNodeDisplayName(memberNode);
          371  +										RegisterMethod(assemblyName, memberId, memberDisplayName, overload);
          372  +									}
          373  +									break;
          374  +								case "operator": {
          375  +										string overload = GetNodeOverload(memberNode);
          376  +										string memberName = GetNodeName(memberNode);
          377  +										RegisterOperator(assemblyName, memberId, memberName, overload);
          378  +									}
          379  +									break;
          380  +								case "event": {
          381  +										string memberName = GetNodeName(memberNode);
          382  +										RegisterEvent(assemblyName, memberId, memberName);
          383  +									}
          384  +									break;
          385  +							}
          386  +						}
          387  +					}
          388  +				}
          389  +			}
          390  +		}
          391  +
          392  +		private void RegisterAssembly(string assemblyName) {
          393  +			Register(assemblyName, null, assemblyName, CalculateFilenameForId(assemblyName, null, null));
          394  +		}
          395  +
          396  +		private void RegisterNamespace(string assemblyName, string namespaceName) {
          397  +			if (string.IsNullOrEmpty(namespaceName)) {
          398  +				namespaceName = "(global)";
          399  +			}
          400  +			string namespaceId = "N:" + namespaceName;
          401  +			Register(assemblyName, namespaceId, namespaceName, CalculateFilenameForId(assemblyName, namespaceId, null));
          402  +		}
          403  +
          404  +		private void RegisterType(string assemblyName, string typeId, string displayName) {
          405  +			Register(assemblyName, typeId, displayName, CalculateFilenameForId(assemblyName, typeId, null));
          406  +		}
          407  +
          408  +		private void RegisterConstructor(string assemblyName, string typeId, string id, string overload) {
          409  +			Register(assemblyName, id, GetDisplayNameForId(assemblyName, typeId), CalculateFilenameForId(assemblyName, id, overload));
          410  +		}
          411  +
          412  +		private void RegisterOperator(string assemblyName, string memberId, string memberName, string overload) {
          413  +			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, overload));
          414  +		}
          415  +
          416  +		private void RegisterMethod(string assemblyName, string memberId, string memberDisplayName, string overload) {
          417  +			Register(assemblyName, memberId, memberDisplayName, CalculateFilenameForId(assemblyName, memberId, overload));
          418  +		}
          419  +
          420  +		private void RegisterProperty(string assemblyName, string memberId, string memberName, string overload) {
          421  +			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, overload));
          422  +		}
          423  +
          424  +		private void RegisterField(string assemblyName, string typeId, string memberId, bool isEnum, string memberName) {
          425  +			if (isEnum) {
          426  +				Register(assemblyName, memberId, memberName, GetFilenameForId(assemblyName, typeId));
          427  +			} else {
          428  +				Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, null));
          429  +			}
          430  +		}
          431  +
          432  +		private void RegisterEvent(string assemblyName, string memberId, string memberName) {
          433  +			Register(assemblyName, memberId, memberName, CalculateFilenameForId(assemblyName, memberId, null));
          434  +		}
          435  +
          436  +
          437  +		#endregion
          438  +
          439  +		#region Registration & Lookup Logic
          440  +
          441  +		private string GetFilenameForIdInternal(string currentAssemblyName, string memberId) {
          442  +			string filename = fileNames[currentAssemblyName + memberId];
          443  +			if (filename == null) {
          444  +				// search for identifier in referenced assemblies
          445  +				string[] assemblyReference = assemblyReferences[currentAssemblyName];
          446  +				if (assemblyReference != null) {
          447  +					foreach (string assemblyName in assemblyReference) {
          448  +						filename = fileNames[assemblyName + memberId];
          449  +						if (filename != null)
          450  +							break;
          451  +					}
          452  +				}
          453  +			}
          454  +
          455  +			if (filename == null && memberId != null) {
          456  +				filename = fileNames[memberId];
          457  +			}
          458  +
          459  +			//			Debug.Assert(filename != null, string.Format("Filename for assembly:memberId [{0}:{1}] not found", currentAssemblyName, memberId));
          460  +			//			Debug.WriteLine(string.Format("GetFilenameForIdInternal('{0}','{1}') => {2}", currentAssemblyName, memberId, filename));
          461  +			if (filename != null)
          462  +				return filename;
          463  +
          464  +			if (utilities != null)
          465  +			{
          466  +				if (memberId.Length > 2 && memberId[1] == ':')
          467  +					memberId = memberId.Substring(2);
          468  +
          469  +				filename = utilities.FormatOnlineSDKLink(memberId);
          470  +
          471  +				if (filename != null)
          472  +					return filename;
          473  +			}
          474  +
          475  +			return String.Empty;
          476  +		}
          477  +
          478  +		private string GetFilenameForIdSpecial(string assemblyName, string memberId, string postfix) {
          479  +			string fn = GetFilenameForIdInternal(assemblyName, memberId);
          480  +			if (fn != null && fn.Length > EXT.Length) {
          481  +				fn = fn.Insert(fn.Length - EXT.Length, postfix);
          482  +			}
          483  +			//			Debug.WriteLine(string.Format("GetFilenameForIdSpecial('{0}','{1}') => {2}", assemblyName, memberId, fn));
          484  +			return fn;
          485  +		}
          486  +
          487  +		private void Register(string assemblyName, string id, string displayName, string fileName) {
          488  +			//			Debug.WriteLine(string.Format("Registering [{0},{1}]=[{2},{3}]", assemblyName, id, displayName, fileName));
          489  +			fileNames[assemblyName + id] = fileName;
          490  +			elemNames[assemblyName + id] = displayName;
          491  +		}
          492  +
          493  +		/// <summary>
          494  +		/// of the form "T:XXX", "F:XXX" etc
          495  +		/// </summary>
          496  +		private static string CalculateFilenameForId(string assemblyName, string id, string overload) {
          497  +			if (id == null) {
          498  +				return assemblyName + EXT;
          499  +			}
          500  +
          501  +			//			char idType = '\0';
          502  +			int ix = id.IndexOf(':');
          503  +			//			if (ix > -1) {
          504  +			//				idType = id[0];
          505  +			//			}
          506  +			id = id.Substring(ix + 1);
          507  +
          508  +			// constructors could be #ctor or #cctor
          509  +			//			int ixDotHash = id.IndexOf(".#c"); 
          510  +			//			if (ixDotHash > -1)
          511  +			//				id = id.Substring(0, ixDotHash);
          512  +
          513  +			// methods could have "("
          514  +			int ixLBrace = id.IndexOf("(");
          515  +			if (ixLBrace > -1)
          516  +				id = id.Substring(0, ixLBrace);
          517  +
          518  +			if (overload != null) {
          519  +				id += overload;
          520  +			}
          521  +
          522  +			id = id.Replace('#', '~');
          523  +			// generic methods have the form "methodname<Arg1, Arg2, ...>"
          524  +			id = id.Replace('<', '{');
          525  +			id = id.Replace('>', '}');
          526  +
          527  +			id = id.Replace('`', '$');
          528  +			return assemblyName + "~" + id + EXT;
          529  +		}
          530  +
          531  +		#endregion
          532  +
          533  +		#region Xml Utility Methods
          534  +
          535  +		private static string GetNodeOverload(XmlNode memberNode) {
          536  +			return XmlUtils.GetAttributeString(memberNode, "overload", false);
          537  +		}
          538  +
          539  +		private static string GetNodeId(XmlNode node) {
          540  +			return XmlUtils.GetNodeId(node);
          541  +		}
          542  +
          543  +		private static string GetNodeName(XmlNode node) {
          544  +			return XmlUtils.GetNodeName(node);
          545  +		}
          546  +
          547  +		private static string GetNodeDisplayName(XmlNode node) {
          548  +			return XmlUtils.GetNodeDisplayName(node);
          549  +		}
          550  +
          551  +		#endregion
          552  +	}
          553  +}