2007-02-18 Marek Sieradzki <marek.sieradzki@gmail.com>
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Discovery / DiscoveryClientProtocol.cs
index 28677d0d8623a7cfc4c10a01b5f62cd9639603d1..64fa18b736a8217b7811e57ad48838bfa03847a6 100644 (file)
-// \r
-// System.Web.Services.Protocols.DiscoveryClientProtocol.cs\r
-//\r
-// Author:\r
-//   Dave Bettin (javabettin@yahoo.com)\r
-//   Lluis Sanchez Gual (lluis@ximian.com)\r
-//\r
-// Copyright (C) Dave Bettin, 2002\r
-//\r
-\r
-//\r
-// Permission is hereby granted, free of charge, to any person obtaining\r
-// a copy of this software and associated documentation files (the\r
-// "Software"), to deal in the Software without restriction, including\r
-// without limitation the rights to use, copy, modify, merge, publish,\r
-// distribute, sublicense, and/or sell copies of the Software, and to\r
-// permit persons to whom the Software is furnished to do so, subject to\r
-// the following conditions:\r
-// \r
-// The above copyright notice and this permission notice shall be\r
-// included in all copies or substantial portions of the Software.\r
-// \r
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
-//\r
-\r
-using System.Collections;\r
-using System.IO;\r
-using System.Web.Services.Protocols;\r
-using System.Web.Services.Description;\r
-using System.Xml;\r
-using System.Xml.Schema;\r
-using System.Xml.Serialization;\r
-using System.Net;\r
-using System.Text.RegularExpressions;\r
-\r
-namespace System.Web.Services.Discovery {\r
-       public class DiscoveryClientProtocol : HttpWebClientProtocol {\r
-\r
-               #region Fields\r
-\r
-               private IList additionalInformation = new ArrayList ();\r
-               private DiscoveryClientDocumentCollection documents = new DiscoveryClientDocumentCollection();\r
-               private DiscoveryExceptionDictionary errors = new DiscoveryExceptionDictionary();\r
-               private DiscoveryClientReferenceCollection references = new DiscoveryClientReferenceCollection();\r
-\r
-               #endregion // Fields\r
-\r
-               #region Constructors\r
-\r
-               public DiscoveryClientProtocol () \r
-               {\r
-               }\r
-               \r
-               #endregion // Constructors\r
-\r
-               #region Properties\r
-\r
-               public IList AdditionalInformation {\r
-                       get { return additionalInformation; }\r
-               }\r
-               \r
-               public DiscoveryClientDocumentCollection Documents {\r
-                       get { return documents; }\r
-               }\r
-               \r
-               public DiscoveryExceptionDictionary Errors {\r
-                       get { return errors; }\r
-               }\r
-\r
-               public DiscoveryClientReferenceCollection References {\r
-                       get { return references; }\r
-               }               \r
-               \r
-               #endregion // Properties\r
-\r
-               #region Methods\r
-\r
-               public DiscoveryDocument Discover (string url)\r
-               {\r
-                       Stream stream = Download (ref url);\r
-                       XmlTextReader reader = new XmlTextReader (url, stream);\r
-                       reader.XmlResolver = null;\r
-                       if (!DiscoveryDocument.CanRead (reader)) \r
-                               throw new InvalidOperationException ("The url '" + url + "' does not point to a valid discovery document");\r
-                               \r
-                       DiscoveryDocument doc = DiscoveryDocument.Read (reader);\r
-                       reader.Close ();\r
-                       documents.Add (url, doc);\r
-                       AddDiscoReferences (doc);\r
-                       return doc;\r
-               }\r
-\r
-               public DiscoveryDocument DiscoverAny (string url)\r
-               {\r
-                       try\r
-                       {\r
-                               string contentType = null;\r
-                               Stream stream = Download (ref url, ref contentType);\r
-       \r
-                               if (contentType.IndexOf ("text/html") != -1)\r
-                               {\r
-                                       // Look for an alternate url\r
-                                       \r
-                                       StreamReader sr = new StreamReader (stream);\r
-                                       string str = sr.ReadToEnd ();\r
-                                       \r
-                                       string rex = "link\\s*rel\\s*=\\s*[\"']?alternate[\"']?\\s*";\r
-                                       rex += "type\\s*=\\s*[\"']?text/xml[\"']?\\s*href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|'(?<1>[^']*)'|(?<1>\\S+))";\r
-                                       Regex rob = new Regex (rex, RegexOptions.IgnoreCase);\r
-                                       Match m = rob.Match (str);\r
-                                       if (!m.Success) \r
-                                               throw new InvalidOperationException ("The HTML document does not contain Web service discovery information");\r
-                                       \r
-                                       if (url.StartsWith ("/"))\r
-                                       {\r
-                                               Uri uri = new Uri (url);\r
-                                               url = uri.GetLeftPart (UriPartial.Authority) + m.Groups[1];\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               int i = url.LastIndexOf ('/');\r
-                                               if (i == -1)\r
-                                                       throw new InvalidOperationException ("The HTML document does not contain Web service discovery information");\r
-\r
-                                               Uri tmp = new Uri (url);\r
-                                               tmp = new Uri (tmp, m.Groups [1].ToString ());\r
-                                               url = tmp.ToString ();\r
-                                       }\r
-                                       stream = Download (ref url);\r
-                               }\r
-                               \r
-                               XmlTextReader reader = new XmlTextReader (url, stream);\r
-                               reader.XmlResolver = null;\r
-                               reader.MoveToContent ();\r
-                               DiscoveryDocument doc;\r
-                               DiscoveryReference refe = null;\r
-                               \r
-                               if (DiscoveryDocument.CanRead (reader))\r
-                               {\r
-                                       doc = DiscoveryDocument.Read (reader);\r
-                                       documents.Add (url, doc);\r
-                                       refe = new DiscoveryDocumentReference ();\r
-                                       AddDiscoReferences (doc);\r
-                               }\r
-                               else if (ServiceDescription.CanRead (reader))\r
-                               {\r
-                                       ServiceDescription wsdl = ServiceDescription.Read (reader);\r
-                                       documents.Add (url, wsdl);\r
-                                       doc = new DiscoveryDocument ();\r
-                                       refe = new ContractReference ();\r
-                                       doc.References.Add (refe);\r
-                                       refe.Url = url;\r
-                                       ((ContractReference)refe).ResolveInternal (this, wsdl);\r
-                               }\r
-                               else\r
-                               {\r
-                                       XmlSchema schema = XmlSchema.Read (reader, null);\r
-                                       documents.Add (url, schema);\r
-                                       doc = new DiscoveryDocument ();\r
-                                       refe = new SchemaReference ();\r
-                                       ((SchemaReference)refe).ResolveInternal (this, schema);\r
-                                       doc.References.Add (refe);\r
-                               }\r
-                               \r
-                               refe.ClientProtocol = this;\r
-                               refe.Url = url;\r
-                               references.Add (url, refe);\r
-                                       \r
-                               reader.Close ();\r
-                               return doc;\r
-                       }\r
-                       catch (DiscoveryException ex) {\r
-                               throw ex.Exception;\r
-                       }\r
-               }\r
-               \r
-               void AddDiscoReferences (DiscoveryDocument doc)\r
-               {\r
-                       foreach (DiscoveryReference re in doc.References)\r
-                       {\r
-                               re.ClientProtocol = this;\r
-                               references.Add (re.Url, re);\r
-                       }\r
-                       \r
-                       if (doc.AdditionalInfo != null) {\r
-                               foreach (object info in doc.AdditionalInfo)\r
-                                       additionalInformation.Add (info);\r
-                       }\r
-               }\r
-               \r
-               public Stream Download (ref string url)\r
-               {\r
-                       string contentType = null;\r
-                       return Download (ref url, ref contentType);\r
-               }\r
-               \r
-               public Stream Download (ref string url, ref string contentType)\r
-               {\r
-                       if (url.StartsWith ("http://") || url.StartsWith ("https://"))\r
-                       {\r
-                               WebRequest request = GetWebRequest (new Uri(url));\r
-                               WebResponse resp = request.GetResponse ();\r
-                               contentType = resp.ContentType;\r
-                               return resp.GetResponseStream ();\r
-                       }\r
-                       else if (url.StartsWith ("file://"))\r
-                       {\r
-                               WebRequest request = WebRequest.Create (new Uri (url));\r
-                               WebResponse resp = request.GetResponse ();\r
-                               contentType = resp.ContentType;\r
-                               return resp.GetResponseStream ();\r
-                       }\r
-                       else\r
-                       {\r
-                               string ext = Path.GetExtension (url).ToLower();\r
-                               if (ext == ".wsdl" || ext == ".xsd")\r
-                               {\r
-                                       contentType = "text/xml";\r
-                                       return new FileStream (url, FileMode.Open, FileAccess.Read);\r
-                               }\r
-                               else\r
-                                       throw new InvalidOperationException ("Unrecognized file type '" + url + "'. Extension must be one of .wsdl or .xsd");\r
-                       }\r
-               }\r
-\r
-               [Obsolete ("This method will be removed from a future version. The method call is no longer required for resource discovery", false)]\r
-               public void LoadExternals ()\r
-               {\r
-               }\r
-\r
-               public DiscoveryClientResultCollection ReadAll (string topLevelFilename)\r
-               {\r
-                       StreamReader sr = new StreamReader (topLevelFilename);\r
-                       XmlSerializer ser = new XmlSerializer (typeof (DiscoveryClientResultsFile));\r
-                       DiscoveryClientResultsFile resfile = (DiscoveryClientResultsFile) ser.Deserialize (sr);\r
-                       sr.Close ();\r
-                       \r
-                       string basePath = Path.GetDirectoryName (topLevelFilename);\r
-                       \r
-                       foreach (DiscoveryClientResult dcr in resfile.Results)\r
-                       {\r
-                               Type type = Type.GetType (dcr.ReferenceTypeName);\r
-                               DiscoveryReference dr = (DiscoveryReference) Activator.CreateInstance (type);\r
-                               dr.Url = dcr.Url;\r
-                               FileStream fs = new FileStream (Path.Combine (basePath, dcr.Filename), FileMode.Open, FileAccess.Read);\r
-                               Documents.Add (dr.Url, dr.ReadDocument (fs));\r
-                               fs.Close ();\r
-                               References.Add (dr.Url, dr);\r
-                       }\r
-                       return resfile.Results;\r
-               }\r
-\r
-               public void ResolveAll ()\r
-               {\r
-                       ArrayList list = new ArrayList (References.Values);\r
-                       foreach (DiscoveryReference re in list)\r
-                       {\r
-                               try\r
-                               {\r
-                                       if (re is DiscoveryDocumentReference)\r
-                                               ((DiscoveryDocumentReference)re).ResolveAll ();\r
-                                       else\r
-                                               re.Resolve ();\r
-                               }\r
-                               catch (DiscoveryException ex)\r
-                               {\r
-                                       Errors [ex.Url] = ex.Exception; \r
-                               }\r
-                               catch (Exception ex)\r
-                               {\r
-                                       Errors [re.Url] = ex;   \r
-                               }\r
-                       }\r
-               }\r
-               \r
-               public void ResolveOneLevel ()\r
-               {\r
-                       ArrayList list = new ArrayList (References.Values);\r
-                       foreach (DiscoveryReference re in list)\r
-                               re.Resolve ();\r
-               }\r
-               \r
-               public DiscoveryClientResultCollection WriteAll (string directory, string topLevelFilename)\r
-               {\r
-                       DiscoveryClientResultsFile resfile = new DiscoveryClientResultsFile();\r
-                       \r
-                       foreach (DiscoveryReference re in References.Values)\r
-                       {\r
-                               object doc = Documents [re.Url];\r
-                               if (doc == null) continue;\r
-                               \r
-                               string fileName = FindValidName (resfile, re.DefaultFilename);\r
-                               resfile.Results.Add (new DiscoveryClientResult (re.GetType(), re.Url, fileName));\r
-                               \r
-                               string filepath = Path.Combine (directory, fileName);\r
-                               FileStream fs = new FileStream (filepath, FileMode.Create, FileAccess.Write);\r
-                               re.WriteDocument (doc, fs);\r
-                               fs.Close ();\r
-                       }\r
-                       \r
-                       StreamWriter sw = new StreamWriter (Path.Combine (directory, topLevelFilename));\r
-                       XmlSerializer ser = new XmlSerializer (typeof (DiscoveryClientResultsFile));\r
-                       ser.Serialize (sw, resfile);\r
-                       sw.Close ();\r
-                       return resfile.Results;\r
-               }\r
-               \r
-               string FindValidName (DiscoveryClientResultsFile resfile, string baseName)\r
-               {\r
-                       string name = baseName;\r
-                       int id = 0;\r
-                       bool found;\r
-                       do\r
-                       {\r
-                               found = false;\r
-                               foreach (DiscoveryClientResult res in resfile.Results)\r
-                               {\r
-                                       if (name == res.Filename) {\r
-                                               found = true; break;\r
-                                       }\r
-                               }\r
-                               if (found)\r
-                                       name = Path.GetFileNameWithoutExtension (baseName) + (++id) + Path.GetExtension (baseName);\r
-                       }\r
-                       while (found);\r
-                       \r
-                       return name;\r
-               }\r
-               \r
-               #endregion // Methods\r
-               \r
-               #region Classes\r
-               \r
-               public sealed class DiscoveryClientResultsFile {\r
-                       \r
-                       #region Fields\r
-                       \r
-                       private DiscoveryClientResultCollection results;\r
-\r
-                       #endregion // Fields\r
-\r
-                       #region Contructors\r
-                       \r
-                       public DiscoveryClientResultsFile () \r
-                       {\r
-                               results = new DiscoveryClientResultCollection ();\r
-                       }\r
-               \r
-                       #endregion // Constructors\r
-                       \r
-                       #region Properties\r
-               \r
-                       public DiscoveryClientResultCollection Results {                                \r
-                               get { return results; }\r
-                       }\r
-                       \r
-                       #endregion // Properties\r
-               }\r
-               \r
-               #endregion // Classes\r
-       }\r
-               \r
-       internal class DiscoveryException : Exception\r
-       {\r
-               public string Url;\r
-               public Exception Exception;\r
-               \r
-               public DiscoveryException (string url, Exception origin)\r
-               {\r
-                       Url = url;\r
-                       Exception = origin;\r
-               }\r
-       }\r
-}\r
+// 
+// System.Web.Services.Protocols.DiscoveryClientProtocol.cs
+//
+// Author:
+//   Dave Bettin (javabettin@yahoo.com)
+//   Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Dave Bettin, 2002
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections;
+using System.IO;
+using System.Web.Services.Protocols;
+using System.Web.Services.Description;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.Serialization;
+using System.Net;
+using System.Text.RegularExpressions;
+
+namespace System.Web.Services.Discovery {
+       public class DiscoveryClientProtocol : HttpWebClientProtocol {
+
+               #region Fields
+
+               private IList additionalInformation = new ArrayList ();
+               private DiscoveryClientDocumentCollection documents = new DiscoveryClientDocumentCollection();
+               private DiscoveryExceptionDictionary errors = new DiscoveryExceptionDictionary();
+               private DiscoveryClientReferenceCollection references = new DiscoveryClientReferenceCollection();
+
+               #endregion // Fields
+
+               #region Constructors
+
+               public DiscoveryClientProtocol () 
+               {
+               }
+               
+               #endregion // Constructors
+
+               #region Properties
+
+               public IList AdditionalInformation {
+                       get { return additionalInformation; }
+               }
+               
+               public DiscoveryClientDocumentCollection Documents {
+                       get { return documents; }
+               }
+               
+               public DiscoveryExceptionDictionary Errors {
+                       get { return errors; }
+               }
+
+               public DiscoveryClientReferenceCollection References {
+                       get { return references; }
+               }               
+               
+               #endregion // Properties
+
+               #region Methods
+
+               public DiscoveryDocument Discover (string url)
+               {
+                       Stream stream = Download (ref url);
+                       XmlTextReader reader = new XmlTextReader (url, stream);
+                       reader.XmlResolver = null;
+                       if (!DiscoveryDocument.CanRead (reader)) 
+                               throw new InvalidOperationException ("The url '" + url + "' does not point to a valid discovery document");
+                               
+                       DiscoveryDocument doc = DiscoveryDocument.Read (reader);
+                       reader.Close ();
+                       documents.Add (url, doc);
+                       AddDiscoReferences (doc);
+                       return doc;
+               }
+
+               public DiscoveryDocument DiscoverAny (string url)
+               {
+                       try
+                       {
+                               string contentType = null;
+                               Stream stream = Download (ref url, ref contentType);
+       
+                               if (contentType.IndexOf ("text/html") != -1)
+                               {
+                                       // Look for an alternate url
+                                       
+                                       StreamReader sr = new StreamReader (stream);
+                                       string str = sr.ReadToEnd ();
+                                       
+                                       string rex = "link\\s*rel\\s*=\\s*[\"']?alternate[\"']?\\s*";
+                                       rex += "type\\s*=\\s*[\"']?text/xml[\"']?\\s*href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|'(?<1>[^']*)'|(?<1>\\S+))";
+                                       Regex rob = new Regex (rex, RegexOptions.IgnoreCase);
+                                       Match m = rob.Match (str);
+                                       if (!m.Success) 
+                                               throw new InvalidOperationException ("The HTML document does not contain Web service discovery information");
+                                       
+                                       if (url.StartsWith ("/"))
+                                       {
+                                               Uri uri = new Uri (url);
+                                               url = uri.GetLeftPart (UriPartial.Authority) + m.Groups[1];
+                                       }
+                                       else
+                                       {
+                                               int i = url.LastIndexOf ('/');
+                                               if (i == -1)
+                                                       throw new InvalidOperationException ("The HTML document does not contain Web service discovery information");
+
+                                               Uri tmp = new Uri (url);
+                                               tmp = new Uri (tmp, m.Groups [1].ToString ());
+                                               url = tmp.ToString ();
+                                       }
+                                       stream = Download (ref url);
+                               }
+                               
+                               XmlTextReader reader = new XmlTextReader (url, stream);
+                               reader.XmlResolver = null;
+                               reader.MoveToContent ();
+                               DiscoveryDocument doc;
+                               DiscoveryReference refe = null;
+                               
+                               if (DiscoveryDocument.CanRead (reader))
+                               {
+                                       doc = DiscoveryDocument.Read (reader);
+                                       documents.Add (url, doc);
+                                       refe = new DiscoveryDocumentReference ();
+                                       AddDiscoReferences (doc);
+                               }
+                               else if (ServiceDescription.CanRead (reader))
+                               {
+                                       ServiceDescription wsdl = ServiceDescription.Read (reader);
+                                       documents.Add (url, wsdl);
+                                       doc = new DiscoveryDocument ();
+                                       refe = new ContractReference ();
+                                       doc.References.Add (refe);
+                                       refe.Url = url;
+                                       ((ContractReference)refe).ResolveInternal (this, wsdl);
+                               }
+                               else
+                               {
+                                       XmlSchema schema = XmlSchema.Read (reader, null);
+                                       documents.Add (url, schema);
+                                       doc = new DiscoveryDocument ();
+                                       refe = new SchemaReference ();
+                                       ((SchemaReference)refe).ResolveInternal (this, schema);
+                                       doc.References.Add (refe);
+                               }
+                               
+                               refe.ClientProtocol = this;
+                               refe.Url = url;
+                               references.Add (url, refe);
+                                       
+                               reader.Close ();
+                               return doc;
+                       }
+                       catch (DiscoveryException ex) {
+                               throw ex.Exception;
+                       }
+               }
+               
+               void AddDiscoReferences (DiscoveryDocument doc)
+               {
+                       foreach (DiscoveryReference re in doc.References)
+                       {
+                               re.ClientProtocol = this;
+                               references.Add (re.Url, re);
+                       }
+                       
+                       if (doc.AdditionalInfo != null) {
+                               foreach (object info in doc.AdditionalInfo)
+                                       additionalInformation.Add (info);
+                       }
+               }
+               
+               public Stream Download (ref string url)
+               {
+                       string contentType = null;
+                       return Download (ref url, ref contentType);
+               }
+               
+               public Stream Download (ref string url, ref string contentType)
+               {
+                       if (url.StartsWith ("http://") || url.StartsWith ("https://"))
+                       {
+                               WebRequest request = GetWebRequest (new Uri(url));
+                               WebResponse resp = request.GetResponse ();
+                               contentType = resp.ContentType;
+                               return resp.GetResponseStream ();
+                       }
+                       else if (url.StartsWith ("file://"))
+                       {
+                               WebRequest request = WebRequest.Create (new Uri (url));
+                               WebResponse resp = request.GetResponse ();
+                               contentType = resp.ContentType;
+                               return resp.GetResponseStream ();
+                       }
+                       else
+                       {
+                               string ext = Path.GetExtension (url).ToLower();
+                               if (ext == ".wsdl" || ext == ".xsd")
+                               {
+                                       contentType = "text/xml";
+                                       return new FileStream (url, FileMode.Open, FileAccess.Read);
+                               }
+                               else
+                                       throw new InvalidOperationException ("Unrecognized file type '" + url + "'. Extension must be one of .wsdl or .xsd");
+                       }
+               }
+
+               [Obsolete ("This method will be removed from a future version. The method call is no longer required for resource discovery", false)]
+               public void LoadExternals ()
+               {
+               }
+
+               public DiscoveryClientResultCollection ReadAll (string topLevelFilename)
+               {
+                       StreamReader sr = new StreamReader (topLevelFilename);
+                       XmlSerializer ser = new XmlSerializer (typeof (DiscoveryClientResultsFile));
+                       DiscoveryClientResultsFile resfile = (DiscoveryClientResultsFile) ser.Deserialize (sr);
+                       sr.Close ();
+                       
+                       string basePath = Path.GetDirectoryName (topLevelFilename);
+                       
+                       foreach (DiscoveryClientResult dcr in resfile.Results)
+                       {
+                               Type type = Type.GetType (dcr.ReferenceTypeName);
+                               DiscoveryReference dr = (DiscoveryReference) Activator.CreateInstance (type);
+                               dr.Url = dcr.Url;
+                               FileStream fs = new FileStream (Path.Combine (basePath, dcr.Filename), FileMode.Open, FileAccess.Read);
+                               Documents.Add (dr.Url, dr.ReadDocument (fs));
+                               fs.Close ();
+                               References.Add (dr.Url, dr);
+                       }
+                       return resfile.Results;
+               }
+
+               public void ResolveAll ()
+               {
+                       ArrayList list = new ArrayList (References.Values);
+                       foreach (DiscoveryReference re in list)
+                       {
+                               try
+                               {
+                                       if (re is DiscoveryDocumentReference)
+                                               ((DiscoveryDocumentReference)re).ResolveAll ();
+                                       else
+                                               re.Resolve ();
+                               }
+                               catch (DiscoveryException ex)
+                               {
+                                       Errors [ex.Url] = ex.Exception; 
+                               }
+                               catch (Exception ex)
+                               {
+                                       Errors [re.Url] = ex;   
+                               }
+                       }
+               }
+               
+               public void ResolveOneLevel ()
+               {
+                       ArrayList list = new ArrayList (References.Values);
+                       foreach (DiscoveryReference re in list)
+                               re.Resolve ();
+               }
+               
+               public DiscoveryClientResultCollection WriteAll (string directory, string topLevelFilename)
+               {
+                       DiscoveryClientResultsFile resfile = new DiscoveryClientResultsFile();
+                       
+                       foreach (DiscoveryReference re in References.Values)
+                       {
+                               object doc = Documents [re.Url];
+                               if (doc == null) continue;
+                               
+                               string fileName = FindValidName (resfile, re.DefaultFilename);
+                               resfile.Results.Add (new DiscoveryClientResult (re.GetType(), re.Url, fileName));
+                               
+                               string filepath = Path.Combine (directory, fileName);
+                               FileStream fs = new FileStream (filepath, FileMode.Create, FileAccess.Write);
+                               re.WriteDocument (doc, fs);
+                               fs.Close ();
+                       }
+                       
+                       StreamWriter sw = new StreamWriter (Path.Combine (directory, topLevelFilename));
+                       XmlSerializer ser = new XmlSerializer (typeof (DiscoveryClientResultsFile));
+                       ser.Serialize (sw, resfile);
+                       sw.Close ();
+                       return resfile.Results;
+               }
+               
+               string FindValidName (DiscoveryClientResultsFile resfile, string baseName)
+               {
+                       string name = baseName;
+                       int id = 0;
+                       bool found;
+                       do
+                       {
+                               found = false;
+                               foreach (DiscoveryClientResult res in resfile.Results)
+                               {
+                                       if (name == res.Filename) {
+                                               found = true; break;
+                                       }
+                               }
+                               if (found)
+                                       name = Path.GetFileNameWithoutExtension (baseName) + (++id) + Path.GetExtension (baseName);
+                       }
+                       while (found);
+                       
+                       return name;
+               }
+               
+               #endregion // Methods
+               
+               #region Classes
+               
+               public sealed class DiscoveryClientResultsFile {
+                       
+                       #region Fields
+                       
+                       private DiscoveryClientResultCollection results;
+
+                       #endregion // Fields
+
+                       #region Contructors
+                       
+                       public DiscoveryClientResultsFile () 
+                       {
+                               results = new DiscoveryClientResultCollection ();
+                       }
+               
+                       #endregion // Constructors
+                       
+                       #region Properties
+               
+                       public DiscoveryClientResultCollection Results {                                
+                               get { return results; }
+                       }
+                       
+                       #endregion // Properties
+               }
+               
+               #endregion // Classes
+       }
+               
+       internal class DiscoveryException : Exception
+       {
+               public string Url;
+               public Exception Exception;
+               
+               public DiscoveryException (string url, Exception origin)
+               {
+                       Url = url;
+                       Exception = origin;
+               }
+       }
+}