(
	function()
	{
		try
		{
			if (!ognc.exists)
			{
				throw "ogncObjUndefined";
			}
			
			ognc.dom2xml =
			{
				// function convert
				// This is the only publicly accessible method of the dom2xml object.
				// Converts a section of the DOM tree into valid XML.
				// PARAMS
				//     selector: [optional] Takes any valid CSS selector to choose the DOM branch to convert. Defaults to 'body'.
				//     index: [optional] Specify which item in an array of selected elements to use. Defaults to '0'.
				convert : (function()
				{
					// Convert is a closure to obscure private members that should not be used on their own.
					// The only interface for this class is the convert method itself.
			
					// Storage array for thus-far parsed XML tokens.
					var xml_array = [];
					
					// function route_and_handle_node
					// Takes a node and hands it off to its correct handler function.
					// PARAMS
					//     node: [required] The DOM node to handle.
					function route_and_handle_node(node)
					{
						switch (node.nodeType)
						{
							case 1:
								handle_element(node);
								break;
							case 3:
								handle_text(node);
								break;
							case 8:
								handle_comment(node);
								break;
							default:
								throw "dom2xml: unknown attribute type";
						}
					}
			
					// function handle_element
					// Takes an element node and converts it, attributes, children, and all to an XML string snippet.
					// PARAMS
					//     node: [required] The DOM node to convert.
					function handle_element(node)
					{
						// Begin the new XML element
						xml_array.push('<'+node.nodeName.toLowerCase());
						
						// Check to see if there are attributes in this node
						if (node.attributes.length)
						{
							// Get the known-existent list of attributes and iterate over them
							var attrs = node.attributes;
							
							for (var length = attrs.length, i = 0; i < length; i++)
							{
								// IE 5-8 (all currently shipping versions) always list all possible attributes, specified or not.
								// The "specified" member of each attribute indicates whether it was existent in the HTML and is required for the purpose here.
								// IE will also report the unique jQuery identifiers as well as jQuery's sizzle engine cache attributes, so parse those out entirely.
			
								if (attrs[i].specified
									&& attrs[i].nodeValue != null
									&& attrs[i].nodeName.indexOf("jQuery") == -1
									&& attrs[i].nodeName.indexOf("$tmp") == -1
									&& attrs[i].nodeName.indexOf("sizcache") == -1
									&& attrs[i].nodeName.indexOf("sizset") == -1)
								{
									// Ensure quotes won't break the string and add the now parsed attribute to the array
									//xml_array.push(' '+attrs[i].nodeName+'="'+attrs[i].nodeValue.replace(/\"/g, "&#34;")+'"');
									var stringAttributeValue = attrs[i].nodeValue.toString();
									
									if(stringAttributeValue.indexOf('function') == -1) 
									{
										xml_array.push(" " + attrs[i].nodeName + "=\"" + stringAttributeValue.replace(/\"/g, "&#34;") + "\"");
									}
								}
							}
						}
						
						// Check to see if this node has child nodes (including text). If not, it's self-closing.
						var children = jQuery(node).contents();
			
						if (children.length)
						{
							xml_array.push(">"); // Close the parent's opening tag
							
							// Iterate over children and recursively route them to the correct function.
							for (var length = children.length, i = 0; i < length; i++)
							{
								route_and_handle_node(children[i]);
							}
			
							// Children have now been handled. Close the parent tag.
							xml_array.push("</" + node.nodeName.toLowerCase() + ">");
						}
						else
						{
							// Tag is self-closing so merely close it right now.
							xml_array.push(" />");
						}
					}
					
					// function handle_text
					// Takes an element node and converts its text to an XML string snippet.
					// PARAMS
					//     node: [required] The DOM text node to convert.
					function handle_text(node)
					{
						xml_array.push(node.nodeValue);
					}
					
					// function handle_comment
					// Takes a comment node and converts its text to an XML string snippet.
					// PARAMS
					//     node: [required] The DOM comment node to convert.
					function handle_comment(node)
					{
						xml_array.push("<!-- " + node.nodeValue + " -->");
					}
			
					// function convert closure
					// The actual function which is publicly accessible.
					// Converts the specified element (by CSS selector and index) into an XML snippet.
					// For more info: see documentation on the convert() function itself.
					return function(selector, index)
					{
						// Remove any previous contents in the XML array 
						xml_array = new Array();
						route_and_handle_node(jQuery(selector || "body").get(index || 0));
						return xml_array.join("");
					}
				})()
			};
		}
		catch(e)
		{
			ognc.standard_error_handler(e);
		}
	}
)();
