示例#1
0
		public Dictionary<string, ErrorDocumentation> Compile (HelpSource hs)
		{
			string[] files = Directory.GetFiles (FilesPath, Match);
			var ret = new Dictionary<string, ErrorDocumentation> ();
			
			foreach (string s in files) {
				ErrorDocumentation d;
				int errorNum = 0;

				try {
					errorNum = int.Parse (Path.GetFileName (s).Substring (ErrorNumSubstringStart, ErrorNumSubstringLength));
				} catch {
					Console.WriteLine ("Ignoring file {0}", s);
				}
				
				string errorName = String.Format (FriendlyFormatString, errorNum);
				
				if (!ret.TryGetValue (errorName, out d))
					ret[errorName] = d = new ErrorDocumentation (errorName);

				if (d.Details == null) {
					string xmlFile = Path.ChangeExtension (s, "xml");
					if (File.Exists (xmlFile)) {
						XmlSerializer cfgRdr = new XmlSerializer (typeof (ErrorDetails));
						d.Details = (ErrorDetails)cfgRdr.Deserialize (new XmlTextReader (xmlFile));
					}
				}
				// Encoding is same as used in MCS, so we will be able to do all those files
				using (StreamReader reader = new StreamReader (s, Encoding.GetEncoding (28591))) {
					d.Examples.Add (reader.ReadToEnd ());
				}
			}
			
			return ret;
		}
示例#2
0
        public override void CloseTree(HelpSource hs, Tree tree)
        {
            var           entries = config.Compile(hs);
            MemoryStream  ms      = new MemoryStream();
            XmlSerializer writer  = new XmlSerializer(typeof(ErrorDocumentation));

            foreach (var de in entries)
            {
                ErrorDocumentation d = de.Value;
                string             s = de.Key;

                tree.RootNode.GetOrCreateNode(s, "error:" + s);

                writer.Serialize(ms, d);
                ms.Position = 0;
                hs.Storage.Store(s, ms);
                ms.SetLength(0);
            }

            tree.RootNode.Sort();
        }
示例#3
0
        public Dictionary <string, ErrorDocumentation> Compile(HelpSource hs)
        {
            string[] files = Directory.GetFiles(FilesPath, Match);
            var      ret   = new Dictionary <string, ErrorDocumentation> ();

            foreach (string s in files)
            {
                ErrorDocumentation d;
                int errorNum = 0;

                try {
                    errorNum = int.Parse(Path.GetFileName(s).Substring(ErrorNumSubstringStart, ErrorNumSubstringLength));
                } catch {
                    Console.WriteLine("Ignoring file {0}", s);
                }

                string errorName = String.Format(FriendlyFormatString, errorNum);

                if (!ret.TryGetValue(errorName, out d))
                {
                    ret[errorName] = d = new ErrorDocumentation(errorName);
                }

                if (d.Details == null)
                {
                    string xmlFile = Path.ChangeExtension(s, "xml");
                    if (File.Exists(xmlFile))
                    {
                        XmlSerializer cfgRdr = new XmlSerializer(typeof(ErrorDetails));
                        d.Details = (ErrorDetails)cfgRdr.Deserialize(new XmlTextReader(xmlFile));
                    }
                }
                // Encoding is same as used in MCS, so we will be able to do all those files
                using (StreamReader reader = new StreamReader(s, Encoding.GetEncoding(28591))) {
                    d.Examples.Add(reader.ReadToEnd());
                }
            }

            return(ret);
        }
示例#4
0
		/// <summary>
		///   Load from file constructor
		/// </summary>
		public Tree (HelpSource hs, string filename)
		{
			Encoding utf8 = new UTF8Encoding (false, true);

			if (!File.Exists (filename)){
				throw new FileNotFoundException ();
			}
		
			InputStream = File.OpenRead (filename);
			InputReader = new BinaryReader (InputStream, utf8);
			byte [] sig = InputReader.ReadBytes (4);
		
			if (!GoodSig (sig))
				throw new Exception ("Invalid file format");
		
			InputStream.Position = 4;
			var position = InputReader.ReadInt32 ();
			rootNode = new Node (this, position);
			InflateNode (rootNode);

			HelpSource = hs;
		}
示例#5
0
        public string Generate(HelpSource hs, string id, Dictionary <string, string> context)
        {
            if (hs == null || string.IsNullOrEmpty(id))
            {
                return(null);
            }

            IEnumerable <string> parts;

            if (hs.IsMultiPart(id, out parts))
            {
                return(GenerateMultiPart(hs, parts, id, context));
            }

            if (hs.IsRawContent(id))
            {
                return(hs.GetText(id) ?? string.Empty);
            }

            var result = hs.IsGeneratedContent(id) ? hs.GetCachedText(id) : new StreamReader(hs.GetCachedHelpStream(id)).ReadToEnd();

            return(result);
        }
示例#6
0
			public bool Generate (HelpSource hs, string id, Dictionary<string, string> context)
			{
				LastCheckMessage = string.Format ("#1 : {0} {1}", hs, id);
				if (hs == null || string.IsNullOrEmpty (id))
					return false;

				// Stripe the arguments parts since we don't need it
				var argIdx = id.LastIndexOf ('?');
				if (argIdx != -1)
					id = id.Substring (0, argIdx);

				LastCheckMessage = string.Format ("#2 : {0} {1}", hs, id);
				if (hs.IsRawContent (id))
					return hs.GetText (id) != null;

				IEnumerable<string> parts;
				if (hs.IsMultiPart (id, out parts)) {
					LastCheckMessage = string.Format ("#4 : {0} {1} ({2})", hs, id, string.Join (", ", parts));
					foreach (var partId in parts)
						if (!Generate (hs, partId, context))
							return false;
				}

				LastCheckMessage = string.Format ("#3 : {0} {1}", hs, id);
				if (hs.IsGeneratedContent (id))
					return hs.GetCachedText (id) != null;
				else {
					var s = hs.GetCachedHelpStream (id);
					if (s != null) {
						s.Close ();
						return true;
					} else {
						return false;
					}
				}
			}
示例#7
0
		//
		// Called at shutdown time after the tree has been populated to perform
		// any fixups or final tasks.
		//
		public abstract void CloseTree (HelpSource hs, Tree tree);
示例#8
0
		void AddEcmaXml (HelpSource hs)
		{
			var xmls = directories
				.SelectMany (Directory.EnumerateDirectories) // Assemblies
				.SelectMany (Directory.EnumerateDirectories) // Namespaces
				.SelectMany (Directory.EnumerateFiles)
				.Where (f => f.EndsWith (".xml")); // Type XML files

			int resID = 0;
			foreach (var xml in xmls)
				using (var file = File.OpenRead (xml))
					hs.Storage.Store ((resID++).ToString (), file);
		}
示例#9
0
		public override void CloseTree (HelpSource hs, Tree tree)
		{
			AddImages (hs);
			AddExtensionMethods (hs);
		}
示例#10
0
		void AddExtensionMethods (HelpSource hs)
		{
			var extensionMethods = directories
				.SelectMany (Directory.EnumerateDirectories)
				.Select (d => Path.Combine (d, "index.xml"))
				.Where (File.Exists)
				.Select (f => {
					using (var file = File.OpenRead (f)) {
						var reader = XmlReader.Create (file);
						reader.ReadToFollowing ("ExtensionMethods");
						return reader.ReadInnerXml ();
					}
			    })
			    .DefaultIfEmpty (string.Empty);

			hs.Storage.Store ("ExtensionMethods.xml",
			                  "<ExtensionMethods>" + extensionMethods.Aggregate (string.Concat) + "</ExtensionMethods>");
		}
示例#11
0
		void AddImages (HelpSource hs)
		{
			var imgs = directories
				.SelectMany (Directory.EnumerateDirectories)
				.Select (d => Path.Combine (d, "_images"))
				.Where (Directory.Exists)
				.SelectMany (Directory.EnumerateFiles);

			foreach (var img in imgs)
				using (var file = File.OpenRead (img))
					hs.Storage.Store (Path.GetFileName (img), file);
		}
示例#12
0
        public static string GetHtml(string url, HelpSource helpSource)
        {
            Node _;

            return(GetHtml(url, helpSource, out _));
        }
示例#13
0
		/// <summary>
		///    Tree creation and merged tree constructor
		/// </summary>
		public Tree (HelpSource hs, string caption, string url) : this (hs, null, caption, url)
		{
		}
        public string Generate(HelpSource hs, string internalId, Dictionary <string, string> context)
        {
            string sourceText = hs.GetText(internalId);

            return(sourceText);
        }
示例#15
0
		public override void CloseTree (HelpSource hs, Tree tree)
		{
		}
示例#16
0
 public Resolver(HelpRegistration registration)
 {
     _source = HelpSource.FromSource(registration.Source);
 }
示例#17
0
        public string Generate(HelpSource hs, string id, Dictionary <string, string> context)
        {
            string specialPage = null;

            if (context != null && context.TryGetValue("specialpage", out specialPage) && specialPage == "master-root")
            {
                return(GenerateMasterRootPage(hs != null ? hs.RootTree : null));
            }

            if (id == "root:" && hs == null)
            {
                return(MakeEmptySummary());
            }

            if (hs == null || string.IsNullOrEmpty(id))
            {
                return(MakeHtmlError(string.Format("Your request has found no candidate provider [hs=\"{0}\", id=\"{1}\"]",
                                                   hs == null ? "(null)" : hs.Name, id ?? "(null)")));
            }

            var cache = defaultCache ?? hs.Cache;

            if (cache != null && cache.IsCached(MakeCacheKey(hs, id, null)))
            {
                return(cache.GetCachedString(MakeCacheKey(hs, id, null)));
            }

            IEnumerable <string> parts;

            if (hs.IsMultiPart(id, out parts))
            {
                return(GenerateMultiPart(hs, parts, id, context));
            }

            if (hs.IsRawContent(id))
            {
                return(hs.GetText(id) ?? string.Empty);
            }

            DocumentType type = hs.GetDocumentTypeForId(id);

            if (cache != null && context != null && cache.IsCached(MakeCacheKey(hs, id, context)))
            {
                return(cache.GetCachedString(MakeCacheKey(hs, id, context)));
            }

            IHtmlExporter exporter;

            if (!converters.TryGetValue(type, out exporter))
            {
                return(MakeHtmlError(string.Format("Input type '{0}' not supported",
                                                   type.ToString())));
            }
            var result = hs.IsGeneratedContent(id) ?
                         exporter.Export(hs.GetCachedText(id), context) :
                         exporter.Export(hs.GetCachedHelpStream(id), context);

            if (cache != null)
            {
                cache.CacheText(MakeCacheKey(hs, id, context), result);
            }
            return(result);
        }
示例#18
0
 public override void CloseTree(HelpSource hs, Tree tree)
 {
 }
示例#19
0
 public override void CloseTree(HelpSource hs, Tree tree)
 {
     AddImages(hs);
     AddExtensionMethods(hs);
 }
示例#20
0
        void LoadUrl(string url, bool syncTreeView = false, HelpSource source = null, bool addToHistory = true)
        {
            if (url == currentUrl)
            {
                return;
            }
            if (url.StartsWith("#"))
            {
                Console.WriteLine("FIXME: Anchor jump");
                return;
            }
            // In case user click on an external link e.g. [Android documentation] link at bottom of MonoDroid docs
            if (url.StartsWith("http://") || url.StartsWith("https://"))
            {
                UrlLauncher.Launch(url);
                return;
            }
            var ts = Interlocked.Increment(ref loadUrlTimestamp);

            Task.Factory.StartNew(() => {
                Node node;
                var res = DocTools.GetHtml(url, source, out node);
                return(new { Node = node, Html = res });
            }).ContinueWith(t => {
                var node = t.Result.Node;
                var res  = t.Result.Html;
                if (res != null)
                {
                    BeginInvoke(new Action(() => {
                        if (ts < loadUrlTimestamp)
                        {
                            return;
                        }
                        Text = currentUrl = node == null ? url : node.PublicUrl;
                        if (addToHistory)
                        {
                            history.AppendHistory(new LinkPageVisit(this, currentUrl));
                        }
                        LoadHtml(res);
                        this.match = node;
                        if (syncTreeView)
                        {
                            if (tabContainer.SelectedIndex == 0 && match != null)
                            {
                                if (ShowNodeInTree(match))
                                {
                                    docTree.SelectedNode = nodeToTreeNodeMap[match];
                                }
                            }
                            else
                            {
                                tabContainer.SelectedIndex = 0;
                            }
                        }
                        // Bookmark spinner management
                        var bookmarkIndex = Program.BookmarkManager.FindIndexOfBookmarkFromUrl(url);
                        if (bookmarkIndex == -1 || bookmarkIndex < bookmarkSelector.Items.Count)
                        {
                            bookmarkSelector.SelectedIndex = bookmarkIndex;
                        }
                    }));
                }
            });
        }
示例#21
0
		public Tree (HelpSource hs, Node parent, string caption, string element)
		{
			HelpSource = hs;
			rootNode = parent == null ? new Node (this, caption, element) : new Node (parent, caption, element);
		}
示例#22
0
		public override void CloseTree (HelpSource hs, Tree tree)
		{
			var entries = config.Compile (hs);
			MemoryStream ms = new MemoryStream ();
			XmlSerializer writer = new XmlSerializer (typeof (ErrorDocumentation));
			
			foreach (var de in entries) {
				ErrorDocumentation d = de.Value;
				string s = de.Key;

				tree.RootNode.GetOrCreateNode (s, "error:" + s);
				
				writer.Serialize (ms, d);
				ms.Position = 0;
				hs.Storage.Store (s, ms);
				ms.SetLength (0);
			}
			
			tree.RootNode.Sort ();
		}
示例#23
0
文件: assembler.cs 项目: mdae/MonoRT
        public override void Run(IEnumerable <string> args)
        {
            string[] validFormats =
            {
                "ecma",
                "ecmaspec",
                "error",
                "hb",
                "man",
                "simple",
                "xhtml"
            };
            var    formats    = new Dictionary <string, List <string> > ();
            string prefix     = "tree";
            string cur_format = "ecma";
            var    options    = new OptionSet()
            {
                { "f|format=",
                  "The documentation {FORMAT} used in DIRECTORIES.  " +
                  "Valid formats include:\n  " +
                  string.Join("\n  ", validFormats) + "\n" +
                  "If not specified, the default format is `ecma'.",
                  v => {
                      if (Array.IndexOf(validFormats, v) < 0)
                      {
                          Error("Invalid documentation format: {0}.", v);
                      }
                      cur_format = v;
                  } },
                { "o|out=",
                  "Provides the output file prefix; the files {PREFIX}.zip and " +
                  "{PREFIX}.tree will be created.\n" +
                  "If not specified, `tree' is the default PREFIX.",
                  v => prefix = v },
                { "<>", v => AddFormat(formats, cur_format, v) },
            };
            List <string> extra = Parse(options, args, "assemble",
                                        "[OPTIONS]+ DIRECTORIES",
                                        "Assemble documentation within DIRECTORIES for use within the monodoc browser.");

            if (extra == null)
            {
                return;
            }

            List <Provider> list = new List <Provider> ();
            EcmaProvider    ecma = null;
            bool            sort = false;

            foreach (string format in formats.Keys)
            {
                switch (format)
                {
                case "ecma":
                    if (ecma == null)
                    {
                        ecma = new EcmaProvider();
                        list.Add(ecma);
                        sort = true;
                    }
                    foreach (string dir in formats[format])
                    {
                        ecma.AddDirectory(dir);
                    }
                    break;

                case "xhtml":
                case "hb":
                    list.AddRange(formats [format].Select(d => (Provider) new XhtmlProvider(d)));
                    break;

                case "man":
                    list.Add(new ManProvider(formats [format].ToArray()));
                    break;

                case "simple":
                    list.AddRange(formats [format].Select(d => (Provider) new SimpleProvider(d)));
                    break;

                case "error":
                    list.AddRange(formats [format].Select(d => (Provider) new ErrorProvider(d)));
                    break;

                case "ecmaspec":
                    list.AddRange(formats [format].Select(d => (Provider) new EcmaSpecProvider(d)));
                    break;

                case "addins":
                    list.AddRange(formats [format].Select(d => (Provider) new AddinsProvider(d)));
                    break;
                }
            }

            HelpSource hs = new HelpSource(prefix, true);

            hs.TraceLevel = TraceLevel;

            foreach (Provider p in list)
            {
                p.PopulateTree(hs.Tree);
            }

            if (sort && hs.Tree != null)
            {
                hs.Tree.Sort();
            }

            //
            // Flushes the EcmaProvider
            //
            foreach (Provider p in list)
            {
                p.CloseTree(hs, hs.Tree);
            }

            hs.Save();
        }
示例#24
0
            public void Dispose()
            {
                if (!_disposed)
                {
                    if (_source != null)
                    {
                        _source.Dispose();
                        _source = null;
                    }

                    _disposed = true;
                }
            }
示例#25
0
        public override void Run(IEnumerable <string> args)
        {
            bool   replaceNTypes = false;
            var    formats       = new Dictionary <string, List <string> > ();
            string prefix        = "tree";
            var    formatOptions = CreateFormatOptions(this, formats);
            var    options       = new OptionSet()
            {
                formatOptions [0],
                { "o|out=",
                  "Provides the output file prefix; the files {PREFIX}.zip and " +
                  "{PREFIX}.tree will be created.\n" +
                  "If not specified, `tree' is the default PREFIX.",
                  v => prefix = v },
                formatOptions [1],
                { "dropns=", "The namespace that has been dropped from this version of the assembly.", v => droppedNamespace = v },
                { "ntypes", "Replace references to native types with their original types.", v => replaceNTypes = true },
                { "fx|framework=",
                  "The name of the framework, which should be used to filter out any other API",
                  v => frameworkName = v },
            };
            List <string> extra = Parse(options, args, "assemble",
                                        "[OPTIONS]+ DIRECTORIES",
                                        "Assemble documentation within DIRECTORIES for use within the monodoc browser.");

            if (extra == null)
            {
                return;
            }

            List <Provider> list = new List <Provider> ();
            EcmaProvider    ecma = null;
            bool            sort = false;

            foreach (string format in formats.Keys)
            {
                switch (format)
                {
                case "ecma":
                    if (ecma == null)
                    {
                        ecma = new EcmaProvider();
                        list.Add(ecma);
                        sort = true;
                    }
                    ecma.FileSource = new MDocFileSource(droppedNamespace, string.IsNullOrWhiteSpace(droppedNamespace) ? ApiStyle.Unified : ApiStyle.Classic, frameworkName)
                    {
                        ReplaceNativeTypes = replaceNTypes
                    };
                    foreach (string dir in formats[format])
                    {
                        ecma.AddDirectory(dir);
                    }
                    break;

                case "xhtml":
                case "hb":
                    list.AddRange(formats [format].Select(d => (Provider) new XhtmlProvider(d)));
                    break;

                case "man":
                    list.Add(new ManProvider(formats [format].ToArray()));
                    break;

                case "error":
                    list.AddRange(formats [format].Select(d => (Provider) new ErrorProvider(d)));
                    break;

                case "ecmaspec":
                    list.AddRange(formats [format].Select(d => (Provider) new EcmaSpecProvider(d)));
                    break;

                case "addins":
                    list.AddRange(formats [format].Select(d => (Provider) new AddinsProvider(d)));
                    break;
                }
            }

            HelpSource hs = new HelpSource(prefix, true);

            hs.TraceLevel = TraceLevel;

            foreach (Provider p in list)
            {
                p.PopulateTree(hs.Tree);
            }

            if (sort && hs.Tree != null)
            {
                hs.Tree.RootNode.Sort();
            }

            //
            // Flushes the EcmaProvider
            //
            foreach (Provider p in list)
            {
                p.CloseTree(hs, hs.Tree);
            }

            hs.Save();
        }
示例#26
0
        public override void Run(IEnumerable <string> args)
        {
            var    formats       = new Dictionary <string, List <string> > ();
            string prefix        = "tree";
            string cur_format    = "ecma";
            var    formatOptions = CreateFormatOptions(this, formats);
            var    options       = new OptionSet()
            {
                formatOptions [0],
                { "o|out=",
                  "Provides the output file prefix; the files {PREFIX}.zip and " +
                  "{PREFIX}.tree will be created.\n" +
                  "If not specified, `tree' is the default PREFIX.",
                  v => prefix = v },
                formatOptions [1],
            };
            List <string> extra = Parse(options, args, "assemble",
                                        "[OPTIONS]+ DIRECTORIES",
                                        "Assemble documentation within DIRECTORIES for use within the monodoc browser.");

            if (extra == null)
            {
                return;
            }

            List <Provider> list = new List <Provider> ();
            EcmaProvider    ecma = null;
            bool            sort = false;

            foreach (string format in formats.Keys)
            {
                switch (format)
                {
                case "ecma":
                    if (ecma == null)
                    {
                        ecma = new EcmaProvider();
                        list.Add(ecma);
                        sort = true;
                    }
                    foreach (string dir in formats[format])
                    {
                        ecma.AddDirectory(dir);
                    }
                    break;

                case "xhtml":
                case "hb":
                    list.AddRange(formats [format].Select(d => (Provider) new XhtmlProvider(d)));
                    break;

                case "man":
                    list.Add(new ManProvider(formats [format].ToArray()));
                    break;

                case "simple":
                    list.AddRange(formats [format].Select(d => (Provider) new SimpleProvider(d)));
                    break;

                case "error":
                    list.AddRange(formats [format].Select(d => (Provider) new ErrorProvider(d)));
                    break;

                case "ecmaspec":
                    list.AddRange(formats [format].Select(d => (Provider) new EcmaSpecProvider(d)));
                    break;

                case "addins":
                    list.AddRange(formats [format].Select(d => (Provider) new AddinsProvider(d)));
                    break;
                }
            }

            HelpSource hs = new HelpSource(prefix, true);

            hs.TraceLevel = TraceLevel;

            foreach (Provider p in list)
            {
                p.PopulateTree(hs.Tree);
            }

            if (sort && hs.Tree != null)
            {
                hs.Tree.Sort();
            }

            //
            // Flushes the EcmaProvider
            //
            foreach (Provider p in list)
            {
                p.CloseTree(hs, hs.Tree);
            }

            hs.Save();
        }
示例#27
0
        public static int Main(string [] args)
        {
            string       output = "tree";
            HelpSource   hs;
            ArrayList    list = new ArrayList();
            EcmaProvider ecma = null;
            bool         sort = false;

            int argc = args.Length;

            for (int i = 0; i < argc; i++)
            {
                string arg = args [i];

                switch (arg)
                {
                case "-o":
                case "--out":
                    if (i < argc)
                    {
                        output = args [++i];
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--ecma":
                    if (i < argc)
                    {
                        if (ecma == null)
                        {
                            ecma = new EcmaProvider();
                            list.Add(ecma);
                            sort = true;
                        }
                        ecma.AddDirectory(args [++i]);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--xhtml":
                case "--hb":
                    if (i < argc)
                    {
                        Provider populator = new XhtmlProvider(args [++i]);

                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--man":
                    if (i < argc)
                    {
                        int      countfiles = args.Length - ++i;
                        string[] xmlfiles   = new String[countfiles];
                        for (int a = 0; a < countfiles; a++)
                        {
                            xmlfiles[a] = args [i];
                            i++;
                        }
                        Provider populator = new ManProvider(xmlfiles);

                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--simple":
                    if (i < argc)
                    {
                        Provider populator = new SimpleProvider(args [++i]);

                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--error":
                    if (i < argc)
                    {
                        Provider populator = new ErrorProvider(args [++i]);

                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--ecmaspec":
                    if (i < argc)
                    {
                        Provider populator = new EcmaSpecProvider(args [++i]);

                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                case "--addins":
                    if (i < argc)
                    {
                        Provider populator = new AddinsProvider(args [++i]);
                        list.Add(populator);
                    }
                    else
                    {
                        Usage();
                        return(1);
                    }
                    break;

                default:
                    Usage();
                    return(1);
                }
            }

            hs = new HelpSource(output, true);

            foreach (Provider p in list)
            {
                p.PopulateTree(hs.Tree);
            }

            if (sort)
            {
                hs.Tree.Sort();
            }

            //
            // Flushes the EcmaProvider
            //
            foreach (Provider p in list)
            {
                p.CloseTree(hs, hs.Tree);
            }

            hs.Save();
            return(0);
        }