
Class = function(base, initializer){
	
	if(arguments.length == 1){
		initializer = base;
		base = Object;
	}
	var NewClass = function(caller){
        if(caller !== Class){
            return this.init.apply(this, arguments);
        }
	}
    NewClass.createPrototype = function(){
        return new NewClass(Class);
    }
    NewClass.superClass = base;
	if(base.createPrototype != null){
		NewClass.prototype = base.createPrototype();
	}else{
		NewClass.prototype = new base();
	}
    if(NewClass.prototype.init==null){
        NewClass.prototype.init=function(){}
    }
    NewClass.prototype.constructor = NewClass;

	var BaseClass = function(self){
		var wrapper = {}
		var proto = base.prototype;
		for(var n in proto){
			if(typeof(proto[n]) == 'function'){
				wrapper[n] = function(){
					var f = arguments.callee;
					return proto[f._name].apply(self, arguments);
				}
                wrapper[n]._name = n;
			}
		}
		return wrapper;
	}

	initializer(NewClass.prototype, BaseClass);
	return NewClass;
}

Package = function(initializer){
	var pkg = new Object();
	initializer(pkg);
	return pkg;
}

gem = Package(function(pkg){

	pkg.Browser = {
		isSafari	: function(){
			var a,ua = navigator.userAgent;
			return ((a=ua.split('AppleWebKit/')[1])?a.split('(')[0]:0) >= 124;
		},
		isKonqueror	: function(){
			var a,ua = navigator.userAgent;
			return ((a=ua.split('Konqueror/')[1])?a.split(';')[0]:0) >= 3.3;
		},
		isMozes		: function(){
			var a,ua = navigator.userAgent;
			return ((a=ua.split('Gecko/')[1])?a.split(" ")[0]:0) >= 20011128;
		},
		isOpera		: function(){
			return (!!window.opera) && ((typeof XMLHttpRequest) == 'function');
		},
		isIE		: function(){
			return (!!window.ActiveXObject);
		},
		getStyle	: function(elm, name){
			var value = null;
			var dv = document.defaultView;
			if(name == 'opacity' && elm.filters){
				value = 1;
				try{
					value = elm.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
				}catch(e){
					try{
						value = elm.filters.item('alpha').opacity / 100;
					}catch(e){}
				}
			}else if(elm.style[name]){
				value = elm.style[name];
			}else if(elm.currentStyle && elm.currentStyle[name]){
				value = elm.currentStyle[name];
			}else if(dv && dv.getComputedStyle){
				var conv = '';
				for(var i = 0, len = name.length; i < len; i++){
					if(name.charAt(i) == name.charAt(i).toUpperCase()){
						conv += '-' + name.charAt(i).toLowerCase();
					}else{
						conv += name.charAt(i);
					}
				}
				if(dv.getComputedStyle(elm, '')
					&& dv.getComputedStyle(elm, '').getPropertyValue(conv)){
					value = dv.getComputedStyle(elm, '').getPropertyValue(conv);
				}
			}
			return value;
		},
		setStyle	: function(elm, name, value){
			if(name == 'opacity'){
				if(this.isIE() && typeof(elm.style.filter) == 'string'){
					elm.style.filter = 'alpha(opacity=' + value * 100 + ')';
					if(!elm.currentStyle || !elm.currentStyle.hasLayout){
						elm.style.zoom = 1;
					}
				}else{
					elm.style.opacity = value;
					elm.style['-moz-opacity'] = value;
					elm.style['-khtml-opacity'] = value;
				}
			}else{
				elm.style[name] = value;
			}
		},
		getPosition	: function(elm){
			if(elm.parentNode == null || this.getStyle(elm, 'display') == 'none'){
				return false;
			}
			var parent;
			var pos = {
				left: 0,
				top : 0
			}
			if(elm.getBoundingClientRect){
				var rect = elm.getBoundingClientRect();
				pos.top = rect.top + 
					Math.max(document.documentElement.scrollTop, document.body.scrollTop) - 2;
				pos.left = rect.left + 
					Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) - 2;
				return pos;
				
			}else if(document.getBoxObjectFor){
				var rect = document.getBoxObjectFor(elm);
				pos.left = rect.x - parseInt(this.getStyle(elm, 'borderLeftWidth'));
				pos.top  = rect.y - parseInt(this.getStyle(elm, 'borderTopWidth'));

			}else{
				pos.left = elm.offsetLeft;
				pos.top = elm.offsetTop;
				parent = elm.offsetParent;
				if(parent != elm){
					while(parent){
						pos.left += parent.offsetLeft;
						pos.top += parent.offsetTop;
						parent =parent.offsetParent;
					}
				}
				if(this.isOpera() ||
					(this.isSafari() && this.getStyle(elm, 'position') == 'absolute')){
					pos.left -= document.body.offsetLeft;
					pos.top -= document.body.offsetTop;
				}
			}
			parent = null;
			if(elm.parentNode){
				parent = elm.parentNode;
			}
			while(parent && parent.tagName != 'BODY' && parent.tagName != 'HTML'){
				pos.left -= parent.scrollleft;
				pos.top -= parent.scrollTop;
				parent = null;
				if(parent.parentNode){
					parent = parent.parentNode;
				}
			}
            return pos;
			
		},
		setPosition	: function(elm, x, y){
			var sPosition = this.getStyle(elm, 'position');
			if(sPosition == 'static'){
				this.setStyle(elm, 'position', 'relative');
				sPosition = 'relative';
			}
			var pos = this.getPosition(elm);
			if(pos == false) return false;
			
			var temp = {
				left : parseInt(this.getStyle(elm, 'left'), 10),
				top  : parseInt(this.getStyle(elm, 'top'), 10)
			}
			if(isNaN(temp.left)){
				temp.left = (sPosition == 'relative') ? 0 : elm.offsetLeft;
			}
			if(isNaN(temp.top)){
				temp.top = (sPosition == 'relative') ? 0 : elm.offsetTop;
			}
			if(x != null) elm.style.left = x - pos.left + temp.left + 'px';
			if(y != null) elm.style.top = y - pos.top + temp.top + 'px';

		}, 
		getViewportWidth: function(){
			var width = -1;
			var mode = document.compatMode;
			if(mode || this.isIE()){
				if(mode == 'CSS1Compat'){
					width = document.documentElement.clientWidth;
				}else{
					width = document.body.clientWidth;
				}
			}else{
				width = self.innserWidth;
			}
			return width;
		},
		getViewportHeight: function(){
			var height = -1;
			var mode = document.compatMode;
			if((mode || this.isIE()) && !this.isOpera()){
				if(mode == 'CSS1Compat'){
					height = document.documentElement.clientHeight;
				}else{
					height = document.body.clientHeight;
				}
			}else{
				height = self.innerHeight;
			}
			return height;
		},
		getDocumentWidth: function(){
			var wDoc = -1;
			var wBody = -1;
			var wWin = -1;
			var margin = parseInt(this.getStyle(document.body, 'marginRight'), 10)
				+ parseInt(this.getStyle(document.body, 'marginLeft'), 10);

			if(document.compatMode || this.isIE()){
				if(document.compatMode == 'CSS1Compat'){
					wDoc = document.documentElement.clientWidth;
					wBody = document.body.offsetWidth + margin;
					wWin = self.innerWidth || -1;
				}else{
					wBody = document.body.clientWidth;
					wWin = document.body.scrollWidth;
				}
			}else{
				wDoc = document.documentElement.clientWidth;
				wBody = document.body.offsetWidth + margin;
				wWin = self.innerWidth;
			}
			var w = [wDoc, wBody, wWin].sort(function(a,b){ return (a-b); });
			return w[2];
		},
		getDocumentHeight: function(){
			var hScr = -1;
			var hWin = -1;
			var hBody = -1;
			var margin = parseInt(this.getStyle(document.body, 'marginTop'), 10)
				+ parseInt(this.getStyle(document.body, 'marginBottom'), 10);
			if((document.compatMode || this.isIE()) && !this.isOpera()){
				if(document.compatMode == 'CSS1Compat'){
					hScr = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
					hWin = [document.documentElement.clientHeight, self.innerHeight || -1].sort(function(a,b){return(a-b);})[1];
					hBody = document.body.offsetHeight + margin;
				}else{
					hScr = document.body.scrollHeight;
					hBody = document.body.clientHeight;
				}
			}else{
				hScr = document.documentElement.scrollHeight;
				hWin = self.innerHeight;
				hBody = document.documentElement.clientHeight;
			}
			var h = [hScr, hWin, hBody].sort(function(a,b){ return (a-b); });
			return h[2];
		},
		setCookie	: function(name, value, days){
			var expires = '';
			if(days){
				var d = new Date();
				d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000 );
				expires = '; expires=' + d.toGMTString();
			}
			document.cookie = name + '=' + value + expires + '; path=/';
		},
		getCookie	: function(name){
			var reg = new RegExp('(\;|^)[^;]*(' + name + ')\=([^;]*)(;|$)');
			var res = reg.exec( document.cookie );
			return res != null ? res[3] : null;
		},
		removeCookie: function(name){
			this.setCookie( name, '', -1);			
		},
		addListener	:	function(elm, evt, func){
			elm['on' + evt] = func;
			return true;
			
			if(typeof(elm.addEventListener) != 'undefined'){
				elm.addEventListener(evt, func, false);
			}else if(typeof(elm.attachEvent) != 'undefined'){
				elm.attachEvent('on' + evt, func);
			}else{
				elm['on' + evt] = func;
			}
		},
		addInitializer	:	function(func){
			if(typeof(window.addEventListener) != 'undefined'){
				window.addEventListener('load', func, false);
			}else if(typeof(window.attachEvent) != 'undefined'){
				window.attachEvent('onload', func);
			}else{
				window.onload = func;
			}
		},
		addCleaner	:	function(func){
			if(typeof(window.addEventListener) != 'undefined'){
				window.addEventListener('unload', func, false);
			}else if(typeof(window.attachEvent) != 'undefined'){
				window.attachEvent('onunload', func);
			}else{
				window.onunload = func;
			}
		}
	}
	pkg.Exception = Class(function(obj){
		obj.message;
		obj.cause;
		obj.init = function(msg, cause){
			this.message = msg;
			if(arguments.length == 2 && !!cause.message){
				obj.message += ':' + cause.message;
			}
		}
	});
	
});

gem.ajax = Package(function(pkg){
	pkg.encoding = 'UTF-8';
	pkg.debug = false;
	
	
	//================================================================
	//	Exception Class
	//================================================================
	pkg.ParserException = Class(gem.Exception, function(obj){});
	pkg.FaultException = Class(gem.Exception, function(obj){
		obj.faultCode;
		obj.faultString;

		obj.init = function(code, msg){
			this.faultCode = code;
			this.message = msg;
			this.faultString = msg;
		}
	
	});
	
	//================================================================
	//	HttpRequest Class
	//================================================================
	pkg.HttpRequest = Class(function(obj){

		obj.async;
		obj.contentType;
		obj.userAgent;
		obj.userName;
		obj.password;
		obj.responseText;
		obj.responseXML;
		
		obj.init = function(){
			this.async = false;
			this.contentType = 'application/x-www-form-urlencoded; charset=' + pkg.encoding;
			this.userAgent = navigator.userAgent;
			this.userName = null;
			this.password = null;
			this.responseText = null;
			this.responseXML = null;
		}
		
		//================================================================
		//	URI Encoder
		//================================================================
		var uriEncode = function(data, url){
			var encdata = (url.indexOf('?') == -1) ? '?dummuy' : '';
			if(typeof data == 'object'){
				for(var i in data)
					encdata += '&' + encodeURIComponent(i) + '=' + encodeURIComponent(data[i]);
			}else if(typeof data == 'string'){
				if(data == '') return '';
				var datas = data.split('&');
				for(var i = 0; i < datas.length; i++){
					var dataq = datas[i].split('=');
					encdata += '&' + encodeURIComponent(dataq[0]) + '=' + encodeURIComponent(dataq[1]);
				}
			}
			return encdata;
		}
		//================================================================
		//	create Http Request
		//================================================================
		var create = function(){
			if(window.XMLHttpRequest){
				return new XMLHttpRequest();
			}else if(window.ActiveXObject){
				//	Windows
				try{
					return new ActiveXObject('Msxml2.XMLHTTP');
				}catch(e){
					try{
						return new ActiveXObject('Microsoft.XMLHTTP');
					}catch(e2){
						return null;
					}
				}
			}else{
				return null;
			}
		}
		
		//================================================================
		//	send Http Request
		//================================================================
		obj.send = function(method, url, data, callback, target){
	
			var request = create();
			if(request == null) return null;
		
			if(gem.Browser.isOpera() || gem.Browser.isSafari() || gem.Browser.isMozes()){
				if(callback != null){
					request.onload = function() { callback(request, target); }
				}
			}else{
				request.onreadystatechange = function(){
					if(request.readyState == 4){
						if(callback != null) callback(request, target);
					}
				}
			}
			if(method.toUpperCase() == 'GET'){
				data = uriEncode(data, url);
				url += data;
				data = '';
			}
			request.open(method, url, this.async, this.userName, this.password);
	
			if(!gem.Browser.isOpera()){
				request.setRequestHeader('Content-Type', this.contentType);
				request.setRequestHeader('User-Agent', this.userAgent);
				request.setRequestHeader('Content-Length', data.length);
			}else{
				if((typeof request.setRequestHeader) == 'function'){
					request.setRequestHeader('Content-Type', this.contentType);
					request.setRequestHeader('User-Agent', this.userAgent);
					request.setRequestHeader('Content-Length', data.length);
				}
			}
			if(pkg.debug){
				alert('Content-Type:' + this.contentType + '\nlength:' + data.length + '\n' + data);
			}
			request.send(data);
			if(!this.async){
				this.responseText = request.responseText;
				this.responseXML = request.responseXML;
			}
			if(pkg.debug) alert(this.responseText);
			
		}
	});

	//================================================================
	//	XMLParser Class
	//================================================================
	pkg.XMLParser = Class(function(obj){
	
		obj.async;
		
		obj.init = function(){
			this.async = false;
		}
		obj.parse = function(doc){
			var root = null;
			if(window.ActiveXObject){
				//	IE
				var parser = null;
				try{
					parser = new ActiveXObject('Msxml2.DomDocument.4.0');
				}catch(e){
					try{
						parser = new ActiveXObject('Msxml2.DomDocument');
					}catch(e){
						try{
							parser = new ActiveXObject('Microsoft.XMLDOM');
						}catch(e){
							return null;
						}
					}
				}
				parser.async = this.async;
				parser.loadXML(doc);
				root = parser.documentElement;
				
			}else if(window.DOMParser){
				//	Mozilla, Firfox
				var parser = new DOMParser();
				parser.async = this.async;
				var dom = parser.parseFromString(doc, 'application/xml');
				if(!dom) return;
				root = dom.documentElement;
			}
			return (!root ? null : root);
		}
	});

	//================================================================
	//	XMLRPCClient Class
	//================================================================
	pkg.XMLRPCClient = Class(function(obj){
		obj.url;
		obj.async;

		obj.init = function(url){
			this.url = url;
		}
		
		obj.createMethodCall = function(method, param){
			
			var xml = '<?xml version="1.0" encoding="' + pkg.encoding + '"?>\n'
					+ '<methodCall>\n'
					+ '<methodName>' + method + '</methodName>\n'
					+ '<params>\n'
					+ '<param><value>' + this.marshall(param) + '</value></param>\n'
					+ '</params>\n'
					+ '</methodCall>';
			return xml;
		}
		
		//================================================================
		//	Call XMLRPC Method
		//================================================================
		obj.call = function(method, param, callback, target){
			try{
				var request = new pkg.HttpRequest();
				var data = this.createMethodCall(method, param);
	
				request.contentType = 'text/xml';
				request.async = this.async;
				this.target = target;
	
				if(this.async){
					var catchFunc = function(request, o){
						try{
							var parser = new gem.ajax.XMLParser();
							var ret = o.unmarshall(parser.parse(request.responseText));
							callback(ret, o.target);
							
						}catch(e){
							if(e.message){
								alert('RPCError:' + e.message);
							}else{
								alert('RPCError:' + e);
							}
						}
					};
					request.async = true;
					request.send('POST', this.url, data, catchFunc, this);
					
				}else{
					request.async = false;
					request.send('POST', this.url, data);
					var parser = new pkg.XMLParser();
					return this.unmarshall(parser.parse(request.responseText));
				}
			}catch(e){
				alert('RPC Call Error:' + e.message
					+ '\nResponse:' + request.responseText);
			}
		}

		//================================================================
		//	Marshall Object
		//================================================================
		   obj.marshall = function(target){
		       if(target.toXMLRPC){
		           return target.toXMLRPC();
		       }else{
		           var ret = '<struct>';
		           for(var attr in target){
		               if(typeof target[attr] != 'function'){
		                   ret += '<member><name>' + attr + '</name><value>' + this.marshall(target[attr]) + '</value></member>';
		               }
		           }
		           ret += '</struct>';
		           return ret;
		       }
		   }
		
		//================================================================
		//	parse xml document
		//================================================================
		obj.unmarshall = function(node){
			try{
				if(node == null){
					throw new pkg.ParserException('No documentElement found');
				}
				switch(node.tagName){
					case 'methodResponse':
						return parseMethodResponse(node);
					case 'methodCall':
						return parseMethodCall(node);
					default:
						throw new pkg.ParserException('methodCall or methodResponse element expected');
				}

			}catch(e){
				if(e instanceof pkg.FaultException){
					throw e;
				}
				throw new pkg.ParserException('Failed to parse document', e);
			}
		}
		//================================================================
		//	Parse Method Response
		//================================================================
		var parseMethodResponse = function(node){
			try{
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'fault':
								throw parseFault(child);
							case 'params':
								var params = parseParams(child);
								if(params.length != 1){
									throw new pkg.ParserException('invalid params tag');
								}
								return params[0];
							default:
								throw new pkg.ParserException('fault or params tag expected');
						}
					}
				}
				throw new pkg.ParserException();
			}catch(e){
				if(e instanceof pkg.FaultException){
					throw e;
				}
				throw new pkg.ParserException('Failed to parse methodResponse', e);
			}
		}
		//================================================================
		//	Parse Params
		//================================================================
		var parseParams = function(node){
			try{
				var params = new Array();
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'param':
								params.push(parseParam(child));
								break;
							default:
								throw new pkg.ParserException('param tag expected');
						}
					}
				}
				return params;

			}catch(e){
				throw new pkg.ParserException('Failed to parse params element', e);
			}
		}

		//================================================================
		//	Parse Param
		//================================================================
		var parseParam = function(node){
			try{
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'value':
								return parseValue(child);
							default:
								throw new pkg.ParserException('value element expected');
						}
					}
				}
			}catch(e){
				throw new pkg.ParserException('Failed to parse param element', e);
			}
		}		
		
		//================================================================
		//	Parse Value
		//================================================================
		var parseValue = function(node){
			try{
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'string':
								return parseString(child);
							case 'i4':
							case 'int':
							case 'double':
								return parseNumber(child);
							case 'boolean':
								return parseBoolean(child);
							case 'base64':
								return parseBase64(child);
							case 'dateTime.iso8601':
								return parseDateTime(child);
							case 'array':
								return parseArray(child);
							case 'struct':
								return parseStruct(child);
	                        default:
	                        	throw new pkg.ParserException();
						}
					}
				}
				var ret = '';
				if(node.firstChild){
					ret = parseString(node);
				}
	            return ret;			

			}catch(e){
				throw new pkg.ParserException('Failed to parse value element', e);
			}
		}

		//================================================================
		//	Parse String
		//================================================================
		var parseString = function(node){
			var str = '';
			for(var i = 0; i < node.childNodes.length; i ++ ){
				str += new String(node.childNodes.item(i).nodeValue);
			}
			return str;
		}
		//================================================================
		//	Parse Number
		//================================================================
		var parseNumber = function(node){
			return (node.firstChild) ? new Number(node.firstChild.nodeValue) : 0;
		}
		//================================================================
		//	Parse Boolean
		//================================================================
		var parseBoolean = function(node){
			return Boolean(isNaN(parseInt(node.firstChild.nodeValue)) ?
				(node.firstChild.nodeValue == "true") : parseInt(node.firstChild.nodeValue));
		}
		//================================================================
		//	Parse BASE64
		//================================================================
		var parseBase64 = function(node){
			try{
				var target = node.firstChild.nodeValue;
				return target.decode('base64');
			}catch(e){
				throw new pkg.ParserException('BASE64 decode failed.');
			}
		}
		//================================================================
		//	Parse Datetime
		//================================================================
		var parseDateTime = function(node){
            if(/^(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})/.test(node.firstChild.nodeValue)){
                return new Date(Date.UTC(RegExp.$1, RegExp.$2-1, RegExp.$3, RegExp.$4, RegExp.$5, RegExp.$6));
            }else{
				throw new pkg.ParserException('Failed to parse Datetime element');
            }
		}
		//================================================================
		//	Parse Array
		//================================================================
		var parseArray = function(node){
			try{
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'data':
								return parseData(child);
							default:
								throw new pkg.ParserException('data tag expected.');
						}
					}
				}
			}catch(e){
				throw new pkg.ParserException('Failed to parse array element', e);
			}
		}
		//================================================================
		//	Parse Data
		//================================================================
		var parseData = function(node){
			try{
				var result = new Array();
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'value':
								result.push(parseValue(child));
								break;
							default:
								throw new pkg.ParserException('value tag expected');
						}
					}
				}
				return result;
			}catch(e){
				throw new pkg.ParserException('Failed to parse data element', e);
			}
		}
		//================================================================
		//	Parse Struct
		//================================================================
		var parseStruct = function(node){
			try{
				var struct = new Object();
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'member':
								var member = parseMember(child);
								if(member[0] != ''){
									struct[member[0]] = member[1];
								}
								break;
							default:
								throw new pkg.ParserException('member tag expected');
						}
					}
				}
				return struct;
			}catch(e){
				throw new pkg.ParserException('Failed to parse struct element', e);
			}
		}
		//================================================================
		//	Parse member element
		//================================================================
		var parseMember = function(node){
			try{
				var name = '';
				var value = null;
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'value':
								value = parseValue(child);
								break;
							case 'name':
								if(child.hasChildNodes()){
									name = new String(child.firstChild.nodeValue);
								}
								break;
							default:
								throw new pkg.ParserException('value or name tag expected');
						}
					}
				}
				return [name, value];
				
			}catch(e){
				throw new pkg.ParserException('Failed to parse member element', e);
			}
		}
		var parseFault = function(node){
			try{
				for(var i = 0; i < node.childNodes.length; i ++){
					var child = node.childNodes.item(i);
					if(child.nodeType == 1){
						switch(child.tagName){
							case 'value':
								var msg = parseValue(child);
								return new pkg.FaultException(msg.faultCode, msg.faultString);
							default:
								throw new pkg.ParserException('value element expected');
						}
					}
				}
				throw new pkg.ParserException('value element expected');
			}catch(e){
				throw new pkg.ParserException('Failed to parse fault element', e);
			}
		}		
		
	});

    Boolean.prototype.toXMLRPC = function(){
    	return (this == true ? '<boolean>1</boolean>' : '<boolean>0</boolean>');
    }
	String.prototype.toXMLRPC = function(){
		return '<string>' + this.replace(/&/g, "&amp;").replace(/</g, '&lt') + '</string>';
 	}
    Number.prototype.toXMLRPC = function(){
        if(this == parseInt(this)){
            return '<int>' + this + '</int>';
        }else if(this == parseFloat(this)){
            return '<double>' + this + '</double>';
        }else{
            return false.toXMLRPC();
        }
    }
    Date.prototype.toXMLRPC = function(){
        var padd=function(s, p){
            s=p+s
            return s.substring(s.length - p.length)
        }
        var y = padd(this.getUTCFullYear(), "0000");
        var m = padd(this.getUTCMonth() + 1, "00");
        var d = padd(this.getUTCDate(), "00");
        var h = padd(this.getUTCHours(), "00");
        var min = padd(this.getUTCMinutes(), "00");
        var s = padd(this.getUTCSeconds(), "00");
        var isodate = y +  m  + d + "T" + h +  ":" + min + ":" + s
        return "<dateTime.iso8601>" + isodate + "</dateTime.iso8601>";
    }
    Array.prototype.toXMLRPC = function(){
        var ret = '<array><data>';
        for(var i=0;i<this.length;i++){
            ret += '<value>' + pkg.marshall(this[i]) + '</value>';
        }
        return ret + '</data></array>';
    }

});
