	
	function ajax_reqestObject()
	{
		var http_request = false;
		
		if (window.XMLHttpRequest)
		{ // Mozilla, Safari, ...
			http_request = new XMLHttpRequest();
			
			if (http_request.overrideMimeType)
				http_request.overrideMimeType('text/xml');
		}
		else if (window.ActiveXObject)
		{ // IE
			try
			{
				http_request = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (e)
			{
				try
				{
					http_request = new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch (e) {}
			}
		}
		
		return http_request;
	}
	
	function ajax_sendRequest(function_handle,other_args,method,url,sync,data)
	{
		var http_req = ajax_reqestObject();
		if (!http_req)			// browser not supported
			return false;
		
		// set defaults ------------
		if (sync == null)
			sync = true;
		
		// set the function handler ------------
		http_req.onreadystatechange = function() {ajax_funcWrapper(function_handle,http_req,other_args); };
		
		// open URL
		http_req.open(method.toUpperCase(),url, sync);
		
		// set the headers -----------
		if (data != null)
			http_req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			
		http_req.send(data);
		return true;
	}
	
	function ajax_funcWrapper(function_handle,http_req,other_args)
	{
		eval(function_handle+ "(http_req,other_args);");	
	}
	
	function ajax_simpleDynamicContent(http_req,arr)
	{
		var div_name = arr[0];
		var error_txt = arr[1];
		
		var elem = document.getElementById(div_name);
		if (elem == null)
			return;
		
		if (http_req.readyState == 4 && http_req.status == 200)
		{
			elem.scrollTop = 0;
			try
			{
				var xmldoc = http_req.responseXML;
				var root_node = xmldoc.getElementsByTagName('root').item(0);
				elem.innerHTML = root_node.firstChild.data;
			}
			catch(e)
			{
				elem.innerHTML = error_txt;	
			}
		}
		else if (http_req.readyState == 4)
		{
			elem.scrollTop = 0;
			if (error_txt == null || error_txt == '')
				error_txt = "Error: Unable to retrieve web page.";
			elem.innerHTML = error_txt;
		}
	}
	
	/*** Below are some helpful DOM manipulation functions
		from mozilla.
		
	* Author: L. David Baron
     * Last Updated Date: January 1, 2003
     * Copyright Information: c 1998-2005 by individual mozilla.org contributors;
     	content available under a Creative Commons license 
		
	*/
	
	/**
	 * Throughout, whitespace is defined as one of the characters
	 *  "\t" TAB \u0009
	 *  "\n" LF  \u000A
	 *  "\r" CR  \u000D
	 *  " "  SPC \u0020
	 *
	 * This does not use Javascript's "\s" because that includes non-breaking
	 * spaces (and also some other characters).
	 */
	
	
	/**
	 * Determine whether a node's text content is entirely whitespace.
	 *
	 * @param nod  A node implementing the |CharacterData| interface (i.e.,
	 *             a |Text|, |Comment|, or |CDATASection| node
	 * @return     True if all of the text content of |nod| is whitespace,
	 *             otherwise false.
	 */
	function is_all_ws( nod )
	{
	  // Use ECMA-262 Edition 3 String and RegExp features
	  return !(/[^\t\n\r ]/.test(nod.data));
	}
	
	
	/**
	 * Determine if a node should be ignored by the iterator functions.
	 *
	 * @param nod  An object implementing the DOM1 |Node| interface.
	 * @return     true if the node is:
	 *                1) A |Text| node that is all whitespace
	 *                2) A |Comment| node
	 *             and otherwise false.
	 */
	
	function is_ignorable( nod )
	{
	  return ( nod.nodeType == 8) || // A comment node
	         ( (nod.nodeType == 3) && is_all_ws(nod) ); // a text node, all ws
	}
	
	/**
	 * Version of |previousSibling| that skips nodes that are entirely
	 * whitespace or comments.  (Normally |previousSibling| is a property
	 * of all DOM nodes that gives the sibling node, the node that is
	 * a child of the same parent, that occurs immediately before the
	 * reference node.)
	 *
	 * @param sib  The reference node.
	 * @return     Either:
	 *               1) The closest previous sibling to |sib| that is not
	 *                  ignorable according to |is_ignorable|, or
	 *               2) null if no such node exists.
	 */
	function node_before( sib )
	{
	  while ((sib = sib.previousSibling)) {
	    if (!is_ignorable(sib)) return sib;
	  }
	  return null;
	}
	
	/**
	 * Version of |nextSibling| that skips nodes that are entirely
	 * whitespace or comments.
	 *
	 * @param sib  The reference node.
	 * @return     Either:
	 *               1) The closest next sibling to |sib| that is not
	 *                  ignorable according to |is_ignorable|, or
	 *               2) null if no such node exists.
	 */
	function node_after( sib )
	{
	  while ((sib = sib.nextSibling)) {
	    if (!is_ignorable(sib)) return sib;
	  }
	  return null;
	}
	
	/**
	 * Version of |lastChild| that skips nodes that are entirely
	 * whitespace or comments.  (Normally |lastChild| is a property
	 * of all DOM nodes that gives the last of the nodes contained
	 * directly in the reference node.)
	 *
	 * @param sib  The reference node.
	 * @return     Either:
	 *               1) The last child of |sib| that is not
	 *                  ignorable according to |is_ignorable|, or
	 *               2) null if no such node exists.
	 */
	function last_child( par )
	{
	  var res=par.lastChild;
	  while (res) {
	    if (!is_ignorable(res)) return res;
	    res = res.previousSibling;
	  }
	  return null;
	}
	
	/**
	 * Version of |firstChild| that skips nodes that are entirely
	 * whitespace and comments.
	 *
	 * @param sib  The reference node.
	 * @return     Either:
	 *               1) The first child of |sib| that is not
	 *                  ignorable according to |is_ignorable|, or
	 *               2) null if no such node exists.
	 */
	function first_child( par )
	{
	  var res=par.firstChild;
	  
	  while (res) {
	    if (!is_ignorable(res)) return res;
	    res = res.nextSibling;
	  }
	  return null;
	}
	
	/**
	 * Version of |data| that doesn't include whitespace at the beginning
	 * and end and normalizes all whitespace to a single space.  (Normally
	 * |data| is a property of text nodes that gives the text of the node.)
	 *
	 * @param txt  The text node whose data should be returned
	 * @return     A string giving the contents of the text node with
	 *             whitespace collapsed.
	 */
	function data_of( txt )
	{
	  var data = txt.data;
	  // Use ECMA-262 Edition 3 String and RegExp features
	  data = data.replace(/[\t\n\r ]+/g, " ");
	  if (data.charAt(0) == " ")
	    data = data.substring(1, data.length);
	  if (data.charAt(data.length - 1) == " ")
	    data = data.substring(0, data.length - 1);
	  return data;
	}