whole_func_string: function print_rr (objRef, strObjRef) 
  {
  	// Objects Properties
  	// Container for this instance of Print_R
  	this.container = {};
  	// Reference to the Title Bar
  	this.titleBar = {};
  	// Reference to the Body 
  	this.body = {};
  	// Reference to Header
  	this.header = {};
  	// Object Reference to Object we are viewing
  	this.objRef = objRef;
  	// String Representation of object we are viewing
  	this.strObjRef = strObjRef;
  	// Object Reference to refresh Button
  	this.refreshBtn = {};
  	// Object Reference to Close Button
  	this.closeBtn = {};
  	// Parsed parts of object we are viewing
  	this.arrStrObjRef = [];
  	// Simple name of Variable we are parsing
  	this.objParseName = "";
  	/*
  		converts strObjRef to an Array of the parts of the object i,e ["window", "document", "childNodes", "[", "0", "]"]
  	*/
  	this.parseStrObjRef = function ()
  	{
  		// first split on the "." character	
  		var temp = this.strObjRef;
  		//alert ("'" + temp + "'");
  		var temp2 = [];
  		var x = 0;
  		var buffer = ""; 	
  		var inSingle = false;
  		var inDouble = false;
  		var inBracket = false;	
  		//Now check for "[" and "]" chars to indicate arrays
  		for (var elem =0;elem < temp.length;elem++)
  		{
  			// make sure we only look at the array elements not the clear() function
  				switch (temp.charAt(elem))
  				{					
  					case "'":
  						if (!inDouble)
  						{	
  							if (inSingle)
  							{
  								inSingle = false;
  							}						
  							else
  							{
  								inSingle = true;
  							}
  						}	
  						buffer += temp.charAt(elem);
  						break;
  					case '"':
  						if (!inSingle)
  						{	
  							if (inDouble)
  							{
  								inDouble = false;
  							}						
  							else
  							{
  								inDouble = true;
  							}
  						}
  						buffer += temp.charAt(elem);
  						break;
  					case "[":
  						if (!inSingle && !inDouble)
  						{
  							inBracket = true;
  							if (buffer != "")
  							{				
  								temp2[temp2.length] = buffer;								
  							}					
  							buffer = new String();						
  							temp2[temp2.length] = temp.charAt(elem);							
  						}
  						else
  						{
  							buffer += temp.charAt(elem);
  						}
  						break;
  					case "]":
  						if (!inSingle && !inDouble)
  						{
  							inBracket = false;
  							if (buffer != "")
  							{				
  								temp2[temp2.length] = buffer;								
  							}
  							buffer = new String();
  							temp2[temp2.length] = temp.charAt(elem);							
  						}	
  						else
  						{
  							buffer += temp.charAt(elem);
  						}					
  						break;
  					case ".":
  						if (!inSingle && !inDouble && !inBracket)
  						{
  							if (buffer != "")
  							{
  								temp2[temp2.length] = buffer;
  								temp2[temp2.length] = temp.charAt(elem);
  							}											
  							buffer = "";	
  						}
  						else
  						{
  							buffer += temp.charAt(elem);
  						}
  						break;
  					default: 						
  						buffer += temp.charAt(elem);						
  						break;
  				}
  				if (buffer != "]" && buffer != "" && buffer != null)
  				{
  					this.objParseName = buffer;
  				}
  								//will be overwritten unless it is the last entry 
  				// which is the one we want							
  			}			
  			
  		
  		if (buffer != "")
  		{
  			temp2[temp2.length] = buffer;			
  		}
  		//alert (temp2);	
  		// add the newly created array to our main object
  		this.arrStrObjRef = temp2;	
  		//alert (temp2);
  	};
  	// function to close the instance
  	this.close = function ()
  	{
  		document.body.removeChild(this.container);
  	}
  	// this function sets up the container for everything else
  	this.createContainers = function ()
  	{
  		//remove any existing Containers if for some reason it is called twice
  		try {
  			document.body.removeChild(this.container);
  		} catch (e){}	
  		this.container = document.createElement('div');
  		this.applyStyles (styleObj.container, this.container);
  		this.titleBar = document.createElement('div');
  		this.applyStyles (styleObj.titleBar, this.titleBar);	
  		this.container.appendChild(this.titleBar);
  		this.header = document.createElement('div');
  		this.container.appendChild(this.header);		
  		this.body = document.createElement('div');		
  		this.container.appendChild(this.body);
  	};	
  	// Function creates the title Bar
  	this.populateTitleBar = function ()
  	{			
  		var table = document.createElement('table');		
  		var tbody = table.appendChild(document.createElement('tbody'));
  		var tr = tbody.appendChild(document.createElement('tr'));
  		var td1 = tr.appendChild(document.createElement('td'));
  		td1.appendChild(document.createTextNode(this.objParseName));
  		var td2 = tr.appendChild(document.createElement('td'));
  		this.refreshBtn = td2.appendChild(document.createElement('button'));	
  		this.refreshBtn.appendChild(document.createTextNode('Refresh'));
  		this.closeBtn = td2.appendChild(document.createElement('button'));	
  		this.closeBtn.appendChild(document.createTextNode('close'));		
  		this.applyStyles(styleObj.propTable, table);		
  		this.applyStyles(styleObj.titleTd1, td1);
  		this.applyStyles(styleObj.titleTd2, td2);
  		this.titleBar.appendChild(table);
  	};
  	/*
  	//function creates the browseable header
  	this.populateHeader = function ()
  	{
  		//alert(this.arrStrObjRef);
  		// the string we will change this.objStrRef when updating object
  		var strRef = "";
  		// iterate through each element of this.arrStrObjRef
  		for (var x =0;x<this.arrStrObjRef.length;x++)
  		{
  			// if it is a "[" or a "]" char
  			if ((this.arrStrObjRef[x].match(/\[/g)) || (this.arrStrObjRef[x].match(/\]/g))) 
  			{
  				// just output a single char "[" or "]"
  				this.header.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  				// if it is a "[" make sure we add it to strRef
  				if (this.arrStrObjRef[x] == "[")
  				{
  					strRef += "[";	
  				}				
  			}
  			// it it is anything but a "[" or "]"
  			else
  			{
  				// we want to make it browseable
  				var a = document.createElement('a');
  				a.href = "javascript:void(0);";
  				// apply our styles
  				this.applyStyles (styleObj.a , a);
  				// add the name of the object we looking at
  				a.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  				// if there is a previous item in the list is it a "]" char 
  				if (this.arrStrObjRef[x-1] && this.arrStrObjRef[x-1] == "]" && x != (this.arrStrObjRef.length -1))
  				{
  					// if so we need to generate the "." char for output and strRef
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";
  				}	
  				// now add the name to strRef we do it here so that the "." is in the right place
  				strRef += this.arrStrObjRef[x];
  				//if the next item in the array is a "]"
  				if (this.arrStrObjRef[x+1] == "]")
  				{
  					// add it to strRef
  					strRef += "]";	
  				}	
  				// now we have a working strRef set the onclick handler for the output
  				a.onclick = clickMe(this, strRef);		
  				// add the "a" element to the dom				
  				this.header.appendChild(a);		
  				// now we need to add the "." operator to the dom and strRef for the next pass		
  				if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  				{
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";					
  				}				
  			}			
  		}
  		try 
  		{
  		// this makes sure we don't have trailing "."'s in our dom
  		if (this.header.lastChild.value == ".")
  		{			
  			this.header.removeChild(this.header.lastChild);
  		}
  		} catch (e){}		
  	};
  	*/
  	//function creates the browseable header
  	this.populateHeader = function ()
  	{
  		//alert(this.arrStrObjRef);
  		// the string we will change this.objStrRef when updating object
  		var strRef = "";
  		// iterate through each element of this.arrStrObjRef
  		var inBracket = false;
  		for (var x =0;x<this.arrStrObjRef.length;x++)
  		{
  			switch (this.arrStrObjRef[x])
  			{				
  				case "[":
  				case "]":				
  				case ".":
  					if (this.arrStrObjRef[x] == "[")
  					{
  						inBracket = true;
  					}	
  					if (this.arrStrObjRef[x] == "]")
  					{
  						inBracket = false;
  					}									
  					this.header.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  					if (this.arrStrObjRef[x] != "]")
  					{
  						strRef += this.arrStrObjRef[x];
  					}
  					break;
  				default:
  					if (this.arrStrObjRef[x-1] == ']')
  					{
  						this.header.appendChild(document.createTextNode("."));
  					strRef += ".";
  					}
  					var a = document.createElement('a');
  					a.appendChild(document.createTextNode(this.arrStrObjRef[x]));					
  					strRef += this.arrStrObjRef[x];					
  					if (inBracket)
  					{
  						strRef += "]";
  					}
  					a.onclick = clickMe(this, strRef);
  					a.href = "javascript:void(0);";
  					this.header.appendChild(a);
  			}
  			/*		
  			// if it is a "[" or a "]" char
  			if ((this.arrStrObjRef[x].match(/\[/g))) 
  			{
  				// just output a single char "[" or "]"
  				
  				// if it is a "[" make sure we add it to strRef
  				if (this.arrStrObjRef[x] == "[")
  				{
  					strRef += "[";	
  				}				
  			}
  			// it it is anything but a "[" or "]"
  			else
  			{
  				// we want to make it browseable
  				
  				
  				// apply our styles
  				this.applyStyles (styleObj.a , a);
  				// add the name of the object we looking at
  				
  				// if there is a previous item in the list is it a "]" char 
  				if (this.arrStrObjRef[x-1] && this.arrStrObjRef[x-1] == "]" && x != (this.arrStrObjRef.length -1))
  				{
  					// if so we need to generate the "." char for output and strRef
  					//this.header.appendChild(document.createTextNode("."));
  					//strRef += ".";
  				}	
  				// now add the name to strRef we do it here so that the "." is in the right place
  				strRef += this.arrStrObjRef[x];
  				//if the next item in the array is a "]"
  				if (this.arrStrObjRef[x] == "]")
  				{	
  					if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  					{
  						this.header.appendChild(document.createTextNode("."));
  						strRef += ".";					
  					}
  				}	
  				
  				if (this.arrStrObjRef[x] != "]")
  				{
  					// now we have a working strRef set the onclick handler for the output
  					a.onclick = clickMe(this, strRef);
  					a.href = "javascript:void(0);";
  				}		
  				// add the "a" element to the dom				
  				this.header.appendChild(a);		
  				// now we need to add the "." operator to the dom and strRef for the next pass		
  				if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  				{
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";					
  				}				
  			}
  			*/	
  			//alert(strRef);
  		}
  		try 
  		{
  		// this makes sure we don't have trailing "."'s in our dom
  		if (this.header.lastChild.value == ".")
  		{			
  			this.header.removeChild(this.header.lastChild);
  		}
  		} catch (e){}		
  	};
  	/*
  		This is the main function to populate the dom
  	*/
  	this.populateBody = function ()
  	{
  		// we want our properties, events, functions alphabatized so we need to cache them so we can sort them
  		var properties = [];
  		var functions = [];
  		var events = [];
  		// start creating the output dom
  		var table = document.createElement('table');
  		var tbodyobj = document.createElement('tbody');
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('th'));
  		this.applyStyles (styleObj.propTableTh, th1);
  		th1.appendChild(document.createTextNode('This Object'));
  		th1.colSpan = "3";
  		//Even if the object has no props we want to make sure we tell them about the object they are looking at
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('Name'));
  
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode(this.objParseName));
  		
  		th1.colSpan = "2";
  		
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('toString'));
  		
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		var pre = document.createElement('pre');
  		// in Some browsers calling the "toString" method of built in objects causes an error so plan for it
  		try 
  		{
  			pre.appendChild(document.createTextNode(getString(this.objRef)));
  				
  		}catch(e) {
  			pre.appendChild(document.createTextNode("undefined"));
  		}
  		th1.appendChild(pre);
  		this.applyStyles (styleObj.tostring, pre);
  		th1.colSpan = "2";
  		
  		
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('Type'));
  		
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);
  		var type= typeof(this.objRef);
  		// Arrays report to be Objects when typeof is used
  		// however if they are true arrays we attempt to compare their constructor to 
  		// known arrays constructor
  		if (properties.constructor == this.objRef.constructor)
  		{
  			type = "array";
  		}			
  		th1.appendChild(document.createTextNode(type));		
  		th1.colSpan = "2";
  		tbodyobj.appendChild(tr);
  		table.appendChild(tbodyobj);	
  		// start the dom ouptut for the props funcs and events		
  		var tbodyprops = document.createElement('tbody');
  		var tbodyfuncs = document.createElement('tbody'); 
  		var tbodyevents = document.createElement('tbody');
  		//this is main walking of object here
  		// it is enclosed in a try because enumerating a built in object sometimes causes an Error
  		var props = [];
  		var x = 0;
  		try{
  		  for (prop in this.objRef)
  		  {
  			props[props.length] = prop;			
  		  }
  		} catch(e) {}
  		
  			// the boolean false is not the same as null so we need another known false to test against
  			var boolFalse = false;
  			// enumerate over every property of this.objRef
  			for (prop in props)
  			{
  				//document.write(props[prop] +  "<br />");
  				if (props[prop] != 'sun')
  				{
  				try 
  				{
  					// as long as it is a valid object and not null run the typeof method on it
  					if (this.objRef[props[prop]] || this.objRef[props[prop]] == boolFalse)
  					{				
  						var type = typeof(this.objRef[props[prop]]);
  					}
  					// if it is null mark it with an * so we know it is not enumerable
  					else
  					{	
  						type = "object*";
  					}
  				}
  				catch (e) {
  					type = "undefined";
  				}
  				
  				// alright depending on the type of object add it to the appropriate array
  				switch (type)
  				{
  					// event handlers are always prefaced with _e__ so lets look for it
  					// btw event handlers are 
  					case "function":
  						if (prop.indexOf('_e__') > -1)
  						{
  							type = "event";
  							events[events.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						}
  						else
  						{													
  							functions[functions.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						}
  						break;						
  					case "boolean":
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;
  					case "string":				
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]) + unescape('%A0'), type:type};			
  						break;
  					case "number":
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;	
  					case "object":												
  						if (properties.constructor == this.objRef[props[prop]].constructor)
  						{
  							type = "array";
  						}						
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;
  					default:
  						properties[properties.length] = {name:props[prop], toString:"null", type:type};
  						break;
  				}
  				}
  				
  			}
  		
  		{
  			//alert('An Error occured ' + e.message);		
  		}
  		//var testObj2 = new Object();
  		//properties.push({name:"isPrototypeOf", toString:this.objRef["constructor"].isPrototypeOf(Array), type:typeof(this.objRef["constructor"])});		
  		// Write table is a reusable function for writing the tables out
  		if (typeof(this.objRef) != 'string')
  		{
  			writeTable(properties, tbodyprops, 'Properties', this);
  			writeTable(functions, tbodyfuncs, 'Methods', this);
  			writeTable(events, tbodyevents, 'Events', this);
  		}
  		// add the new Tbody elements to the table
  		table.appendChild(tbodyprops);
  		table.appendChild(tbodyfuncs);
  		table.appendChild(tbodyevents);
  		// apply appropriate styles
  		this.applyStyles (styleObj.propTable, table);
  		// Add to the body object
  		this.body.appendChild(table);
  		// Sometimes calling the toString of an object generates an error so we catch it here
  		function getString(ref)
  		{
  			try
  			{
  				if (ref)
  				{
  					try 
  					{	
  						return ref;
  					} catch (e) {
  						return ref.toString();
  					}
  				}
  				else {
  					try 
  					{
  						return ref.toString();
  					}
  					catch (e) 
  					{
  						return "undefined";
  					}
  				}
  				
  			} catch (e)
  			{
  				// if we can not convert it to a string write "undefined" just like javascript
  				return "undefined";
  			}
  		}
  		// helper function to perform repeating tasks
  		function writeTable(properties, tbodyprops, name, print_r)
  		{
  			// only output to the tbody if there are actually props to enumerate
  			if (properties.length > 0)
  			{
  				// Build the Header Row
  				var tr = tbodyprops.appendChild(document.createElement('tr'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTh, th1);
  				th1.appendChild(document.createTextNode(name));
  				th1.colSpan = "3";	
  				// Build the Header
  				var tr = tbodyprops.appendChild(document.createElement('tr'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);				
  				th1.appendChild(document.createTextNode('Name'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);
  				th1.appendChild(document.createTextNode('toString'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);
  				th1.appendChild(document.createTextNode('Type'));
  				// before we do anything lets alphabatize the list
  				properties.sort(arrSort);
  				// now we iterate through the list
  				for (prop in properties)
  				{
  					if (properties[prop] && properties[prop].name)
  					{
  					// create a row for the object
  					var tr = document.createElement('tr');
  					var tdname = document.createElement('td');
  					// output the div that will be clickable for appropriate elements				
  					var z = document.createElement('div');	
  					var a = document.createElement('a');		
  					a.appendChild(document.createTextNode(properties[prop].name));					
  					var type = 	properties[prop].type;				
  					// if the object is enumerable or null don't run the onclick function
  					if (type  != "object*")
  					{
  						a.href = "javascript:void(0);";
  						// if the property name is a number access it as an array otherwise access it as an object 
  						//i.e. array obj[4] object obj.prop
  						if (isNaN(parseInt(properties[prop].name.charAt(0))))
  						{
  							try
  							{
  								var test = eval(print_r.strObjRef + "." + properties[prop].name);
  								a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							} catch(e) 
  							{
  								try {									
  									var test = eval(print_r.strObjRef + "[" + properties[prop].name + "]");									
  									a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");
  								}
  								catch (e) 
  								{
  									a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  								}
  							}
  							//a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							/*
  							if (properties[prop].name.match(/[^a-zA-Z_\-]/g))
  							{
  								a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  							}
  							else
  							{
  								a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							}	
  							*/			
  						}	
  						else
  						{
  							try
  							{
  								var test = eval(print_r.strObjRef + "." + properties[prop].name);	
  								a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");	
  							} catch(e) 
  							{
  								try {
  									var test = eval(print_r.strObjRef + "[" + properties[prop].name + "]");									
  									a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");
  								}
  								catch (e) 
  								{
  									a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  								}
  							}							
  						}
  					}
  					z.appendChild(a);
  					tdname.appendChild(z);
  						
  					// now add the toString representation of the code.
  					// some browsers keep formatting so add it to a <pre> element					
  					var tdstring = document.createElement('td');	
  					var pre = document.createElement('pre');
  					try 
  					{
  						pre.appendChild(document.createTextNode(properties[prop].toString));
  					} catch (e) {
  						pre.appendChild(document.createTextNode('undefined1'));						
  					}
  					tdstring.appendChild(pre);
  					// finally add the type and apply appropriate styles
  					var tdtype = document.createElement('td');				
  					tdtype.appendChild(document.createTextNode(properties[prop].type));
  					print_r.applyStyles (styleObj.propTableTd, tdname);
  					print_r.applyStyles (styleObj.name, z);
  					print_r.applyStyles (styleObj.propTableTd, tdstring);
  					print_r.applyStyles (styleObj.propTableTd, tdtype);					
  					print_r.applyStyles (styleObj.tostring, pre);					
  					tr.appendChild(tdname);
  					tr.appendChild(tdstring);
  					tr.appendChild(tdtype);
  					tbodyprops.appendChild(tr);	
  										
  					} 
  				}
  				
  			}
  		}
  	};
  	this.center = function ()
  	{
  		
  	}
  	// this function will be used to rebuild the information stored in the container
  	this.refresh = function ()
  	{
  		this.container.removeChild(this.titleBar);
  		this.container.removeChild(this.header);
  		this.container.removeChild(this.body);
  		this.titleBar = document.createElement('div');
  		this.container.appendChild(this.titleBar);
  		this.header = document.createElement('div');
  		this.container.appendChild(this.header);		
  		this.body = document.createElement('div');
  		this.container.appendChild(this.body);
  		this.parseStrObjRef();
  		this.populateTitleBar();
  		this.refreshBtn.onclick = refreshThis(this);
  		this.closeBtn.onclick = closeThis(this);
  		this.applyStyles(styleObj.titleBar, this.titleBar);
  		this.populateHeader();
  		this.populateBody();
  		this.container.style.left = (this.container.offsetLeft + (parseInt(this.container.style.width)/2)) + "px";
  		this.container.style.top = (this.container.offsetTop + (parseInt(this.container.style.height)/2)) + "px";
  		if (!this.container.style.MarginLeft)
  		{
  			this.container.style.MarginTop = "";
  			this.container.style.MarginLeft = "";
  		}		
  		
  		// make it draggable
  		Drag.init(this.titleBar, this.container);
  		// internal closure for the refresh button
  	function refreshThis(print_r)
  	{
  		return (function(){
  			return print_r.refresh();
  		});
  	}
  	// internal closure for the close button
  	function closeThis(print_r)
  	{
  		return (function(){
  			return print_r.close();				
  		});
  	}
  	};
  	// similar to above but initializes rather than refreshes
  	this.render = function ()
  	{
  		// Add Container to Document.	
  		document.body.appendChild(this.container);
  		// populate the refresh  amd close buttons
  		this.refreshBtn.onclick = refreshThis(this);
  		this.closeBtn.onclick = closeThis(this);
  		this.applyStyles(styleObj.titleBar, this.titleBar);
  		// Ugly Fix to make DOM DRAG WORK right
  		this.container.style.left = (this.container.offsetLeft + (parseInt(this.container.style.width)/2)) + "px";
  		this.container.style.top = (this.container.offsetTop + (parseInt(this.container.style.height)/2)) + "px";
  		if (!this.container.style.MarginLeft)
  		{
  			this.container.style.MarginTop = "";
  			this.container.style.MarginLeft = "";
  		}		
  		// start dragging
  		Drag.init(this.titleBar, this.container);
  		// internal closure for the refresh button
  	function refreshThis(print_r)
  	{
  		return (function(){
  			return print_r.refresh();
  		});
  	}
  	// internal closure for the close button
  	function closeThis(print_r)
  	{
  		return (function(){
  			return print_r.close();				
  		});
  	}
  	};	
  	/*
  		Since I could not get a css file to work consistently accross browsers in the 
  		Bookmarklet edition, I went with this approach so I would not have so many
  		dom.style.***** = "50px"; lines. And also to make it easy to customize
  	*/
  	this.applyStyles = function (styleObject, domObject)
  	{
  		for (prop in styleObject)
  		{
  			try 
  			{
  				domObject.style[prop] = styleObject[prop];
  			} catch (e)
  			{
  			}
  		}
  	};	
  	// initialize the function
  	// parse the string
  	this.parseStrObjRef();
  	// create the Containers
  	this.createContainers();
  	// create the title bar
  	this.populateTitleBar();
  	// write the header
  	this.populateHeader();
  	// and the meat and potatoes
  	this.populateBody();
  	// the render function adds the final touches and makes it visible
  	this.render();
  	
  	// internal function for the clickable Elements
  	function clickMe (print_r, str)
  	{
  		return (function(){
  			print_r.objRef = eval(str);
  			print_r.strObjRef = str;
  			print_r.refresh();					
  		});
  	}
  	// Function to help sort the arrays
  	function arrSort(a,b)
  	{
  		var acomp = a['name'].toString(10);
  		var bcomp = b['name'].toString(10);
  		if (!isNaN(Number(acomp)))
  		{
  			acomp = Number(acomp);
  		}
  		if (!isNaN(Number(bcomp)))
  		{
  			bcomp = Number(bcomp);
  		}
  		if (acomp < bcomp)
  		{
  			return -1;
  		}
  		if (acomp > bcomp)
  		{
  			return 1;
  		}
  		return 0;
  	}		
  }
func_code_string: function print_rr (objRef, strObjRef) 
  {
  	// Objects Properties
  	// Container for this instance of Print_R
  	this.container = {};
  	// Reference to the Title Bar
  	this.titleBar = {};
  	// Reference to the Body 
  	this.body = {};
  	// Reference to Header
  	this.header = {};
  	// Object Reference to Object we are viewing
  	this.objRef = objRef;
  	// String Representation of object we are viewing
  	this.strObjRef = strObjRef;
  	// Object Reference to refresh Button
  	this.refreshBtn = {};
  	// Object Reference to Close Button
  	this.closeBtn = {};
  	// Parsed parts of object we are viewing
  	this.arrStrObjRef = [];
  	// Simple name of Variable we are parsing
  	this.objParseName = "";
  	/*
  		converts strObjRef to an Array of the parts of the object i,e ["window", "document", "childNodes", "[", "0", "]"]
  	*/
  	this.parseStrObjRef = function ()
  	{
  		// first split on the "." character	
  		var temp = this.strObjRef;
  		//alert ("'" + temp + "'");
  		var temp2 = [];
  		var x = 0;
  		var buffer = ""; 	
  		var inSingle = false;
  		var inDouble = false;
  		var inBracket = false;	
  		//Now check for "[" and "]" chars to indicate arrays
  		for (var elem =0;elem < temp.length;elem++)
  		{
  			// make sure we only look at the array elements not the clear() function
  				switch (temp.charAt(elem))
  				{					
  					case "'":
  						if (!inDouble)
  						{	
  							if (inSingle)
  							{
  								inSingle = false;
  							}						
  							else
  							{
  								inSingle = true;
  							}
  						}	
  						buffer += temp.charAt(elem);
  						break;
  					case '"':
  						if (!inSingle)
  						{	
  							if (inDouble)
  							{
  								inDouble = false;
  							}						
  							else
  							{
  								inDouble = true;
  							}
  						}
  						buffer += temp.charAt(elem);
  						break;
  					case "[":
  						if (!inSingle && !inDouble)
  						{
  							inBracket = true;
  							if (buffer != "")
  							{				
  								temp2[temp2.length] = buffer;								
  							}					
  							buffer = new String();						
  							temp2[temp2.length] = temp.charAt(elem);							
  						}
  						else
  						{
  							buffer += temp.charAt(elem);
  						}
  						break;
  					case "]":
  						if (!inSingle && !inDouble)
  						{
  							inBracket = false;
  							if (buffer != "")
  							{				
  								temp2[temp2.length] = buffer;								
  							}
  							buffer = new String();
  							temp2[temp2.length] = temp.charAt(elem);							
  						}	
  						else
  						{
  							buffer += temp.charAt(elem);
  						}					
  						break;
  					case ".":
  						if (!inSingle && !inDouble && !inBracket)
  						{
  							if (buffer != "")
  							{
  								temp2[temp2.length] = buffer;
  								temp2[temp2.length] = temp.charAt(elem);
  							}											
  							buffer = "";	
  						}
  						else
  						{
  							buffer += temp.charAt(elem);
  						}
  						break;
  					default: 						
  						buffer += temp.charAt(elem);						
  						break;
  				}
  				if (buffer != "]" && buffer != "" && buffer != null)
  				{
  					this.objParseName = buffer;
  				}
  								//will be overwritten unless it is the last entry 
  				// which is the one we want							
  			}			
  			
  		
  		if (buffer != "")
  		{
  			temp2[temp2.length] = buffer;			
  		}
  		//alert (temp2);	
  		// add the newly created array to our main object
  		this.arrStrObjRef = temp2;	
  		//alert (temp2);
  	};
  	// function to close the instance
  	this.close = function ()
  	{
  		document.body.removeChild(this.container);
  	}
  	// this function sets up the container for everything else
  	this.createContainers = function ()
  	{
  		//remove any existing Containers if for some reason it is called twice
  		try {
  			document.body.removeChild(this.container);
  		} catch (e){}	
  		this.container = document.createElement('div');
  		this.applyStyles (styleObj.container, this.container);
  		this.titleBar = document.createElement('div');
  		this.applyStyles (styleObj.titleBar, this.titleBar);	
  		this.container.appendChild(this.titleBar);
  		this.header = document.createElement('div');
  		this.container.appendChild(this.header);		
  		this.body = document.createElement('div');		
  		this.container.appendChild(this.body);
  	};	
  	// Function creates the title Bar
  	this.populateTitleBar = function ()
  	{			
  		var table = document.createElement('table');		
  		var tbody = table.appendChild(document.createElement('tbody'));
  		var tr = tbody.appendChild(document.createElement('tr'));
  		var td1 = tr.appendChild(document.createElement('td'));
  		td1.appendChild(document.createTextNode(this.objParseName));
  		var td2 = tr.appendChild(document.createElement('td'));
  		this.refreshBtn = td2.appendChild(document.createElement('button'));	
  		this.refreshBtn.appendChild(document.createTextNode('Refresh'));
  		this.closeBtn = td2.appendChild(document.createElement('button'));	
  		this.closeBtn.appendChild(document.createTextNode('close'));		
  		this.applyStyles(styleObj.propTable, table);		
  		this.applyStyles(styleObj.titleTd1, td1);
  		this.applyStyles(styleObj.titleTd2, td2);
  		this.titleBar.appendChild(table);
  	};
  	/*
  	//function creates the browseable header
  	this.populateHeader = function ()
  	{
  		//alert(this.arrStrObjRef);
  		// the string we will change this.objStrRef when updating object
  		var strRef = "";
  		// iterate through each element of this.arrStrObjRef
  		for (var x =0;x<this.arrStrObjRef.length;x++)
  		{
  			// if it is a "[" or a "]" char
  			if ((this.arrStrObjRef[x].match(/\[/g)) || (this.arrStrObjRef[x].match(/\]/g))) 
  			{
  				// just output a single char "[" or "]"
  				this.header.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  				// if it is a "[" make sure we add it to strRef
  				if (this.arrStrObjRef[x] == "[")
  				{
  					strRef += "[";	
  				}				
  			}
  			// it it is anything but a "[" or "]"
  			else
  			{
  				// we want to make it browseable
  				var a = document.createElement('a');
  				a.href = "javascript:void(0);";
  				// apply our styles
  				this.applyStyles (styleObj.a , a);
  				// add the name of the object we looking at
  				a.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  				// if there is a previous item in the list is it a "]" char 
  				if (this.arrStrObjRef[x-1] && this.arrStrObjRef[x-1] == "]" && x != (this.arrStrObjRef.length -1))
  				{
  					// if so we need to generate the "." char for output and strRef
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";
  				}	
  				// now add the name to strRef we do it here so that the "." is in the right place
  				strRef += this.arrStrObjRef[x];
  				//if the next item in the array is a "]"
  				if (this.arrStrObjRef[x+1] == "]")
  				{
  					// add it to strRef
  					strRef += "]";	
  				}	
  				// now we have a working strRef set the onclick handler for the output
  				a.onclick = clickMe(this, strRef);		
  				// add the "a" element to the dom				
  				this.header.appendChild(a);		
  				// now we need to add the "." operator to the dom and strRef for the next pass		
  				if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  				{
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";					
  				}				
  			}			
  		}
  		try 
  		{
  		// this makes sure we don't have trailing "."'s in our dom
  		if (this.header.lastChild.value == ".")
  		{			
  			this.header.removeChild(this.header.lastChild);
  		}
  		} catch (e){}		
  	};
  	*/
  	//function creates the browseable header
  	this.populateHeader = function ()
  	{
  		//alert(this.arrStrObjRef);
  		// the string we will change this.objStrRef when updating object
  		var strRef = "";
  		// iterate through each element of this.arrStrObjRef
  		var inBracket = false;
  		for (var x =0;x<this.arrStrObjRef.length;x++)
  		{
  			switch (this.arrStrObjRef[x])
  			{				
  				case "[":
  				case "]":				
  				case ".":
  					if (this.arrStrObjRef[x] == "[")
  					{
  						inBracket = true;
  					}	
  					if (this.arrStrObjRef[x] == "]")
  					{
  						inBracket = false;
  					}									
  					this.header.appendChild(document.createTextNode(this.arrStrObjRef[x]));
  					if (this.arrStrObjRef[x] != "]")
  					{
  						strRef += this.arrStrObjRef[x];
  					}
  					break;
  				default:
  					if (this.arrStrObjRef[x-1] == ']')
  					{
  						this.header.appendChild(document.createTextNode("."));
  					strRef += ".";
  					}
  					var a = document.createElement('a');
  					a.appendChild(document.createTextNode(this.arrStrObjRef[x]));					
  					strRef += this.arrStrObjRef[x];					
  					if (inBracket)
  					{
  						strRef += "]";
  					}
  					a.onclick = clickMe(this, strRef);
  					a.href = "javascript:void(0);";
  					this.header.appendChild(a);
  			}
  			/*		
  			// if it is a "[" or a "]" char
  			if ((this.arrStrObjRef[x].match(/\[/g))) 
  			{
  				// just output a single char "[" or "]"
  				
  				// if it is a "[" make sure we add it to strRef
  				if (this.arrStrObjRef[x] == "[")
  				{
  					strRef += "[";	
  				}				
  			}
  			// it it is anything but a "[" or "]"
  			else
  			{
  				// we want to make it browseable
  				
  				
  				// apply our styles
  				this.applyStyles (styleObj.a , a);
  				// add the name of the object we looking at
  				
  				// if there is a previous item in the list is it a "]" char 
  				if (this.arrStrObjRef[x-1] && this.arrStrObjRef[x-1] == "]" && x != (this.arrStrObjRef.length -1))
  				{
  					// if so we need to generate the "." char for output and strRef
  					//this.header.appendChild(document.createTextNode("."));
  					//strRef += ".";
  				}	
  				// now add the name to strRef we do it here so that the "." is in the right place
  				strRef += this.arrStrObjRef[x];
  				//if the next item in the array is a "]"
  				if (this.arrStrObjRef[x] == "]")
  				{	
  					if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  					{
  						this.header.appendChild(document.createTextNode("."));
  						strRef += ".";					
  					}
  				}	
  				
  				if (this.arrStrObjRef[x] != "]")
  				{
  					// now we have a working strRef set the onclick handler for the output
  					a.onclick = clickMe(this, strRef);
  					a.href = "javascript:void(0);";
  				}		
  				// add the "a" element to the dom				
  				this.header.appendChild(a);		
  				// now we need to add the "." operator to the dom and strRef for the next pass		
  				if (this.arrStrObjRef[x+1] && this.arrStrObjRef[x+1] != "]" && this.arrStrObjRef[x+1] != "[")
  				{
  					this.header.appendChild(document.createTextNode("."));
  					strRef += ".";					
  				}				
  			}
  			*/	
  			//alert(strRef);
  		}
  		try 
  		{
  		// this makes sure we don't have trailing "."'s in our dom
  		if (this.header.lastChild.value == ".")
  		{			
  			this.header.removeChild(this.header.lastChild);
  		}
  		} catch (e){}		
  	};
  	/*
  		This is the main function to populate the dom
  	*/
  	this.populateBody = function ()
  	{
  		// we want our properties, events, functions alphabatized so we need to cache them so we can sort them
  		var properties = [];
  		var functions = [];
  		var events = [];
  		// start creating the output dom
  		var table = document.createElement('table');
  		var tbodyobj = document.createElement('tbody');
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('th'));
  		this.applyStyles (styleObj.propTableTh, th1);
  		th1.appendChild(document.createTextNode('This Object'));
  		th1.colSpan = "3";
  		//Even if the object has no props we want to make sure we tell them about the object they are looking at
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('Name'));
  
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode(this.objParseName));
  		
  		th1.colSpan = "2";
  		
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('toString'));
  		
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		var pre = document.createElement('pre');
  		// in Some browsers calling the "toString" method of built in objects causes an error so plan for it
  		try 
  		{
  			pre.appendChild(document.createTextNode(getString(this.objRef)));
  				
  		}catch(e) {
  			pre.appendChild(document.createTextNode("undefined"));
  		}
  		th1.appendChild(pre);
  		this.applyStyles (styleObj.tostring, pre);
  		th1.colSpan = "2";
  		
  		
  		var tr = tbodyobj.appendChild(document.createElement('tr'));
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);				
  		th1.appendChild(document.createTextNode('Type'));
  		
  		var th1 = tr.appendChild(document.createElement('td'));
  		this.applyStyles (styleObj.propTableTd, th1);
  		var type= typeof(this.objRef);
  		// Arrays report to be Objects when typeof is used
  		// however if they are true arrays we attempt to compare their constructor to 
  		// known arrays constructor
  		if (properties.constructor == this.objRef.constructor)
  		{
  			type = "array";
  		}			
  		th1.appendChild(document.createTextNode(type));		
  		th1.colSpan = "2";
  		tbodyobj.appendChild(tr);
  		table.appendChild(tbodyobj);	
  		// start the dom ouptut for the props funcs and events		
  		var tbodyprops = document.createElement('tbody');
  		var tbodyfuncs = document.createElement('tbody'); 
  		var tbodyevents = document.createElement('tbody');
  		//this is main walking of object here
  		// it is enclosed in a try because enumerating a built in object sometimes causes an Error
  		var props = [];
  		var x = 0;
  		try{
  		  for (prop in this.objRef)
  		  {
  			props[props.length] = prop;			
  		  }
  		} catch(e) {}
  		
  			// the boolean false is not the same as null so we need another known false to test against
  			var boolFalse = false;
  			// enumerate over every property of this.objRef
  			for (prop in props)
  			{
  				//document.write(props[prop] +  "<br />");
  				if (props[prop] != 'sun')
  				{
  				try 
  				{
  					// as long as it is a valid object and not null run the typeof method on it
  					if (this.objRef[props[prop]] || this.objRef[props[prop]] == boolFalse)
  					{				
  						var type = typeof(this.objRef[props[prop]]);
  					}
  					// if it is null mark it with an * so we know it is not enumerable
  					else
  					{	
  						type = "object*";
  					}
  				}
  				catch (e) {
  					type = "undefined";
  				}
  				
  				// alright depending on the type of object add it to the appropriate array
  				switch (type)
  				{
  					// event handlers are always prefaced with _e__ so lets look for it
  					// btw event handlers are 
  					case "function":
  						if (prop.indexOf('_e__') > -1)
  						{
  							type = "event";
  							events[events.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						}
  						else
  						{													
  							functions[functions.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						}
  						break;						
  					case "boolean":
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;
  					case "string":				
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]) + unescape('%A0'), type:type};			
  						break;
  					case "number":
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;	
  					case "object":												
  						if (properties.constructor == this.objRef[props[prop]].constructor)
  						{
  							type = "array";
  						}						
  						properties[properties.length] = {name:props[prop], toString:getString(this.objRef[props[prop]]), type:type};
  						break;
  					default:
  						properties[properties.length] = {name:props[prop], toString:"null", type:type};
  						break;
  				}
  				}
  				
  			}
  		
  		{
  			//alert('An Error occured ' + e.message);		
  		}
  		//var testObj2 = new Object();
  		//properties.push({name:"isPrototypeOf", toString:this.objRef["constructor"].isPrototypeOf(Array), type:typeof(this.objRef["constructor"])});		
  		// Write table is a reusable function for writing the tables out
  		if (typeof(this.objRef) != 'string')
  		{
  			writeTable(properties, tbodyprops, 'Properties', this);
  			writeTable(functions, tbodyfuncs, 'Methods', this);
  			writeTable(events, tbodyevents, 'Events', this);
  		}
  		// add the new Tbody elements to the table
  		table.appendChild(tbodyprops);
  		table.appendChild(tbodyfuncs);
  		table.appendChild(tbodyevents);
  		// apply appropriate styles
  		this.applyStyles (styleObj.propTable, table);
  		// Add to the body object
  		this.body.appendChild(table);
  		// Sometimes calling the toString of an object generates an error so we catch it here
  		function getString(ref)
  		{
  			try
  			{
  				if (ref)
  				{
  					try 
  					{	
  						return ref;
  					} catch (e) {
  						return ref.toString();
  					}
  				}
  				else {
  					try 
  					{
  						return ref.toString();
  					}
  					catch (e) 
  					{
  						return "undefined";
  					}
  				}
  				
  			} catch (e)
  			{
  				// if we can not convert it to a string write "undefined" just like javascript
  				return "undefined";
  			}
  		}
  		// helper function to perform repeating tasks
  		function writeTable(properties, tbodyprops, name, print_r)
  		{
  			// only output to the tbody if there are actually props to enumerate
  			if (properties.length > 0)
  			{
  				// Build the Header Row
  				var tr = tbodyprops.appendChild(document.createElement('tr'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTh, th1);
  				th1.appendChild(document.createTextNode(name));
  				th1.colSpan = "3";	
  				// Build the Header
  				var tr = tbodyprops.appendChild(document.createElement('tr'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);				
  				th1.appendChild(document.createTextNode('Name'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);
  				th1.appendChild(document.createTextNode('toString'));
  				var th1 = tr.appendChild(document.createElement('th'));
  				print_r.applyStyles (styleObj.propTableTd, th1);
  				th1.appendChild(document.createTextNode('Type'));
  				// before we do anything lets alphabatize the list
  				properties.sort(arrSort);
  				// now we iterate through the list
  				for (prop in properties)
  				{
  					if (properties[prop] && properties[prop].name)
  					{
  					// create a row for the object
  					var tr = document.createElement('tr');
  					var tdname = document.createElement('td');
  					// output the div that will be clickable for appropriate elements				
  					var z = document.createElement('div');	
  					var a = document.createElement('a');		
  					a.appendChild(document.createTextNode(properties[prop].name));					
  					var type = 	properties[prop].type;				
  					// if the object is enumerable or null don't run the onclick function
  					if (type  != "object*")
  					{
  						a.href = "javascript:void(0);";
  						// if the property name is a number access it as an array otherwise access it as an object 
  						//i.e. array obj[4] object obj.prop
  						if (isNaN(parseInt(properties[prop].name.charAt(0))))
  						{
  							try
  							{
  								var test = eval(print_r.strObjRef + "." + properties[prop].name);
  								a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							} catch(e) 
  							{
  								try {									
  									var test = eval(print_r.strObjRef + "[" + properties[prop].name + "]");									
  									a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");
  								}
  								catch (e) 
  								{
  									a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  								}
  							}
  							//a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							/*
  							if (properties[prop].name.match(/[^a-zA-Z_\-]/g))
  							{
  								a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  							}
  							else
  							{
  								a.onclick = clickMe(print_r, print_r.strObjRef + "." + properties[prop].name);
  							}	
  							*/			
  						}	
  						else
  						{
  							try
  							{
  								var test = eval(print_r.strObjRef + "." + properties[prop].name);	
  								a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");	
  							} catch(e) 
  							{
  								try {
  									var test = eval(print_r.strObjRef + "[" + properties[prop].name + "]");									
  									a.onclick = clickMe(print_r, print_r.strObjRef + "[" + properties[prop].name + "]");
  								}
  								catch (e) 
  								{
  									a.onclick = clickMe(print_r, print_r.strObjRef + "['" + properties[prop].name + "']");
  								}
  							}							
  						}
  					}
  					z.appendChild(a);
  					tdname.appendChild(z);
  						
  					// now add the toString representation of the code.
  					// some browsers keep formatting so add it to a <pre> element					
  					var tdstring = document.createElement('td');	
  					var pre = document.createElement('pre');
  					try 
  					{
  						pre.appendChild(document.createTextNode(properties[prop].toString));
  					} catch (e) {
  						pre.appendChild(document.createTextNode('undefined1'));						
  					}
  					tdstring.appendChild(pre);
  					// finally add the type and apply appropriate styles
  					var tdtype = document.createElement('td');				
  					tdtype.appendChild(document.createTextNode(properties[prop].type));
  					print_r.applyStyles (styleObj.propTableTd, tdname);
  					print_r.applyStyles (styleObj.name, z);
  					print_r.applyStyles (styleObj.propTableTd, tdstring);
  					print_r.applyStyles (styleObj.propTableTd, tdtype);					
  					print_r.applyStyles (styleObj.tostring, pre);					
  					tr.appendChild(tdname);
  					tr.appendChild(tdstring);
  					tr.appendChild(tdtype);
  					tbodyprops.appendChild(tr);	
  										
  					} 
  				}
  				
  			}
  		}
  	};
  	this.center = function ()
  	{
  		
  	}
  	// this function will be used to rebuild the information stored in the container
  	this.refresh = function ()
  	{
  		this.container.removeChild(this.titleBar);
  		this.container.removeChild(this.header);
  		this.container.removeChild(this.body);
  		this.titleBar = document.createElement('div');
  		this.container.appendChild(this.titleBar);
  		this.header = document.createElement('div');
  		this.container.appendChild(this.header);		
  		this.body = document.createElement('div');
  		this.container.appendChild(this.body);
  		this.parseStrObjRef();
  		this.populateTitleBar();
  		this.refreshBtn.onclick = refreshThis(this);
  		this.closeBtn.onclick = closeThis(this);
  		this.applyStyles(styleObj.titleBar, this.titleBar);
  		this.populateHeader();
  		this.populateBody();
  		this.container.style.left = (this.container.offsetLeft + (parseInt(this.container.style.width)/2)) + "px";
  		this.container.style.top = (this.container.offsetTop + (parseInt(this.container.style.height)/2)) + "px";
  		if (!this.container.style.MarginLeft)
  		{
  			this.container.style.MarginTop = "";
  			this.container.style.MarginLeft = "";
  		}		
  		
  		// make it draggable
  		Drag.init(this.titleBar, this.container);
  		// internal closure for the refresh button
  	function refreshThis(print_r)
  	{
  		return (function(){
  			return print_r.refresh();
  		});
  	}
  	// internal closure for the close button
  	function closeThis(print_r)
  	{
  		return (function(){
  			return print_r.close();				
  		});
  	}
  	};
  	// similar to above but initializes rather than refreshes
  	this.render = function ()
  	{
  		// Add Container to Document.	
  		document.body.appendChild(this.container);
  		// populate the refresh  amd close buttons
  		this.refreshBtn.onclick = refreshThis(this);
  		this.closeBtn.onclick = closeThis(this);
  		this.applyStyles(styleObj.titleBar, this.titleBar);
  		// Ugly Fix to make DOM DRAG WORK right
  		this.container.style.left = (this.container.offsetLeft + (parseInt(this.container.style.width)/2)) + "px";
  		this.container.style.top = (this.container.offsetTop + (parseInt(this.container.style.height)/2)) + "px";
  		if (!this.container.style.MarginLeft)
  		{
  			this.container.style.MarginTop = "";
  			this.container.style.MarginLeft = "";
  		}		
  		// start dragging
  		Drag.init(this.titleBar, this.container);
  		// internal closure for the refresh button
  	function refreshThis(print_r)
  	{
  		return (function(){
  			return print_r.refresh();
  		});
  	}
  	// internal closure for the close button
  	function closeThis(print_r)
  	{
  		return (function(){
  			return print_r.close();				
  		});
  	}
  	};	
  	/*
  		Since I could not get a css file to work consistently accross browsers in the 
  		Bookmarklet edition, I went with this approach so I would not have so many
  		dom.style.***** = "50px"; lines. And also to make it easy to customize
  	*/
  	this.applyStyles = function (styleObject, domObject)
  	{
  		for (prop in styleObject)
  		{
  			try 
  			{
  				domObject.style[prop] = styleObject[prop];
  			} catch (e)
  			{
  			}
  		}
  	};	
  	// initialize the function
  	// parse the string
  	this.parseStrObjRef();
  	// create the Containers
  	this.createContainers();
  	// create the title bar
  	this.populateTitleBar();
  	// write the header
  	this.populateHeader();
  	// and the meat and potatoes
  	this.populateBody();
  	// the render function adds the final touches and makes it visible
  	this.render();
  	
  	// internal function for the clickable Elements
  	function clickMe (print_r, str)
  	{
  		return (function(){
  			print_r.objRef = eval(str);
  			print_r.strObjRef = str;
  			print_r.refresh();					
  		});
  	}
  	// Function to help sort the arrays
  	function arrSort(a,b)
  	{
  		var acomp = a['name'].toString(10);
  		var bcomp = b['name'].toString(10);
  		if (!isNaN(Number(acomp)))
  		{
  			acomp = Number(acomp);
  		}
  		if (!isNaN(Number(bcomp)))
  		{
  			bcomp = Number(bcomp);
  		}
  		if (acomp < bcomp)
  		{
  			return -1;
  		}
  		if (acomp > bcomp)
  		{
  			return 1;
  		}
  		return 0;
  	}		
  }
func_documentation_string: /*
  end Dom Drag
   /*
  Main Object