/// <summary>
        /// This method is called to log into the system and establish  
        /// the cookie.  Once the cookie is established, you can call
        /// the search function to perform searches.
        /// </summary>
        /// <param name="uid">The user id to use for login.</param>
        /// <param name="pwd">The password to use for login.</param>
        /// <returns>True if the login was successful.</returns>
        private bool Login(String uid, String pwd)
        {
            Uri url = new Uri("http://www.httprecipes.com/1/8/cookie.php");
            HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create(url);
            http.CookieContainer = cookies;
            http.Timeout = 30000;
            http.ContentType = "application/x-www-form-urlencoded";
            http.Method = "POST";
            Stream ostream = http.GetRequestStream();

            FormUtility form = new FormUtility(ostream, null);
            form.Add("uid", uid);
            form.Add("pwd", pwd);
            form.Add("action", "Login");
            form.Complete();
            ostream.Close();
            
            HttpWebResponse response = (HttpWebResponse)http.GetResponse();

            foreach (Cookie cookie in cookies.GetCookies(url))
            {
                if( String.Compare(cookie.Name,"hri-cookie",true)==0)
                    return true;
            }
            return false;
        }
        /// <summary>
        /// Upload a file.
        /// </summary>
        /// <param name="uid">The user id for the form.</param>
        /// <param name="pwd">The password for the form.</param>
        /// <param name="file">The file to upload.</param>
        public void Upload(String uid, String pwd, String file)
        {
            // Get the boundary used for the multipart upload.
            String boundary = FormUtility.getBoundary();

            Uri url = new Uri("http://www.httprecipes.com/1/7/uploader.php");
            WebRequest http = HttpWebRequest.Create(url);
            http.Timeout = 30000;
            // specify that we will use a multipart form
            http.ContentType = "multipart/form-data; boundary=" + boundary;
            http.Method = "POST";
            Stream ostream = http.GetRequestStream();

            // Construct a form.
            FormUtility form = new FormUtility(ostream, boundary);
            form.Add("uid", uid);
            form.Add("pwd", pwd);
            form.AddFile("uploadedfile", file);
            form.Complete();
            ostream.Close();
            
            // Perform the upload.
            WebResponse response = http.GetResponse();
            Stream istream = response.GetResponseStream();
            istream.Close();
        }
        /// <summary>
        /// This method is called to log into the system and return 
        /// a session id.  Once you have the session ID you can call
        /// the search function to perform searches.
        /// </summary>
        /// <param name="uid">The user id to use for login.</param>
        /// <param name="pwd">The password to use for login.</param>
        /// <returns>The session id if login was successful, null if it was not.</returns>
        private String Login(String uid, String pwd)
        {
            Uri url = new Uri("http://www.httprecipes.com/1/8/cookieless.php");
            WebRequest http = HttpWebRequest.Create(url);
            http.Timeout = 30000;
            http.ContentType = "application/x-www-form-urlencoded";
            http.Method = "POST";
            Stream ostream = http.GetRequestStream();

            FormUtility form = new FormUtility(ostream, null);
            form.Add("uid", uid);
            form.Add("pwd", pwd);
            form.Add("action", "Login");
            form.Complete();
            ostream.Close();
            WebResponse response = http.GetResponse();
            response.GetResponseStream();

            String query = response.ResponseUri.Query;
            if (query != null)
            {
                NameValueCollection c = HttpUtility.ParseQueryString(query);

                return c.Get("session");
            }
            else
                return null;
        }
        /// <summary>
        /// This method will download an amortization table for the 
        /// specified parameters.
        /// </summary>
        /// <param name="interest">The interest rate for the loan.</param>
        /// <param name="term">The term(in months) of the loan.</param>
        /// <param name="principle">The principle amount of the loan.</param>
        public void process(double interest, int term, int principle)
        {


            Uri url = new Uri("http://www.httprecipes.com/1/9/loan.php");
            WebRequest http = HttpWebRequest.Create(url);
            http.Timeout = 30000;
            http.ContentType = "application/x-www-form-urlencoded";
            http.Method = "POST";
            Stream ostream = http.GetRequestStream();



            FormUtility form = new FormUtility(ostream, null);
            form.Add("interest", "" + interest);
            form.Add("term", "" + term);
            form.Add("principle", "" + principle);
            form.Complete();
            ostream.Close();
            WebResponse response = http.GetResponse();

            Stream istream = response.GetResponseStream();
            ParseHTML parse = new ParseHTML(istream);
            StringBuilder buffer = new StringBuilder();
            List<String> list = new List<String>();
            bool capture = false;

            Advance(parse, "table", 3);

            int ch;
            while ((ch = parse.Read()) != -1)
            {
                if (ch == 0)
                {
                    HTMLTag tag = parse.Tag;
                    if (String.Compare(tag.Name, "tr", true) == 0)
                    {
                        list.Clear();
                        capture = false;
                        buffer.Length = 0;
                    }
                    else if (String.Compare(tag.Name, "/tr", true) == 0)
                    {
                        if (list.Count > 0)
                        {
                            ProcessTableRow(list);
                            list.Clear();
                        }
                    }
                    else if (String.Compare(tag.Name, "td", true) == 0)
                    {
                        if (buffer.Length > 0)
                            list.Add(buffer.ToString());
                        buffer.Length = 0;
                        capture = true;
                    }
                    else if (String.Compare(tag.Name, "/td", true) == 0)
                    {
                        list.Add(buffer.ToString());
                        buffer.Length = 0;
                        capture = false;
                    }
                    else if (String.Compare(tag.Name, "/table", true) == 0)
                    {
                        break;
                    }
                }
                else
                {
                    if (capture)
                        buffer.Append((char)ch);
                }
            }
        }
        /// <summary>
        /// Use the cookie to search for the specified state or capital.  The search
        /// method can be called multiple times per login.
        /// </summary>
        /// <param name="search">The search string to use.</param>
        /// <param name="type">What to search for(s=state,c=capital).</param>
        /// <returns>A list of states or capitals.</returns>
        public List<String> Search(String search, String type)
        {
            String listType = "ul";
            String listTypeEnd = "/ul";
            StringBuilder buffer = new StringBuilder();
            bool capture = false;
            List<String> result = new List<String>();

            // build the request
            Uri url = new Uri("http://www.httprecipes.com/1/8/menuc.php");
            

            HttpWebRequest http = (HttpWebRequest)HttpWebRequest.Create(url);
            http.CookieContainer = cookies;
            http.Timeout = 30000;
            http.ContentType = "application/x-www-form-urlencoded";
            http.Method = "POST";
            
            Stream ostream = http.GetRequestStream();

            // perform the post
            FormUtility form = new FormUtility(ostream, null);
            form.Add("search", search);
            form.Add("type", type);
            form.Add("action", "Search");
            form.Complete();
            ostream.Close();

            // read the results
            WebResponse response = http.GetResponse();
            Stream istream = response.GetResponseStream();
            ParseHTML parse = new ParseHTML(istream);

            // parse from the URL

            Advance(parse, listType, 0);

            int ch;
            while ((ch = parse.Read()) != -1)
            {
                if (ch == 0)
                {
                    HTMLTag tag = parse.Tag;
                    if (String.Compare(tag.Name, "li", true) == 0)
                    {
                        if (buffer.Length > 0)
                            result.Add(buffer.ToString());
                        buffer.Length = 0;
                        capture = true;
                    }
                    else if (String.Compare(tag.Name, "/li", true) == 0)
                    {
                        result.Add(buffer.ToString());
                        buffer.Length = 0;
                        capture = false;
                    }
                    else if (String.Compare(tag.Name, listTypeEnd, true) == 0)
                    {
                        result.Add(buffer.ToString());
                        break;
                    }
                }
                else
                {
                    if (capture)
                        buffer.Append((char)ch);
                }
            }

            return result;
        }
        /// <summary>
        /// Access the website and perform a search for either states or capitals.
        /// </summary>
        /// <param name="search">A search string.</param>
        /// <param name="type">What to search for(s=state, c=capital)</param>
        public void Process(String search, String type)
        {
            String listType = "ul";
            String listTypeEnd = "/ul";
            StringBuilder buffer = new StringBuilder();
            bool capture = false;

            // Build the URL.
            MemoryStream mstream = new MemoryStream();
            FormUtility form = new FormUtility(mstream, null);
            form.Add("search", search);
            form.Add("type", type);
            form.Add("action", "Search");
            form.Complete();

            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();

            String str = enc.GetString(mstream.GetBuffer());
            String surl = "http://www.httprecipes.com/1/7/get.php?" + str;
            Uri url = new Uri(surl);
            WebRequest http = HttpWebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)http.GetResponse();
            Stream istream = response.GetResponseStream();
            ParseHTML parse = new ParseHTML(istream);

            // Parse from the URL.

            Advance(parse, listType, 0);

            int ch;
            while ((ch = parse.Read()) != -1)
            {
                if (ch == 0)
                {
                    HTMLTag tag = parse.Tag;
                    if (String.Compare(tag.Name, "li", true) == 0)
                    {
                        if (buffer.Length > 0)
                            ProcessItem(buffer.ToString());
                        buffer.Length = 0;
                        capture = true;
                    }
                    else if (String.Compare(tag.Name, "/li", true) == 0)
                    {
                        ProcessItem(buffer.ToString());
                        buffer.Length = 0;
                        capture = false;
                    }
                    else if (String.Compare(tag.Name, listTypeEnd, true) == 0)
                    {
                        ProcessItem(buffer.ToString());
                        break;
                    }
                }
                else
                {
                    if (capture)
                        buffer.Append((char)ch);
                }
            }
        }
        /**
         * Access the website and perform a search for either states or capitals.
         * @param search A search string.
         * @param type What to search for(s=state, c=capital)
         * @throws IOException Thrown if an IO exception occurs.
         */
        public void Process(String search, String type)
        {
            String listType = "ul";
            String listTypeEnd = "/ul";
            StringBuilder buffer = new StringBuilder();
            bool capture = false;

            // Build the URL and POST.
            Uri url = new Uri("http://www.httprecipes.com/1/7/post.php");
            WebRequest http = HttpWebRequest.Create(url);
            http.Timeout = 30000;
            http.ContentType = "application/x-www-form-urlencoded";
            http.Method = "POST";
            Stream ostream = http.GetRequestStream();

            FormUtility form = new FormUtility(ostream, null);
            form.Add("search", search);
            form.Add("type", type);
            form.Add("action", "Search");
            form.Complete();
            ostream.Close();

            // read the results
            HttpWebResponse response = (HttpWebResponse)http.GetResponse();
            Stream istream = response.GetResponseStream();

            ParseHTML parse = new ParseHTML(istream);

            // parse from the URL

            Advance(parse, listType, 0);

            int ch;
            while ((ch = parse.Read()) != -1)
            {
                if (ch == 0)
                {
                    HTMLTag tag = parse.Tag;
                    if (String.Compare(tag.Name, "li", true) == 0)
                    {
                        if (buffer.Length > 0)
                            ProcessItem(buffer.ToString());
                        buffer.Length = 0;
                        capture = true;
                    }
                    else if (String.Compare(tag.Name, "/li", true) == 0)
                    {
                        ProcessItem(buffer.ToString());
                        buffer.Length = 0;
                        capture = false;
                    }
                    else if (String.Compare(tag.Name, listTypeEnd, true) == 0)
                    {
                        ProcessItem(buffer.ToString());
                        break;
                    }
                }
                else
                {
                    if (capture)
                        buffer.Append((char)ch);
                }
            }
        }