function DOM()
{
	this.ELEMENT_NODE = 1;
	this.ATTRIBUTE_NODE = 2;
	this.TEXT_NODE = 3;
	this.CDATA_SECTION_NODE = 4;
	this.ENTITY_REFERENCE_NODE = 5;
	this.ENTITY_NODE = 6;
	this.PROCESSING_INSTRUCTION_NODE = 7;
	this.COMMENT_NODE = 8;
	this.DOCUMENT_NODE = 9;
	this.DOCUMENT_TYPE_NODE = 10;
	this.DOCUMENT_FRAGMENT_NODE = 11;
	this.NOTATION_NODE = 12;
	/**
	 * This method creates an element of type as specified by the tag and attaches the
	 * specified attributes.
	 * @param pElementTag - The Name of the element that has to be created.
	 * @param pAttributes - An array of Attribute objects having details of attributes to be
	 * associated with the element.
     */
	this.createNewElement = function(pElementTag, pAttributes)
	{
		var lCount;
		var lElement;
		var lElementString;
		//To determine that the browser is IE. document.all is available only in IE.
		if (document.all)
		{
			lElementString = "<" + pElementTag + " ";
			if (pAttributes != null)
			{
				for (lCount = 0; lCount < pAttributes.length; lCount++)
				{
					if (pAttributes[lCount] != null )
					{
						if (pAttributes[lCount].name.length > 0)
						{
							lElementString += pAttributes[lCount].name + "=\"" + pAttributes[lCount].value + "\" ";
						}
					}
				}
			}
			lElementString += ">";
			lElement = document.createElement(lElementString);
		}
		else
		{
			lElement = document.createElement(pElementTag);
			if (pAttributes != null)
			{
				for (lCount = 0; lCount < pAttributes.length; lCount++)
				{
					if (pAttributes[lCount] != null )
					{
						if (pAttributes[lCount].name.length > 0)
						{
							lElement.setAttribute(pAttributes[lCount].name, pAttributes[lCount].value);
						}
					}
				}
			}
		}
		return lElement;
	};
	/**
	 * This method returns the element of the type requested based with the
	 * attribute value as specified.
	 * @param {Object} pRoot - The base element from which we need to search.
	 * @param {Object} pNodeName - The Name of the Node that needs to be searched for
	 * @param {Object} pAttribute - The Attribute Name and Value to be searched for.
	 */
	this.getElementByAttributeValue = function(pRoot, pNodeName, pAttribute)
	{
		var lCount;
		var lRequiredElementCount;
		var lElement;
		var lChildNode;
		var lAttribute;
		lElement = null;
		lRequiredElementCount = 0;
		pNodeName = pNodeName.toUpperCase();
		pAttribute.value = pAttribute.value.toUpperCase();
		pAttribute.name = pAttribute.name.toUpperCase();
		if (pRoot.childNodes != null)
		{
			for (lCount = 0; lCount < pRoot.childNodes.length; lCount++)
			{
				lChildNode = pRoot.childNodes[lCount];
				if (lChildNode.nodeName.toUpperCase() == pNodeName)
				{
					lAttribute = lChildNode.attributes.getNamedItem(pAttribute.name);
					if (lAttribute)
					{
						if (lAttribute.value.toUpperCase() == pAttribute.value)
						{
							lElement = lChildNode;
							break;
						}
					}
				}
			}
		}
		return lElement;
	};
	/**
	 * This gets the element with the specified node name from the specified root.
	 * @param {Object} pRoot - The Root from which to search.
	 * @param {Object} pNodeName - The Node Name that needs to be searched for.
	 */
	this.getElement = function(pRoot, pNodeName)
	{
		var lCount;
		var lElement;
		var lChild;
		lElement = null;
		pNodeName = pNodeName.toUpperCase();
		if (pRoot.childNodes != null)
		{
			for (lCount = 0; lCount < pRoot.childNodes.length; lCount++)
			{
				lChild = pRoot.childNodes[lCount];
				if (lChild.nodeName.toUpperCase() == pNodeName)
				{
					lElement = lChild;
					break;
				}
			}
		}
		return lElement;
	};
	/**
	 * This method gets tthe element with the specified node name and at the position
	 * specified with respect to the root node.
	 * @param {Object} pRootNode - The Root Node from which the search is to be started.
	 * @param {Object} pNodeName - The name of the Node that is to be fetched.
	 * @param {Object} pPosition - The position of the Node with respect to the Root Node.
	 */
	this.getElementByPosition = function(pRootNode, pNodeName, pPosition)
	{
		var lCount;
		var lRequiredElementCount;
		var lElement;
		var lChildNode;
		lElement = null;
		lRequiredElementCount = 0;
		pNodeName = pNodeName.toUpperCase();
		if (pRootNode.childNodes != null)
		{
			for (lCount = 0; lCount < pRootNode.childNodes.length; lCount++)
			{
				lChildNode = pRootNode.childNodes[lCount];
				if (lChildNode.nodeName.toUpperCase() == pNodeName)
				{
					lRequiredElementCount++;
					if (lRequiredElementCount == pPosition)
					{
						lElement = lChildNode;
						break;
					}
				}
			}
		}
		return lElement;
	};
	/**
	 * The counts the number of elements with the specified node name under the specified
	 * Root Node.
	 * @param {Object} pRootNode - The Root Node under which the specified node needs to be counted.
	 * @param {Object} pNodeName - The name of the Node that needs to be counted.
	 */
	this.countElements = function(pRootNode, pNodeName)
	{
		var lChildNode;
		var lCount;
		var lElementCount;
		lElementCount = 0;
		pNodeName = pNodeName.toUpperCase();
		if (pRootNode.childElements != null)
		{
			for (lCount = 0; lCount < pRootNode.childNodes.length; lCount++)
			{
				lChildNode = pRootNode.childNodes[lCount];
				if (lChildNode.nodeName.toUpperCase() == pNodeName)
				{
					lElementCount++;
				}
			}
		}
		return lElementCount;
	};
	/**
	 * This adds an event listener to an element.
	 * @param {Object} pElement - The element to which the event listener has to be added.
	 * @param {Object} pEvent - The Event for which the Event Listener has to be added.
	 * @param {Object} pFunction - The Event Listener function.
	 * @param {Object} pUseCapture - This is required.
	 */
	this.addEventListener = function(pElement, pEvent, pFunction, pUseCapture)
	{
		if (pElement.addEventListener)
		{
			pElement.addEventListener(pEvent, pFunction, pUseCapture);
		}
		else
		{
			pElement.attachEvent("on" + pEvent, pFunction);
		}
	};
	/**
	 * This gets the target element with the the specified Event is associated.
	 * @param {Object} pEvent - The Event from which the Target node is to be fetched.
	 */
	this.getTargetElement = function(pEvent)
	{
		var lTargetElement;
		if (pEvent.srcElement)
		{
			lTargetElement = pEvent.srcElement;
		}
		else
		{
			lTargetElement = pEvent.target;
		}
		return lTargetElement;
	};
	/**
	 * This gets the position of an element.
	 * @param {Object} pElement - The Element the position of which is to be returned.
	 */
	this.getPosition = function (pElement)
	{
		var lCurrentLeft = 0;
		var lCurrentTop = 0;
		if (pElement.offsetParent)
		{
			lCurrentLeft = pElement.offsetLeft;
			lCurrentTop = pElement.offsetTop;
			while (pElement = pElement.offsetParent)
			{
				lCurrentLeft += pElement.offsetLeft;
				lCurrentTop += pElement.offsetTop;
			}
		}
		return [lCurrentLeft,lCurrentTop];
	};
	/**
	 * This gets the size of an element.
	 * @param {Object} pElement - The Element the size of which is to be returned.
	 */
	this.getSize = function (pElement)
	{
		var lWidth = 0;
		var lHeight = 0;
		return [lWidth, lHeight];
	};
	/**
	 * This method gets the width of the Window visible on the screen.
	 */
	this.getWindowWidth = function()
	{
		var lWidth;
		if( typeof( window.innerWidth ) == 'number' )
		{
    		//Non-IE
    		lWidth = window.innerWidth;
  		}
		else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
		{
	    	//IE 6+ in 'standards compliant mode'
    		lWidth = document.documentElement.clientWidth;
  		}
		else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
		{
    		//IE 4 compatible
    		lWidth = document.body.clientWidth;
  		}
		return lWidth;		
	};
	/**
	 * This method gets the height of the Window visible on the screen.
	 */
	this.getWindowHeight = function()
	{
		var lHeigth;
		if(typeof(window.innerWidth) == 'number')
		{
    		//Non-IE
		    lHeight = window.innerHeight;
  		}
		else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight))
		{
    		//IE 6+ in 'standards compliant mode'
    		lHeight = document.documentElement.clientHeight;
  		}
		else if (document.body && ( document.body.clientWidth || document.body.clientHeight))
		{
    		//IE 4 compatible
    		lHeight = document.body.clientHeight;
  		}
		return lHeight;
	};
	/**
	 * This gets the XScroll position of the body with respect to the browser window.
	 */
	this.getXScroll = function()
	{
		var lXScroll;
	  	if (typeof( window.pageYOffset ) == 'number')
		{
	    	//Netscape compliant
	    	lXScroll = window.pageXOffset;
	  	}
		else if (document.body && ( document.body.scrollLeft || document.body.scrollTop))
		{
	    	//DOM compliant
		    lScrollX = document.body.scrollLeft;
	  	}
		else if (document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop))
		{
	    	//IE6 standards compliant mode
		    lScrollX = document.documentElement.scrollLeft;
	  	}
	  	return lScrollX;
	};
	/**
	 * This gets the YScroll position of the body with respect to the browser window.
	 */
	this.getYScroll = function()
	{
		var lScrollY;
	  	if (typeof( window.pageYOffset ) == 'number' )
		{
	    	//Netscape compliant
	    	lScrollY = window.pageYOffset;
	  	}
		else if (document.body && ( document.body.scrollLeft || document.body.scrollTop))
		{
	    	//DOM compliant
	    	lScrollY = document.body.scrollTop;
	  	}
		else if(document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop))
		{
		    //IE6 standards compliant mode
		    lScrollY = document.documentElement.scrollTop;
		}
	  	return lScrollY;
	};
	this.parseXML = function(pText)
	{
	    if (typeof DOMParser != "undefined")
		{
	        // Mozilla, Firefox, and related browsers
	        return (new DOMParser()).parseFromString(pText, "application/xml");
	    }
	    else if (typeof ActiveXObject != "undefined")
		{
	        // Internet Explorer.
	        var doc = XML.newDocument();  // Create an empty document
	        doc.loadXML(pTet);            // Parse text into it
	        return doc;                   // Return it
	    }
	    else
		{
	        // As a last resort, try loading the document from a data: URL
	        // This is supposed to work in Safari. Thanks to Manos Batsis and
	        // his Sarissa library (sarissa.sourceforge.net) for this technique.
	        var url = "data:text/xml;charset=utf-8," + encodeURIComponent(pText);
	        var request = new XMLHttpRequest();
	        request.open("GET", url, false);
	        request.send(null);
	        return request.responseXML;
	    }
	}
	/**
	 * This method checks if a specified node is null. I.e. the node has not values.
	 * @param {Object} pNode - The Node to be checked.
	 */
	this.isNodeNull = function(pNode)
	{
		var lIsNull = true;
		if (pNode.nodeType == this.TEXT_NODE && pNode.nodeValue)
		{
			var lCount;
			var lChar;
			for (lCount = 0; lCount < pNode.nodeValue.length && lIsNull; lCount++)
			{
				lChar = pNode.nodeValue.substring(lCount, lCount + 1);
				lIsNull = (lChar == " " || lChar == "\n" || lChar == "\r" || lChar == "\t");
			}
		}
		else
		{
			lIsNull = false;
		}
		return lIsNull;
	}
}