<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6146753014571848686</id><updated>2011-11-22T02:56:48.402-08:00</updated><category term='MS SQL'/><category term='JavaScript'/><category term='XSS'/><category term='WCF'/><category term='Oracle'/><category term='IIS'/><category term='Google'/><category term='ASP.NET'/><title type='text'>ASP.NET Caffe</title><subtitle type='html'>ASP.NET, JavaScript, Oracle and SQL articles and code.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>27</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-6002705979219470888</id><published>2011-09-28T03:46:00.000-07:00</published><updated>2011-09-28T03:50:24.181-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>WCF Security Guide</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;span style="font-family:times new roman;"&gt;The content is procured from &lt;a href="https://www.owasp.org/index.php/WCF_Security_Best_Practices"&gt;OWASP&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;h3 align="center"&gt;From OWASP&lt;/h3&gt;&lt;p&gt;From &lt;a rel="nofollow" href="http://www.codeplex.com/WCFSecurity/Wiki/View.aspx?title=Guidelines"&gt;WCF 3.5 Security Guidelines&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(@Codeplex by J.D. Meier , Jason Taylor , Prashant Bansode , Carlos Farre, Madhu Sundararajan, Steve Gregersen.)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Design Considerations&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Design your service as a wrapper&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are coming from ASMX then use basicHttpBinding to support your existing clients&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are coming from DCOM then, use netTcpBinding&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your clients are deployed within intranet then choose transport security&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your clients are deployed over the internet then choose message security&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Know your Authentication options&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Know your binding options&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to Interop with non MS clients, use basicHttpBinding or wsHttpBinding&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your non-MS clients understand WS stack, use wsHttpBinding&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Auditing and Logging&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Use WCF auditing to audit your service&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If non-repudiation is important, consider setting SuppressAuditFailure property to false&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use message logging to log operations on your service&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Instrument for user management events&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Instrument for significant business operations&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Protect log files from unauthorized access&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Do not log sensitive information&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Authentication&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Know your authentication options&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use Windows Authentication when you can&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you support non-WCF clients using windows authentication and message security, consider using the Kerberos direct option&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your users are in AD, but you can’t use windows authentication, consider using username authentication&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are using username authentication, use Membership Provider instead of custom authentication&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your users are in a SQL membership store, use the SQL Membership Provider&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your users are in a custom store, consider using username authentication with a custom validator&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your clients have certificates, consider using client certificate authentication&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your partner applications need to be authenticated when calling WCF services, use client certificate authentication.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are using username authentication, validate user login information&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Do not store passwords directly in the user store&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Enforce strong passwords&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Protect access to your credential store&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are using Windows Forms to connect to WCF, do not cache credentials&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Authorization&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; If you store role information in Windows Groups, consider using the WCF PrincipalPermissionAttribute class for roles authorization&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you use ASP.NET roles, use the ASP.NET Role Provider&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you use windows groups for authorization, use ASP.NET Role Provider with AspNetWindowsTokenRoleProvider&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you store role information in SQL, consider using the SQL Server Role Provider for roles authorization&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you store role information in ADAM, use the Authorization Store Role Provider for roles authorization&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to authorize access to WCF operations, use declarative authorization&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to perform fine-grained authorization based on business logic, use imperative authorization&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Binding&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; If you need to support clients over the internet, consider using wsHttpBinding.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to expose your WCF service to legacy clients as an ASMX web service, use basicHttpBinding&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to support remote WCF clients within an intranet, consider using netTcpBinding.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to support local WCF clients, consider using netNamedPipeBinding.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to support disconnected queued calls, use netMsmqBinding.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to support bidirectional communication between WCF Client and WCF service, use wsDualHttpBinding.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Configuration Management&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Use Replay detection to protect against message replay attacks&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you host your service in a Windows service, expose a metadata exchange (mex) binding&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you don’t want to expose your WSDL, turn off HttpGetEnabled and metadata exchange (mex)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Manage bindings and endpoints in config not code&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Associate names with the service configuration when you create service behavior, endpoint behavior, and binding configuration&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Encrypt configuration sections that contain sensitive data&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Exception Management&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Use structured exception handling&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Do not divulge exception details to clients in production&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use a fault contract to return error information to clients&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use a global exception handler to catch unhandled exceptions&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hosting&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; If you are hosting your service in a Windows Service, use a least privileged custom domain account&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are hosting your service in IIS, use a least privileged service account&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use IIS to host your service unless you need to use a transport that IIS does not support&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Impersonation and Delegation&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Know the impersonation options&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you have to flow the original caller, use constrained delegation&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Consider LogonUser when you need to impersonate but you don’t have trusted delegation&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Consider S4U when you need a Windows token and you don’t have the original caller’s credentials&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use programmatic impersonation to impersonate based on business logic&lt;br /&gt;&lt;/li&gt;&lt;li&gt; When impersonating programmatically be sure to revert to original context&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Only impersonate on operations that require it&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use OperationBehavior to impersonate declaratively&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Input/Data Validation&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; If you need to validate parameters, use parameter inspectors&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If your service has operations that accept message or data contracts, use schemas to validate your messages&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you need to do schema validation, use message inspectors&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Validate operation parameters for length, range, format and type&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Validate parameter input on the server&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Validate service responses on the client&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Do not rely on client-side validation&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Avoid user-supplied file name and path input&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Do not echo untrusted input&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Proxy Considerations&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Publish your metadata over HTTPS to protect your clients from proxy spoofing&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you turn off mutual authentication, be aware of service spoofing&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Deployment considerations&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Do not use temporary certificates in production&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are using a custom domain account in the identity pool for your WCF application, create an SPN for Kerberos to authenticate the client.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are using a custom service account and need to use trusted for delegation, create an SPN&lt;br /&gt;&lt;/li&gt;&lt;li&gt; If you are hosting your service in a Windows Service, using a custom domain identity, and ASP.NET needs to use constrained trusted for delegation when calling the service, create an SPN&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use IIS to host your service unless you need to use a transport that IIS does not support&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Use a least privileged account to run your WCF service&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Protect sensitive data in your configuration files&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-6002705979219470888?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/6002705979219470888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=6002705979219470888' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6002705979219470888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6002705979219470888'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2011/09/wcf-security-guide.html' title='WCF Security Guide'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2288409657306127020</id><published>2011-07-20T13:19:00.000-07:00</published><updated>2011-07-20T22:57:21.909-07:00</updated><title type='text'>HTTP Data Client - An abstract way of web scraping</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt;&lt;p&gt;The purpose of this article is to describe how you can implement a generic “HTTP Data Client” (I apologize if it sounds fussy) using C# which would allow you to query in an elegant manner any web based resources you would like (in one word it allows you to do &lt;b&gt;web scraping&lt;/b&gt;). I would like to mention from the beginning that this is not “the perfect solution” and that for sure it can be improved in many ways, so, please feel free to do so. The entire concept it is based on HTTPWebRequest object offered by .NET under System.Net name space.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Prerequisites&lt;/h2&gt;&lt;p&gt;Before I’ll start to dwell into architecture and code, there are some extra libraries which are used and required by the “HTTP Data Client” project.&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;Here is the list of libraries:&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Db4Object&lt;/strong&gt; (this is a object oriented database, I am using it meanly for embedded applications; there are two assembly files which are referenced: Db4objects.Db4o.dll and Db4objects.Db4o.NativeQueries.dll; you can get the DB4Object from the following location: http://www.db4o.com/DownloadNow.aspx)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Html Agility Pack&lt;/strong&gt; (this is a library which allows you to process HTML content using various techniques, it is very handy when you would like to convert the HTML DOM to XML; there is one assembly file referenced: HtmlAgilityPack.dll; you can get the library from the following location: http://htmlagilitypack.codeplex.com)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Microsoft mshtml&lt;/strong&gt; (its purpose is to render and parse HTML and JavaScript content)&lt;/li&gt;&lt;/ul&gt;If you are wondering why I have decided to use two different libraries to parse HTML content, the answer is straight forward. Html Agility Pack is performing really well most of the time; the output you get is usually what you are expecting, but not always. So if one library fails to provide the expected results I can switch to the other one. &lt;/br&gt;The major drawback of MSHTML library in my opinion is the slow processing speed when it is integrated in a non desktop application (e.g.: web sites, web services, etc).&lt;/br&gt;&lt;br /&gt;The role of DB4Object in this project is to store configuration settings and cache content. One important thing that has to mentioned about DB4Object is that the non server version doesn’t support multi-threading (you can easily replace with any other storage which is suitable for you).&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Architecture&lt;/h2&gt;&lt;p&gt;My solution is contains four projects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;HtmlAgilityPack&lt;/strong&gt; (the actual Html Agility Pack project with source code)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;HttpData.Client&lt;/strong&gt; (main project which implements the rules of HTML processing)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;HttpData.Client.MsHtmlToXml&lt;/strong&gt; (wrapper project over MSHTML and some extensions of it)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;HttpData.Client.Pdf&lt;/strong&gt; (project which implements some PDF processing using IFilter; not important for this article)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;There is no point to discuss about HtmlAgilityPack since you can find all details and documentation about it on http://htmlagilitypack.codeplex.com.&lt;br /&gt;I will focus mainly on HttpData.Client and try to offer you as many details and explanations as possible. The http data client is design to work in a similar way with .NET SQL client (System.Data.SqlClient), you will notice that the classes included in project and their logic resembles a lot (I hope is not just my imagination). I will enumerate the interfaces and classes and provide details about their logic and purpose.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;IHDPAdapter and HDPAdapter&lt;/h2&gt;&lt;p&gt;The purpose of HDPAdapter class is to allow integration of XML data to with other data objects as DataTable and DataSet. The IHDPAdapter interface exposes two methods which convert XML data into either a DataTable or a DataSet. At current time only DataTable conversion method is implemented. &lt;/br&gt;Here is the code snippet for the interface and class:&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;IHDPAdapter Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System.Data;&lt;br /&gt;using System.Xml;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Provides functionality for integration with data objects (DataTable, DataSet, etc). Is implemented by HDPAdapter.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; public interface IHDPAdapter&lt;br /&gt; {&lt;br /&gt;  #region&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the select HDPCommand object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        IHDPCommand SelectCommand{ get; set; }&lt;br /&gt;  #endregion&lt;br /&gt;&lt;br /&gt;  #region METHODS&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Fill a data table with the content from a specified xml document object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="table"&amp;gt;Data table to be filled.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="source"&amp;gt;Xml document object of which content will fill the data table.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="useNodes"&amp;gt;True if nodes names should be used for columns names, otherwise attributes will be used.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of filled rows.&amp;lt;/returns&amp;gt;&lt;br /&gt;     int Fill(DataTable table, XmlDocument source, bool useNodes);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// (NOT IMPLEMENTED) Fill a data set with the content from a specified xml document object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="dataset"&amp;gt;Data set to be filled.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="source"&amp;gt;Xml document object of which content will fill the data table.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="useNodes"&amp;gt;True if nodes names should be used for columns names, otherwise attributes will be used.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of filled rows.&amp;lt;/returns&amp;gt;&lt;br /&gt;        int Fill(DataSet dataset, XmlDocument source, bool useNodes);&lt;br /&gt;  #endregion&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;HDPAdapter Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System;&lt;br /&gt;using System.Xml;&lt;br /&gt;using System.Xml.XPath;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt; /// Provides functionality for integration with data objects (DataTable, DataSet, etc).&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; public class HDPAdapter : IHDPAdapter &lt;br /&gt; {&lt;br /&gt;  #region PRIVATE VARIABLES&lt;br /&gt;  private IHDPCommand _selectCommand;&lt;br /&gt;&lt;br /&gt;     #endregion&lt;br /&gt;&lt;br /&gt;  #region Properties&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the select IHDPCommand object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  IHDPCommand IHDPAdapter.SelectCommand&lt;br /&gt;  {&lt;br /&gt;   get{ return _selectCommand; }&lt;br /&gt;   set{ _selectCommand = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the select HDPCommand object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  public HDPCommand SelectCommand&lt;br /&gt;  {&lt;br /&gt;   get{ return (HDPCommand)_selectCommand; }&lt;br /&gt;   set{ _selectCommand = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;     /// &amp;lt;summary&amp;gt;&lt;br /&gt;     /// Get or set the connection string.&lt;br /&gt;     /// &amp;lt;/summary&amp;gt;&lt;br /&gt;     public string ConnectionString { get; set; }&lt;br /&gt;&lt;br /&gt;     #endregion&lt;br /&gt;&lt;br /&gt;  #region .ctor&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new instance of HDPAdapter.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPAdapter()&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new instance of HDPAdapter.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="connectionString"&amp;gt;Connection string associated with HDPAdapter object.&amp;lt;/param&amp;gt;&lt;br /&gt;        public HDPAdapter(string connectionString)&lt;br /&gt;        {&lt;br /&gt;            this.ConnectionString = connectionString;&lt;br /&gt;        }&lt;br /&gt;  #endregion&lt;br /&gt;&lt;br /&gt;  #region Public Methods&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Fill a data table with the content from a specified xml document object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="table"&amp;gt;Data table to be filled.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="source"&amp;gt;Xml document object of which content will fill the data table.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="useNodes"&amp;gt;True if nodes names should be used for columns names, otherwise attributes will be used.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of filled rows.&amp;lt;/returns&amp;gt;&lt;br /&gt;        public int Fill(DataTable table, XmlDocument source, bool useNodes)&lt;br /&gt;        {&lt;br /&gt;            bool columnsCreated = false;&lt;br /&gt;            bool resetRow = false;&lt;br /&gt;&lt;br /&gt;            if(table == null || source == null)&lt;br /&gt;                return 0;&lt;br /&gt;&lt;br /&gt;            if (table.TableName.Length == 0)&lt;br /&gt;                return 0;&lt;br /&gt;&lt;br /&gt;            StringBuilder sbExpression = new StringBuilder("//");&lt;br /&gt;            sbExpression.Append(table.TableName);&lt;br /&gt;&lt;br /&gt;            XPathNavigator xpNav = source.CreateNavigator();&lt;br /&gt;            if (xpNav != null)&lt;br /&gt;            {&lt;br /&gt;                XPathNodeIterator xniNode = xpNav.Select(sbExpression.ToString());&lt;br /&gt;&lt;br /&gt;                while(xniNode.MoveNext())&lt;br /&gt;                {&lt;br /&gt;                    XPathNodeIterator xniRowNode = xniNode.Current.SelectChildren(XPathNodeType.Element);&lt;br /&gt;                    while (xniRowNode.MoveNext())&lt;br /&gt;                    {&lt;br /&gt;                        if(resetRow)&lt;br /&gt;                        {&lt;br /&gt;                            xniRowNode.Current.MoveToFirst();&lt;br /&gt;                            resetRow = false;&lt;br /&gt;                        }&lt;br /&gt;&lt;br /&gt;                        DataRow row = null;&lt;br /&gt;                        if (columnsCreated)&lt;br /&gt;                            row = table.NewRow();&lt;br /&gt;                    &lt;br /&gt;                        if(useNodes)&lt;br /&gt;                        {&lt;br /&gt;                            XPathNodeIterator xniColumnNode = xniRowNode.Current.SelectChildren(XPathNodeType.Element);&lt;br /&gt;                            while (xniColumnNode.MoveNext())&lt;br /&gt;                            {&lt;br /&gt;                                if (!columnsCreated)&lt;br /&gt;                                {&lt;br /&gt;                                    DataColumn column = new DataColumn(xniColumnNode.Current.Name);&lt;br /&gt;                                    table.Columns.Add(column);&lt;br /&gt;                                }&lt;br /&gt;                                else&lt;br /&gt;                                    row[xniColumnNode.Current.Name] = xniColumnNode.Current.Value;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                        {&lt;br /&gt;                            XPathNodeIterator xniColumnNode = xniRowNode.Clone();&lt;br /&gt;                            bool onAttribute = xniColumnNode.Current.MoveToFirstAttribute();&lt;br /&gt;                            while (onAttribute)&lt;br /&gt;                            {&lt;br /&gt;                                if (!columnsCreated)&lt;br /&gt;                                {&lt;br /&gt;                                    DataColumn column = new DataColumn(xniColumnNode.Current.Name);&lt;br /&gt;                                    table.Columns.Add(column);&lt;br /&gt;                                }&lt;br /&gt;                                else&lt;br /&gt;                                    row[xniColumnNode.Current.Name] = xniColumnNode.Current.Value;&lt;br /&gt;&lt;br /&gt;                                onAttribute = xniColumnNode.Current.MoveToNextAttribute();&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;&lt;br /&gt;                        if (!columnsCreated)&lt;br /&gt;                        {&lt;br /&gt;                            columnsCreated = true;&lt;br /&gt;                            resetRow = true;&lt;br /&gt;                        }&lt;br /&gt;&lt;br /&gt;                        if (row != null)&lt;br /&gt;                            table.Rows.Add(row);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return table.Rows.Count;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// (NOT IMPLEMENTED) Fill a data set with the content from a specified xml document object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="dataset"&amp;gt;Data set to be filled.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="source"&amp;gt;Xml document object of which content will fill the data table.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="useNodes"&amp;gt;True if nodes names should be used for columns names, otherwise attributes will be used.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of filled rows.&amp;lt;/returns&amp;gt;&lt;br /&gt;  public int Fill(DataSet dataset, XmlDocument source, bool useNodes)&lt;br /&gt;  {&lt;br /&gt;            throw new NotImplementedException();&lt;br /&gt;  }&lt;br /&gt;  #endregion&lt;br /&gt;&lt;br /&gt;        #region Private Methods&lt;br /&gt;     #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;IHDPConnection and HDPConnection&lt;/h2&gt;&lt;p&gt;As the name says this represents the connection class which will manage in an abstract way how a connection behaves. The interface exposes a set of methods and properties relevant to it. &lt;/br&gt;There are only three methods exposed and implemented: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Open&lt;/i&gt; method (changes the connection state to open; this method has an override which accepts as parameter the URL of the web resource which will be opened)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Close&lt;/i&gt; method (changes the connection state to close and if there is a cache storage in use it closes it)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;CreateCommand&lt;/i&gt; method (it creates a new HDPCommand  object and assigns the current connection to it)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Now let us take a look at the properties exposed by IHDPConnection and implemented by HDPConnection:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;ConnectionURL&lt;/i&gt; (represents the web resource URL which will be opened using current connection)&lt;/li&gt;&lt;li&gt;&lt;i&gt;KeepAlive&lt;/i&gt; (defines if the connection should be kept opened or not once the querying is done)&lt;/li&gt;&lt;li&gt;&lt;i&gt;AutoRedirect&lt;/i&gt; (defines if the connection allows any auto-redirects to be performed)&lt;/li&gt;&lt;li&gt;&lt;i&gt;MaxAutoRedirects&lt;/i&gt; (defines how many auto-redirects can be performed)&lt;/li&gt;&lt;li&gt;&lt;i&gt;UserAgent&lt;/i&gt; (defines what user agent will be associated with the connection, e.g.: Internet Explorer, Chrome, Opera, etc)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ConnectionState&lt;/i&gt; (read only property which provides information about the connection state; is connection opened or closed)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Proxy&lt;/i&gt; (defines what proxy will be used when querying is performed)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Cookies&lt;/i&gt; (cookies associated with the connection currently or on when the querying takes place)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ContentType&lt;/i&gt; (defines what content type is expected when querying takes place, e.g.: application/x-www-form-urlencoded, application/json, etc)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Headers&lt;/i&gt; (contains the headers associated with the connection currently or when the querying takes place)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Referer&lt;/i&gt; (contains the referrer which is going to be used when querying the connection URL)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;IHDPConnection Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System.Collections.Generic;&lt;br /&gt;using System.Net;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt; /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Provides functionality for connection management of different web sources. Is implemented by HDPConnection.&lt;br /&gt; /// &amp;lt;/summary&amp;gt;&lt;br /&gt; public interface IHDPConnection&lt;br /&gt; {&lt;br /&gt;  #region MEMBERS&lt;br /&gt;  #region METHODS&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Open connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  void Open();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Close connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  void Close();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new HDPCommand object associated with this connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;HDPCommand object associated with this connection.&amp;lt;/returns&amp;gt;&lt;br /&gt;  IHDPCommand CreateCommand();&lt;br /&gt;  #endregion&lt;br /&gt;&lt;br /&gt;  #region PROPERTIES&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set connection url.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  string ConnectionURL { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if the connection should be maintained openend.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        bool KeepAlive { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if auto redirection is allowed.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        bool AutoRedirect { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if maximum number of auto redirections.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        int MaxAutoRedirects { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the user agent to be used.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string UserAgent { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the value which specifies the state of the connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;  HDPConnectionState ConnectionState { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the connection proxy.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        HDPProxy Proxy { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the coockies used by connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        CookieCollection Cookies { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the content type.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string ContentType { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set headers details used in HttpWebRequest operations.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        List&amp;lt;HDPConnectionHeader&amp;gt; Headers { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set Http referer.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string Referer { get; set; }&lt;br /&gt;        #endregion&lt;br /&gt;  #endregion&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt; &lt;/pre&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;HDPConnection Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System.Collections.Generic;&lt;br /&gt;using System.Net;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt;    /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Provides functionality for connection management of different web sources.&lt;br /&gt;    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;    public class HDPConnection : IHDPConnection&lt;br /&gt;    {&lt;br /&gt;        #region Private Variables&lt;br /&gt;        private HDPConnectionState _connectionState;&lt;br /&gt;        private string _connectionURL;&lt;br /&gt;        private HDPCache cache;&lt;br /&gt;        private bool useCache;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Properties&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the value which specifies if caching will be used.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool UseCahe&lt;br /&gt;        {&lt;br /&gt;            get { return useCache; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get HDPCache object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPCache Cache&lt;br /&gt;        {&lt;br /&gt;            get { return cache; }&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region .ctor&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPConnection object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPConnection()&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Closed;&lt;br /&gt;            _connectionURL = "";&lt;br /&gt;            Cookies = new CookieCollection();&lt;br /&gt;            MaxAutoRedirects = 1;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPConnection object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="connectionURL"&amp;gt;Url of the web source.&amp;lt;/param&amp;gt;&lt;br /&gt;        public HDPConnection(string connectionURL)&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Closed;&lt;br /&gt;            _connectionURL = connectionURL;&lt;br /&gt;            Cookies = new CookieCollection();&lt;br /&gt;            MaxAutoRedirects = 1;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPConnection object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="cacheDefinitions"&amp;gt;HDPCacheDefinition object used by caching mechanism.&amp;lt;/param&amp;gt;&lt;br /&gt;        public HDPConnection(HDPCacheDefinition cacheDefinitions)&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Closed;&lt;br /&gt;            _connectionURL = "";&lt;br /&gt;            Cookies = new CookieCollection();&lt;br /&gt;            MaxAutoRedirects = 1;&lt;br /&gt;            cache = cacheDefinitions != null ? new HDPCache(cacheDefinitions) : null;&lt;br /&gt;            useCache = true;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPConnection object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="connectionURL"&amp;gt;Url of the web source.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="cacheDefinitions"&amp;gt;HDPCacheDefinition object used by caching mechanism.&amp;lt;/param&amp;gt;&lt;br /&gt;        public HDPConnection(string connectionURL, HDPCacheDefinition cacheDefinitions)&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Closed;&lt;br /&gt;            _connectionURL = connectionURL;&lt;br /&gt;            Cookies = new CookieCollection();&lt;br /&gt;            MaxAutoRedirects = 1;&lt;br /&gt;            cache = cacheDefinitions != null ? new HDPCache(cacheDefinitions) : null;&lt;br /&gt;            useCache = true;&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Public Methods&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region IHDPConnection Members&lt;br /&gt;        #region Methods&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Open connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public void Open()&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Open;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Open connection using a specific url.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="connectionURL"&amp;gt;Url of the web source.&amp;lt;/param&amp;gt;&lt;br /&gt;        public void Open(string connectionURL)&lt;br /&gt;        {&lt;br /&gt;            _connectionURL = connectionURL;&lt;br /&gt;            _connectionState = HDPConnectionState.Open;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Close connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public void Close()&lt;br /&gt;        {&lt;br /&gt;            _connectionState = HDPConnectionState.Closed;&lt;br /&gt;&lt;br /&gt;            if (cache != null)&lt;br /&gt;                cache.CloseStorageConnection();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new IHDPCommand object associated with this connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;IHDPCommand object associated with this connection.&amp;lt;/returns&amp;gt;&lt;br /&gt;        IHDPCommand IHDPConnection.CreateCommand()&lt;br /&gt;        {&lt;br /&gt;            HDPCommand command = new HDPCommand { Connection = this };&lt;br /&gt;            return command;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new HDPCommand object associated with this connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;HDPCommand object associated with this connection.&amp;lt;/returns&amp;gt;&lt;br /&gt;        public HDPCommand CreateCommand()&lt;br /&gt;        {&lt;br /&gt;            HDPCommand command = new HDPCommand { Connection = this };&lt;br /&gt;            return command;&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Properties&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set connection url.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string ConnectionURL&lt;br /&gt;        {&lt;br /&gt;            get { return _connectionURL; }&lt;br /&gt;            set { _connectionURL = value; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if auto redirection is allowed.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool AutoRedirect { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if maximum number of auto redirections.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public int MaxAutoRedirects { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies if the connection should be maintained openend.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool KeepAlive { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the user agent to be used.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string UserAgent { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the content type.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string ContentType { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the coockies used by connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public CookieCollection Cookies { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the value which specifies the state of the connection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPConnectionState ConnectionState&lt;br /&gt;        {&lt;br /&gt;            get { return _connectionState; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the value which specifies the connection proxy.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPProxy Proxy { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set headers details used in HttpWebRequest operations.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public List&amp;lt;HDPConnectionHeader&amp;gt; Headers { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set Http referer.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string Referer { get; set; }&lt;br /&gt;        #endregion&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region IDisposable Members&lt;br /&gt;        ///&amp;lt;summary&amp;gt;&lt;br /&gt;        /// Dispose current object.&lt;br /&gt;        ///&amp;lt;/summary&amp;gt;&lt;br /&gt;        public void Dispose()&lt;br /&gt;        {&lt;br /&gt;            this.dispose();&lt;br /&gt;            System.GC.SuppressFinalize(this);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void dispose()&lt;br /&gt;        {&lt;br /&gt;            if (_connectionState == HDPConnectionState.Open)&lt;br /&gt;                this.Close();&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; &lt;/pre&gt;&lt;/p&gt;&lt;h2&gt;IHDPCommand and HDPCommand&lt;/h2&gt;&lt;p&gt;This represents our engine which provides functionality for querying web resources and processing the result (response). It offers a variety of way that can be used to process the response content of the query as: XPath, RegEx, XSLT, reflection, etc. I will discuss in detail only the main methods, rest of them are leveraged on those and I assume the comments which accompany the methods are suffice to provide guidance in the right direction. But before I’ll reach the methods, let me present you the properties.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Connection&lt;/i&gt; (defines the connection object associated with this command)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Parameters&lt;/i&gt; (defines the parameters used in the querying process)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;CommandType&lt;/i&gt; (defines the command type used in querying process; it is either GET either POST)&lt;/li&gt;&lt;li&gt;&lt;i&gt;CommandText&lt;/i&gt; (defines the content of the command which is going to executed; if this is a GET command then the URL with query parameters are stored, if it is a POST command, then the body content of the post action is stored)&lt;/li&gt;&lt;li&gt;&lt;i&gt;CommandTimeout&lt;/i&gt; (defines the time period in which a response is expected from the web resource)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Response&lt;/i&gt; (contains the response string received from the web resource based on a query action)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Uri&lt;/i&gt; (contains the URI of the queried web resource)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Path&lt;/i&gt; (contains the path of the web resource queried)&lt;/li&gt;&lt;li&gt;&lt;i&gt;LastError&lt;/i&gt; (contains the last error message encountered in the process)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;ContentLength&lt;/i&gt; (contains the length of the content received from the web resource based on a query action)&lt;/li&gt;&lt;/ul&gt;We can move now to the exposed/implemented methods.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;GetParametersCount&lt;/i&gt; (gets the number of parameters used in the query process)&lt;/li&gt;&lt;li&gt;&lt;i&gt;CreateParameter&lt;/i&gt; (create a new parameter to be used in the query process)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteNonQuery&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns the number of results received. It has one parameter which specifies if the collection of parameters used in the query process should be cleaned at the end)&lt;/li&gt;&lt;li&gt;&lt;i&gt;Execute&lt;/i&gt;(executes a query on a web resources using either GET or POST methods and it returns a Boolean value, true if the query was executed with success, false if it failed)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteStream&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns the underlying http response stream)&lt;/li&gt;&lt;li&gt;&lt;i&gt;CloseResponse&lt;/i&gt; (it closes the http response stream opened by ExecuteStream method)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteNavigator&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns a XPathNavigator object used to navigate thru the response converted to XML. It has one parameter which specifies if the collection of parameters used in the query process should be cleaned at the end)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteDocument&lt;/i&gt; (it has an override, executes a query on a web resources using either GET or POST methods and it returns a IXPathNavigable object used to navigate thru the response converted to XML, the “expression” parameter represents a XPath expression which will be used in the processing of the result)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteBinary&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns a result in byte array format. This is mostly used when querying binary content from web resources e.g.: PDF files, images. One of the overridden method parameters imposes a limit on the output buffer)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteBinaryConversion&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns a result as string. This is used when querying binary content from web resources e.g.: PDF files and the content of a PDF file is converted from binary to string)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteString&lt;/i&gt; (executes a query on a web resources using either GET or POST methods and it returns a result as plain string)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteValue&lt;/i&gt; (executes a query on a web resource using either GET or POST methods and it returns a result as string which is a representation of an XPath expression applied. Instead of an XPath expression it can be an RegEx)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteCollection&lt;/i&gt; (executes a query on a web resource using either GET or POST methods and it returns a result as generic string collection. The result is a representation of an either XPath or RegEx expression applied on the result)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ExecuteArray&lt;/i&gt; (executes a query on a web resource using either GET or POST methods and it returns a result as a string array. The result is a representation of an either XPath or RegEx expression applied on the result)&lt;/li&gt;&lt;/ul&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;IHDPCommand Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System.Collections.Generic;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Xml.XPath;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt;    /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Provides functionality for querying and processing data from different web sources. Is implemented by HDPCommand.&lt;br /&gt;    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;    public interface IHDPCommand&lt;br /&gt;    {&lt;br /&gt;        #region Members&lt;br /&gt;        #region Properties&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the command connection object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        IHDPConnection Connection { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the command parameters collection.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        IHDPParameterCollection Parameters { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the command type.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        HDPCommandType CommandType { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the command text. &lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string CommandText { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the command timeout.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        int CommandTimeout { get; set; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the response retrieved from the server.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string Response { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get web resource URI.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string Uri { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get web resource absolute path.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string Path { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the last error occurend.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        string LastError { get; }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the content length of response.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        long ContentLength { get; }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Methods&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get the parameters number.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of parameters.&amp;lt;/returns&amp;gt;&lt;br /&gt;        int GetParametersCount();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Create a new IHDPParameter object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;IHDPParameter parameter object.&amp;lt;/returns&amp;gt;&lt;br /&gt;        IHDPParameter CreateParameter();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a expression against the web server and return the number of results.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Number of results determined by the expression.&amp;lt;/returns&amp;gt;&lt;br /&gt;        int ExecuteNonQuery(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and does not read the response stream.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;True is the command executed with success otherwise false.&amp;lt;/returns&amp;gt;&lt;br /&gt;        bool Execute();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;True is the command executed with success otherwise false.&amp;lt;/returns&amp;gt;&lt;br /&gt;        bool Execute(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Returns the underlying http response stream.&amp;lt;/returns&amp;gt;&lt;br /&gt;        Stream ExecuteStream(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Closes the http response object..&lt;br /&gt;        /// Usable only with ExecuteStream method.  &lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        void CloseResponse();&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and return a XPathNavigator object used to navigate thru the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;XPathNavigator object used to navigate thru the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        XPathNavigator ExecuteNavigator(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and return a IXPathNavigable object used to navigate thru the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;IXPathNavigable object used to navigate thru the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        IXPathNavigable ExecuteDocument(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a xpath expression and return a IXPathNavigable object used to navigate thru query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;XPath expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;IXPathNavigable object used to navigate thru query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        IXPathNavigable ExecuteDocument(string expression, bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and return a byte[] object which contains the binary query result. Used when querying binary content from web server (E.g: PDF files).&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Byte array object which contains the binary query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        byte[] ExecuteBinary(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and return a byte[] object which contains the binary query result. Used when querying binary content from web server (E.g: PDF files).&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="boundaryLimit"&amp;gt;Specify the limit of the buffer which must be read.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;Byte array object which contains the binary query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        byte[] ExecuteBinary(int boundaryLimit, bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        ///  Execute a query against the web server and return a string object which contains the representation of the binary query result. Used when querying binary content from web server (E.g: PDF files).&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String object which contains the representation of the binary query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string ExecuteBinaryConversion(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server and return a string object which contains the representation of the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String object which contains the representation of the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string ExecuteString(bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a xpath expression and return a string object which contains the representation of the query result value.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;XPath expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String object which contains the representation of the query result value.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string ExecuteValue(string expression, bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a regular expression and return a string object which contains the representation of the query result value.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;Regular expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="isRegEx"&amp;gt;Specify the a regular expression is used, it must always be to true.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String object which contains the representation of the query result value.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string ExecuteValue(string expression, bool clearParams, bool isRegEx);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a regular expression and return a List object which contains the representation of the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;Regular expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="isRegEx"&amp;gt;Specify the a regular expression is used, it must always be to true.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;List object which contains the representation of the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        List&amp;lt;string&amp;gt; ExecuteCollection(string expression, bool clearParams, bool isRegEx);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a xpath expression and return a List object which contains the representation of the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;XPath expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;List object which contains the representation of the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        List&amp;lt;string&amp;gt; ExecuteCollection(string expression, bool clearParams);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a regular expression and return a string array object which contains the representation of the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;Regular expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="isRegEx"&amp;gt;Specify the a regular expression is used, it must always be to true.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String array object which contains the representation of the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string[] ExecuteArray(string expression, bool clearParams, bool isRegEx);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Execute a query against the web server, on query reult it will apply a xpath expression and return a string array object which contains the representation of the query result.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="expression"&amp;gt;XPath expression.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="clearParams"&amp;gt;Specify if the parameters collection should be cleared after the query is executed.&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;returns&amp;gt;String array object which contains the representation of the query result.&amp;lt;/returns&amp;gt;&lt;br /&gt;        string[] ExecuteArray(string expression, bool clearParams);&lt;br /&gt;        #endregion&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h2&gt;HDPCache, HDPCacheDefinition, HDPCacheObject and HDPCacheStorage&lt;/h2&gt;&lt;p&gt;HDPCache, HDPCacheDefinition, HDPCacheObject and HDPCacheStorage are the classes which handle the cache. I will not insist on this subject since is not so important in this case. If you like you can study those classes in more detail by yourself. I think the code comments will help you to grasp they purpose and functionality quite fast.&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;The class HDPCacheObject is straight forward; it contains a set of properties which define the cache behavior. Here are its properties:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;StorageActiveUntil&lt;/i&gt;  (defines the date until the cache is considered to be valid)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;MemorySizeLimit&lt;/i&gt; (imposes a memory size limit of the cache)&lt;/li&gt;&lt;li&gt;&lt;i&gt;ObjectsNumberLimit&lt;/i&gt; (imposes a objects number limit on the cache)&lt;/li&gt;&lt;li&gt;&lt;i&gt;UseStorage&lt;/i&gt; (defines if the cache should be persisted on disk)&lt;/li&gt;&lt;li&gt;&lt;i&gt;RetrieveFromStorage&lt;/i&gt; (defines if a specific value should be searched on the persisted cache on disk)&lt;/li&gt;&lt;li&gt;&lt;i&gt;RealtimePersistance&lt;/i&gt; (defines if the cache will be persisted on disk in real time, once a new value has been added to it)&lt;/li&gt;&lt;li&gt;&lt;i&gt;StorageName&lt;/i&gt; (defines the file name of the posited cache on disk)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The class HDPCacheObject is just a value pair set of properties and a time stamp field used to identify the cached object age. The caching system works in a very clear and simple manner. When a web resource is queried the URL of it represents the cache object key and the result of the query represents the cache object value. If the cache is activated when using HDPCommand object to query web resources each query URL and response content are stored in the memory cache. If same web resource is queried again using same URL the HTTP request is not performed and response content is retrieved from the memory cache. There are extra options defined in HDPCacheDefinition which allow you to control how the cache behaves. For example if you impose a cache memory limit of 1024Kb then every time a new value is added to the cache its memory footprint is calculated. In case the imposed limit is exceeded, based on other behavior definitions the cache content is either stored on disk or either deleted. I would like to mention that MemorySizeLimit and ObjectsNumberLimit are mutual exclusive. So if you define a value for the MemorySizeLimit greater than 0 then there is no point to define a value for ObjectsNumberLimit because it will not be taken into consideration and vice versa.&lt;br /&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;HDPCacheDefinition Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt;    ///&amp;lt;summary&amp;gt;&lt;br /&gt;    /// Defines the cache options.&lt;br /&gt;    ///&amp;lt;/summary&amp;gt;&lt;br /&gt;    public class HDPCacheDefinition&lt;br /&gt;    {&lt;br /&gt;        #region Public Variables&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies the date until which the cache is valid.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public DateTime StorageActiveUntil = DateTime.Now.AddDays(1);&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies the limit size of the cache memory.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public long MemorySizeLimit;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies the limit number of objects which can be stored in the cache.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public int ObjectsNumberLimit = 10000;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies if disk storage will be used.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool UseStorage = true;&lt;br /&gt;        &lt;br /&gt;        ///&amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies if the data should be retrieved from the disk storage.&lt;br /&gt;        ///&amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool RetrieveFromStorage;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies if the persistance of the cache on disk will be done in real time.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public bool RealtimePersistance;&lt;br /&gt;        &lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Specifies the name of the file of the disk storage.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string StorageName = "HttpDataProcessorCahe.che";&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;&lt;b&gt;HDPCacheObject Code&lt;/b&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace HttpData.Client&lt;br /&gt;{&lt;br /&gt;    /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Container for the cached data based on key value pair.&lt;br /&gt;    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;    [Serializable]&lt;br /&gt;    public class HDPCacheObject&lt;br /&gt;    {&lt;br /&gt;        #region Private Variables&lt;br /&gt;        private string key;&lt;br /&gt;        private object value;&lt;br /&gt;        private DateTime cacheDate;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Properties&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the cache object key.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public string Key&lt;br /&gt;        {&lt;br /&gt;            get { return key; }&lt;br /&gt;            set { key = value; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the cache object value.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public object Value&lt;br /&gt;        {&lt;br /&gt;            get { return value; }&lt;br /&gt;            set { this.value = value; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Get or set the cache object date.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public DateTime CacheDate&lt;br /&gt;        {&lt;br /&gt;            get { return cacheDate; }&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region .ctor&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPCacheObject object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        public HDPCacheObject()&lt;br /&gt;        {&lt;br /&gt;            cacheDate = DateTime.Now;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Instantiate a new HDPCacheObject object.&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="key"&amp;gt;Key for the cache object&amp;lt;/param&amp;gt;&lt;br /&gt;        /// &amp;lt;param name="value"&amp;gt;Value for the cache object&amp;lt;/param&amp;gt;&lt;br /&gt;        public HDPCacheObject(string key, object value)&lt;br /&gt;        {&lt;br /&gt;            this.key = key;&lt;br /&gt;            this.value = value;&lt;br /&gt;&lt;br /&gt;            cacheDate = DateTime.Now;&lt;br /&gt;        }&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Public Methods&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;        #region Private Methods&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Using the code&lt;/h2&gt;&lt;p&gt;I will provide a couple of examples so you can figure it out how things work. I consider this to be the best way to understand how the earth spins.&lt;br /&gt;Let us say for example that we would like to retrieve all Florida cities from the following page: http://www.stateofflorida.com/Portal/DesktopDefault.aspx?tabid=34.&lt;br /&gt;Here is the  code to achieve the above mentioned task.&lt;br /&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using HttpData.Client;&lt;br /&gt;&lt;br /&gt;namespace CityStates&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            private const string connectionUrl = "http://www.stateofflorida.com/Portal/DesktopDefault.aspx?tabid=34";&lt;br /&gt;&lt;br /&gt;     //Create a new instance of HDPCacheDefinition object.&lt;br /&gt;            HDPCacheDefinition cacheDefinition = new HDPCacheDefinition&lt;br /&gt;            {&lt;br /&gt;                UseStorage = false,&lt;br /&gt;                StorageActiveUntil = DateTime.Now,&lt;br /&gt;                ObjectsNumberLimit = 10000,&lt;br /&gt;                RealtimePersistance = false,&lt;br /&gt;                RetrieveFromStorage = false,&lt;br /&gt;         //We will not use a disk storage&lt;br /&gt;                StorageName = null&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            //Create a new instance of HDPConnection object.&lt;br /&gt;            //Pass as parameters the initial connection URL and the cache definition object.&lt;br /&gt;            HDPConnection connection = new HDPConnection(connectionUrl, cacheDefinition)&lt;br /&gt;            {&lt;br /&gt;                //Define the content type we would expect.&lt;br /&gt;                ContentType = HDPContentType.TEXT,&lt;br /&gt;                //We want to allow autoredirects&lt;br /&gt;                AutoRedirect = true,&lt;br /&gt;                //Do not perform more than 10 autoredirects&lt;br /&gt;                MaxAutoRedirects = 10,&lt;br /&gt;                //The user agent is FireFox 3&lt;br /&gt;                UserAgent = HDPAgents.FIREFOX_3,&lt;br /&gt;                //We do not want to use a proxy&lt;br /&gt;                Proxy = null // If you want to use a proxy: Proxy = new HDPProxy("http://127.0.0.1:999/"/*This is your proxy address and its port*/, "PROXY_USER_NAME", "PROXY_PASSWORD")&lt;br /&gt;            };&lt;br /&gt;            //Open the connection&lt;br /&gt;            connection.Open();&lt;br /&gt;&lt;br /&gt;            //Create a new instance of HDPCommand object.&lt;br /&gt;            //Pass as parameter the HDPConnection object.&lt;br /&gt;            HDPCommand command = new HDPCommand(connection)&lt;br /&gt;            {&lt;br /&gt;                //Activate the memory cache for fast access on same  web resource multiple times&lt;br /&gt;                ActivatePool = true,&lt;br /&gt;                //We will perform an GET action&lt;br /&gt;                CommandType = HDPCommandType.Get,&lt;br /&gt;                //Set the time out period&lt;br /&gt;                CommandTimeout = 60000,&lt;br /&gt;                //Use MSHTML library instead of HtmlAgilityPack (if the value is false then HtmlAgilityPack would be used)&lt;br /&gt;                UseMsHtml = true&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            //Execute the query on the web resource. The received HTTPWebResponse content will be converted to XML and the XPath expression will be executed.&lt;br /&gt;            //The method will return the list of Florida state cities.&lt;br /&gt;            List&lt;string&gt; cities = command.ExecuteCollection("//ul/li/b//text()[normalize-space()]", true);&lt;br /&gt;   &lt;br /&gt;     foreach (string city in cities)&lt;br /&gt;         Console.WriteLine(city);&lt;br /&gt;   &lt;br /&gt;     connection.Close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here is a different example now. Let us say that we would like to login on Linkedin network using an account user name and password. Here is the code to achieve that.&lt;br /&gt;&lt;br /&gt;&lt;pre lang="CS"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using HttpData.Client;&lt;br /&gt;&lt;br /&gt;namespace CityStates&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            private const string connectionUrl = "https://www.linkedin.com/secure/login?trk=hb_signin";&lt;br /&gt;&lt;br /&gt;     //Create a new instance of HDPCacheDefinition object.&lt;br /&gt;            HDPCacheDefinition cacheDefinition = new HDPCacheDefinition&lt;br /&gt;            {&lt;br /&gt;                UseStorage = false,&lt;br /&gt;                StorageActiveUntil = DateTime.Now,&lt;br /&gt;                ObjectsNumberLimit = 10000,&lt;br /&gt;                RealtimePersistance = false,&lt;br /&gt;                RetrieveFromStorage = false,&lt;br /&gt;         //We will not use a disk storage&lt;br /&gt;                StorageName = null&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            //Create a new instance of HDPConnection object.&lt;br /&gt;            //Pass as parameters the initial connection URL and the cache definition object.&lt;br /&gt;            HDPConnection connection = new HDPConnection(connectionUrl, cacheDefinition)&lt;br /&gt;            {&lt;br /&gt;                //Define the content type we would expect.&lt;br /&gt;                ContentType = HDPContentType.TEXT,&lt;br /&gt;                //We want to allow autoredirects&lt;br /&gt;                AutoRedirect = true,&lt;br /&gt;                //Do not perform more than 10 autoredirects&lt;br /&gt;                MaxAutoRedirects = 10,&lt;br /&gt;                //The user agent is FireFox 3&lt;br /&gt;                UserAgent = HDPAgents.FIREFOX_3,&lt;br /&gt;                //We do not want to use a proxy&lt;br /&gt;                Proxy = null // If you want to use a proxy: Proxy = new HDPProxy("http://127.0.0.1:999/"/*This is your proxy address and its port*/, "PROXY_USER_NAME", "PROXY_PASSWORD")&lt;br /&gt;            };&lt;br /&gt;            //Open the connection&lt;br /&gt;            connection.Open();&lt;br /&gt;&lt;br /&gt;            //Create a new instance of HDPCommand object.&lt;br /&gt;            //Pass as parameter the HDPConnection object.&lt;br /&gt;            HDPCommand command = new HDPCommand(connection)&lt;br /&gt;            {&lt;br /&gt;                //Activate the memory cache for fast access on same  web resource multiple times&lt;br /&gt;                ActivatePool = true,&lt;br /&gt;                //We will perform an GET action&lt;br /&gt;                CommandType = HDPCommandType.Get,&lt;br /&gt;                //Set the time out period&lt;br /&gt;                CommandTimeout = 60000,&lt;br /&gt;                //Use HtmlAgilityPack (if the value is true then MSHTML would be used)&lt;br /&gt;                UseMsHtml = false&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            //Define the query parameters used in the POST action.&lt;br /&gt;            //The actual parameter name used by a browser to authenticate you on Linkedin is without '@' sign.&lt;br /&gt;            //Use a HTTP request analyzer and you will notice the difference.&lt;br /&gt;            //This is how the actual POST body will look like: csrfToken="ajax:-3801133150663455891"&amp;session_key="YOUR_EMAIL@gmail.com"&amp;session_password="YOUR_PASSWORD"&amp;session_login="Sign+In"&amp;session_login=""&amp;session_rikey=""&lt;br /&gt;            HDPParameterCollection parameters = new HDPParameterCollection();&lt;br /&gt;            HDPParameter pToken = new HDPParameter("@csrfToken", "ajax:-3801133150663455891");&lt;br /&gt;            HDPParameter pSessionKey = new HDPParameter("@session_key", "YOUR_EMAIL@gmail.com");&lt;br /&gt;            HDPParameter pSessionPass = new HDPParameter("@session_password", "YOUR_PASSWORD");&lt;br /&gt;            HDPParameter pSessionLogin = new HDPParameter("@session_login", "Sign+In");&lt;br /&gt;            HDPParameter pSessionLogin_ = new HDPParameter("@session_login", "");&lt;br /&gt;            HDPParameter pSessionRiKey = new HDPParameter("@session_rikey", "");&lt;br /&gt;&lt;br /&gt;            parameters.Add(pToken);&lt;br /&gt;            parameters.Add(pSessionKey);&lt;br /&gt;            parameters.Add(pSessionPass);&lt;br /&gt;            parameters.Add(pSessionLogin);&lt;br /&gt;            parameters.Add(pSessionLogin_);&lt;br /&gt;            parameters.Add(pSessionRiKey);&lt;br /&gt;&lt;br /&gt;     //If everything went ok then linkeding will ask us to redirect (unfortunately autoredirect doesn't work in this case).&lt;br /&gt;            //Get the manual redirect URL value. &lt;br /&gt;     string value = command.ExecuteValue("//a[@id='manual_redirect_link']/@href", true);&lt;br /&gt;            if (value != null &amp;&amp; String.Compare(value, "http://www.linkedin.com/home") == 0)&lt;br /&gt;            {&lt;br /&gt;                command.Connection.ConnectionURL = value;&lt;br /&gt;                command.CommandType = HDPCommandType.Get;&lt;br /&gt;&lt;br /&gt;    //Using the manual redirect URL, check if the opened web page contains the welcome message.&lt;br /&gt;                //If it does contain the message, then we are in.&lt;br /&gt;                string content = command.ExecuteString("//title[contains(.,'Welcome,')]", true);&lt;br /&gt;&lt;br /&gt;                if (content.Length &gt; 0)&lt;br /&gt;                    Console.WriteLine(content);&lt;br /&gt;    else&lt;br /&gt;     Console.WriteLine("Login failed!");&lt;br /&gt;            }&lt;br /&gt;   &lt;br /&gt;   connection.Close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;On your sample project please add the following app.config content if you are going to use MSHTML.&lt;br /&gt;&lt;pre lang="CS"&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;  &amp;lt;appSettings&amp;gt;&lt;br /&gt;    &amp;lt;add key="LogFilePath" value="..\Log\My-Log.txt"/&amp;gt;&lt;br /&gt;    &amp;lt;add key="HtmlTagsPath" value="HtmlTags.txt"/&amp;gt;&lt;br /&gt;    &amp;lt;add key="AttributesTagsPath" value="HtmlAttributes.txt"/&amp;gt;&lt;br /&gt;  &amp;lt;/appSettings&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Downloads and Source Code&lt;/h2&gt;&lt;p&gt;You can download the source code of the library and a sample project from &lt;a href="http://www.codeproject.com/KB/library/httpdataclient.aspx"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2288409657306127020?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2288409657306127020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2288409657306127020' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2288409657306127020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2288409657306127020'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2011/07/http-data-client-abstract-way-of.html' title='HTTP Data Client - An abstract way of web scraping'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-6418429609722885832</id><published>2011-05-23T06:13:00.000-07:00</published><updated>2011-05-23T06:14:12.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>ASP.NET/IIS7 Custom HTTP Handlers</title><content type='html'>It's been a while since I had to write custom HTTP handlers. One of my current projects required resourses to be provided using a custom HTTP handler. That was quite an easy job and for sure you will find many detailed posts related to HTTP handlers development under .NET. The only thing which gave me some headaches was the deployment of such a handler. There is a different approach under IIS7 (integrated mode) compared with IIS6. Here are the required steps:&lt;br /&gt;&lt;br /&gt;1. From IIS management interface create a web application which points to the root folder where you have your HTTP handler. Please note that the actual DLL (assembly) should be located under root directory in a "bin" folder (e.g.: C:\MyHandlerRootFolder\bin\myhandler.dll). Please be sure that you are configuring your web application to run under the correct application pool. So if your HTTP handler assembly is compiled with .NET 4.0 be sure that the web application is configured to run under ASP.NET v4.0 application pool. My issue was caused by a missconfiguration of the HTTP handler. Due to this, everyt time when I was trying to access the handler I was getting the following exception: &lt;strong&gt;"Could not load type 'MyHandlerClass'"&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;2. In the web.config file which should be hosted in your web application root folder add (or change if it is the case) the following configuration elements:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;system.webServer&amp;gt;&lt;br /&gt;    &amp;lt;handlers&amp;gt;&lt;br /&gt;      &amp;lt;add verb="*" path="*.myextension"&lt;br /&gt;        name="MyHttpHandler"&lt;br /&gt;        type=" MyFullNamespace.MyHandlerClass, MyFullHttpHandlerAssemblyName"/&amp;gt;&lt;br /&gt;    &amp;lt;/handlers&amp;gt;&lt;br /&gt;  &amp;lt;/system.webServer&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's all, now you handler should be up and running.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-6418429609722885832?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/6418429609722885832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=6418429609722885832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6418429609722885832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6418429609722885832'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2011/05/aspnetiis7-custom-http-handlers.html' title='ASP.NET/IIS7 Custom HTTP Handlers'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-3307218864797872674</id><published>2010-09-09T08:55:00.000-07:00</published><updated>2010-09-09T08:56:13.291-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS SQL'/><title type='text'>Get Table Structure Description</title><content type='html'>Use the following script to get the structure description of a specific table:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;SELECT&lt;br /&gt;clmns.name AS [Name],&lt;br /&gt;usrt.name AS [DataType],&lt;br /&gt;ISNULL(baset.name, N'') AS [SystemType],&lt;br /&gt;CAST(CASE WHEN baset.name IN (N'nchar', N'nvarchar') AND clmns.max_length &lt;&gt; -1 THEN clmns.max_length/2 ELSE clmns.max_length END AS int) AS [Length],&lt;br /&gt;CAST(clmns.precision AS int) AS [NumericPrecision]&lt;br /&gt;FROM sys.tables AS tbl&lt;br /&gt;INNER JOIN sys.all_columns AS clmns ON clmns.object_id = tbl.object_id&lt;br /&gt;LEFT OUTER JOIN sys.types AS usrt ON usrt.user_type_id = clmns.user_type_id&lt;br /&gt;LEFT OUTER JOIN sys.types AS baset ON baset.user_type_id = clmns.system_type_id and &lt;br /&gt;baset.user_type_id = baset.system_type_id&lt;br /&gt;WHERE tbl.name='YOURTABLENAME' and SCHEMA_NAME(tbl.schema_id)=N'dbo'&lt;br /&gt;ORDER BY clmns.column_id ASC&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The source of the script is: &lt;a href="http://www.geekzilla.co.uk/ViewF3E9658C-7B7A-472C-BE4A-5C25CD26C0E8.htm"&gt;www.geekzilla.co.uk&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-3307218864797872674?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/3307218864797872674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=3307218864797872674' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3307218864797872674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3307218864797872674'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2010/09/get-table-structure-description.html' title='Get Table Structure Description'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-6121312601706549756</id><published>2010-07-09T00:35:00.000-07:00</published><updated>2010-07-09T00:40:05.127-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XSS'/><title type='text'>Monster Website and XSS</title><content type='html'>&lt;span style="color: red;"&gt;&lt;b&gt;Note:&lt;/b&gt;&lt;span style="font-family: times new roman;"&gt;All websites owners where informed more than a week ago about the vulnerabilities I have "accidentally" found.&lt;br /&gt;The purpose of this information is educational only!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: black;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the last week I was playing with some websites trying to find out if they are exposed to any XSS attacks.&lt;br /&gt;Among those websites was also &lt;a href="http://www.monster.com/"&gt;www.monster.com&lt;/a&gt;. I know that in the past years Monster had big issues regarding security. They were hacked three times and a huge amount of data was stolen back then. Well...what I have discovered is that they still have vulnerabilities, specially XSS ones. Their filtering system has flaws, considering that it will remove with success &lt;b&gt;&amp;lt;script&amp;gt;, &amp;lt;object&amp;gt;, &amp;lt;iframe&amp;gt;&lt;/b&gt; tags but it fails on removing &lt;b&gt;&amp;lt;img&amp;gt;, &amp;lt;html&amp;gt;, &amp;lt;body&amp;gt;&lt;/b&gt; and &lt;b&gt;&amp;lt;?import&amp;gt;&lt;/b&gt;.&lt;br /&gt;Based on the above mentioned things I created a "Job Seeker" account with a fake CV and in the content of that CV I have inserted the following script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;HTML&amp;gt;&amp;lt;BODY&amp;gt;&amp;lt;?xml:namespace prefix='t' ns='urn:schemas-microsoft-com:time'&amp;gt;&amp;lt;?import namespace='t' implementation='#default#time2'&amp;gt;&amp;lt;t:set attributeName='innerHTML' to='XSS&amp;amp;lt;script DEFER&amp;amp;gt;(function(){alert("Here you can do very nasty things!")})()&amp;amp;lt;/script&amp;amp;gt;'&amp;gt;&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When I previewed the CV...voila, the alert dialog appeared. In this way I was able to hijack the user session by making use of cookies and extract any information I wanted. The most interesting thing is that in this way some one can hijack the session of any "Employer" which is going to take a look at the CV and with custom "POST" and "GET" commands, infest the job posts of the "Employer" with similar malicious code. In this way a real web could be created starting just from one malicious CV.&lt;br /&gt;&lt;br /&gt;There are also issues on Monster website in the section which allows you to upload your CV. You have the option to upload text files and Microsoft Word documents. In a text file I have inserted and &lt;b&gt;&amp;lt;img&amp;gt;&lt;/b&gt; tag with an &lt;b&gt;'onload'&lt;/b&gt; event. When the content was rendered on the page and the invisible image was loaded and the 'onload' event was triggered I was able to execute any JavaScript code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-6121312601706549756?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/6121312601706549756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=6121312601706549756' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6121312601706549756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6121312601706549756'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2010/07/monster-website-and-xss.html' title='Monster Website and XSS'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-8287377787623422867</id><published>2009-12-17T10:55:00.000-08:00</published><updated>2009-12-17T10:57:13.071-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>IIS - The worker process failed to preload .Net Runtime version</title><content type='html'>When I moved to windows 7 (clean install) I have done a mistake regarding the order in which I have set up the development environment. First, by mistake, I have installed Visual Studio 2008, .NET framework 3.5 and at the end .NET framework 2.0.*. This caused a big issue on IIS 7. Every virtual directory or application created on IIS caused an error on the application pool. I have tried different application pools but got same error: &lt;b&gt;“The worker process failed to preload .Net Runtime version v2.0.40607”&lt;/b&gt; and &lt;b&gt;“The worker process failed to initialize correctly and therefore could not be started.  The data is the error.”&lt;/b&gt;.  After some searched over the internet I have found a solution &lt;a href="http://forums.iis.net/t/1053655.aspx"&gt;HERE&lt;/a&gt;. The fix consists in removing from Windows\Microsoft.Net\Framework of any folder like v2.0.* which is different than v2.0.50727.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-8287377787623422867?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/8287377787623422867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=8287377787623422867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8287377787623422867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8287377787623422867'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/iis-worker-process-failed-to-preload.html' title='IIS - The worker process failed to preload .Net Runtime version'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2818125007944561208</id><published>2009-12-14T01:41:00.000-08:00</published><updated>2010-11-17T23:32:29.041-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript ArrayList, JavaScript Dictionay, JavaScript Strong Type Array</title><content type='html'>I always felt the need to have in JavaScript a more robust set of collections, like those from .NET: ArrayList, Dictionary, strong typed collections. So, some time ago I have decided to implement them everything having as base the JavaScript array object. The code I assume is self explanatory except the class definition which makes use of the custom pattern presented earlier on this blog. It shouldn’t matter too much because it’s very easy for you to implement same functionality using any desired inheritance pattern, like Base2 and Prototype. I think it’s a matter of copy/paste in most cases.  You will notice that I didn’t use any special tricks in the code, just the well known JavaScript array object methods and properties. I did not use closures in this case so the ‘_array ‘ property it is consider private base on ‘_’ notation. Using closures eats up more resources so I preferred to avoid them in his case. If you have any questions feel free to post them and I’ll try to give you an answer as fast as possible. You can download the source from &lt;a href="http://38.107.67.35/jsmugen.zip"&gt;HERE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if (typeof (MG) == 'undefined')&lt;br /&gt;    throw ("MG.Core.js is required!");&lt;br /&gt;if (typeof (MG.Collections) == 'undefined')&lt;br /&gt;    MG.Collections = {};&lt;br /&gt;&lt;br /&gt;MG.Collections.IComparer = function() {&lt;br /&gt;    throw ("IComparer is an interface. Interfaces can't be instantiated directly!");&lt;br /&gt;};&lt;br /&gt;MG.Collections.IComparer.prototype = {&lt;br /&gt;    Compare: function(object1, object2) { }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// IList interface definition.&lt;br /&gt;/******************************************************************************/&lt;br /&gt;MG.Collections.IList = function() {&lt;br /&gt;    throw ("IList is an interface. Interfaces can't be instantiated directly!");&lt;br /&gt;};&lt;br /&gt;MG.Collections.IList.prototype = {&lt;br /&gt;    ___name: "IList",&lt;br /&gt;    Add: function(object) { },&lt;br /&gt;    Clear: function() { },&lt;br /&gt;    Contains: function(object) { },&lt;br /&gt;    Remove: function(object) { },&lt;br /&gt;    IsReadOnly: Boolean,&lt;br /&gt;    Item: function(index) { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// ICollection interface definition.&lt;br /&gt;/******************************************************************************/&lt;br /&gt;MG.Collections.ICollection = function() {&lt;br /&gt;    throw ("ICollection is an interface. Interfaces can't be instantiated directly!");&lt;br /&gt;};&lt;br /&gt;MG.Collections.ICollection.prototype = {&lt;br /&gt;    ___name: "ICollection",&lt;br /&gt;    CopyTo: function(array, arrayIndex) { },&lt;br /&gt;    Count: function() { }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// IDictionary interface definition.&lt;br /&gt;/******************************************************************************/&lt;br /&gt;MG.Collections.IDictionary = function() {&lt;br /&gt;    throw ("IDictionary is an interface. Interfaces can't be instantiated directly!");&lt;br /&gt;};&lt;br /&gt;MG.Collections.IDictionary.prototype = {&lt;br /&gt;    ___name: "IDictionary",&lt;br /&gt;    Add: function(key, value) { },&lt;br /&gt;    Clear: function() { },&lt;br /&gt;    Contains: function(key) { },&lt;br /&gt;    Remove: function(key) { },&lt;br /&gt;    IsReadOnly: Boolean,&lt;br /&gt;    Item: function(key) { }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// ArrayList class definition.&lt;br /&gt;// Implements interfaces: ICollection&lt;br /&gt;/******************************************************************************/&lt;br /&gt;&lt;br /&gt;MG.Collections.ArrayList = MG.Class.Create(&lt;br /&gt;                {&lt;br /&gt;                    _array: null,&lt;br /&gt;                    IsReadOnly: Boolean,&lt;br /&gt;&lt;br /&gt;                    constructor: function() {&lt;br /&gt;                        this._array = [];&lt;br /&gt;                        this.IsReadOnly = false;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Add: function(object) {&lt;br /&gt;                        if (!this.IsReadOnly)&lt;br /&gt;                            this._array.push(object);&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Clear: function() {&lt;br /&gt;                        if (!this.IsReadOnly)&lt;br /&gt;                            this._array = [];&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Contains: function(object) {&lt;br /&gt;                        for (var index = 0; index &lt; this._array.length; index++) {&lt;br /&gt;                            if (this._array[index] == object)&lt;br /&gt;                                return true;&lt;br /&gt;                        }&lt;br /&gt;                        return false;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    CopyTo: function(array, arrayIndex) {&lt;br /&gt;                        if (!array)&lt;br /&gt;                            throw ("Destination array is null!");&lt;br /&gt;                        if (arrayIndex &lt; 0 || arrayIndex &gt; array.length)&lt;br /&gt;                            throw ("Index of destination array out of bound! Index value is: " + arrayIndex);&lt;br /&gt;&lt;br /&gt;                        for (var i = this._array.length - 1; i &gt;= 0; i--)&lt;br /&gt;                            array.splice(arrayIndex, 0, this._array[i]);&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Remove: function(object) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            for (var index = 0; index &lt; this._array.length; index++) {&lt;br /&gt;                                if (this._array[index] == object)&lt;br /&gt;                                    this._array.splice(index, 1);&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Count: function() {&lt;br /&gt;                        return this._array.length;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Item: function(index) {&lt;br /&gt;                        if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                            throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;&lt;br /&gt;                        return this._array[index];&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    IndexOf: function(object) {&lt;br /&gt;                        for (var index = 0; index &lt; this._array.length; index++) {&lt;br /&gt;                            if (this._array[index] == object)&lt;br /&gt;                                return index;&lt;br /&gt;                        }&lt;br /&gt;                        return -1;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    LastIndexOf: function(object) {&lt;br /&gt;                        var lastIndex = -1;&lt;br /&gt;                        for (var index = 0; index &lt; this._array.length; index++) {&lt;br /&gt;                            if (this._array[index] == object)&lt;br /&gt;                                lastIndex = index;&lt;br /&gt;                        }&lt;br /&gt;                        return lastIndex;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    RemoveAt: function(index) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                                throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;&lt;br /&gt;                            this._array.splice(index, 1);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    RemoveRange: function(index, Count) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                                throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;                            if (Count &lt; 0 || (Count + index) &gt; this._array.length)&lt;br /&gt;                                throw ("Range out of bound! Range value is: " + Count);&lt;br /&gt;&lt;br /&gt;                            this._array.splice(index, Count);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    InsertAt: function(index, object) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                                throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;&lt;br /&gt;                            this._array.splice(index, 0, object);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    InsertRange: function(index, _ICollection) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                                throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;&lt;br /&gt;                            var _newarray = _ICollection.GetRange(0, _ICollection.Count());&lt;br /&gt;&lt;br /&gt;                            for (var i = 0; i &lt; _newarray.length; i++)&lt;br /&gt;                                this.InsertAt(index, _newarray[i]);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    GetRange: function(index, Count) {&lt;br /&gt;                        if (index &lt; 0 || index &gt;= this._array.length)&lt;br /&gt;                            throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;                        if (Count &lt; 0 || (Count + index) &gt; this._array.length)&lt;br /&gt;                            throw ("Range out of bound! Range value is: " + Count);&lt;br /&gt;&lt;br /&gt;                        var arrayList = new ArrayList();&lt;br /&gt;                        arrayList._array = this._array.slice(index, (Count + index));&lt;br /&gt;                        return arrayList;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Reverse: function() {&lt;br /&gt;                        if (!this.IsReadOnly)&lt;br /&gt;                            this._array.reverse();&lt;br /&gt;                        else&lt;br /&gt;                            throw ("ArrayList is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Sort: function() {&lt;br /&gt;                        this._array.sort();&lt;br /&gt;                    }&lt;br /&gt;                }, null, [MG.Collections.ICollection]);&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// DictionaryEntry class definition.&lt;br /&gt;/******************************************************************************/&lt;br /&gt;MG.Collections.DictionaryEntry = MG.Class.Create(&lt;br /&gt;                    {&lt;br /&gt;                        key: null,&lt;br /&gt;                        value: null,&lt;br /&gt;                        constructor: function(key, value) {&lt;br /&gt;                            this.key = key;&lt;br /&gt;                            this.value = value;&lt;br /&gt;                        }&lt;br /&gt;                    });&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// Dictionary class definition.&lt;br /&gt;// Implements interfaces: IDictionary&lt;br /&gt;//                        ICollection&lt;br /&gt;/******************************************************************************/&lt;br /&gt;                    MG.Collections.Dictionary = MG.Class.Create(&lt;br /&gt;                {&lt;br /&gt;                    _dictionary: null,&lt;br /&gt;                    IsReadOnly: Boolean,&lt;br /&gt;&lt;br /&gt;                    constructor: function() {&lt;br /&gt;                        this._dictionary = [];&lt;br /&gt;                        this.IsReadOnly = false;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Add: function(key, value) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (this.Contains(key))&lt;br /&gt;                                throw ("Dictionary does not allow duplicate keys!");&lt;br /&gt;&lt;br /&gt;                            var dicEntry = new MG.Collections.DictionaryEntry(key, value);&lt;br /&gt;                            this._dictionary.push(dicEntry);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Clear: function() {&lt;br /&gt;                        if (!this.IsReadOnly)&lt;br /&gt;                            this._dictionary = [];&lt;br /&gt;                        else&lt;br /&gt;                            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Contains: function(key) {&lt;br /&gt;                        for (var index = 0; index &lt; this._dictionary.length; index++) {&lt;br /&gt;                            if (this._dictionary[index].key == key)&lt;br /&gt;                                return true;&lt;br /&gt;                        }&lt;br /&gt;                        return false;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Remove: function(key) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            for (var index = 0; index &lt; this._dictionary.length; index++) {&lt;br /&gt;                                if (this._dictionary[index].key == key)&lt;br /&gt;                                    this._dictionary.splice(index, 1);&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Item: function(key) {&lt;br /&gt;                        if (!key)&lt;br /&gt;                            throw ("Invalid key! Key value is: " + key);&lt;br /&gt;&lt;br /&gt;                        for (var index = 0; index &lt; this._dictionary.length; index++) {&lt;br /&gt;                            if (this._dictionary[index].key == key)&lt;br /&gt;                                return this._dictionary[index].value;&lt;br /&gt;                        }&lt;br /&gt;                        return null;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    CopyTo: function(array, arrayIndex) {&lt;br /&gt;                        if (!array)&lt;br /&gt;                            throw ("Destination array is null!");&lt;br /&gt;                        if (arrayIndex &lt; 0 || arrayIndex &gt; array.length)&lt;br /&gt;                            throw ("Index of destination array out of bound! Index value is: " + arrayIndex);&lt;br /&gt;&lt;br /&gt;                        for (var i = this._dictionary.length - 1; i &gt;= 0; i--)&lt;br /&gt;                            array.splice(arrayIndex, 0, this._dictionary[i]);&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Count: function() {&lt;br /&gt;                        return this._dictionary.length;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Keys: function() {&lt;br /&gt;                        var keys = [];&lt;br /&gt;                        for (var index = 0; index &lt; this._dictionary.length; index++)&lt;br /&gt;                            keys.push(this._dictionary[index].key);&lt;br /&gt;&lt;br /&gt;                        return keys.reverse();&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Values: function() {&lt;br /&gt;                        var values = [];&lt;br /&gt;                        for (var index = 0; index &lt; this._dictionary.length; index++)&lt;br /&gt;                            values.push(this._dictionary[index].value);&lt;br /&gt;&lt;br /&gt;                        return values.reverse();&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    IndexOf: function(key) {&lt;br /&gt;                        var keys = [];&lt;br /&gt;                        for (var index = 0; index &lt; this._dictionary.length; index++) {&lt;br /&gt;                            if (this._dictionary[index].key == key)&lt;br /&gt;                                return index;&lt;br /&gt;                        }&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    InsertAt: function(index, key, value) {&lt;br /&gt;                        if (!this.IsReadOnly) {&lt;br /&gt;                            if (index &lt; 0 || index &gt;= this._dictionary.length)&lt;br /&gt;                                throw ("Index out of bound! Index value is: " + index);&lt;br /&gt;&lt;br /&gt;                            var dicEntry = new MG.Collections.DictionaryEntry(key, value);&lt;br /&gt;                            this._dictionary.splice(index, 0, dicEntry);&lt;br /&gt;                        }&lt;br /&gt;                        else&lt;br /&gt;                            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                    Reverse: function() {&lt;br /&gt;                        if (!this.IsReadOnly)&lt;br /&gt;                            this._dictionary.reverse();&lt;br /&gt;                        else&lt;br /&gt;                            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;                    }&lt;br /&gt;                }, null, [MG.Collections.IDictionary, MG.Collections.ICollection]);&lt;br /&gt;&lt;br /&gt;/******************************************************************************/&lt;br /&gt;// Comparer class definition.&lt;br /&gt;// Implements interfaces: IComparer&lt;br /&gt;/******************************************************************************/&lt;br /&gt;MG.Collections.Comparer = MG.Class.Create({&lt;br /&gt;    constructor: function() { },&lt;br /&gt;    Compare: function(object1, object2) {&lt;br /&gt;        var result = false;&lt;br /&gt;        var type = typeof object1;&lt;br /&gt;        if (type !== typeof object2)&lt;br /&gt;            throw ("Object 'object1' doesn't have same type as object 'object2'!");&lt;br /&gt;        else if (type === "object") {&lt;br /&gt;            switch (object1.constructor) {&lt;br /&gt;                case Array:&lt;br /&gt;                    {&lt;br /&gt;                        if (object1.length === object2.length) {&lt;br /&gt;                            for (var index = 0; index &lt; object1.length; index++) {&lt;br /&gt;                                result = this.Compare(object1[index], object2[index]);&lt;br /&gt;                                if (!result)&lt;br /&gt;                                    break;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;                case Dictionary:&lt;br /&gt;                    {&lt;br /&gt;                        if (object1.Count() === object2.Count()) {&lt;br /&gt;                            var keys = object1.Keys();&lt;br /&gt;                            for (var index = 0; index &lt; keys.length; index++) {&lt;br /&gt;                                if (object2.Contains(keys[index])) {&lt;br /&gt;                                    result = this.Compare(object1.Item(keys[index]),&lt;br /&gt;                                                                                        object2.Item(keys[index]));&lt;br /&gt;&lt;br /&gt;                                    if (!result)&lt;br /&gt;                                        break;&lt;br /&gt;                                }&lt;br /&gt;                                else {&lt;br /&gt;                                    result = false;&lt;br /&gt;                                    break;&lt;br /&gt;                                }&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;                case ArrayList:&lt;br /&gt;                    {&lt;br /&gt;                        if (object1.Count() === object2.Count()) {&lt;br /&gt;                            for (var index = 0; index &lt; object1.Count(); index++) {&lt;br /&gt;                                result = this.Compare(object1.Item(index), object2.Item(index));&lt;br /&gt;&lt;br /&gt;                                if (!result)&lt;br /&gt;                                    break;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;                default:&lt;br /&gt;                    {&lt;br /&gt;                        if (object1 === object2)&lt;br /&gt;                            result = true;&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        switch (type) {&lt;br /&gt;            case "string":&lt;br /&gt;            case "number":&lt;br /&gt;            case "boolean":&lt;br /&gt;                if (object1 === object2)&lt;br /&gt;                    result = true;&lt;br /&gt;                break;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return result;&lt;br /&gt;    }&lt;br /&gt;}, null, [MG.Collections.IComparer]);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;MG.Collections.TypedCollection = MG.Class.Create({&lt;br /&gt;    Type: null,&lt;br /&gt;    Browser: null,&lt;br /&gt;&lt;br /&gt;    constructor: function(type) {&lt;br /&gt;        var _type = typeof type;&lt;br /&gt;        if (_type &amp;&amp; _type === "function")&lt;br /&gt;            this.Type = type;&lt;br /&gt;        else&lt;br /&gt;            throw ("The 'type' parameter must be a function object.");&lt;br /&gt;&lt;br /&gt;        this.Browser = MG.Browser.getInstance();&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    Add: function() {&lt;br /&gt;        var key = null;&lt;br /&gt;        var value = null;&lt;br /&gt;&lt;br /&gt;        if (arguments.length == 2) {&lt;br /&gt;            key = arguments[0];&lt;br /&gt;            value = arguments[1];&lt;br /&gt;        }&lt;br /&gt;        else if (arguments.length == 1)&lt;br /&gt;            value = arguments[0];&lt;br /&gt;        else&lt;br /&gt;            throw ("Invalid number of parameters. Number of parameters expected is two or one.");&lt;br /&gt;&lt;br /&gt;        if (this.Browser.NS) {&lt;br /&gt;            if (value.constructor !== this.Type.constructor)&lt;br /&gt;                throw ("The 'value' parameter doesn't have same type as this collection.");&lt;br /&gt;        }&lt;br /&gt;        else if (this.Browser.IE) {&lt;br /&gt;            if (value.constructor !== this.Type)&lt;br /&gt;                throw ("The 'value' parameter doesn't have same type as this collection.");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (!this.IsReadOnly) {&lt;br /&gt;            if (key) {&lt;br /&gt;                var dicEntry = new MG.Collections.DictionaryEntry(key, value);&lt;br /&gt;                this._dictionary.push(dicEntry);&lt;br /&gt;            }&lt;br /&gt;            else {&lt;br /&gt;                var dicEntry = new MG.Collections.DictionaryEntry("key", value);&lt;br /&gt;                this._dictionary.push(dicEntry);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;            throw ("Dictionary is read only! Check IsReadOnly value.");&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    Item: function() {&lt;br /&gt;        if (!arguments.length == 1)&lt;br /&gt;            throw ("Invalid number of parameters. Number of parameters expected is two or one.");&lt;br /&gt;&lt;br /&gt;        var arg = arguments[0];&lt;br /&gt;        var type = typeof arg;&lt;br /&gt;        var value = null;&lt;br /&gt;&lt;br /&gt;        if (type == "string")&lt;br /&gt;            value = this.___Item(arg);&lt;br /&gt;        else if (type == "number") {&lt;br /&gt;            if (this._dictionary.length &gt; arg)&lt;br /&gt;                value = this._dictionary[arg].value;&lt;br /&gt;            else&lt;br /&gt;                throw ("Index is out of range.");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}, MG.Collections.Dictionary, null);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2818125007944561208?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2818125007944561208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2818125007944561208' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2818125007944561208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2818125007944561208'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-arraylist-dictionay-strong.html' title='JavaScript ArrayList, JavaScript Dictionay, JavaScript Strong Type Array'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2548072294018186975</id><published>2009-12-13T09:51:00.000-08:00</published><updated>2010-11-17T23:32:46.016-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript XML Document and XPath</title><content type='html'>Here is a small library/wrapper for JavaScript XML. Some parts of it belong to other authors like the Opera serialization and the loading of the XML document from a string. I had to do a lot of work on the part related to namespaces, especially on Opera. At this time, the library doesn’t work under Chrome if the XML document makes use of namespaces. So you will not be able to create XPath expression for namespace-d XML documents under Chrome browser. You will notice that the library exposes two layers, first of them is an abstraction of the native DOM and of all its functionality and the second one is the native DOM its self. I have used this library for different XML related tasks; the most important one in my case is the SOAP library and the .NET DataSet serialization to JavaScript data objects. I’m too lazy to explain it in details, but if you have questions feel free to ask them and I’ll give you an answer as fast as possible. You can download the source from &lt;a href="http://38.107.67.35/jsmugen.zip"&gt;HERE&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if (typeof (MG) == 'undefined')&lt;br /&gt;    throw ("MG.Core.js is required!");&lt;br /&gt;    &lt;br /&gt;if(typeof(MG.Collections) === 'undefined')&lt;br /&gt;    throw ("MG.Collections.js is required!");    &lt;br /&gt;    &lt;br /&gt;if (typeof (MG.Xml) == 'undefined')&lt;br /&gt;    MG.Xml = {};&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlDocument = function(rootTagName, namespaceURL)&lt;br /&gt;        {&lt;br /&gt;            if(document.implementation &amp;&amp; document.implementation.createDocument)&lt;br /&gt;            {&lt;br /&gt;                Document.prototype.loadXML = function(strXML)&lt;br /&gt;                {&lt;br /&gt;                    var domParser = new DOMParser();&lt;br /&gt;                    var xmlDoc = domParser.parseFromString(strXML, "text/xml");&lt;br /&gt;                                                    &lt;br /&gt;                    while(this.hasChildNodes())&lt;br /&gt;      this.removeChild(this.lastChild);&lt;br /&gt;                                                        &lt;br /&gt;                    for(var index = 0; index &lt; xmlDoc.childNodes.length; index++)&lt;br /&gt;                    {&lt;br /&gt;      var impNode = this.importNode(xmlDoc.childNodes[index], true);&lt;br /&gt;                        this.appendChild(impNode);&lt;br /&gt;                    }&lt;br /&gt;                                                    &lt;br /&gt;                    var nsResolvers = new MG.Collections.Dictionary();&lt;br /&gt;                    if(xmlDoc.childNodes.length &gt; 0)&lt;br /&gt;                    {&lt;br /&gt;      nsResolvers = fixNS(strXML);&lt;br /&gt;                    }&lt;br /&gt;                                                    &lt;br /&gt;                    function fixNS(xml)&lt;br /&gt;                    {&lt;br /&gt;      var regEx = /&lt;[a-z\dA-Z\d]+:/g;&lt;br /&gt;                        var results = xml.match(regEx);&lt;br /&gt;                        var prefixes = new MG.Collections.ArrayList();&lt;br /&gt;                        var resolvedPrefixes = new MG.Collections.ArrayList();&lt;br /&gt;                        var unresolvedPrefixes = new MG.Collections.ArrayList();&lt;br /&gt;                                                        &lt;br /&gt;                        var count = results !== null ? results.length : 0;&lt;br /&gt;                        for(var index = 0; index &lt; count; index++)&lt;br /&gt;                        {&lt;br /&gt;       var matchValue = results[index];&lt;br /&gt;       var value = matchValue.slice(1, matchValue.length - 1);&lt;br /&gt;                                                            &lt;br /&gt;                            if(prefixes.IndexOf(value) &lt; 0)&lt;br /&gt;        prefixes.Add(value);&lt;br /&gt;                        }&lt;br /&gt;                                                        &lt;br /&gt;                        regEx = /:[a-zA-Z]+=|[a-zA-Z]+=/g;&lt;br /&gt;                        results = xml.match(regEx);&lt;br /&gt;                                                        &lt;br /&gt;                        count = results !== null ? results.length : 0;&lt;br /&gt;                        var prefixesCount = prefixes.Count();&lt;br /&gt;                        for(var index = 0; index &lt; prefixesCount; index++)&lt;br /&gt;                        {&lt;br /&gt;       var resolved = false;&lt;br /&gt;                            var prefix = prefixes.Item(index);&lt;br /&gt;                            for(var j = 0; j &lt; count; j++)&lt;br /&gt;                            {&lt;br /&gt;        var attribute = results[j];&lt;br /&gt;                                var value= null;&lt;br /&gt;                                if(attribute.indexOf(":") === 0)&lt;br /&gt;         value = attribute.slice(1, attribute.length - 1);&lt;br /&gt;                                else&lt;br /&gt;                                    value = attribute.slice(0, attribute.length - 1);&lt;br /&gt;                                                                    &lt;br /&gt;                                if(prefix === value)&lt;br /&gt;        {&lt;br /&gt;         if(resolvedPrefixes.IndexOf(value) &lt; 0)&lt;br /&gt;          resolvedPrefixes.Add(prefixes.Item(index));&lt;br /&gt;                                                                    &lt;br /&gt;         resolved = true;&lt;br /&gt;                                }&lt;br /&gt;                                else&lt;br /&gt;                                {&lt;br /&gt;                                    if(resolvedPrefixes.IndexOf(value) &lt; 0)&lt;br /&gt;          resolvedPrefixes.Add(value);&lt;br /&gt;                                }&lt;br /&gt;                            }&lt;br /&gt;                                                             &lt;br /&gt;                            if(!resolved)&lt;br /&gt;                            unresolvedPrefixes.Add(prefixes.Item(index));&lt;br /&gt;                        }&lt;br /&gt;                                                         &lt;br /&gt;                        var uniqueNamespaces = new MG.Collections.Dictionary();&lt;br /&gt;                                                         &lt;br /&gt;                        var exPrefixesCount = resolvedPrefixes.Count();&lt;br /&gt;                        for(var index = 0; index &lt; exPrefixesCount; index++)&lt;br /&gt;                        {&lt;br /&gt;       var prefix = resolvedPrefixes.Item(index);&lt;br /&gt;                            var regexS = "\\b" + prefix + "=\s*\".*?\"";&lt;br /&gt;                            var regex = new RegExp(regexS);&lt;br /&gt;                            var results = regex.exec(xml);&lt;br /&gt;                                                            &lt;br /&gt;                            if(results !== null &amp;&amp; results.length &gt; 0)&lt;br /&gt;                            {&lt;br /&gt;        var prefixValues = new MG.Collections.ArrayList();&lt;br /&gt;                                for(var j = 0; j &lt; results.length; j++)&lt;br /&gt;                                {&lt;br /&gt;         var value = results[j].substring(prefix.length + 2, results[j].length - 1);&lt;br /&gt;                                    prefixValues.Add(value);&lt;br /&gt;                                }&lt;br /&gt;                                                                &lt;br /&gt;        uniqueNamespaces.Add(prefix, prefixValues);&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                                                         &lt;br /&gt;       return uniqueNamespaces;&lt;br /&gt;                    }&lt;br /&gt;                                                    &lt;br /&gt;                    function createNSResolvers(node)&lt;br /&gt;                    {&lt;br /&gt;      var childNodes = node.childNodes;&lt;br /&gt;                        for(var index = 0; index &lt; childNodes.length; index++)&lt;br /&gt;                        {&lt;br /&gt;                            var prefix = childNodes[index].prefix;&lt;br /&gt;                            var nsURI = childNodes[index].namespaceURI;&lt;br /&gt;                                                            &lt;br /&gt;                            if(prefix &amp;&amp; nsURI)&lt;br /&gt;                            {&lt;br /&gt;        if(!nsResolvers.Item(prefix))&lt;br /&gt;         nsResolvers.Add(prefix, nsURI);&lt;br /&gt;                            }&lt;br /&gt;                                                            &lt;br /&gt;                            createNSResolvers(childNodes[index]);    &lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                                                    &lt;br /&gt;      this.nsResolvers = nsResolvers;&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;                function __getXml()&lt;br /&gt;                {&lt;br /&gt;                    var xmlSerializer = new XMLSerializer();&lt;br /&gt;                    var xml = xmlSerializer.serializeToString(this);&lt;br /&gt;                    return xml;&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;                if(Node.prototype.__defineGetter__)                                &lt;br /&gt;                    Node.prototype.__defineGetter__("xml", __getXml);&lt;br /&gt;                &lt;br /&gt;                return new MG.Xml.XmlNode(document.implementation.createDocument(namespaceURL, rootTagName, null)); &lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                var doc = new ActiveXObject("MSXML2.DOMDocument");&lt;br /&gt;                &lt;br /&gt;                if(rootTagName)&lt;br /&gt;                {&lt;br /&gt;                    var prefix = "";&lt;br /&gt;                    var tagName = rootTagName;&lt;br /&gt;                    var pos = rootTagName.indexOf(":");&lt;br /&gt;                    &lt;br /&gt;                    if(pos != -1)&lt;br /&gt;                    {&lt;br /&gt;                        rootTagName = rootTagName.substring(0, pos);&lt;br /&gt;                        tagName = rootTagName.substring(pos + 1);&lt;br /&gt;                    }&lt;br /&gt;                 &lt;br /&gt;                    if (namespaceURL)&lt;br /&gt;                    { &lt;br /&gt;                        if (!prefix)&lt;br /&gt;                            prefix = "a0";&lt;br /&gt;                    }&lt;br /&gt;                    else&lt;br /&gt;                        prefix = ""; &lt;br /&gt;&lt;br /&gt;                    var text = "&lt;" + (prefix?(prefix+":"):"") + tagName +&lt;br /&gt;                                (namespaceURL?(" xmlns:" + prefix + '="' + namespaceURL +'"'):"") + "/&gt;";&lt;br /&gt;            &lt;br /&gt;                    doc.loadXML(text);&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;                return new MG.Xml.XmlNode(doc); &lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        };&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode = function(nativeNode)&lt;br /&gt;    {&lt;br /&gt;        if(nativeNode)&lt;br /&gt;        {&lt;br /&gt;            this.NativeNode = nativeNode;&lt;br /&gt;            this.NativeAttributes = nativeNode.attributes;&lt;br /&gt;            this.NativeChildNodes = nativeNode.childNodes;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode.prototype.mdcXPath = function(node, xpathExpression, queryType)&lt;br /&gt;    {&lt;br /&gt;        var xpe = new XPathEvaluator();&lt;br /&gt;        var nsResolver = function(prefix)&lt;br /&gt;                { &lt;br /&gt;                    var nsResolvers = node.nsResolvers;&lt;br /&gt;                    if(!nsResolvers)&lt;br /&gt;                        nsResolvers = node.ownerDocument.nsResolvers;&lt;br /&gt;                    var item = nsResolvers.Item(prefix);&lt;br /&gt;                    &lt;br /&gt;                    if(item)&lt;br /&gt;                    {&lt;br /&gt;                        if (item.Count() &gt; 0) &lt;br /&gt;                        {&lt;br /&gt;                            return item.Item(0); &lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    else&lt;br /&gt;                        return xpe.createNSResolver(node.ownerDocument == null ? node.documentElement : node.ownerDocument.documentElement);&lt;br /&gt;                };&lt;br /&gt;        &lt;br /&gt;        var result = xpe.evaluate(xpathExpression, node, nsResolver, queryType, null);&lt;br /&gt;        return result;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode.prototype.fixNameSpaces = function(node, nsResolvers, xml)&lt;br /&gt;    {&lt;br /&gt;        if(nsResolvers)&lt;br /&gt;        {&lt;br /&gt;            if(node.prefix)&lt;br /&gt;            {&lt;br /&gt;                var nsResolver = nsResolvers.Item(node.prefix);&lt;br /&gt;                if(nsResolver)&lt;br /&gt;                {&lt;br /&gt;                    xml += " " + "xmlns:" + node.prefix + "=\"" + nsResolver + "\"";&lt;br /&gt;                    nsResolvers.Remove(node.prefix);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            &lt;br /&gt;            for(var index = 0; index &lt; node.childNodes.length; index++)&lt;br /&gt;                xml = this.fixNameSpaces(node.childNodes[index], nsResolvers, xml);&lt;br /&gt;        }&lt;br /&gt;            &lt;br /&gt;        return xml;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;MG.Xml.XmlNode.prototype.operaSerialize = function(nativeNode)&lt;br /&gt;    {&lt;br /&gt;        var xml = null;&lt;br /&gt;        switch(nativeNode.nodeType) &lt;br /&gt;        {&lt;br /&gt;            case 1:&lt;br /&gt;                {&lt;br /&gt;                    if(this.Name() === nativeNode.nodeName)&lt;br /&gt;                        xml = "&amp;lt;" + nativeNode.localName;&lt;br /&gt;                    else&lt;br /&gt;                        xml = "&amp;lt;" + nativeNode.tagName;&lt;br /&gt;                    &lt;br /&gt;                    var nsResolvers = null;&lt;br /&gt;                    var xmlnsAdded = false;&lt;br /&gt;                    &lt;br /&gt;                    for (var i = 0; i &amp;lt; nativeNode.attributes.length; i++) &lt;br /&gt;                    {&lt;br /&gt;                        var localName = nativeNode.attributes[i].localName;&lt;br /&gt;                        var name = nativeNode.attributes[i].name;&lt;br /&gt;                        var value = nativeNode.attributes[i].value;&lt;br /&gt;                        &lt;br /&gt;                        if(this.Name() === nativeNode.nodeName)&lt;br /&gt;                        {&lt;br /&gt;                            if(nativeNode.ownerDocument)&lt;br /&gt;                            {&lt;br /&gt;                                nsResolvers = nativeNode.ownerDocument.nsResolvers;&lt;br /&gt;                                if(nsResolvers &amp;&amp; nativeNode.ownerDocument.nsResolvers.Contains(localName))&lt;br /&gt;                                    nsResolvers.Remove(localName);&lt;br /&gt;                            }&lt;br /&gt;                            else&lt;br /&gt;                            {&lt;br /&gt;                                nsResolvers = nativeNode.nsResolvers;&lt;br /&gt;                                if(nsResolvers &amp;&amp; nsResolvers.Contains(name))&lt;br /&gt;                                    nsResolvers.Remove(name);&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                        &lt;br /&gt;                        if(name === "xmlns")&lt;br /&gt;                            xmlnsAdded = true;&lt;br /&gt;                        &lt;br /&gt;                        xml += " " + name + "=\"" + value + "\"";&lt;br /&gt;                    }&lt;br /&gt;                    &lt;br /&gt;                    if(this.Name() === nativeNode.nodeName)&lt;br /&gt;                    {&lt;br /&gt;                        if(!nsResolvers)&lt;br /&gt;                        {&lt;br /&gt;                            if(nativeNode.ownerDocument)&lt;br /&gt;                                nsResolvers = nativeNode.ownerDocument.nsResolvers;&lt;br /&gt;                            else&lt;br /&gt;                                nsResolvers = nativeNode.nsResolvers;&lt;br /&gt;                        }&lt;br /&gt;                        &lt;br /&gt;                        if(nsResolvers)&lt;br /&gt;                        {&lt;br /&gt;                            var item = nsResolvers.Item("xmlns");&lt;br /&gt;                            if(item)&lt;br /&gt;                                xml += " " + "xmlns" + "=\"" + item + "\"";&lt;br /&gt;                            else if(!xmlnsAdded)&lt;br /&gt;                                xml += " " + "xmlns" + "=\"" + "http://tempuri.org/" + "\"";&lt;br /&gt;                        &lt;br /&gt;                            xml = this.fixNameSpaces(nativeNode, nsResolvers, xml);     &lt;br /&gt;                        } &lt;br /&gt;                    }&lt;br /&gt;                                       &lt;br /&gt;                    xml += "&amp;gt;";&lt;br /&gt;            &lt;br /&gt;                    for (var i = 0; i &amp;lt; nativeNode.childNodes.length; i++)&lt;br /&gt;                        xml += this.operaSerialize(nativeNode.childNodes[i]);&lt;br /&gt;                    &lt;br /&gt;                    if(this.Name() === nativeNode.nodeName)&lt;br /&gt;                        xml += "&amp;lt;/" + nativeNode.localName + "&amp;gt;";&lt;br /&gt;                    else&lt;br /&gt;                        xml += "&amp;lt;/" + nativeNode.tagName + "&amp;gt;";&lt;br /&gt;                }&lt;br /&gt;             break;&lt;br /&gt;            case 3:&lt;br /&gt;                    xml = nativeNode.nodeValue;&lt;br /&gt;             break;&lt;br /&gt;         case 4:&lt;br /&gt;                    xml = "&amp;lt;![CDATA[" + nativeNode.nodeValue + "]]&amp;gt;";&lt;br /&gt;             break;&lt;br /&gt;         case 7:&lt;br /&gt;                 xml = "&amp;lt;?" + nativeNode.nodevalue + "?&amp;gt;";&lt;br /&gt;             break;&lt;br /&gt;         case 8:&lt;br /&gt;                 xml = "&amp;lt;!--" + nativeNode.nodevalue + "--&amp;gt;";&lt;br /&gt;                break;&lt;br /&gt;            case 9:&lt;br /&gt;                {&lt;br /&gt;                    for (var i = 0; i &amp;lt; nativeNode.childNodes.length; i++)&lt;br /&gt;                        xml += this.operaSerialize(nativeNode.childNodes[i]);&lt;br /&gt;                }&lt;br /&gt;                break;   &lt;br /&gt;        }&lt;br /&gt;        return xml;  &lt;br /&gt;    };&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;MG.Xml.XmlNode.prototype.ChildNodes = function(index)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeChildNodes)&lt;br /&gt;        {&lt;br /&gt;            if(arguments.length === 0)&lt;br /&gt;                return new MG.Xml.XmlNodes(this.NativeChildNodes);&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                var nativeNode = this.NativeChildNodes[index];&lt;br /&gt;                return (new MG.Xml.XmlNode(nativeNode));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.NextSibling = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            return new MG.Xml.XmlNode(this.NativeNode.nextSibling);&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.FirstChild = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            return new MG.Xml.XmlNode(this.NativeNode.firstChild);&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode.prototype.Name = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.OPERA)&lt;br /&gt;                return this.NativeNode.nodeName;&lt;br /&gt;            else if(browser.IE)&lt;br /&gt;                return this.NativeNode.nodeName;&lt;br /&gt;        }&lt;br /&gt;       &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.LocalName = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.OPERA)&lt;br /&gt;                return this.NativeNode.localName;&lt;br /&gt;            else if(browser.IE)&lt;br /&gt;                return this.NativeNode.baseName;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.Text = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            &lt;br /&gt;            if(arguments.length === 1)&lt;br /&gt;            {&lt;br /&gt;                if(browser.NS || browser.OPERA)&lt;br /&gt;                    return this.NativeNode.textContent =  arguments[0];&lt;br /&gt;                else if(browser.IE)&lt;br /&gt;                    return this.NativeNode.text = arguments[0];&lt;br /&gt;            }&lt;br /&gt;            else if(arguments.length === 0)&lt;br /&gt;            {&lt;br /&gt;                if(browser.NS || browser.OPERA)&lt;br /&gt;                    return this.NativeNode.textContent;&lt;br /&gt;                else if(browser.IE)&lt;br /&gt;                    return this.NativeNode.text;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;                throw("Only one parameter is expected.");&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.Value = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            if(arguments.length === 1)&lt;br /&gt;                this.NativeNode.nodeValue = arguments[0];&lt;br /&gt;            else if(arguments.length === 0)&lt;br /&gt;                return this.NativeNode.nodeValue;&lt;br /&gt;            else&lt;br /&gt;                throw("Only one parameter is expected.");&lt;br /&gt;        }&lt;br /&gt;    };    &lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.Xml = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.IE)&lt;br /&gt;                return this.NativeNode.xml;&lt;br /&gt;            else if(browser.OPERA)&lt;br /&gt;                return this.NativeNode.xml;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode.prototype.SelectSingleNode = function(xpathExpression)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var nativeNode = null;&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.OPERA)&lt;br /&gt;            {&lt;br /&gt;                var result = this.mdcXPath(this.NativeNode, xpathExpression, XPathResult.FIRST_ORDERED_NODE_TYPE);&lt;br /&gt;                nativeNode = result ? result.singleNodeValue : null;&lt;br /&gt;            }&lt;br /&gt;            else if(browser.IE)&lt;br /&gt;                nativeNode = this.NativeNode.selectSingleNode(xpathExpression);&lt;br /&gt;            &lt;br /&gt;            if(nativeNode)&lt;br /&gt;                return new MG.Xml.XmlNode(nativeNode);  &lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.SelectNodes = function(xpathExpression)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var nativeNodes = null;&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.OPERA)&lt;br /&gt;            {&lt;br /&gt;                var result = this.mdcXPath(this.NativeNode, xpathExpression, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);&lt;br /&gt;                &lt;br /&gt;                if(result)&lt;br /&gt;                {&lt;br /&gt;                    var pseudoNodes = new MG.Collections.ArrayList();&lt;br /&gt;                    for(var index = 0; index &amp;lt; result.snapshotLength; index++)&lt;br /&gt;                        pseudoNodes.Add(new MG.Xml.XmlNode(result.snapshotItem(index)));&lt;br /&gt;                        &lt;br /&gt;                   nativeNodes = pseudoNodes;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            else if(browser.IE)&lt;br /&gt;                nativeNodes = this.NativeNode.selectNodes(xpathExpression);&lt;br /&gt;            if(nativeNodes)&lt;br /&gt;                return new MG.Xml.XmlNodes(nativeNodes);&lt;br /&gt;        }&lt;br /&gt;                &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.CreateNode = function(type, name, namespaceURI)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;        {&lt;br /&gt;            var nativeNode = this.NativeNode.createNode(type, name, namespaceURI);&lt;br /&gt;            if(nativeNode)&lt;br /&gt;                return new MG.Xml.XmlNode(nativeNode);&lt;br /&gt;        }&lt;br /&gt;                &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.AppendChild = function(node)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            this.NativeNode.appendChild(node.NativeNode);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.RemoveChild = function(node)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            this.NativeNode.removeChild(node.NativeNode);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.ReplaceChild = function(newNode, oldNode)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            this.NativeNode.replaceChild(newNode.NativeNode, oldNode.NativeNode);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.ParentNode = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            return new MG.Xml.XmlNode(this.NativeNode.parentNode);&lt;br /&gt;                &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.Prefix = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            return this.NativeNode.prefix;&lt;br /&gt;                &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.LoadXML = function(xmlString)&lt;br /&gt;    {&lt;br /&gt;        this.NativeNode.loadXML(xmlString);&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNode.prototype.SetAttributeNode = function(attributeNode)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            this.NativeNode.setAttributeNode(attributeNode.NativeAttribute);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.SetAttribute = function(name, value)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNode)&lt;br /&gt;            this.NativeNode.setAttribute(name, value);&lt;br /&gt;    };    &lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNode.prototype.Attributes = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttributes)&lt;br /&gt;            return new MG.Xml.Attributes(this.NativeAttributes);&lt;br /&gt;            &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.Attributes = function(nativeAttributes)&lt;br /&gt;    {&lt;br /&gt;        this.NativeAttributes = nativeAttributes;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.Attributes.prototype.GetNamedItem = function(itemName)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttributes)&lt;br /&gt;           return new MG.Xml.Attribute(this.NativeAttributes.getNamedItem(itemName));&lt;br /&gt;           &lt;br /&gt;       return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.Attributes.prototype.Item = function(index)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttributes)&lt;br /&gt;            return new MG.Xml.Attribute(this.NativeAttributes[index]);&lt;br /&gt;            &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.Attributes.prototype.Length = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttributes)&lt;br /&gt;            return this.NativeAttributes.length;&lt;br /&gt;            &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.Attribute = function(nativeAttribute)&lt;br /&gt;    {&lt;br /&gt;        this.NativeAttribute = nativeAttribute;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.Attribute.prototype.Value = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttribute)&lt;br /&gt;            return this.NativeAttribute.value;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.Attribute.prototype.Name = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeAttribute)&lt;br /&gt;            return this.NativeAttribute.name;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;MG.Xml.XmlNodes = function(nativeNodes)&lt;br /&gt;    {&lt;br /&gt;        var isPseudo = false;&lt;br /&gt;        var browser = MG.Browser.getInstance();&lt;br /&gt;        if(browser.NS || browser.OPERA)&lt;br /&gt;        {&lt;br /&gt;            if(nativeNodes.constructor === MG.Collections.ArrayList.constructor)&lt;br /&gt;                isPseudo = true;&lt;br /&gt;        }&lt;br /&gt;        else if(browser.IE)&lt;br /&gt;        {&lt;br /&gt;            if(nativeNodes.constructor === MG.Collections.ArrayList)&lt;br /&gt;                isPseudo = true;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        if(!isPseudo)&lt;br /&gt;        {&lt;br /&gt;            this.NativeNodes = new MG.Collections.ArrayList();&lt;br /&gt;            for(var index = 0; index &amp;lt; nativeNodes.length; index++)&lt;br /&gt;                this.NativeNodes.Add(new MG.Xml.XmlNode(nativeNodes[index]));&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;            this.NativeNodes = nativeNodes;&lt;br /&gt;    };&lt;br /&gt;   &lt;br /&gt;MG.Xml.XmlNodes.prototype.Length = function()&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNodes)&lt;br /&gt;        {&lt;br /&gt;            var browser = MG.Browser.getInstance();&lt;br /&gt;            if(browser.NS || browser.OPERA)&lt;br /&gt;            {&lt;br /&gt;                if(this.NativeNodes.constructor === MG.Collections.ArrayList.constructor)&lt;br /&gt;                    return this.NativeNodes.Count();&lt;br /&gt;                else&lt;br /&gt;                    return this.NativeNodes.length;&lt;br /&gt;            }&lt;br /&gt;            else if(browser.IE)&lt;br /&gt;            {&lt;br /&gt;                if(this.NativeNodes.constructor === MG.Collections.ArrayList)&lt;br /&gt;                    return this.NativeNodes.Count();&lt;br /&gt;                else    &lt;br /&gt;                    return this.NativeNodes.length;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;            &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;MG.Xml.XmlNodes.prototype.Item = function(index)&lt;br /&gt;    {&lt;br /&gt;        if(this.NativeNodes)&lt;br /&gt;            return this.NativeNodes.Item(index);    &lt;br /&gt;        &lt;br /&gt;        return null;&lt;br /&gt;    };&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2548072294018186975?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2548072294018186975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2548072294018186975' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2548072294018186975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2548072294018186975'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-xml-xpath.html' title='JavaScript XML Document and XPath'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-881295639882382264</id><published>2009-12-09T06:09:00.000-08:00</published><updated>2009-12-09T06:09:27.775-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Google - Google Shit</title><content type='html'>Today I tried to create a Gmail account for a friend of mine. I was stupefied when I saw that they require you to provide your phone number to confirm that you are not a spammer. This is crap, the capcha is more than enough to do the job. They are going to far this time.&lt;br /&gt;&lt;br /&gt;BWOOOOO!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-881295639882382264?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/881295639882382264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=881295639882382264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/881295639882382264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/881295639882382264'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/google-google-shit.html' title='Google - Google Shit'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-1734265355267744131</id><published>2009-12-09T01:56:00.000-08:00</published><updated>2009-12-28T06:30:37.659-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Mugen Library Benchmark</title><content type='html'>Here are the benchmark results from JSLitmus for JavaScript inheritance from Mugen library which I have presented in the previous posts compared with other existing JavaScript libraries.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1. Results for IE7&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx65LnbJRRI/AAAAAAAABIg/kY3WjOH7Tgg/s1600-h/chart-baseclass2.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx65LnbJRRI/AAAAAAAABIg/kY3WjOH7Tgg/s320/chart-baseclass2.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx64-FT2h0I/AAAAAAAABIU/TC2-sWpHF3o/s1600-h/chart-ajaxsoft.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx64-FT2h0I/AAAAAAAABIU/TC2-sWpHF3o/s320/chart-ajaxsoft.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx65ZaXkizI/AAAAAAAABIw/vU6ULuJ4noA/s1600-h/chart-dojo.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx65ZaXkizI/AAAAAAAABIw/vU6ULuJ4noA/s320/chart-dojo.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx65WOHMbAI/AAAAAAAABIo/1wWebvBN4Bs/s1600-h/chart-defineclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx65WOHMbAI/AAAAAAAABIo/1wWebvBN4Bs/s320/chart-defineclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx65jldwpXI/AAAAAAAABJA/-VS-9-QV84s/s1600-h/chart-j3class2.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx65jldwpXI/AAAAAAAABJA/-VS-9-QV84s/s320/chart-j3class2.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx65dQ3b0OI/AAAAAAAABI4/9Th-iP7ABQc/s1600-h/chart-j3class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx65dQ3b0OI/AAAAAAAABI4/9Th-iP7ABQc/s320/chart-j3class.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx6534aapkI/AAAAAAAABJw/VFiYKXlHdFo/s1600-h/chart-mugen.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx6534aapkI/AAAAAAAABJw/VFiYKXlHdFo/s320/chart-mugen.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx65sdj0-9I/AAAAAAAABJY/2yetJG8Icus/s1600-h/chart-prototype.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx65sdj0-9I/AAAAAAAABJY/2yetJG8Icus/s320/chart-prototype.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2. Results for Mozilla&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx66oR8srJI/AAAAAAAABLY/SkQWcf4Ltvo/s1600-h/chart-ajaxsoftclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx66oR8srJI/AAAAAAAABLY/SkQWcf4Ltvo/s320/chart-ajaxsoftclass.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx66rn3ql3I/AAAAAAAABLg/2Q-OCdr3oXM/s1600-h/chart-base2class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx66rn3ql3I/AAAAAAAABLg/2Q-OCdr3oXM/s320/chart-base2class.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx66u3bYK5I/AAAAAAAABLo/EsSv1LwNpLo/s1600-h/chart-defineclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx66u3bYK5I/AAAAAAAABLo/EsSv1LwNpLo/s320/chart-defineclass.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx66yf0Ew3I/AAAAAAAABLw/rzyLqGVrwNg/s1600-h/chart-dojoclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx66yf0Ew3I/AAAAAAAABLw/rzyLqGVrwNg/s320/chart-dojoclass.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx6612D7Q2I/AAAAAAAABL4/hbAu_KFTOGI/s1600-h/chart-j3class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx6612D7Q2I/AAAAAAAABL4/hbAu_KFTOGI/s320/chart-j3class.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx665DnK8UI/AAAAAAAABMA/E1gPjwkZNJM/s1600-h/chart-j3class2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx665DnK8UI/AAAAAAAABMA/E1gPjwkZNJM/s320/chart-j3class2.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx667-GHIrI/AAAAAAAABMI/XNKQxY8EvrM/s1600-h/chart-jclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx667-GHIrI/AAAAAAAABMI/XNKQxY8EvrM/s320/chart-jclass.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx66912wooI/AAAAAAAABMQ/i3pnoBuq6EE/s1600-h/chart-joosclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx66912wooI/AAAAAAAABMQ/i3pnoBuq6EE/s320/chart-joosclass.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx67Asf59TI/AAAAAAAABMY/IDcI1IA4Fks/s1600-h/chart-mootools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx67Asf59TI/AAAAAAAABMY/IDcI1IA4Fks/s320/chart-mootools.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67DZpg9YI/AAAAAAAABMg/eRbUUPf-O9I/s1600-h/chart-prototypeclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67DZpg9YI/AAAAAAAABMg/eRbUUPf-O9I/s320/chart-prototypeclass.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx67F9zozYI/AAAAAAAABMo/kJC3xF_F2xw/s1600-h/chart-wrclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx67F9zozYI/AAAAAAAABMo/kJC3xF_F2xw/s320/chart-wrclass.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67IbM81lI/AAAAAAAABMw/HE_RnUwZYTk/s1600-h/chart-mugenclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67IbM81lI/AAAAAAAABMw/HE_RnUwZYTk/s320/chart-mugenclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3. Results for Opera&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx67zL0ms8I/AAAAAAAABNA/M6NB4pijMoY/s1600-h/chart-base2class.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx67zL0ms8I/AAAAAAAABNA/M6NB4pijMoY/s320/chart-base2class.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx67xPM8mXI/AAAAAAAABM4/mfuuFpasMQo/s1600-h/chart-ajaxsoftclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx67xPM8mXI/AAAAAAAABM4/mfuuFpasMQo/s320/chart-ajaxsoftclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx676iJqVVI/AAAAAAAABNQ/eJ9CNfqp4Mw/s1600-h/chart-dojoclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx676iJqVVI/AAAAAAAABNQ/eJ9CNfqp4Mw/s320/chart-dojoclass.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx673PXON6I/AAAAAAAABNI/NWJAv9T-_24/s1600-h/chart-defineclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx673PXON6I/AAAAAAAABNI/NWJAv9T-_24/s320/chart-defineclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67_yYquBI/AAAAAAAABNg/-oour4DkYcc/s1600-h/chart-j3class2.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx67_yYquBI/AAAAAAAABNg/-oour4DkYcc/s320/chart-j3class2.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx6782KXmiI/AAAAAAAABNY/IrNYNsJ-FxY/s1600-h/chart-j3class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx6782KXmiI/AAAAAAAABNY/IrNYNsJ-FxY/s320/chart-j3class.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68D8kIRAI/AAAAAAAABNw/BrLSrR3pMbo/s1600-h/chart-joosclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68D8kIRAI/AAAAAAAABNw/BrLSrR3pMbo/s320/chart-joosclass.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68CNHPr5I/AAAAAAAABNo/7bq_mAy64sE/s1600-h/chart-jclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68CNHPr5I/AAAAAAAABNo/7bq_mAy64sE/s320/chart-jclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68JWre-nI/AAAAAAAABOA/U2KnSSNIq9M/s1600-h/chart-prototypeclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68JWre-nI/AAAAAAAABOA/U2KnSSNIq9M/s320/chart-prototypeclass.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx68G1IPwYI/AAAAAAAABN4/KuQlmN2x6WM/s1600-h/chart-mootools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx68G1IPwYI/AAAAAAAABN4/KuQlmN2x6WM/s320/chart-mootools.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68Ofb6nUI/AAAAAAAABOQ/nVDUWPZ9tYI/s1600-h/chart-mugenclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" er="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx68Ofb6nUI/AAAAAAAABOQ/nVDUWPZ9tYI/s320/chart-mugenclass.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx68LkTbroI/AAAAAAAABOI/4yCn45lC7sk/s1600-h/chart-wrclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" er="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx68LkTbroI/AAAAAAAABOI/4yCn45lC7sk/s320/chart-wrclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4. Results for Safari&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx9zQXPq9GI/AAAAAAAABUY/kn70DFfOPgk/s1600-h/char-ajaxsoftt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx9zQXPq9GI/AAAAAAAABUY/kn70DFfOPgk/s320/char-ajaxsoftt.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zUleMXvI/AAAAAAAABUg/LBTIRIpJeKU/s1600-h/chart-base2class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zUleMXvI/AAAAAAAABUg/LBTIRIpJeKU/s320/chart-base2class.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zazr_5PI/AAAAAAAABUw/bjPgxx4NHkU/s1600-h/chart-dojo.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" ps="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zazr_5PI/AAAAAAAABUw/bjPgxx4NHkU/s320/chart-dojo.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zYgDevwI/AAAAAAAABUo/M8ZQ4NOR-Hc/s1600-h/chart-defineclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zYgDevwI/AAAAAAAABUo/M8ZQ4NOR-Hc/s320/chart-defineclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zf7Rnn4I/AAAAAAAABVA/vMrHhoBMoPo/s1600-h/chart-j3class2.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" ps="true" src="http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx9zf7Rnn4I/AAAAAAAABVA/vMrHhoBMoPo/s320/chart-j3class2.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zdgynXvI/AAAAAAAABU4/iIkonWhNApc/s1600-h/chart-j3class.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zdgynXvI/AAAAAAAABU4/iIkonWhNApc/s320/chart-j3class.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zor--1_I/AAAAAAAABVQ/YVD8V0hSdFE/s1600-h/chart-joosclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" ps="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zor--1_I/AAAAAAAABVQ/YVD8V0hSdFE/s320/chart-joosclass.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zihdX42I/AAAAAAAABVI/LqgKLnTwaPo/s1600-h/chart-jclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zihdX42I/AAAAAAAABVI/LqgKLnTwaPo/s320/chart-jclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx9zsudVUHI/AAAAAAAABVY/42IVpa-gNrs/s1600-h/chart-mootools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/Sx9zsudVUHI/AAAAAAAABVY/42IVpa-gNrs/s320/chart-mootools.png" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zvz_iy_I/AAAAAAAABVg/Lk0ctiptxJQ/s1600-h/chart-prototype.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://3.bp.blogspot.com/_P3oPhAnBfsw/Sx9zvz_iy_I/AAAAAAAABVg/Lk0ctiptxJQ/s320/chart-prototype.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9z2gHezZI/AAAAAAAABVw/5VWMEKmPGNw/s1600-h/char-mugenclass.png" imageanchor="1" style="clear: right; cssfloat: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" ps="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9z2gHezZI/AAAAAAAABVw/5VWMEKmPGNw/s320/char-mugenclass.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zzbLrLFI/AAAAAAAABVo/eONyjriGtHc/s1600-h/chart-wrclass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://2.bp.blogspot.com/_P3oPhAnBfsw/Sx9zzbLrLFI/AAAAAAAABVo/eONyjriGtHc/s320/chart-wrclass.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-1734265355267744131?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/1734265355267744131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=1734265355267744131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/1734265355267744131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/1734265355267744131'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-mugen-library-benchmark.html' title='JavaScript Mugen Library Benchmark'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_P3oPhAnBfsw/Sx65LnbJRRI/AAAAAAAABIg/kY3WjOH7Tgg/s72-c/chart-baseclass2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-8863285896967134194</id><published>2009-12-08T09:38:00.000-08:00</published><updated>2009-12-28T06:30:54.496-08:00</updated><title type='text'>JavaScript Inheritance Part II</title><content type='html'>Here are two different approaches in using the previous motioned inheritance technique.&lt;br /&gt;&lt;br /&gt;1. Standard way where all members are public:&lt;br /&gt;&lt;pre&gt;var Human = MG.Class.Create({&lt;br /&gt;                Gender: null,&lt;br /&gt;                constructor: function(gender) {&lt;br /&gt;                    this.Gender = gender;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                IsMale: function() {&lt;br /&gt;                    return this.Gender == 'F' ? false : true;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                GenderString: function() {&lt;br /&gt;                    return this.Gender == 'F' ? "female" : "male";&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                ToOverride: function() { return "Called from Human"; }&lt;br /&gt;            }, null, null);&lt;br /&gt;            &lt;br /&gt;            var Individual = MG.Class.Create({&lt;br /&gt;                Unique: null,&lt;br /&gt;                constructor: function(unique) {&lt;br /&gt;                    this.Unique = unique;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                IsUnique: function() {&lt;br /&gt;                    return this.Unique ? "Yes" : "No";&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                DummyMethod: function() {&lt;br /&gt;                    return "Individual dummy method.";&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                ToOverride: function() { return "Called from Individual which is " + (this.Unique ? "unique" : "not unique") + " / " + this.base(); }&lt;br /&gt;            }, Human, null);&lt;br /&gt;&lt;br /&gt;            var Person = MG.Class.Create({&lt;br /&gt;                constructor: function(firstName, lastName, birthDate) {&lt;br /&gt;                    this.FirstName = firstName;&lt;br /&gt;                    this.LastName = lastName;&lt;br /&gt;                    this.BirthDate = birthDate;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                GetName: function() {&lt;br /&gt;                    return this.FirstName + " " + this.LastName;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                GetDetails: function() {&lt;br /&gt;                    return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                ToOverride: function() { return "Called from Person with first name " + this.FirstName + " / " + this.base(); }&lt;br /&gt;            }, Individual, null);&lt;br /&gt;&lt;br /&gt;            var Jhon = MG.Class.Create({&lt;br /&gt;                constructor: function(age) {&lt;br /&gt;                    this.Age = age;&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                GetDetails: function() {&lt;br /&gt;                    return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate + ".";&lt;br /&gt;                },&lt;br /&gt;&lt;br /&gt;                ToOverride: function() { return "Called from Jhon/ " + this.base(); }&lt;br /&gt;            }, Person, null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. Classes with private members:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var Human = MG.Class.Create({&lt;br /&gt;                constructor: function(gender) {&lt;br /&gt;                    this.Gender = gender;&lt;br /&gt;&lt;br /&gt;                    return { IsMale: function() {&lt;br /&gt;                        return this.Gender == 'F' ? false : true;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                        GenderString: function() {&lt;br /&gt;                            return this.Gender == 'F' ? "female" : "male";&lt;br /&gt;                        },&lt;br /&gt;&lt;br /&gt;                        ToOverride: function() { return "Called from Human"; } &lt;br /&gt;                    };&lt;br /&gt;                }&lt;br /&gt;            }, null, null);&lt;br /&gt;&lt;br /&gt;            var Individual = MG.Class.Create({&lt;br /&gt;                constructor: function(unique) {&lt;br /&gt;                    this.Unique = unique;&lt;br /&gt;                    &lt;br /&gt;                     var PrivateDummyMethod = function() {&lt;br /&gt;                            return "Individual dummy method.";&lt;br /&gt;                        };&lt;br /&gt;&lt;br /&gt;                    return { IsUnique: function() {&lt;br /&gt;                        return this.Unique ? "Yes" : "No";&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                        ToOverride: function() { return "Called from Individual / " + this.base(); } &lt;br /&gt;                    };&lt;br /&gt;                }&lt;br /&gt;            }, Human, null);&lt;br /&gt;&lt;br /&gt;            var Person = MG.Class.Create({&lt;br /&gt;                constructor: function(firstName, lastName, birthDate) {&lt;br /&gt;                    this.FirstName = firstName;&lt;br /&gt;                    this.LastName = lastName;&lt;br /&gt;                    this.BirthDate = birthDate;&lt;br /&gt;&lt;br /&gt;                    return { GetName: function() {&lt;br /&gt;                        return this.FirstName + " " + this.LastName;&lt;br /&gt;                    },&lt;br /&gt;&lt;br /&gt;                        GetDetails: function() {&lt;br /&gt;                            return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate;&lt;br /&gt;                        },&lt;br /&gt;&lt;br /&gt;                        ToOverride: function() { return "Called from Person / " + this.base(); } &lt;br /&gt;                    };&lt;br /&gt;                }&lt;br /&gt;            }, Individual, null);&lt;br /&gt;&lt;br /&gt;            var Kate = MG.Class.Create({&lt;br /&gt;                constructor: function(age) {&lt;br /&gt;                    this.Age = age;&lt;br /&gt;&lt;br /&gt;                    return { GetDetails: function() {&lt;br /&gt;                                    return this.GetName() + " it's a " + this.GenderString() + " borned on date " + this.BirthDate + ".";&lt;br /&gt;                                },&lt;br /&gt;&lt;br /&gt;                            ToOverride: function() { return "Called from Kate/ " + this.base(); }};&lt;br /&gt;                }&lt;br /&gt;            }, Person, null);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I observed one thing about Base2 and Prototype. When you call a chain method and you reach the parent method, inside the method you have access to the derived object members using “this”. In my opinion once the call is navigating thru the chain on each base class the user should not be able to access the derived class members based on OOP definitions. In the future I'll fix this also in my technique.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-8863285896967134194?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/8863285896967134194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=8863285896967134194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8863285896967134194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8863285896967134194'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-inheritance-part-ii.html' title='JavaScript Inheritance Part II'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-6400970946005247494</id><published>2009-12-08T06:35:00.000-08:00</published><updated>2009-12-28T06:31:09.102-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Inheritance Part I</title><content type='html'>As a background I’m a .NET developer (C#) and I really like this technology :D. Since I got in contact with JavaScript, I always wanted to find an approach, a way to adapt it and used it as more as possible as an object oriented programming language. I found different approaches/techniques regarding this aspect of JavaScript (Crockford inheritance, Dean Edward with base2, Prototype, John Resig with a mixture of base2 and Prototype). After I studied the previous mentioned techniques I decided to have fun by trying to create a mixture and add new desired functionality. You can download the source from &lt;a href="http://cypruscaffe.com/sourcecode/javascript/mg.core.zip"&gt;HERE&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;For example in the case of Base2 inheritance you can’t create an object which has private and public members in a elegant way. Let us assume that we have following object:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var Human = base2.Base.extend({&lt;br /&gt;             constructor: function(name, hairColour, eyeColour, height, weight) {&lt;br /&gt;                 this.Name = name;&lt;br /&gt;                        this.HairColour = hairColour;&lt;br /&gt;                        this.EyeColour =  eyeColour;&lt;br /&gt;                        this.Height =  height;&lt;br /&gt;                        this.Weight =  weight},&lt;br /&gt;                    IsHeavy: function() {&lt;br /&gt;                        return this.Weight &gt; 100 ? true : false;&lt;br /&gt;                    },&lt;br /&gt;                    Dance: function() {&lt;br /&gt;                        return this.Name + " is dancing!";&lt;br /&gt;                    }});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case all members of the Human class are public. If I try to make Dace member private in the following way then all public members will not be available to the descendant of the Human class.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var Human = base2.Base.extend({&lt;br /&gt;             constructor: function(name, hairColour, eyeColour, height, weight) {&lt;br /&gt;    var Dance = function() {&lt;br /&gt;                        return this.Name + " is dancing!";};&lt;br /&gt;    &lt;br /&gt;                 return{Name: name,&lt;br /&gt;                        HairColour: hairColour,&lt;br /&gt;                        EyeColour: eyeColour,&lt;br /&gt;                        Height:  height,&lt;br /&gt;                        Weight:  weight,&lt;br /&gt;      IsHeavy: function() {&lt;br /&gt;                        return this.Weight &gt; 100 ? true : false;&lt;br /&gt;      }};&lt;br /&gt;    });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To test this case I have created a class called Person which extends the Human. Here is the code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var Person = Human.extend({&lt;br /&gt;             constructor: function(name, hairColour, eyeColour, height, weight) {&lt;br /&gt;    this.base(name, hairColour, eyeColour, height, weight);&lt;br /&gt;    },&lt;br /&gt;                    IsUnique: function() {&lt;br /&gt;                        return true;&lt;br /&gt;                    }});&lt;br /&gt;&lt;br /&gt;var obj = new Person("Bob Doe", "brown'", "blue", 6, 12);&lt;br /&gt;obj.IsHeavy();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, to extend the functionality to cover the above mentioned scenario I have used a different approach for inheritance. In this way the public members of a base class declared as in the above example and also those declared using prototype will be inherited by the derived class.&lt;br /&gt;&lt;br /&gt;Here is the code which I will discuss it later on:&lt;br /&gt;&lt;pre&gt;MG.Class.Create = function() {&lt;br /&gt;    var ___descendant = arguments[0];&lt;br /&gt;    var ___parent = arguments[1];&lt;br /&gt;    var interfaces = arguments[2];&lt;br /&gt;    var Implements = MG.Class.Implements;&lt;br /&gt;&lt;br /&gt;    var instance = function() {&lt;br /&gt;        // Copy 'base' (overridden) properties&lt;br /&gt;        this.base = instance.base;&lt;br /&gt;&lt;br /&gt;        // Copy properties from 'instance'&lt;br /&gt;        // structure object&lt;br /&gt;        for (var prop in instance) {&lt;br /&gt;            this[prop] = instance[prop];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var publicParentProps = [];&lt;br /&gt;        /**********************************************/&lt;br /&gt;        // Create the appropriate arguments and&lt;br /&gt;        // initialize ___parent/___descendant by calling&lt;br /&gt;        // their constructors&lt;br /&gt;        /**********************************************/&lt;br /&gt;        var args = arguments;&lt;br /&gt;        var desArgsCount = ___descendant.constructor.length;&lt;br /&gt;        var desArgs = new Array(desArgsCount);&lt;br /&gt;&lt;br /&gt;        for (var index = 0; index &lt; desArgsCount; index++)&lt;br /&gt;            desArgs[index] = args[index];&lt;br /&gt;&lt;br /&gt;        if (this.base &amp;&amp; this.base.inheritanceList) {&lt;br /&gt;            var length = this.base.inheritanceList.length;&lt;br /&gt;            var startParams = args.length;&lt;br /&gt;            for (var k = 0; k &lt; length; k++) {&lt;br /&gt;                var ctor = this.base.inheritanceList[k];&lt;br /&gt;                var prnArgsCount = ctor.length;&lt;br /&gt;                var prnArgs = new Array(prnArgsCount);&lt;br /&gt;&lt;br /&gt;                startParams -= prnArgsCount;&lt;br /&gt;                var nextParams = prnArgsCount &gt; startParams ? (startParams + prnArgsCount) : (startParams - prnArgsCount);&lt;br /&gt;                for (var index = startParams, i = 0; (prnArgsCount &gt; startParams ? index &lt; nextParams : index &gt; nextParams); (prnArgsCount &gt; startParams ? index++ : index--)) {&lt;br /&gt;                    prnArgs[i] = args[Math.abs(index)];&lt;br /&gt;                    i++;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                var publicParentProp = ctor.apply(this, prnArgs);&lt;br /&gt;                if (publicParentProp) {&lt;br /&gt;                    if (publicParentProps.length &gt; 0)&lt;br /&gt;                        publicParentProps[publicParentProps.length] = publicParentProp;&lt;br /&gt;                    else&lt;br /&gt;                        publicParentProps[0] = publicParentProp;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                this.base.inheritanceList[k] = null;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            this.base.inheritanceList = null;&lt;br /&gt;            delete this.base.inheritanceList;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var publicDescendant = instance.constructor.apply(this, desArgs);&lt;br /&gt;&lt;br /&gt;        if (publicDescendant) {&lt;br /&gt;            for (var prop in publicDescendant)&lt;br /&gt;                this[prop] = publicDescendant[prop];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (publicParentProps) {&lt;br /&gt;            var length = publicParentProps.length;&lt;br /&gt;            for (var index = 0; index &lt; length; index++) {&lt;br /&gt;                var publicParentProperty = publicParentProps[index];&lt;br /&gt;                for (var prop in publicParentProperty) {&lt;br /&gt;                    if (!this[prop])&lt;br /&gt;                        this[prop] = publicParentProperty[prop];&lt;br /&gt;                    else {&lt;br /&gt;                        this.base[prop] = publicParentProperty[prop];&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return this;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    /**************************************************/&lt;br /&gt;    // Create the structure of the object&lt;br /&gt;    // which will be instantiated&lt;br /&gt;    /**************************************************/&lt;br /&gt;    // Set the constructor from the ___descendant&lt;br /&gt;    instance.constructor = ___descendant.constructor;&lt;br /&gt;&lt;br /&gt;    // Copy peoperties from ___descendant&lt;br /&gt;    for (var prop in ___descendant)&lt;br /&gt;        instance[prop] = ___descendant[prop];&lt;br /&gt;&lt;br /&gt;    if (___parent) {&lt;br /&gt;        // Create a 'base' function which will hold properties&lt;br /&gt;        // overridden by the ___descendant&lt;br /&gt;        instance.base = function() {&lt;br /&gt;            var overrideFunction = null;&lt;br /&gt;            for (var prop in this) {&lt;br /&gt;                if (typeof (this[prop]) !== 'function')&lt;br /&gt;                    instance.base[prop] = this[prop];&lt;br /&gt;                else if (this[prop] === arguments.caller.callee)&lt;br /&gt;                    overrideFunction = prop;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (overrideFunction)&lt;br /&gt;                instance.base[overrideFunction]();&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        var inheritanceList = new Array();&lt;br /&gt;        if (___parent.base &amp;&amp; ___parent.base.inheritanceList) {&lt;br /&gt;            var parentInheritanceList = ___parent.base['inheritanceList'];&lt;br /&gt;            var length = parentInheritanceList.length;&lt;br /&gt;&lt;br /&gt;            for (var index = 0; index &lt; length; index++)&lt;br /&gt;                inheritanceList[index] = parentInheritanceList[index];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        var constructorExists = inheritanceList[inheritanceList.length - 1] === ___parent.constructor;&lt;br /&gt;&lt;br /&gt;        if (inheritanceList.length &gt; 0 &amp;&amp; !constructorExists)&lt;br /&gt;            inheritanceList[inheritanceList.length] = ___parent.constructor;&lt;br /&gt;        else if (!constructorExists)&lt;br /&gt;            inheritanceList[0] = ___parent.constructor;&lt;br /&gt;&lt;br /&gt;        instance.base.inheritanceList = inheritanceList;&lt;br /&gt;&lt;br /&gt;        // Copy properties from ___parent&lt;br /&gt;        for (var prop in ___parent) {&lt;br /&gt;            if (!instance[prop])&lt;br /&gt;                instance[prop] = ___parent[prop];&lt;br /&gt;            else {&lt;br /&gt;                if (typeof (___parent[prop]) == 'function')&lt;br /&gt;                    instance.base[prop] = ___parent[prop];&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Copy properties from ___parent prototype&lt;br /&gt;        if (___parent.prototype) {&lt;br /&gt;            for (var prop in ___parent.prototype) {&lt;br /&gt;                if (!instance[prop])&lt;br /&gt;                    instance[prop] = ___parent.prototype[prop];&lt;br /&gt;                else&lt;br /&gt;                    instance.base[prop] = ___parent.prototype[prop];&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    instance.Compare = function(object) {&lt;br /&gt;        for (var prop in this) {&lt;br /&gt;            if (this[prop] === object[prop])&lt;br /&gt;                return false;&lt;br /&gt;        }&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return instance;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-6400970946005247494?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/6400970946005247494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=6400970946005247494' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6400970946005247494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6400970946005247494'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-inheritance.html' title='JavaScript Inheritance Part I'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-8949105930811223126</id><published>2009-12-08T06:03:00.000-08:00</published><updated>2009-12-08T06:03:59.805-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Oracle - Lost package</title><content type='html'>Today something very stupid happened. I’ve managed to lose the changes of an entire package.  As you know if a package is opened in two different sessions, like session A and session B, if changes are made from session A to the package and session B still has the package opened, when session B will make its changes, all modifications performed by session A on the opened package will be lost. Thanks God that I was able to retrieve the lost changes by making use of SYS.SOURCE$ table. This table is composed from 3 columns:  OBJ# which represents the object ID, LINE which is the line number of the source in the object, and SOURCE the column which store the line of code.&lt;br /&gt;&lt;br /&gt;SELECT * FROM SYS.SOURCE$;&lt;br /&gt;SELECT * FROM SYS.SOURCE$ WHERE SOURCE LIKE ‘%MYPACKAGE%’;&lt;br /&gt;&lt;br /&gt;After digging into the results returned, I was able to find 3 versions of my package. One of them contained the lost changes.&lt;br /&gt;&lt;br /&gt;You can find more details about SYS.SOURCE$ table &lt;a href="http://docstore.mik.ua/orelly/oracle/advprog/ch15_04.htm"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-8949105930811223126?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/8949105930811223126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=8949105930811223126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8949105930811223126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8949105930811223126'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/oracle-lost-package.html' title='Oracle - Lost package'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2845089991663437128</id><published>2009-12-02T04:52:00.000-08:00</published><updated>2009-12-02T04:52:58.354-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>PL/SQL &amp; Oracle 64 bit Client</title><content type='html'>At the office I’m using Windows Vista 64 bit, we had a lot of bad surprises when it came to combine 32 bit DLLs from Oracle client with 64 bit DLLs of the projects. The most common exception in which we bumped was “Invalid image format”. We were using Oracle 10.2.0.3 which is a 32 bit client. To solve the issue we had to migrate to Oracle 10.2.0.4 client which has support for 64 bit applications. Once we did this we have discovered other inconvenient, PL/SQL didn't worked at all, the reason…it required a 32 bit Oracle client to be installed on the machine. The only solution found by one of my colleagues is that beside Oracle 10.2.0.4 client we should install also 10.2.0.3. Until now everything works just fine. By the way, same thing applies also to TOAD.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2845089991663437128?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2845089991663437128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2845089991663437128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2845089991663437128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2845089991663437128'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/plsql-oracle-64-bit-client.html' title='PL/SQL &amp; Oracle 64 bit Client'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-5453012338160891781</id><published>2009-12-02T02:14:00.000-08:00</published><updated>2009-12-28T06:31:57.578-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Ajax Characterset</title><content type='html'>In one of the project I have been involved, I had to create an Ajax menu. The issue showed up when the resource text of the menu items were in Greek. The response of the Ajax request was just junk. The issue resided in the fact that I have not specified on my Ajax request what character set it should be used. The problem was solved once I have specified that the value of charset it should be utf-8.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var url = location.protocol + "//" + location.host + "/MyWebSite/Default.aspx/GetMenuXml";&lt;br /&gt;        &lt;br /&gt;            xmlHttp = GetXmlHttpObject();&lt;br /&gt;            xmlHttp.open("POST", url, true);&lt;br /&gt;&lt;br /&gt;            xmlHttp.onreadystatechange = initializeMenu;&lt;br /&gt;&lt;br /&gt;            xmlHttp.setRequestHeader("Man", "POST" + url);&lt;br /&gt;            xmlHttp.setRequestHeader("MessageType", "CALL");&lt;br /&gt;            xmlHttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");&lt;br /&gt;                &lt;br /&gt;            xmlHttp.send(null);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-5453012338160891781?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/5453012338160891781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=5453012338160891781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/5453012338160891781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/5453012338160891781'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-ajax-greek-characters.html' title='JavaScript Ajax Characterset'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-4060999894797818097</id><published>2009-12-02T00:40:00.000-08:00</published><updated>2009-12-28T06:32:20.412-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JSLitmus creating JavaScript benchmark tests</title><content type='html'>Here is a very useful tool which allows you to create nice benchmark tests for your JavaScript code. You can check all the details on their home page:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.broofa.com/Tools/JSLitmus/"&gt;JSLitmus&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-4060999894797818097?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/4060999894797818097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=4060999894797818097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/4060999894797818097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/4060999894797818097'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/jslitmus-creating-javascript-benchmark.html' title='JSLitmus creating JavaScript benchmark tests'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-6691575905680599817</id><published>2009-12-01T12:13:00.000-08:00</published><updated>2009-12-01T12:13:40.913-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Get Current Date dd/mm/yyyy</title><content type='html'>The followinf function will return current date in dd/mm/yyyy format.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.Date = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.Date.Current = function(){&lt;br /&gt;  var current = new Date();&lt;br /&gt;  //In JavaScript Date object the months counter starts from 0, so&lt;br /&gt;  //we have to correct this.&lt;br /&gt;  current.setMonth(current.getMonth() + 1);&lt;br /&gt;  var changedDate = current.getDate() + "/" + current.getMonth() + "/" + current.getYear();&lt;br /&gt;&lt;br /&gt;  return changedDate;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-6691575905680599817?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/6691575905680599817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=6691575905680599817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6691575905680599817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/6691575905680599817'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-get-current-date-ddmmyyyy.html' title='JavaScript Get Current Date dd/mm/yyyy'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-8701559410233562882</id><published>2009-12-01T11:56:00.000-08:00</published><updated>2009-12-01T12:03:39.418-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Compare Two Dates</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;span style="font-family:times new roman;"&gt;Please check JavaScript Utility Functions Note.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following javascript function allows you to compare two dates. At this time only dd/mm/yyyy format is supported, but you can extend it very easily. The function will return -1 if first date is smaller than the second date, 1 if it is greater and 0 if both dates are equal.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.Date = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.Date.Compare = function(firstDate, secondDate, format) {&lt;br /&gt;                if (!(typeof firstDate === "string") || !(typeof secondDate === "string"))&lt;br /&gt;                    throw "Date must be a string.";&lt;br /&gt;&lt;br /&gt;                if (!format)&lt;br /&gt;                    throw "invalid date format specified.";&lt;br /&gt;&lt;br /&gt;                var result = -1;&lt;br /&gt;                switch (format) {&lt;br /&gt;                    case "dd/mm/yyyy":&lt;br /&gt;                        {&lt;br /&gt;                            var fdate = firstDate.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);&lt;br /&gt;                            var ldate = secondDate.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);&lt;br /&gt;&lt;br /&gt;                            if (parseInt(fdate[3]) &lt; parseInt(ldate[3]))&lt;br /&gt;                                result = -1;&lt;br /&gt;                            else if (parseInt(fdate[3]) &gt; parseInt(ldate[3]))&lt;br /&gt;                                result = 1;&lt;br /&gt;                            else&lt;br /&gt;                                result = 0;&lt;br /&gt;&lt;br /&gt;                            if (result == 0) {&lt;br /&gt;                                if (parseInt(fdate[2]) &lt; parseInt(ldate[2]))&lt;br /&gt;                                    result = -1;&lt;br /&gt;                                else if (parseInt(fdate[2]) &gt; parseInt(ldate[2]))&lt;br /&gt;                                    result = 1;&lt;br /&gt;                                else&lt;br /&gt;                                    result = 0;&lt;br /&gt;                            }&lt;br /&gt;&lt;br /&gt;                            if (result == 0) {&lt;br /&gt;                                if (parseInt(fdate[1]) &lt; parseInt(ldate[1]))&lt;br /&gt;                                    result = -1;&lt;br /&gt;                                else if (parseInt(fdate[1]) &gt; parseInt(ldate[1]))&lt;br /&gt;                                    result = 1;&lt;br /&gt;                                else&lt;br /&gt;                                    result = 0;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                        break;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;        return result;&lt;br /&gt;    };&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-8701559410233562882?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/8701559410233562882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=8701559410233562882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8701559410233562882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8701559410233562882'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-compare-two-dates.html' title='JavaScript Compare Two Dates'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-9180449393061438621</id><published>2009-12-01T11:39:00.000-08:00</published><updated>2009-12-01T12:04:11.275-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript UTC Date Format</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;span style="font-family:times new roman;"&gt;Please check JavaScript Utility Functions Note.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following javascript function allows you to convert an UTC date into a user specified format. At this time the implementation will convert the UTC date into dd/mm/yyyy and dd/mm/yyyy hh:mm:ss formats. You can easily extend it's functionality.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.Date = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.Date.UtcFormat = function(utcDate, format) {&lt;br /&gt;if (!(typeof utcDate === "string"))&lt;br /&gt;throw "UTC date must be a string.";&lt;br /&gt;&lt;br /&gt;if (!format)&lt;br /&gt;throw "invalid date format specified.";&lt;br /&gt;&lt;br /&gt;//Extract UTC date components using regex.&lt;br /&gt;var date = utcDate.match(/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z(([+-])(\d{2}):(\d{2}))?)$/i);&lt;br /&gt;&lt;br /&gt;if (!date)&lt;br /&gt;throw "Invalid UTC date format.";&lt;br /&gt;&lt;br /&gt;var newDate = null;&lt;br /&gt;switch (format) {&lt;br /&gt;case "dd/mm/yyyy":&lt;br /&gt;{&lt;br /&gt;newDate = date[3] + "/" + date[2] + "/" + date[1];&lt;br /&gt;}&lt;br /&gt;break;&lt;br /&gt;case "dd/mm/yyyy hh:mm:ss":&lt;br /&gt;{&lt;br /&gt;newDate = date[3] + "/" + date[2] + "/" + date[1] + " " + date[4] + ":" + date[5] + ":" + date[6];&lt;br /&gt;}&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return newDate;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next JavaScript function will convert date of dd/mm/yyyy format in UTC format. By default the time section will be ignored, being initialized with 00:00:00.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;JavaScript.Utils.Date.ToUtcFormat = function(date) {&lt;br /&gt;        if (!(typeof date === "string"))&lt;br /&gt;            throw "Date must be a string.";&lt;br /&gt;&lt;br /&gt;        var ndate = date.match(/^(\d{2})\/(\d{2})\/(\d{4})$/i);&lt;br /&gt;&lt;br /&gt;        if (!ndate)&lt;br /&gt;            throw "Invalid date format. Format must be dd/mm/yyyy";&lt;br /&gt;&lt;br /&gt;        var newDate = ndate[3] + "-" + ndate[2] + "-" + ndate[1] + "T00:00:00Z";&lt;br /&gt;&lt;br /&gt;        return newDate;&lt;br /&gt;    &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-9180449393061438621?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/9180449393061438621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=9180449393061438621' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/9180449393061438621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/9180449393061438621'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-utc-date-format.html' title='JavaScript UTC Date Format'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-5556542491307744626</id><published>2009-12-01T11:09:00.000-08:00</published><updated>2009-12-01T11:53:15.516-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Change URL Parameter Value</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;span style="font-family:times new roman;"&gt;Please check JavaScript Utility Functions Note.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:times new roman;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following function will allow you to change the value of a specified parameter from the URL. You just have to pass the parameter name and desired parameter value.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.URL = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.URL.ReplaceUrlParam = function(name, value) {&lt;br /&gt;    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");&lt;br /&gt;    var regexS = "[\\?&amp;amp;]" + name + "=([^&amp;amp;#]*)";&lt;br /&gt;    var regex = new RegExp(regexS);&lt;br /&gt;    var results = regex.exec(window.location.href);&lt;br /&gt;    if (results == null)&lt;br /&gt;        return false;&lt;br /&gt;    else {&lt;br /&gt;        var form = document.forms[0];&lt;br /&gt;        if (form) {&lt;br /&gt;            form.action = form.action.replace(results[0], results[0].replace(/=(.*)/, '=' + value));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-5556542491307744626?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/5556542491307744626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=5556542491307744626' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/5556542491307744626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/5556542491307744626'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-change-url-parameter-value.html' title='JavaScript Change URL Parameter Value'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-3537104756099370749</id><published>2009-12-01T10:57:00.000-08:00</published><updated>2009-12-01T11:53:04.690-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Extract URL Parameter</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;span style="font-family:times new roman;"&gt;Please check JavaScript Utility Functions Note.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;br /&gt;The following two functions will allow you to extract a specified parameter from the URL.&lt;br /&gt;To be more precise, only the first one will extract it automatically from the URL, the second function, which is an extension of the first one, will extract the specified parameter value from user defined source which is passed as a parameter.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.URL = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.URL.GetURLParam = function(param) {&lt;br /&gt;    param = param.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");&lt;br /&gt;    var regexS = "[\\?&amp;]" + param + "=([^&amp;#]*)";&lt;br /&gt;    var regex = new RegExp(regexS);&lt;br /&gt;    var results = regex.exec(window.location.href);&lt;br /&gt;&lt;br /&gt;    if (results == null)&lt;br /&gt;        return "";&lt;br /&gt;    else&lt;br /&gt;        return results[1];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.URL .GetUrlParamEx = function(source, name) {&lt;br /&gt;  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");&lt;br /&gt;  var regexS = "[\\?&amp;amp;]" + name + "=([^&amp;amp;#]*)";&lt;br /&gt;  var regex = new RegExp(regexS);&lt;br /&gt;  var results = regex.exec(source);&lt;br /&gt;  if (results == null)&lt;br /&gt;   return "";&lt;br /&gt;  else&lt;br /&gt;  &lt;br /&gt; return results[1];&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-3537104756099370749?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/3537104756099370749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=3537104756099370749' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3537104756099370749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3537104756099370749'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-extract-url-parameter.html' title='JavaScript Extract URL Parameter'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2083848379015589163</id><published>2009-12-01T10:49:00.000-08:00</published><updated>2009-12-01T11:09:09.186-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript Create Script Node</title><content type='html'>&lt;span style="color:#ff0000;"&gt;&lt;strong&gt;Note: &lt;/strong&gt;Please check JavaScript Utility Functions Note.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;br /&gt;Here is short JavaScript function which creates and returns a script node based on the string you specify as parameter:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/*Define the namespaces*/&lt;br /&gt;var JavaScript = {};&lt;br /&gt;JavaScript.Utils = {};&lt;br /&gt;JavaScript.Utils.DOM = {};&lt;br /&gt;&lt;br /&gt;JavaScript.Utils.DOM.CreateScriptElement = function(scriptValue) {&lt;br /&gt;    var node = document.createElement("script");&lt;br /&gt;    node.setAttribute('type', 'text/javascript');&lt;br /&gt;&lt;br /&gt;    if (node.canHaveChildren == null || node.canHaveChildren)&lt;br /&gt;        node.appendChild(document.createTextNode(scriptValue));&lt;br /&gt;    else&lt;br /&gt;        node.text = scriptValue;&lt;br /&gt;&lt;br /&gt;    return node;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2083848379015589163?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2083848379015589163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2083848379015589163' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2083848379015589163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2083848379015589163'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-create-script-node.html' title='JavaScript Create Script Node'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-3807354079063896878</id><published>2009-12-01T10:48:00.000-08:00</published><updated>2009-12-01T10:56:23.430-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JavaScript - Utility Functions Note</title><content type='html'>First of all I would like to let all of you know that most of the utility functions which I'm going to post here are inspired or are clones of other developer’s pieces of code. By this I have no intention to assume any credit. The reason why their names or web links are not posted is simple, I don't remember them :). If you recognize your work in any of the following lines just let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-3807354079063896878?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/3807354079063896878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=3807354079063896878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3807354079063896878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/3807354079063896878'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2009/12/javascript-utility-functions-note.html' title='JavaScript - Utility Functions Note'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-2530973391285053743</id><published>2007-09-03T06:37:00.000-07:00</published><updated>2009-12-02T04:55:50.131-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Garbage Collector (General Overview)</title><content type='html'>As you all know any program is using resources. These resources can be files, data base resources, network connections, memory buffers, objects, etc. The usage of any resources requires memory to be allocated. This is achieved using the following steps:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1&lt;/b&gt;.Allocate memory for the type that represents the resource by calling newobj intermediate language instruction. This instruction is emitted when you use the new operator.&lt;br /&gt;&lt;b&gt;2&lt;/b&gt;.Initialize the memory to make the resource available. The initial state of the resource is created by the constructor of the type.&lt;br /&gt;&lt;b&gt;3&lt;/b&gt;.Use the resource by accessing type members.&lt;br /&gt;&lt;b&gt;4&lt;/b&gt;.Clean up the resource state.&lt;br /&gt;&lt;b&gt;5&lt;/b&gt;.Free the memory occupied by the resource. This task is performed by garbage collector.&lt;br /&gt;&lt;br /&gt;The previous steps were generating two major bugs. First, often programmers forgotten to free memory when this was any longer needed. Second, programmers tried to access memory after this was freed. These two cases represent the worst bugs that can reside in an application because the behavior of the application in unpredictable and it's also very difficult to track them.&lt;br /&gt;Resource management it's a difficult task and distracts you, the programmer from the main problems that you have to solve. So this is the reason why garbage collector was created. It will take all the burden of memory handling from your shoulders. You must keep in mind that garbage collector does not knows about a resource that is represented by types in memory. So, this means that it can not clean up the resource in proper manner. This steps must be performed by you, by writing the corresponding code which will clean up the resource. There are two methods that you can make use of to perform the resource cleaning, Finalize and Dispose.&lt;br /&gt;&lt;br /&gt;Most types existent in .NET framework do not require resource clean up, types such as Int32, String, ArrayList . But there are also types which wrap some unmanaged resource like a network connection, a database connection, an icon, etc. &lt;br /&gt;The Common Language Runtime also known as CLR requires that all resources to be allocated from the managed heap. This managed heap resembles with the heap from C runtime heap with one major difference, you never free objects from the managed heap, object will be automatically freed when the application doesn't needs them. Now let's see what happens when a process get's initialized. The CLR will reserve a contiguous zone of address space. This address zone represents the managed heap. The managed heap maintains pointer to this address space, we'll call it NextObjectPtr. This pointer indicates where in the managed heap the next object will be allocated. Initially NextObjectPtr points to the base address from the reserved address space. As your intuition tells you, newobj instruction creates a new object. As I have mentioned earlier, this instruction is emitted when you make use of new key word. The newobj instruction will determine the CLR to perform the next steps:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1&lt;/b&gt;.Calculate the number of bytes required by the type for which memory will be allocated and also for all it's based types.&lt;br /&gt;&lt;b&gt;2&lt;/b&gt;.Add the bytes required for an object overhead. Each object has two overhead fields, a method table pointer and a SyncBLockIndex. If you are using an 32 bit system, each field requires 32 bits, this will add 8 bytes to each object. In the case of a 64 bit system, each field requires 64 bits which will add 16 bytes to each object.&lt;br /&gt;&lt;b&gt;3&lt;/b&gt;.CLR then checks if the bytes required to allocate the object are available in the reserved address space (managed heap), if the will fit, then it is allocated at the address pointed by NextObjectPtr, the constructor is called passing NextObjectPtr for this parameter and the new operator will return the address of the object. The NextObjectPtr is moved after the currently allocated object and indicates the address where the next object will be allocated at in the managed heap.&lt;br /&gt;&lt;br /&gt;When an application calls the new operator to create a new object there might not be enough space for it. The managed heap checks this by adding the required bytes of the objet to the address in NextObjectPtr. If the value exceeds the address space the managed heap is full and garbage collection takes action.&lt;br /&gt;Garbage collector checks if there are any unused objects in the managed heap. If this kind of objects do exists, then the memory used by them can be reclaimed. If there is no more memory in the heap the new operator will throw an OutOfMemoryException.&lt;br /&gt;An application has a set of roots. A root can be considered to be a memory storage location which contains a pointer to a reference type. This pointer can refer to an object or is set to null if the object doesn't exists. All global or static reference type variables are considered roots also any local variable reference type or parameter variable on a thread stack are considered as being roots. When garbage collector starts running (garbage collector starts when generation 0 of object is full, the garbage collector generation mechanism is used for performance improving, I'm not going to discuss this matter in this article), it will assume that all roots from the managed heap do not refer to any object. The garbage collector starts to iterate thru all roots and creates a graph with all objects that can be reached. In the image objects A and B are directly referenced by the roots so they will be added to the graph. When garbage collector will reach object C it will observer that this objects references another object from the managed heap, object D. So, object will be also added to the garbage collector graph. The entire iteration is performed recursively.&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_P3oPhAnBfsw/RtwO1a3ldTI/AAAAAAAAAAM/I1EiCSedoHE/s1600-h/Roots.GIF" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5105972388439618866" src="http://1.bp.blogspot.com/_P3oPhAnBfsw/RtwO1a3ldTI/AAAAAAAAAAM/I1EiCSedoHE/s320/Roots.GIF" style="cursor: pointer; float: left; margin: 0pt 10px 10px 0pt;" /&gt;&lt;/a&gt;&lt;br /&gt;After the graph is completed, this will contain all objects reachable from your application. All other objects which are not a part of this graph are considered garbage. The garbage collector will iterate the heap linearly searching for free large continuous blocks of memory where new object could be allocated. Also garbage collector will shift non garbage objects in memory using memcpy function to compact the memory heap. This operation will make all pointers to objects invalid. So the garbage collector will correct all the invalid pointers. After the managed heap memory is compacted the NextObjectPtr will point exactly after the last non garbage object.&lt;br /&gt;Now that you have a general overview of how garbage collector works you can design you applications properly.&lt;br /&gt;In the next article I will talk with more details about object generations and also about Finalize and Dispose methods and how they should be used.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-2530973391285053743?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/2530973391285053743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=2530973391285053743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2530973391285053743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/2530973391285053743'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2007/09/as-you-all-know-any-program-is-using.html' title='Garbage Collector (General Overview)'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_P3oPhAnBfsw/RtwO1a3ldTI/AAAAAAAAAAM/I1EiCSedoHE/s72-c/Roots.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-8003122624526796707</id><published>2007-08-25T12:35:00.000-07:00</published><updated>2009-12-02T04:54:58.179-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS SQL'/><title type='text'>Logical query processing</title><content type='html'>Logical query processing step numbers&lt;br /&gt;(8)  SELECT (9) DISTINCT (11) &lt;top_specification&gt; &lt;select_list&gt;&lt;br /&gt;(1)  FROM &lt;left_table&gt;&lt;br /&gt;(3)    &lt;join_type&gt; JOIN &lt;right_table&gt;&lt;br /&gt;(2)      ON &lt;join_condition&gt;&lt;br /&gt;(4)  WHERE &lt;where_condition&gt;&lt;br /&gt;(5)  GROUP BY &lt;group_by_list&gt;&lt;br /&gt;(6)  WITH {CUBE | ROLLUP}&lt;br /&gt;(7)  HAVING &lt;having_condition&gt;&lt;br /&gt;(10) ORDER BY &lt;order_by_list&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The first noticeable aspect of SQL that is different than other programming languages is the order in which the code is processed. In most programming languages, the code is processed in the order in which it is written. In SQL, the first clause that is processed is the FROM clause, while the SELECT clause, which appears first, is processed almost last.&lt;br /&gt;&lt;br /&gt;Each step generates a virtual table that is used as the input to the following step. These virtual tables are not available to the caller (client application or outer query). Only the table generated by the final step is returned to the caller. If a certain clause is not specified in a query, the corresponding step is simply skipped. Following is a brief description of the different logical steps applied in both SQL Server 2000 and SQL Server 2005.&lt;br /&gt;&lt;br /&gt;Brief Description of Logical Query Processing Phases&lt;br /&gt;&lt;br /&gt;1.  FROM: A Cartesian product (cross join) is performed between the first two tables in the FROM clause, and as a result, virtual table VT1 is generated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2.  ON: The ON filter is applied to VT1. Only rows for which the &lt;join_condition&gt; is TRUE are inserted to VT2.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3.  OUTER (join): If an OUTER JOIN is specified (as opposed to a CROSS JOIN or an INNER JOIN), rows from the preserved table or tables for which a match was not found are added to the rows from VT2 as outer rows, generating VT3. If more than two tables appear in the FROM clause, steps 1 through 3 are applied repeatedly between the result of the last join and the next table in the FROM clause until all tables are processed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4.  WHERE: The WHERE filter is applied to VT3. Only rows for which the &lt;where_condition&gt; is TRUE are inserted to VT4.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5.  GROUP BY: The rows from VT4 are arranged in groups based on the column list specified in the GROUP BY clause. VT5 is generated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6.  CUBE | ROLLUP: Supergroups (groups of groups) are added to the rows from VT5, generating VT6.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;7.  HAVING: The HAVING filter is applied to VT6. Only groups for which the &lt;having_condition&gt; is TRUE are inserted to VT7.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;8.  SELECT: The SELECT list is processed, generating VT8.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;9.  DISTINCT: Duplicate rows are removed from VT8. VT9 is generated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;10.  ORDER BY: The rows from VT9 are sorted according to the column list specified in the ORDER BY clause. A cursor is generated (VC10).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;11.  TOP: The specified number or percentage of rows is selected from the beginning of VC10. Table VT11 is generated and returned to the caller.&lt;br /&gt;&lt;br /&gt;Itzik Ben-Gan and Lubor Kollar - Inside Microsoft® SQL Server™ 2005 T-SQL Querying&lt;/having_condition&gt;&lt;/where_condition&gt;&lt;/join_condition&gt;&lt;/order_by_list&gt;&lt;/having_condition&gt;&lt;/group_by_list&gt;&lt;/where_condition&gt;&lt;/join_condition&gt;&lt;/right_table&gt;&lt;/join_type&gt;&lt;/left_table&gt;&lt;/select_list&gt;&lt;/top_specification&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-8003122624526796707?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/8003122624526796707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=8003122624526796707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8003122624526796707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/8003122624526796707'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2007/08/logical-query-processing.html' title='Logical query processing'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-1632657601993111686</id><published>2007-06-22T03:58:00.000-07:00</published><updated>2009-12-02T04:55:19.068-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Auto data binding panel</title><content type='html'>&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;While I was browsing some old projects of mine, I have discovered that in one of them I have approached an interesting topic of .NET framework. That topic was "Data Binding".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Many of you know that the process of data binding it's a complex one, and differs from web application to windows application, being optimized for each of them. From my point of view data binding can be splinted in two branches: simple data binding and complex data binding.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We can speak about simple data binding when you are in the situation of binding a single value to a property of a control. Simple data binding operation is performed using &amp;lt;%#  %&amp;gt;. The expression between data binding tags is evaluated only when the control's data binding method is invoked. Here is an example of simple data binding:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Customer: &amp;lt;%# custID %&amp;gt;&lt;br /&gt;&lt;/pre&gt;Where "Customer" is a label and  "custID" is a public property. &lt;br /&gt;Simple data binding works only with scalar values like strings and integers. Complex data binding is a different story. It works with any data type that implements IEnumerable interface. At the end of this article we should have a panel which will act as a container for the child custom controls and it will automatically fill them with the corresponding values from it's data source. For this to work we need to create two custom interfaces. First of them is IDataBound. IDataBound interface defines the data types (DataTypes) of values that will be bounded to our control, "BoundColumn" property which will keep the name of the column used in binding process, BoundValue property used to store the new value of the control after the binding process. And finally IDataBoundInfo interface which contains the name of the table used in data binding.&lt;br /&gt;Please note that DataTypes enum contains at this time only data types that are found on System.Type. The reason why I have added it to the code is that I might want to use in the feature a custom object as a data type for the data binding.    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;DataTypes definition&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public enum DataTypes&lt;br /&gt;{&lt;br /&gt;Default,&lt;br /&gt;String,&lt;br /&gt;Integer,&lt;br /&gt;DateTime,&lt;br /&gt;Double&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;IDataBound interface definition&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public interface IDataBound&lt;br /&gt;{&lt;br /&gt;DataTypes DataType { get; set; }&lt;br /&gt;string BoundColumn { get; set; }&lt;br /&gt;object BoundValue { get; set; }&lt;br /&gt;bool SingleBind { get; set; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;IDataBoundInfo interface definition&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public interface IDataBoundInfo : IDataBound&lt;br /&gt;{&lt;br /&gt;string TableName { get; set; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;BindingTextBox Control&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;After this short presentation of those two helper interfaces let's get to the business.&lt;br /&gt;I will create a text box custom control, which will be called "BindingTextBox". Here is the code of this control:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;using System;&lt;br /&gt;using System.Web.UI.WebControls;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Summary description for BindingTextBox&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public class BindingTextBox : TextBox, IDataBoundInfo&lt;br /&gt;{&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// IDataBound members.&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;private DataTypes _datatype = DataTypes.Default;&lt;br /&gt;private string _boundcolumn;&lt;br /&gt;private bool _singlebind;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// IDataBoundInfo members.&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;private string _tablename;&lt;br /&gt;&lt;br /&gt;public DataTypes DataType&lt;br /&gt;{&lt;br /&gt;get { return _datatype; }&lt;br /&gt;set { _datatype = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public string BoundColumn&lt;br /&gt;{&lt;br /&gt;get { return _boundcolumn; }&lt;br /&gt;set { _boundcolumn = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public virtual object BoundValue&lt;br /&gt;{&lt;br /&gt;get { return ControlHelper.ConvertValue&lt;br /&gt;(_datatype, this.Text); }&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;if (value is DBNull)&lt;br /&gt;this.Text = "";&lt;br /&gt;else&lt;br /&gt;this.Text = value.ToString();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public bool SingleBind&lt;br /&gt;{&lt;br /&gt;get { return _singlebind; }&lt;br /&gt;set { _singlebind = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public string TableName&lt;br /&gt;{&lt;br /&gt;get { return _tablename; }&lt;br /&gt;set { _tablename = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;At this time please ignore SingleBid property, I have used it in other purposes (data binding with multiple values) which I will not describe in this article.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;ControlHelper class&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;I have forgotten to mention about ControlHelper class. If you remember I have made an observation regarding DataTypes enum that at this time&lt;br /&gt;contains only data types that are found on System.Type, and I have give you an explanation also. Same thing goes for ControlHelper class. It contains only one method used for conversion, but if you would have some custom object, you could implement different methods for conversion and not only. Here is the code for ControlHelper class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;using System;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Summary description for ControlHelper&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public class ControlHelper&lt;br /&gt;{&lt;br /&gt;public static object ConvertValue(DataTypes toType, object value)&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;switch (toType)&lt;br /&gt;{&lt;br /&gt;case DataTypes.String: return Convert.ToString(value);&lt;br /&gt;case DataTypes.Integer: return Convert.ToInt32(value);&lt;br /&gt;case DataTypes.DateTime:&lt;br /&gt;return Convert.ToDateTime(value);&lt;br /&gt;case DataTypes.Double:&lt;br /&gt;return Convert.ToDouble(value);&lt;br /&gt;case DataTypes.Default: return value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;catch&lt;br /&gt;{&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I consider that both pieces of code are straight, simple and self explanatory (BindingTextBox and ControlHelper).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;BindingPanel Control&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;The BindingPanel code is more complicated so first I'll show you the code and after I'll present it step by step.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;using System;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;using System.Web.UI.WebControls;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Summary description for BindingPanel&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;namespace MyControls&lt;br /&gt;{&lt;br /&gt;public class BindingPanel : Panel&lt;br /&gt;{&lt;br /&gt;private string _data_member;&lt;br /&gt;private object _datasource;&lt;br /&gt;&lt;br /&gt;#region public string DataMember&lt;br /&gt;[Browsable(false)]&lt;br /&gt;public string DataMember&lt;br /&gt;{&lt;br /&gt;get { return _data_member; }&lt;br /&gt;set { _data_member = value; }&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public object DataSource&lt;br /&gt;[Browsable(false)]&lt;br /&gt;public object DataSource&lt;br /&gt;{&lt;br /&gt;get { return _datasource; }&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;if ((value == null) || (value is IListSource) ||&lt;br /&gt;(value is IEnumerable))&lt;br /&gt;{&lt;br /&gt;_datasource = value;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;throw new ArgumentException(@"Invalid object.&lt;br /&gt;Object must implement IListSource&lt;br /&gt;or IEnumerable", "DataSource");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region private void UpdateFromControlsRecursive&lt;br /&gt;(Control control, object row)&lt;br /&gt;private void updateFromControlsRecursive&lt;br /&gt;(Control control, object row)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;object _old_value = null;&lt;br /&gt;&lt;br /&gt;if (boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;_old_value = ((DataRow)row)[boundField];&lt;br /&gt;&lt;br /&gt;if (_old_value != idbc.BoundValue)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;{&lt;br /&gt;if (idbc.BoundValue != null)&lt;br /&gt;((DataRow)row)[boundField] =&lt;br /&gt;idbc.BoundValue;&lt;br /&gt;else&lt;br /&gt;((DataRow)row)[boundField] =&lt;br /&gt;DBNull.Value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region private void BindControlsRecursive(Control control,&lt;br /&gt;object row)&lt;br /&gt;private void bindControlsRecursive(Control control,&lt;br /&gt;object row)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;&lt;br /&gt;if (boundField != null &amp;amp;&amp;amp; boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;idbc.BoundValue = ((DataRow)row)[boundField];&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region private void clearControlsRecursive(Control control)&lt;br /&gt;private void clearControlsRecursive(Control control)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;&lt;br /&gt;if (boundField != null &amp;amp;&amp;amp; boundField.Length &amp;gt; 0)&lt;br /&gt;idbc.BoundValue = DBNull.Value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region private PropertyDescriptor[]&lt;br /&gt;GetColumnPropertyDescriptors(object dataItem)&lt;br /&gt;private PropertyDescriptor[]&lt;br /&gt;GetColumnPropertyDescriptors(object dataItem)&lt;br /&gt;{&lt;br /&gt;ArrayList props = new ArrayList();&lt;br /&gt;PropertyDescriptorCollection propDescps =&lt;br /&gt;TypeDescriptor.GetProperties(dataItem);&lt;br /&gt;foreach (PropertyDescriptor pd in propDescps)&lt;br /&gt;{&lt;br /&gt;Type propType = pd.PropertyType;&lt;br /&gt;TypeConverter converter =&lt;br /&gt;TypeDescriptor.GetConverter(propType);&lt;br /&gt;&lt;br /&gt;if ((converter != null) &amp;amp;&amp;amp;&lt;br /&gt;converter.CanConvertTo(typeof(string)))&lt;br /&gt;props.Add(pd);&lt;br /&gt;}&lt;br /&gt;props.Sort(new PropertyDescriptorComparer());&lt;br /&gt;PropertyDescriptor[] columns =&lt;br /&gt;new PropertyDescriptor[props.Count];&lt;br /&gt;props.CopyTo(columns, 0);&lt;br /&gt;return columns;&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region protected virtual IEnumerable GetDataSource()&lt;br /&gt;protected virtual IEnumerable GetDataSource()&lt;br /&gt;{&lt;br /&gt;if (_datasource == null)&lt;br /&gt;return null;&lt;br /&gt;IEnumerable resolvedDataSource = _datasource as IEnumerable;&lt;br /&gt;if (resolvedDataSource != null)&lt;br /&gt;return resolvedDataSource;&lt;br /&gt;IListSource listDataSource = _datasource as IListSource;&lt;br /&gt;if (listDataSource != null)&lt;br /&gt;{&lt;br /&gt;IList listMember = listDataSource.GetList();&lt;br /&gt;if (listDataSource.ContainsListCollection == false)&lt;br /&gt;return (IEnumerable)listMember;&lt;br /&gt;ITypedList typedListMember = listMember as ITypedList;&lt;br /&gt;if (typedListMember != null)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptorCollection propDescps =&lt;br /&gt;typedListMember.GetItemProperties(null);&lt;br /&gt;PropertyDescriptor propertyMember = null;&lt;br /&gt;if ((propDescps != null) &amp;amp;&amp;amp; (propDescps.Count != 0))&lt;br /&gt;{&lt;br /&gt;string dataMember = DataMember;&lt;br /&gt;if (dataMember != null)&lt;br /&gt;{&lt;br /&gt;if (dataMember.Length == 0)&lt;br /&gt;propertyMember = propDescps[0];&lt;br /&gt;else&lt;br /&gt;propertyMember =&lt;br /&gt;propDescps.Find(dataMember, true);&lt;br /&gt;if (propertyMember != null)&lt;br /&gt;{&lt;br /&gt;object listRow = listMember[0];&lt;br /&gt;object list =&lt;br /&gt;propertyMember.GetValue(listRow);&lt;br /&gt;if (list is IEnumerable)&lt;br /&gt;return (IEnumerable)list;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;throw new Exception("A list that coresponds to the&lt;br /&gt;selected DataMember cannot be&lt;br /&gt;found.");&lt;br /&gt;}&lt;br /&gt;throw new Exception("The DataSource does not contain&lt;br /&gt;any data members to bind to.");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public void BindControls(DataRow row)&lt;br /&gt;public void BindControls(DataRow row)&lt;br /&gt;{&lt;br /&gt;bindControlsRecursive(this, row);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public void BindControls(object datasource)&lt;br /&gt;public void BindControls(object datasource)&lt;br /&gt;{&lt;br /&gt;bindControlsRecursive(this, datasource);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public void ClearControls()&lt;br /&gt;public void ClearControls()&lt;br /&gt;{&lt;br /&gt;clearControlsRecursive(this);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public void UpdateFromControls(DataRow row)&lt;br /&gt;public void UpdateFromControls(DataRow row)&lt;br /&gt;{&lt;br /&gt;updateFromControlsRecursive(this, row);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public void UpdateFromControls(object datasource)&lt;br /&gt;public void UpdateFromControls(object datasource)&lt;br /&gt;{&lt;br /&gt;updateFromControlsRecursive(this, datasource);&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region public override void DataBind()&lt;br /&gt;public override void DataBind()&lt;br /&gt;{&lt;br /&gt;IEnumerable dataSource = null;&lt;br /&gt;base.OnDataBinding(EventArgs.Empty);&lt;br /&gt;dataSource = GetDataSource();&lt;br /&gt;if (dataSource != null)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor[] properties = null;&lt;br /&gt;foreach (Control ctrl in this.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;if (boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;foreach (object dataItem in dataSource)&lt;br /&gt;{&lt;br /&gt;properties =&lt;br /&gt;GetColumnPropertyDescriptors(dataItem);&lt;br /&gt;for (int i = 0; i &amp;lt; properties.Length; i++)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor pd = properties[i];&lt;br /&gt;if (boundField.CompareTo(pd.Name) == 0)&lt;br /&gt;{&lt;br /&gt;object ctlValue =&lt;br /&gt;pd.GetValue(dataItem);&lt;br /&gt;idbc.BoundValue =&lt;br /&gt;pd.Converter.ConvertTo(ctlValue,&lt;br /&gt;typeof(string));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;if (idbc.SingleBind)&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;#region NESTED CLASSES&lt;br /&gt;#region private sealed class PropertyDescriptorComparer :&lt;br /&gt;IComparer&lt;br /&gt;private sealed class PropertyDescriptorComparer : IComparer&lt;br /&gt;{&lt;br /&gt;public int Compare(object objectA, object objectB)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor pd1 = (PropertyDescriptor)objectA;&lt;br /&gt;PropertyDescriptor pd2 = (PropertyDescriptor)objectB;&lt;br /&gt;return String.Compare(pd1.Name, pd2.Name);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;#endregion&lt;br /&gt;#endregion&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The property DataMember is the data member name with which the panel will be bonded. In our case it will be a table name from a data set.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The DataSource property is used to set or get the data source that will be involved in the binding process. We will use a data set filled from a NorthWind database. Our data set will contain one table that will be the data member. You can observe that the data source must inherit IList interface or IEnumerable interface else an exception will be throwed.&lt;br /&gt;&lt;br /&gt;Let's take a look at GetDataSource() method. It return's a IEnumerable which is our data source object. As I mentioned early, in the data binding process we can use as a data source any object which implements IEnumerable. Because of this rule we have to check that our data source object type is IEnumerable (or IList which inherits from IEnumerable).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if (_datasource == null)&lt;br /&gt;return null;&lt;br /&gt;&lt;br /&gt;IEnumerable resolvedDataSource = _datasource as IEnumerable;&lt;br /&gt;&lt;br /&gt;if (resolvedDataSource != null)&lt;br /&gt;return resolvedDataSource;&lt;br /&gt;&lt;br /&gt;IListSource listDataSource = _datasource as IListSource;&lt;br /&gt;&lt;br /&gt;if (listDataSource != null)&lt;br /&gt;{.....}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;IListSource is nothing more than an interface that provides the functionality for an object to return a list that can be bonded to a data source. It also exposes ContainsListCollection property that indicates if the collection is a collection of IList objects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;IList listMember = listDataSource.GetList();&lt;br /&gt;&lt;br /&gt;if (listDataSource.ContainsListCollection == false)&lt;br /&gt;return (IEnumerable)listMember;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We set the value of listMember variable using GetList() method. After this, check to see if listDataSource object is a collection of IList objects. If it's not, then listMember must be of type IEnumerable, make a cast and exit from the method by returning it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;ITypedList typedListMember = listMember as ITypedList;&lt;br /&gt;&lt;br /&gt;if (typedListMember != null)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptorCollection propDescps =&lt;br /&gt;typedListMember.GetItemProperties(null)&lt;br /&gt;if ((propDescps != null) &amp;amp;&amp;amp; (propDescps.Count != 0))&lt;br /&gt;{&lt;br /&gt;string dataMember = DataMember;&lt;br /&gt;&lt;br /&gt;if (dataMember != null)&lt;br /&gt;{&lt;br /&gt;if (dataMember.Length == 0)&lt;br /&gt;propertyMember = propDescps[0];&lt;br /&gt;else&lt;br /&gt;propertyMember = propDescps.Find(dataMember, true);&lt;br /&gt;&lt;br /&gt;if (propertyMember != null)&lt;br /&gt;{&lt;br /&gt;object listRow = listMember[0];&lt;br /&gt;object list = propertyMember.GetValue(listRow);&lt;br /&gt;&lt;br /&gt;if (list is IEnumerable)&lt;br /&gt;return (IEnumerable)list;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;throw new Exception("A list that coresponds to the selected&lt;br /&gt;DataMember can not be found.");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;throw new Exception("The DataSource does not contains any data&lt;br /&gt;members to bind to.");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If the data source is a collection of IList objects, get the schema of our bondable list object and save it in typedListMember. MSDN offers the following description for ITypedList "Provides functionality to discover the schema for a bondable list, where the properties available for binding differ from the public properties of  the object to bind to". If there is such a schema, get the PropertyDescriptorCollection that represents the properties on each item used to bind data. We do this by using GetItemProperties() method that is exposed by typedListMember object. This method requires an array of PropertyDescriptor object as parameter, or you can pass a null reference. The PropertyDescriptor array is used to find the bondable objects from the collection. Now create a PropertyDescriptor object called propertyMember and initialize it with null. If propDescps collection is not null or it contains at least one item, then set the value for dataMember string from DataMember property. If dataMember is empty, we will get the first PropertyDescriptor object from propDescps collection. If it's not empty, then use Find(string name,  bool ignoreCase) method which is exposed by propDescps. This method will return the PropertyDescriptor object with the specified name. The boolean parameter (ignoreCase) indicates whether to ignore the name case. After we have obtained the propertyMember, we will take the first object from listMember which will be passed as paramater to GetValue(object component) method exposed by propertyMember. This method will return the value of a property for the specified component. Now the last thing to do is to check if the returned value is of type IEnumerable, if it's not, throw and exception to notify you that the specified data member can not be found.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private PropertyDescriptor[]&lt;br /&gt;GetColumnPropertyDescriptors(object dataItem)&lt;br /&gt;{&lt;br /&gt;ArrayList props = new ArrayList();&lt;br /&gt;PropertyDescriptorCollection propDescps =&lt;br /&gt;TypeDescriptor.GetProperties(dataItem);&lt;br /&gt;&lt;br /&gt;foreach (PropertyDescriptor pd in propDescps)&lt;br /&gt;{&lt;br /&gt;Type propType = pd.PropertyType;&lt;br /&gt;TypeConverter converter = TypeDescriptor.GetConverter(propType);&lt;br /&gt;&lt;br /&gt;if ((converter != null) &amp;amp;&amp;amp;&lt;br /&gt;converter.CanConvertTo(typeof(string)))&lt;br /&gt;props.Add(pd);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;props.Sort(new PropertyDescriptorComparer());&lt;br /&gt;PropertyDescriptor[] columns = new PropertyDescriptor[props.Count];&lt;br /&gt;props.CopyTo(columns, 0);&lt;br /&gt;&lt;br /&gt;return columns;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In general, same explanation goes for GetColumnPropertyDescriptors(object dataItem) which returns a PropertyDescriptor array. We get the PropertyDescriptor that corresponds to each column, get the TypeConverter and check if the property type can be converted to string, add them to an array list and sort them using PropertyDescriptorComparer as parameter and finally insert them into the PropertyDescriptor array (columns).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally we have reached at the most known method involved in data binding process, DataBind(). Here is the code of this method :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public override void DataBind()&lt;br /&gt;{&lt;br /&gt;IEnumerable dataSource = null;&lt;br /&gt;&lt;br /&gt;base.OnDataBinding(EventArgs.Empty);&lt;br /&gt;&lt;br /&gt;dataSource = GetDataSource();&lt;br /&gt;&lt;br /&gt;if (dataSource != null)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor[] properties = null;&lt;br /&gt;&lt;br /&gt;foreach (Control ctrl in this.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;&lt;br /&gt;if (boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;foreach (object dataItem in dataSource)&lt;br /&gt;{&lt;br /&gt;properties = GetColumnPropertyDescriptors(dataItem);&lt;br /&gt;&lt;br /&gt;for (int i = 0; i &amp;lt; properties.Length; i++)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor pd = properties[i];&lt;br /&gt;if (boundField.CompareTo(pd.Name) == 0)&lt;br /&gt;{&lt;br /&gt;object ctlValue = pd.GetValue(dataItem);&lt;br /&gt;idbc.BoundValue =&lt;br /&gt;pd.Converter.ConvertTo(ctlValue,&lt;br /&gt;typeof(string));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (idbc.SingleBind)&lt;br /&gt;break;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here are the steps performed :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Call OnDataBinding(EventArgs e) method of the base class.&lt;/li&gt;&lt;li&gt;Get the data source that will be used in data binding.&lt;/li&gt;&lt;pre&gt;dataSource = GetDataSource()&lt;/pre&gt;&lt;li&gt;Iterate through the controls contained in this panel.&lt;/li&gt;&lt;pre&gt;foreach (Control ctrl in this.Controls)&lt;/pre&gt;&lt;li&gt;Check if current control implements IDataBound interface, if it does, cast it to it and get the BoundColumn property.&lt;/li&gt;&lt;pre&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;Iterate through data source data item objects, get the properties for each data item object using GetColumnPropertyDescriptors method.&lt;/li&gt;&lt;pre&gt;foreach (object dataItem in dataSource)&lt;br /&gt;{&lt;br /&gt;properties = GetColumnPropertyDescriptors(dataItem);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;For each property, get the corresponding property descriptor, compare it's name with the BoundColumn value (boundField). If they match, get the value of the property descriptor, convert it to string and assign it to the current control BoundValue property.&lt;/li&gt;&lt;pre&gt;for (int i = 0; i &amp;lt; properties.Length; i++)&lt;br /&gt;{&lt;br /&gt;PropertyDescriptor pd = properties[i];&lt;br /&gt;if (boundField.CompareTo(pd.Name) == 0)&lt;br /&gt;{&lt;br /&gt;object ctlValue = pd.GetValue(dataItem);&lt;br /&gt;idbc.BoundValue = pd.Converter.ConvertTo(ctlValue,&lt;br /&gt;typeof(string));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;These methods represent the back bone of our binding panel control. The BindingPanel control also contains other three important methods: bindControlsRecursive, updateFromControlsRecursive, clearControlsRecursive. I will start the presentation with bindControlsRecursive method.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private void bindControlsRecursive(Control control, object row)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;&lt;br /&gt;if (boundField != null &amp;amp;&amp;amp; boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;idbc.BoundValue = ((DataRow)row)[boundField];&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This method requires two parameters, a Control which is the container for the child controls that will be involved in the binding process, and the data object (row). The method iterates through all the child controls, checkbs if they implement IDataBound interface. If they do implement it, it gets the corresponding column value based on BoundColumn property and populates our control with data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private void updateFromControlsRecursive(Control control, object row)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;object _old_value = null;&lt;br /&gt;&lt;br /&gt;if (boundField.Length &amp;gt; 0)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;_old_value = ((DataRow)row)[boundField];&lt;br /&gt;&lt;br /&gt;if (_old_value != idbc.BoundValue)&lt;br /&gt;{&lt;br /&gt;if (row is DataRow)&lt;br /&gt;{&lt;br /&gt;if (idbc.BoundValue != null)&lt;br /&gt;((DataRow)row)[boundField] = idbc.BoundValue;&lt;br /&gt;else&lt;br /&gt;((DataRow)row)[boundField] = DBNull.Value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The method updateFromControlsRecursive performs same operations as bindControlsRecursive method but with the logic reversed. It iterates through all the child controls, checkbs if they implement IDataBound interface. If they do implement it, it gets the current control value and populates the corresponding column of the data object (row) based on BoundColumn property.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private void clearControlsRecursive(Control control)&lt;br /&gt;{&lt;br /&gt;foreach (Control ctrl in control.Controls)&lt;br /&gt;{&lt;br /&gt;if (ctrl is IDataBound)&lt;br /&gt;{&lt;br /&gt;IDataBound idbc = (IDataBound)ctrl;&lt;br /&gt;string boundField = idbc.BoundColumn;&lt;br /&gt;&lt;br /&gt;if (boundField != null &amp;amp;&amp;amp; boundField.Length &amp;gt; 0)&lt;br /&gt;idbc.BoundValue = DBNull.Value;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For cleaning up the controls values we use clear ControlsRecursive method. It simply iterates through all child controls, checkbs if they implement IDataBound interface. If they do implement it, clears their values (control value will be DBNull.Value).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well, these are the most important things about this control.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;As you can see, for the data binding process we have used reflection. The idea is simple; let's say for example that our custom text box control has the BoundColumn property value "ContactName" and the TableName property value "customers". After you set the DataMember and DataSource properties of BindingPanel, when DataBind() method is called, the panel will iterate thru it's child controls and for each child control will also iterate thru it's DataMember columns. When a match is found between BoundColumn property of the child control and a column name from the DataMember, the control's value will be updated with the value of the corresponding column. I want to make an observation, that in the example project I'm using only the first row from the DataMember, because the panel control is not iterating thru all DataMemberbs rows. If you want to iterate thru all rows, then use a repeater, make a template for it and include the custom panel in it.   &lt;br /&gt;If you want, you can extend all the functionality presented here. The zip file contains the entire project and also and usage example. As database I have used NorthWind, just change the connection string if required .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-1632657601993111686?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/1632657601993111686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=1632657601993111686' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/1632657601993111686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/1632657601993111686'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2007/06/auto-data-binding-panel.html' title='Auto data binding panel'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6146753014571848686.post-4248766385692113513</id><published>2006-11-12T09:31:00.000-08:00</published><updated>2009-12-02T04:55:39.690-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Web applications performance rules</title><content type='html'>&lt;div align="left"&gt;&lt;span style="font-family: verdana;"&gt;&lt;span style="font-size: 85%;"&gt;When you design and develop your web application you always must take in consideration the performance factor. By doing this you will remove the cost of rewriting modules, modifying code or redistributing the application. A good practice that must be kept in mind, for writing quality code, is to make frequent code reviews. For example, I often find a better implementation of a certain module after a code review. Also you should test different ways of implementing your code to determine the performance impact over your application.&lt;br /&gt;Here are some rules that should be fallowed for writing high performing applications.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Store your content by using caching&lt;br /&gt;&lt;/b&gt;As you know ASP.NET allow you to cache entire pages, fragment of pages or controls. You can cache also variable data by specifying the parameters that the data depends. By using caching you help ASP.NET engine to return data for repeated request for the same page much faster. There is one catch here, caching consumes server memory, so it’s not recommended to be used when you need to get updated data on your page.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Avoid session state&lt;br /&gt;&lt;/b&gt;Whether you store your data in in-process or on state server or in a Sql Database, session state requires memory and it’s also time consuming when you sore or retrieve data from it. If you do not want to use session state, disable it on your web form using &lt;span style="color: #000099;"&gt;&amp;lt;@%Page EnableSessionState=”false”%&amp;gt;&lt;/span&gt; directive. In case you use the session state only to retrieve data from it and not to update it, make the session state read only by using &lt;span style="color: #000099;"&gt;&amp;lt;@%Page EnableSessionState =”ReadOnly”%&amp;gt;&lt;/span&gt; directive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Avoid ViewSate&lt;/b&gt;&lt;br /&gt;ViewState allow you to keep the content of a control across trips to server. This comes with a cost, a greater amount of data is sent from the server to client end vice versa, so the speed and network bandwidth can be affected. You can avoid this drawback by setting the &lt;span style="color: #000099;"&gt;EnableViewState&lt;/span&gt; property of your web controls to false, when you don’t need them to keep their state across server trips.    &lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Use low cost authentication&lt;br /&gt;&lt;/b&gt;Authentication can also have an impact over the performance of your application.&lt;br /&gt;For example passport authentication is slower than form-base authentication which in here turn is slower than Windows authentication.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Use Server.Transfer() method for server side page redirection&lt;br /&gt;&lt;/b&gt;It is better to use the &lt;span style="color: #000099;"&gt;Server.Transfer()&lt;/span&gt; method for server side aspx page redirection in the same application than &lt;span style="color: #000099;"&gt;Response.Redirect()&lt;/span&gt; method. This will reduce the extra roundtrip required by the second method (&lt;span style="color: #000099;"&gt;Response.Redirect()&lt;/span&gt;) to perform client side redirection.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;6. The number of web server controls&lt;/b&gt;&lt;br /&gt;The use of web server controls increases the response time of your application because they need time to be processed on the server side before they are rendered on the client side. Therefore take in consideration the usage of HTML elements where they are suited, for example if you want to display static text.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;7. Avoid frequent usage of boxing and unboxing&lt;/b&gt;&lt;br /&gt;When a value type such as a structure it is copied to a reference type such as a class, the compiler creates an object on the heap and copies the value of the value type from the stack to this newly created object on the heap. This process is called boxing and requires more overhead than just a simple from value type to value type. When you copy a reference type to a value type, the value of the object from the heap is copied to the value type from the stack. This process is called unboxing. You should take in consideration the overhead of these processes when you design your application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;8. Avoid using string for complex strings operations&lt;/b&gt;&lt;br /&gt;The string type is immutable; this means that after a &lt;span style="color: #000099;"&gt;string&lt;/span&gt; is created it can’t be modified. When you modify a string the CRL creates a new one based on your modifications and returns it. The old &lt;span style="color: #000099;"&gt;string&lt;/span&gt; remains in memory until garbage collector will clean it. If your application is extensively modifying strings, then use the &lt;span style="color: #000099;"&gt;StringBuilder&lt;/span&gt; class. This class stores the string as an array of characters. The &lt;span style="color: #000099;"&gt;StringBuilder&lt;/span&gt; object is mutable and dose in-place modifications of strings.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;9. Use AddRange() method with collections&lt;/b&gt;&lt;br /&gt;There is a large number of collection classes that expose &lt;span style="color: #000099;"&gt;AddRange()&lt;/span&gt; method, which you can use to add an array of items to the collection instead of calling repeatedly  &lt;span style="color: #000099;"&gt;Add()&lt;/span&gt; method inside a loop.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;10. Avoid throwing exceptions&lt;br /&gt;&lt;/b&gt;Throwing exceptions is a costly operation. You should be very careful when you throw exception from your application. Exceptions should be throwing only to signify exceptional error cases. You should never throw exceptions just for managing your application flow.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;11. Avoid using unmanaged code&lt;/b&gt;&lt;br /&gt;Calls to unmanaged code are a costly marshaling operation. Try to reduce the number calls between the managed and unmanaged code.  Consider to do more work in each call rather than making frequent calls to do small tasks.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;b&gt;12. Avoid making frequent calls across processes&lt;/b&gt;&lt;br /&gt;If you are working with distributed applications, this involves additional overhead negotiating network and application level protocols. In this case network speed can also be a bottleneck. Try to do as much work as possible in fewer calls over the network.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;13. Make use of optimized managed providers&lt;/b&gt;&lt;br /&gt;As you know &lt;span style="color: #000099;"&gt;OleDb&lt;/span&gt; is a generic provider which offers access to data exposed by any &lt;span style="color: #000099;"&gt;OleDb&lt;/span&gt; provider. Managed providers are specifically optimized for some databases. For example when you use &lt;span style="color: #000099;"&gt;OleDb&lt;/span&gt; to connect to a Sql server database, &lt;span style="color: #000099;"&gt;OleDb&lt;/span&gt; first passes your request to the OLE DB COM components which in turn translate the request to Sql Native Tabular Data Stream (&lt;span style="color: #000099;"&gt;TDS&lt;/span&gt;) format. If you will use &lt;span style="color: #000099;"&gt;SqlClient&lt;/span&gt;, this will directly construct the &lt;span style="color: #000099;"&gt;TDS&lt;/span&gt; packets and communicate with Sql server. The removal of extra translation will significantly improve the performance of your application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;14. Use stored procedure and not sql statements&lt;/b&gt;&lt;br /&gt;When you are working with a RDBMS as Sql server you should use stored procedures rather than sql statements given as a text command, because stored procedure are highly optimized for server side data access.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;15. Use DataReader instead of DataSet for forward-only sequential access&lt;/b&gt;&lt;br /&gt;If you are reading a table sequentially you should use the &lt;span style="color: #000099;"&gt;DataReader&lt;/span&gt; rather than &lt;span style="color: #000099;"&gt;DataSet&lt;/span&gt;. &lt;span style="color: #000099;"&gt;DataReader&lt;/span&gt; object creates a read only stream of data that will increase your application performance because only one row is in memory at a time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;16. Use connection pooling&lt;br /&gt;&lt;/b&gt;The slowest operation performed in a database application scenario is establishing a connection with a database. The Sql server .NET Data Provider offers connection pooling to improve performance when connecting to a Sql server database. In connection pooling old connection information is stored in a connection pool so it can be reused for the next connection. If you are using dynamic connection strings, you will disallow connection pooling mechanism because connections are only pooled on the exact connection string.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;17. Use transactions&lt;/b&gt;&lt;br /&gt;Distributed transactions might add performance overhead to your application, so you should use them only when required and keep their life as short as possible.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6146753014571848686-4248766385692113513?l=dotnetcaffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetcaffe.blogspot.com/feeds/4248766385692113513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6146753014571848686&amp;postID=4248766385692113513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/4248766385692113513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6146753014571848686/posts/default/4248766385692113513'/><link rel='alternate' type='text/html' href='http://dotnetcaffe.blogspot.com/2006/11/web-applications-performance-rules.html' title='Web applications performance rules'/><author><name>Michael Heliso</name><uri>http://www.blogger.com/profile/18294901951415285299</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
