context: //
  // Authors:
  //   Rafael Mizrahi   <rafim@mainsoft.com>
  //   Erez Lotan       <erezl@mainsoft.com>
  //   Vladimir Krasnov <vladimirk@mainsoft.com>
  //   
  // 
  // Copyright (c) 2002-2005 Mainsoft Corporation.
  // 
  // 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;
  using System.IO;
  using System.Xml;
  using System.Net;
  using System.Text;
  using System.Collections;
  
  namespace MonoTests.stand_alone.WebHarness
  {
  	public abstract class XmlComparableTest
  	{
  		public abstract XmlDocument GetTestXml(TestInfo testInfo);
  		public abstract bool XmlCompare(XmlDocument d1, XmlDocument d2, bool ignoreAlmost);
  	}
  
  	public class HtmlDiff : XmlComparableTest
  	{
  		private string _testsBaseUrl = "";
  		private string _ignoreListFile = "";
  		private XmlDocument _xmlIgnoreList = null;
  		private string _compareStatus = "";
  
  		public HtmlDiff()
  		{
  		}
  
  		public string TestsBaseUrl
  		{
  			get {return _testsBaseUrl;}
  			set {_testsBaseUrl = value;}
  		}
  		public string IgnoreListFile
  		{
  			get {return _ignoreListFile;}
  			set {_ignoreListFile = value;}
  		}
  		public string CompareStatus
  		{
  			get {return _compareStatus.ToString();}
  		}
  
  		public override XmlDocument GetTestXml(TestInfo testInfo)
  		{
  			return BuildXml( GetSubTests( GetUrl(testInfo.Url) ), testInfo );
  		}
  
  		public override bool XmlCompare(XmlDocument d1, XmlDocument d2, bool ignoreAlmost)
  		{
  			XmlComparer comparer = new XmlComparer();
  			if (ignoreAlmost == false)
  			{
  				DoAlmost(d1);
  				DoAlmost(d2);
  			}
  			bool c = comparer.AreEqual(d1, d2);
  			_compareStatus = comparer.LastCompare;
  			return c;
  		}
  
  		//============================================================================
  		//
  
  		private string GetUrl(string url)
  		{
  			try
  			{
  				HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_testsBaseUrl + url);
  				request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
  				request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*";
  
  				HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  
  				Stream responseStream = response.GetResponseStream();
  				StreamReader sr = new StreamReader(responseStream);
  
  				string s = sr.ReadToEnd();
  				sr.Close();
  
  				return s;
  			}
  			catch(Exception e)
  			{
  				Console.WriteLine("Cannot retrieve document from url " + _testsBaseUrl + url);
  				Console.WriteLine(e.Message);
  			}
  
  			return "";
  		}
  
  		private ArrayList GetSubTests(string s)
  		{
  			ArrayList subTestList = new ArrayList();
  			int startIndex = SkipViewstate (s);
  			string subTest = FindSubTest(s, startIndex);
  			
  			while (subTest != "")
  			{
  				if (subTest.ToLower().IndexOf("ghtsubtest") != -1)
  					subTestList.Add(subTest);
  				subTest = FindSubTest(s, s.IndexOf(subTest) + subTest.Length);
  			}
  
  			return subTestList;
  		}
  		#region "Sub Test extraction routines"
  		private string FindSubTest(string s, int startIndex)
  		{
  			int tagBeginCount = 0;
  			int stringPosition = startIndex;
  			int tagPosition = 0;
  
  			tagPosition = GetNextDivPosition(s, stringPosition);
  			if (tagPosition == -1) return "";
  
  			if (isBeginTag(s, tagPosition))
  				tagBeginCount++;
  			else
  				return "";
  
  			startIndex = tagPosition;
  
  			while (tagBeginCount > 0)
  			{
  				stringPosition = tagPosition + 1;
  				tagPosition = GetNextDivPosition(s, stringPosition);
  				if (tagPosition == -1) return "";
  
  				if (isBeginTag(s, tagPosition))
  					tagBeginCount++;
  				else
  					tagBeginCount--;
  			}
  
  			return s.Substring(startIndex, tagPosition - startIndex + 6);
  		}
  
  		private int GetNextDivPosition(string s, int startIndex)
  		{
  			int tagBeginPos = GetBeginDivPosition(s, startIndex);
  			int tagEndPos = GetEndDivPosition(s, startIndex);
  
  			if ((tagBeginPos == -1) && (tagEndPos == -1)) return -1;
  			if ((tagBeginPos > 0) && (tagEndPos > 0))
  			{
  				if (tagBeginPos < tagEndPos)
  					return tagBeginPos;
  				else
  					return tagEndPos;
  			}
  			else
  			{
  				if (tagBeginPos > tagEndPos)
  					return tagBeginPos;
  				else
  					return tagEndPos;
  			}
  		}
  
  		private int SkipViewstate (string s)
  		{
  			int start = s.IndexOf ("<div id");
  			int startVS = s.IndexOf ("<div>");
  			int vs = s.IndexOf ("VIEWSTATE");
  			int endVS = s.IndexOf ("</div>");
  
  			if (startVS > 0 && startVS < vs && vs < endVS && startVS < start)
  				return endVS + 7;
  
  			return 0;
  		}
  
  		private int GetBeginDivPosition(string s, int startIndex)
  		{
  			return s.IndexOf("<div id", startIndex);
  		}
  
  		private int GetEndDivPosition(string s, int startIndex)
  		{
  			return s.IndexOf("</div", startIndex);
  		}
  
  		private bool isBeginTag(string tag, int pos)
  		{
  			return tag.Substring(pos).StartsWith("<div");
  		}
  		private bool isEndTag(string tag, int pos)
  		{
  			return tag.Substring(pos).StartsWith("</div");
  		}
  		#endregion
  
  		private XmlDocument BuildXml(ArrayList subTests, TestInfo ti)
  		{
  
gt: 			StringBuilder xmltext = new StringBuilder();