function dump(arr,level) 
{
	var dumped_text = "";
	if (!level) 
		level = 0;

	//The padding given at the beginning of the line.
	var level_padding = "";
	var value;
	for( var j=0; j<level+1; j++) 
		level_padding += "    ";

	if(typeof(arr) == 'object') 
	{ //Array/Hashes/Objects
		for (var it in arr) 
		{
			if (!it)
				continue;

			value = arr[it];
 
			if (typeof value == 'object' ) 
			{ 
				dumped_text += level_padding + "'" + it + "' ...\n";
				if (typeof arr != 'object')
					dumped_text += dump(value,level+1);
			} 
			else 
			{
				if (typeof value == "function")
					continue;

					dumped_text += level_padding + "'" + it + "' => \"" + value + "\"\n";
			}
		}
	} 
	else 
	{ //Stings/Chars/Numbers etc.
		dumped_text = arr+" ("+typeof(arr)+")";
	}
	return dumped_text;
} 

function iremove(obj)
{
	obj.parentNode.removeChild(obj);
}

function nodeName(elem, name)
{
	return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
}

// args is for internal usage only
function each( obj, fn, args ) 
{
	if ( obj.length == undefined )
//		for ( var i in obj )
			fn.apply( obj[i], args || [i, obj[i]] );
	else
		for ( var i = 0, ol = obj.length; i < ol; i++ )
			if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
	return obj;
}

function DOMmanip(o, args, table, dir, fn)
{
	var clone = o.length > 1; 
	var a = createfrom(args);
	if ( dir < 0 )
		a.reverse();

	return each(o, function(){
		var obj = o;

		if ( table && nodeName(o, "table") && nodeName(a[0], "tr") )
			obj = o.getElementsByTagName("tbody")[0] || o.appendChild(document.createElement("tbody"));

		each( a, function(){
			fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
		})});
}


function iparent(obj, type)
{
	cur = obj.parentNode;
	while ( cur && cur != document ) 
	{
		if (cur.nodeName == type)
			return cur;
		cur = cur.parentNode;
	}
}

function byid(id)
{
	return document.getElementById(id);
}

function before(obj, ins)
{
	return DOMmanip(obj, ins, false, 1, function(a) {
		obj.parentNode.insertBefore( a, obj );
		});
}

function createfrom(s)
{
	if (!s)
		return;

	var r = [];

	if ( typeof s == "string" ) 
	{
		var b = navigator.userAgent.toLowerCase();
	
		// Figure out what browser is being used
		var browser = {
			safari: /webkit/.test(b),
			opera: /opera/.test(b),
			msie: /msie/.test(b) && !/opera/.test(b),
			mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b)
		};

		var wrap =
			 // option or optgroup
			!s.indexOf("<opt") &&
			[1, "<select>", "</select>"] ||
		
			(!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot")) &&
			[1, "<table>", "</table>"] ||
			
			!s.indexOf("<tr") &&
			[2, "<table><tbody>", "</tbody></table>"] ||
		
		 	// <thead> matched above
			(!s.indexOf("<td") || !s.indexOf("<th")) &&
			[3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
		
			[0,"",""];

		div = create("div");
		div.innerHTML = wrap[1] + s + wrap[2];

		// Move to the right depth
		while ( wrap[0]-- )
			div = div.firstChild;

		// Remove IE's autoinserted <tbody> from table fragments
		if ( browser.msie ) 
		{
			var tb = [];
			// String was a <table>, *may* have spurious <tbody>
			if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 ) 
				tb = div.firstChild && div.firstChild.childNodes;

			// String was a bare <thead> or <tfoot>
			else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
				tb = div.childNodes;

			for ( var n = tb.length-1; n >= 0 ; --n )
				if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
				tb[n].parentNode.removeChild(tb[n]);
		}

		for (var i=0, l=div.childNodes.length; i<l; i++)
			r.push(div.childNodes[i]);
	}
	else
	{
		r = s;
	}

	return r;
}


function create(type)
{
	if (document.createElementNS)
		return document.createElementNS("http://www.w3.org/1999/xhtml", type);
	else
		return document.createElement(type);
}
