
var JSJAC_HAVEKEYS = false;  // whether to use keys
var JSJAC_NKEYS = 16;    // number of keys to generate
var JSJAC_INACTIVITY = 300; // qnd hack to make suspend/resume work more smoothly with polling
var JSJAC_ERR_COUNT = 10;   // number of retries in case of connection errors
var JSJAC_ALLOW_PLAIN = true; // whether to allow plaintext logins
var JSJAC_CHECKQUEUEINTERVAL = 100; // msecs to poll send queue
var JSJAC_CHECKINQUEUEINTERVAL = 100; // msecs to poll incoming queue

// Options specific to HTTP Binding (BOSH)
var JSJACHBC_BOSH_VERSION = "1.6";
var JSJACHBC_USE_BOSH_VER = true;
var JSJACHBC_MAX_HOLD = 1;
var JSJACHBC_MAX_WAIT = 120;
var JSJACHBC_MAXPAUSE = 120;
/*** END CONFIG ***/

// (c) 2005-2007 Stefan Strigler <steve@zeank.in-berlin.de>
String.prototype.htmlEnc = function () {
	var str = this.replace(/&/g, "&amp;");
	str = str.replace(/</g, "&lt;");
	str = str.replace(/>/g, "&gt;");
	str = str.replace(/\"/g, "&quot;");
	str = str.replace(/\n/g, "<br />");
	return str;
};
Date.jab2date = function (ts) {
	var date = new Date(Date.UTC(ts.substr(0, 4), ts.substr(5, 2) - 1, ts.substr(8, 2), ts.substr(11, 2), ts.substr(14, 2), ts.substr(17, 2)));
	if (ts.substr(ts.length - 6, 1) != "Z") {
		var offset = new Date();
		offset.setTime(0);
		offset.setUTCHours(ts.substr(ts.length - 5, 2));
		offset.setUTCMinutes(ts.substr(ts.length - 2, 2));
		if (ts.substr(ts.length - 6, 1) == "+") {
			date.setTime(date.getTime() - offset.getTime());
		} else {
			if (ts.substr(ts.length - 6, 1) == "-") {
				date.setTime(date.getTime() + offset.getTime());
			}
		}
	}
	return date;
};
Date.hrTime = function (ts) {
	return Date.jab2date(ts).toLocaleString();
};
Date.prototype.jabberDate = function () {
	var padZero = function (i) {
		if (i < 10) {
			return "0" + i;
		}
		return i;
	};
	var jDate = this.getUTCFullYear() + "-";
	jDate += padZero(this.getUTCMonth() + 1) + "-";
	jDate += padZero(this.getUTCDate()) + "T";
	jDate += padZero(this.getUTCHours()) + ":";
	jDate += padZero(this.getUTCMinutes()) + ":";
	jDate += padZero(this.getUTCSeconds()) + "Z";
	return jDate;
};
Number.max = function (A, B) {
	return (A > B) ? A : B;
};
var hexcase = 0;
var b64pad = "=";
var chrsz = 8;
function XmlDocument() {
}
XmlDocument.create = function (name, ns) {
	name = name || "foo";
	ns = ns || "";
	try {
		var doc;
		if (document.implementation && document.implementation.createDocument) {
			doc = document.implementation.createDocument(ns, name, null);
			if (doc.readyState == null) {
				doc.readyState = 1;
				doc.addEventListener("load", function () {
					doc.readyState = 4;
					if (typeof doc.onreadystatechange == "function") {
						doc.onreadystatechange();
					}
				}, false);
			}
		} else {
			if (window.ActiveXObject) {
				doc = new ActiveXObject(XmlDocument.getPrefix() + ".DomDocument");
			}
		}
		if (!doc.documentElement || doc.documentElement.tagName != name || (doc.documentElement.namespaceURI && doc.documentElement.namespaceURI != ns)) {
			try {
				if (ns != "") {
					doc.appendChild(doc.createElement(name)).setAttribute("xmlns", ns);
				} else {
					doc.appendChild(doc.createElement(name));
				}
			}
			catch (dex) {
				doc = document.implementation.createDocument(ns, name, null);
				if (doc.documentElement == null) {
					doc.appendChild(doc.createElement(name));
				}
				if (ns != "" && doc.documentElement.getAttribute("xmlns") != ns) {
					doc.documentElement.setAttribute("xmlns", ns);
				}
			}
		}
		return doc;
	}
	catch (ex) {
		alert(ex.name + ": " + ex.message);
	}
	throw new Error("Your browser does not support XmlDocument objects");
};
XmlDocument.getPrefix = function () {
	if (XmlDocument.prefix) {
		return XmlDocument.prefix;
	}
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			o = new ActiveXObject(prefixes[i] + ".DomDocument");
			return XmlDocument.prefix = prefixes[i];
		}
		catch (ex) {
		}
	}
	throw new Error("Could not find an installed XML parser");
};
if (typeof (Document) != "undefined" && window.DOMParser) {
	Document.prototype.loadXML = function (s) {
		var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
		while (this.hasChildNodes()) {
			this.removeChild(this.lastChild);
		}
		for (var i = 0; i < doc2.childNodes.length; i++) {
			this.appendChild(this.importNode(doc2.childNodes[i], true));
		}
	};
}
if (window.XMLSerializer && window.Node && Node.prototype && Node.prototype.__defineGetter__) {
	XMLDocument.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
	Document.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
	Node.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
}
var JSJaCBuilder = {buildNode:function (doc, elementName) {
	var element;
	if (arguments[2]) {
		if (JSJaCBuilder._isStringOrNumber(arguments[2]) || (arguments[2] instanceof Array)) {
			element = doc.createElement(elementName);
			JSJaCBuilder._children(doc, element, arguments[2]);
		} else {
			if (arguments[2]["xmlns"]) {
				try {
					element = doc.createElementNS(arguments[2]["xmlns"], elementName);
				}
				catch (e) {
					element = doc.createElement(elementName);
				}
			} else {
				element = doc.createElement(elementName);
			}
			for (attr in arguments[2]) {
				if (arguments[2].hasOwnProperty(attr)) {
					if (attr == "xmlns" && element.namespaceURI == arguments[2][attr]) {
						continue;
					}
					element.setAttribute(attr, arguments[2][attr]);
				}
			}
		}
	} else {
		element = doc.createElement(elementName);
	}
	if (arguments[3]) {
		JSJaCBuilder._children(doc, element, arguments[3]);
	}
	return element;
}, _text:function (doc, text) {
	return doc.createTextNode(text);
}, _children:function (doc, element, children) {
	if (typeof children == "object") {
		for (var i in children) {
			if (children.hasOwnProperty(i)) {
				var e = children[i];
				if (typeof e == "object") {
					if (e instanceof Array) {
						var node = JSJaCBuilder.buildNode(doc, e[0], e[1], e[2]);
						element.appendChild(node);
					} else {
						element.appendChild(e);
					}
				} else {
					if (JSJaCBuilder._isStringOrNumber(e)) {
						element.appendChild(JSJaCBuilder._text(doc, e));
					}
				}
			}
		}
	} else {
		if (JSJaCBuilder._isStringOrNumber(children)) {
			element.appendChild(JSJaCBuilder._text(doc, children));
		}
	}
}, _attributes:function (attributes) {
	var attrs = [];
	for (attribute in attributes) {
		if (attributes.hasOwnProperty(attribute)) {
			attrs.push(attribute + "=\"" + attributes[attribute].toString().htmlEnc() + "\"");
		}
	}
	return attrs.join(" ");
}, _isStringOrNumber:function (param) {
	return (typeof param == "string" || typeof param == "number");
}};
if (typeof JSJaC == "undefined") {
	JSJaC = {Version:"1.2"};
}
function JSJaCConnection(oArg) {
	oCon = this;
	if (oArg && oArg.oDbg && oArg.oDbg.log) {
		this.oDbg = oArg.oDbg;
	} else {
		this.oDbg = new Object();
		this.oDbg.log = function () {
		};
	}
	if (oArg && oArg.httpbase) {
		this._httpbase = oArg.httpbase;
	}
	if (oArg && oArg.allow_plain) {
		this.allow_plain = oArg.allow_plain;
	} else {
		this.allow_plain = JSJAC_ALLOW_PLAIN;
	}
	this._connected = false;
	this._events = new Array();
	this._keys = null;
	this._ID = 0;
	this._inQ = new Array();
	this._pQueue = new Array();
	this._regIDs = new Array();
	this._req = new Array();
	this._status = "intialized";
	this._errcnt = 0;
	this._inactivity = JSJAC_INACTIVITY;
	if (oArg && oArg.timerval) {
		this.setPollInterval(oArg.timerval);
	}
}
JSJaCConnection.prototype.connected = function () {
	return this._connected;
};
JSJaCConnection.prototype.getPollInterval = function () {
	return this._timerval;
};
JSJaCConnection.prototype.registerHandler = function (event) {
	event = event.toLowerCase();
	var eArg = {handler:arguments[arguments.length - 1], childName:"*", childNS:"*", type:"*"};
	if (arguments.length > 2) {
		eArg.childName = arguments[1];
	}
	if (arguments.length > 3) {
		eArg.childNS = arguments[2];
	}
	if (arguments.length > 4) {
		eArg.type = arguments[3];
	}
	if (!this._events[event]) {
		this._events[event] = new Array(eArg);
	} else {
		this._events[event] = this._events[event].concat(eArg);
	}
	this._events[event] = this._events[event].sort(function (a, b) {
		with (a) {
			if (type == "*") {
				if (b.type == "*") {
					return 0;
				}
				return 1;
			}
			if (childNS == "*") {
				if (b.childNS == "*") {
					return 0;
				}
				return 1;
			}
			if (childName == "*") {
				if (b.childName == "*") {
					return 0;
				}
				return 1;
			}
		}
		return -1;
	});
	this.oDbg.log("registered handler for event '" + event + "'", 2);
};
JSJaCConnection.prototype.resume = function () {
	try {
		this._setStatus("resuming");
		var s = unescape(JSJaCCookie.read("JSJaC_State").getValue());
		this.oDbg.log("read cookie: " + s, 2);
		var o = s.parseJSON();
		for (var i in o) {
			if (o.hasOwnProperty(i)) {
				this[i] = o[i];
			}
		}
		try {
			JSJaCCookie.read("JSJaC_State").erase();
		}
		catch (e) {
		}
		if (this._connected) {
			this._handleEvent("onresume");
			setTimeout("oCon._resume()", this.getPollInterval());
		}
		return this._connected;
	}
	catch (e) {
		if (e.message) {
			this.oDbg.log("Resume failed: " + e.message, 1);
		} else {
			this.oDbg.log("Resume failed: " + e, 1);
		}
		return false;
	}
};
JSJaCConnection.prototype.send = function (packet, cb, arg) {
	if (!packet || !packet.pType) {
		this.oDbg.log("no packet: " + packet, 1);
		return false;
	}
	if (cb) {
		if (!packet.getID()) {
			packet.setID("JSJaCID_" + this._ID++);
		}
		this._registerPID(packet.getID(), cb, arg);
	}
	try {
		this._handleEvent(packet.pType() + "_out", packet);
		this._handleEvent("packet_out", packet);
		this._pQueue = this._pQueue.concat(packet.xml());
	}
	catch (e) {
		this.oDbg.log(e.toString(), 1);
		return false;
	}
	return true;
};
JSJaCConnection.prototype.sendIQ = function (iq, handlers, arg) {
	handlers = handlers || {};
	var error_handler = handlers.error_handler || function (aIq) {
		oCon.oDbg.log(iq.xml(), 1);
	};
	var result_handler = handlers.result_handler || function (aIq) {
		oCon.oDbg.log(aIq.xml(), 2);
	};
	var default_handler = handlers.default_handler || function (aIq) {
		oCon.oDbg.log(aIq.xml(), 2);
	};
	var iqHandler = function (aIq, arg) {
		switch (aIq.getType()) {
		  case "error":
			error_handler(aIq);
			break;
		  case "result":
			result_handler(aIq, arg);
			break;
		  default:
			default_handler(aIq, arg);
		}
	};
	this.send(iq, iqHandler, arg);
};
JSJaCConnection.prototype.setPollInterval = function (timerval) {
	if (!timerval || isNaN(timerval)) {
		this.oDbg.log("Invalid timerval: " + timerval, 1);
		throw "Invalid interval";
	}
	this._timerval = timerval;
	return this._timerval;
};
JSJaCConnection.prototype.status = function () {
	return this._status;
};
JSJaCConnection.prototype.suspend = function () {
	clearTimeout(this._timeout);
	clearInterval(this._interval);
	clearInterval(this._inQto);
	this._suspend();
	var u = ("_connected,_keys,_ID,_inQ,_pQueue,_regIDs,_errcnt,_inactivity,domain,username,resource,jid,fulljid,_sid,_httpbase,_timerval,_is_polling").split(",");
	u = u.concat(this._getSuspendVars());
	var s = new Object();
	for (var i = 0; i < u.length; i++) {
		if (!this[u[i]]) {
			continue;
		}
		if (this[u[i]]._getSuspendVars) {
			var uo = this[u[i]]._getSuspendVars();
			var o = new Object();
			for (var j = 0; j < uo.length; j++) {
				o[uo[j]] = this[u[i]][uo[j]];
			}
		} else {
			var o = this[u[i]];
		}
		s[u[i]] = o;
	}
	var c = new JSJaCCookie("JSJaC_State", escape(s.toJSONString()), this._inactivity);
	this.oDbg.log("writing cookie: " + unescape(c.value) + "\n(length:" + unescape(c.value).length + ")", 2);
	c.write();
	try {
		var c2 = JSJaCCookie.read("JSJaC_State");
		if (c.value != c2.value) {
			this.oDbg.log("Suspend failed writing cookie.\nRead: " + unescape(JSJaCCookie.read("JSJaC_State")), 1);
			c.erase();
		}
		this._connected = false;
		this._setStatus("suspending");
	}
	catch (e) {
		this.oDbg.log("Failed reading cookie 'JSJaC_State': " + e.message);
	}
};
JSJaCConnection.prototype._abort = function () {
	clearTimeout(this._timeout);
	this._connected = false;
	this._setStatus("aborted");
	this.oDbg.log("Disconnected.", 1);
	this._handleEvent("ondisconnect");
	this._handleEvent("onerror", JSJaCError("500", "cancel", "service-unavailable"));
};
JSJaCConnection.prototype._checkInQ = function () {
	for (var i = 0; i < this._inQ.length && i < 10; i++) {
		var item = this._inQ[0];
		this._inQ = this._inQ.slice(1, this._inQ.length);
		var packet = JSJaCPacket.wrapNode(item);
		if (!packet) {
			return;
		}
		this._handleEvent("packet_in", packet);
		if (packet.pType && !this._handlePID(packet)) {
			this._handleEvent(packet.pType() + "_in", packet);
			this._handleEvent(packet.pType(), packet);
		}
	}
};
JSJaCConnection.prototype._checkQueue = function () {
	if (this._pQueue.length != 0) {
		this._process();
	}
	return true;
};
JSJaCConnection.prototype._doAuth = function () {
	if (this.has_sasl && this.authtype == "nonsasl") {
		this.oDbg.log("Warning: SASL present but not used", 1);
	}
	if (!this._doSASLAuth() && !this._doLegacyAuth()) {
		this.oDbg.log("Auth failed for authtype " + this.authtype, 1);
		this.disconnect();
		return false;
	}
	return true;
};
JSJaCConnection.prototype._doInBandReg = function () {
	if (this.authtype == "saslanon" || this.authtype == "anonymous") {
		return;
	}
	var iq = new JSJaCIQ();
	iq.setType("set");
	iq.setID("reg1");
	iq.appendNode("query", {xmlns:"jabber:iq:register"}, [["username", this.username], ["password", this.pass], ["email", this.email], ["familyname", this.familyname], ["givenname", this.givenname], ["orgname", this.companyname], ["Sex_Add", this.sex], ["orgtitle", this.duty]]);
	this.send(iq, this._doInBandRegDone);
};
JSJaCConnection.prototype._doInBandRegDone = function (iq) {
	if (iq && iq.getType() == "error") {
		oCon.oDbg.log("registration failed for " + oCon.username, 0);
		oCon._handleEvent("onerror", iq.getChild("error"));
		return;
	}
	if(document.getElementById("reg_ok")){
		document.getElementById("NewCon").style.display = "none";
		document.getElementById("reg_ok").style.display = "block";
		document.getElementById("loading").style.display = "none";
		document.getElementById("jid_ok").innerHTML = document.forms["userinfo"].username.value + "@" + this.domain;
		document.getElementById("url_ok").innerHTML = document.forms["userinfo"].username.value + "." + this.domain;
		document.getElementById("url_ok").href = "http://" + document.forms["userinfo"].username.value + "." + this.domain;
	}
	this._connected = false;
	clearInterval(this._interval);
	clearInterval(this._inQto);
	if (this._timeout) {
		clearTimeout(this._timeout);
	}
	var slot = this._getFreeSlot();
	this._req[slot] = this._setupRequest(false);
	var reqstr = "<body type='terminate' xmlns='http://jabber.org/protocol/httpbind' sid='" + this._sid + "' rid='" + this._rid + "'";
	if (JSJAC_HAVEKEYS) {
		reqstr += " key='" + this._keys.getKey() + "'";
	}
	reqstr += ">";
	while (this._pQueue.length) {
		var curNode = this._pQueue[0];
		reqstr += curNode;
		this._pQueue = this._pQueue.slice(1, this._pQueue.length);
	}
	reqstr += "</body>";
	this._req[slot].r.send(reqstr);
};
JSJaCConnection.prototype._doLegacyAuth = function () {
	if (this.authtype != "nonsasl" && this.authtype != "anonymous") {
		return false;
	}
	var iq = new JSJaCIQ();
	if(typeof this.orgid != dd_u){
		iq.setIQ(oCon.server, "set", "auth1");
		iq.appendNode("query", {xmlns:"jabber:iq:auth"}, [["username", oCon.username], ["orgid", oCon.orgid], ["resource", oCon.resource], ["referrer", document.referrer], ["appname", navigator.appName], ["appcodename", navigator.appCodeName], ["appversion", navigator.appVersion], ["platform", navigator.platform], ["language", navigator.language], ["sourceurl", document.location.href], ["sourcehost", document.location.hostname]]);
		this.send(iq, this._doLegacyAuthDone);
	}else if(typeof uin != "undefined" && uin !=""){
		iq.setIQ(oCon.server, "set", "auth1");
		iq.appendNode("query", {xmlns:"jabber:iq:webauth"}, [["username", oCon.username], ["uin", oCon.uin], ["resource", oCon.resource]]);
		this.send(iq, this._doLegacyAuthDone);
	}else{
		iq.setIQ(oCon.server, "get", "auth1");
		iq.appendNode("query", {xmlns:"jabber:iq:auth"}, [["username", oCon.username]]);
		this.send(iq, this._doLegacyAuth2);
	}
	return true;
};
JSJaCConnection.prototype._doLegacyAuth2 = function (iq) {
    if (!iq || iq.getType() != "result") {
        if (iq && iq.getType() == "error") {
            oCon._handleEvent("onerror", iq.getChild("error"));
        }
        oCon.disconnect();
        return;
    }
    var use_digest = (iq.getChild("digest") != null);
    var iq = new JSJaCIQ();
    iq.setIQ(oCon.server, "set", "auth2");
    query = iq.appendNode("query", {xmlns:"jabber:iq:auth"}, [["username", oCon.username], ["resource", oCon.resource]]);
    if (use_digest) {
        query.appendChild(iq.buildNode("digest", hex_sha1(oCon.streamid + oCon.pass)));
    } else {
        if (oCon.allow_plain) {
            query.appendChild(iq.buildNode("password", oCon.pass));
        } else {
            oCon.oDbg.log("no valid login mechanism found", 1);
            oCon.disconnect();
            return false;
        }
    }
    oCon.send(iq, oCon._doLegacyAuthDone);
};
JSJaCConnection.prototype._doLegacyAuthDone = function (iq) {
	if (iq.getType() != "result") {
		if (iq.getType() == "error") {
			oCon._handleEvent("onerror", iq.getChild("error"));
		}
		oCon.disconnect();
	} else {
		loginComplete();
		oCon._handleEvent("onconnect",iq);
	}
};
JSJaCConnection.prototype._sendRaw = function (xml, cb, arg) {
	var slot = this._getFreeSlot();
	this._req[slot] = this._setupRequest(true);
	this._req[slot].r.onload = function () {
		if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
			return;
		}
		if (oCon._req[slot].r.readyState == 4) {
			oCon.oDbg.log("async recv: " + oCon._req[slot].r.responseText, 4);
			if (typeof (cb) != "undefined") {
				eval("oCon." + cb + "(oCon._req[slot]," + arg + ")");
			}
		}
	};
	if (typeof (this._req[slot].r.onerror) != "undefined") {
		this._req[slot].r.onerror = function (e) {
			if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
				return;
			}
			oCon.oDbg.log("XmlHttpRequest error", 1);
			return false;
		};
	}
	var reqstr = this._getRequestString(xml);
	this.oDbg.log("sending: " + reqstr, 4);
	this._req[slot].r.send(reqstr);
	return true;
};
JSJaCConnection.prototype._doSASLAuth = function () {
	if (this.authtype == "nonsasl" || this.authtype == "anonymous") {
		return false;
	}
	if (this.authtype == "saslanon") {
		if (this.mechs["ANONYMOUS"]) {
			this.oDbg.log("SASL using mechanism 'ANONYMOUS'", 2);
			return this._sendRaw("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='ANONYMOUS'/>", "_doSASLAuthDone");
		}
		this.oDbg.log("SASL ANONYMOUS requested but not supported", 1);
	} else {
		if (this.mechs["DIGEST-MD5"]) {
			this.oDbg.log("SASL using mechanism 'DIGEST-MD5'", 2);
			return this._sendRaw("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>", "_doSASLAuthDigestMd5S1");
		} else {
			if (this.allow_plain && this.mechs["PLAIN"]) {
				this.oDbg.log("SASL using mechanism 'PLAIN'", 2);
				var authStr = this.username + "@" + this.domain + String.fromCharCode(0) + this.username + String.fromCharCode(0) + this.pass;
				this.oDbg.log("authenticating with '" + authStr + "'", 2);
				authStr = btoa(authStr);
				return this._sendRaw("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" + authStr + "</auth>", "_doSASLAuthDone");
			}
		}
		this.oDbg.log("No SASL mechanism applied", 1);
		this.authtype = "nonsasl";
	}
	return false;
};
JSJaCConnection.prototype._doSASLAuthDigestMd5S1 = function (req) {
	this.oDbg.log(req.r.responseText, 2);
	var doc = oCon._prepareResponse(req);
	if (!doc || doc.getElementsByTagName("challenge").length == 0) {
		this.oDbg.log("challenge missing", 1);
		oCon._handleEvent("onerror", JSJaCError("401", "auth", "not-authorized"));
		this.disconnect();
	} else {
		var challenge = atob(doc.getElementsByTagName("challenge").item(0).firstChild.nodeValue);
		this.oDbg.log("got challenge: " + challenge, 2);
		this._nonce = challenge.substring(challenge.indexOf("nonce=") + 7);
		this._nonce = this._nonce.substring(0, this._nonce.indexOf("\""));
		this.oDbg.log("nonce: " + this._nonce, 2);
		if (this._nonce == "" || this._nonce.indexOf("\"") != -1) {
			this.oDbg.log("nonce not valid, aborting", 1);
			this.disconnect();
			return;
		}
		this._digest_uri = "xmpp/";
		this._digest_uri += this.domain;
		this._cnonce = cnonce(14);
		this._nc = "00000001";
		var A1 = str_md5(this.username + ":" + this.domain + ":" + this.pass) + ":" + this._nonce + ":" + this._cnonce;
		var A2 = "AUTHENTICATE:" + this._digest_uri;
		var response = hex_md5(hex_md5(A1) + ":" + this._nonce + ":" + this._nc + ":" + this._cnonce + ":auth:" + hex_md5(A2));
		var rPlain = "username=\"" + this.username + "\",realm=\"" + this.domain + "\",nonce=\"" + this._nonce + "\",cnonce=\"" + this._cnonce + "\",nc=\"" + this._nc + "\",qop=auth,digest-uri=\"" + this._digest_uri + "\",response=\"" + response + "\",charset=utf-8";
		this.oDbg.log("response: " + rPlain, 2);
		this._sendRaw("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + binb2b64(str2binb(rPlain)) + "</response>", "_doSASLAuthDigestMd5S2");
	}
};
JSJaCConnection.prototype._doSASLAuthDigestMd5S2 = function (req) {
	this.oDbg.log(req.r.responseText, 2);
	var doc = this._prepareResponse(req);
	if (doc.firstChild.nodeName == "failure") {
		if (doc.firstChild.xml) {
			this.oDbg.log("auth error: " + doc.firstChild.xml, 1);
		} else {
			this.oDbg.log("auth error", 1);
		}
		oCon._handleEvent("onerror", JSJaCError("401", "auth", "not-authorized"));
		this.disconnect();
		return;
	}
	var response = atob(doc.firstChild.firstChild.nodeValue);
	this.oDbg.log("response: " + response, 2);
	var rspauth = response.substring(response.indexOf("rspauth=") + 8);
	this.oDbg.log("rspauth: " + rspauth, 2);
	var A1 = str_md5(this.username + ":" + this.domain + ":" + this.pass) + ":" + this._nonce + ":" + this._cnonce;
	var A2 = ":" + this._digest_uri;
	var rsptest = hex_md5(hex_md5(A1) + ":" + this._nonce + ":" + this._nc + ":" + this._cnonce + ":auth:" + hex_md5(A2));
	this.oDbg.log("rsptest: " + rsptest, 2);
	/*if (rsptest != rspauth) {
		this.oDbg.log("SASL Digest-MD5: server repsonse with wrong rspauth", 1);
		this.disconnect();
		return;
	}*/
	if (doc.firstChild.nodeName == "success") {
		this._reInitStream(this.domain, "_doStreamBind");
	} else {
		this._sendRaw("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>", "_doSASLAuthDone");
	}
};
JSJaCConnection.prototype._doSASLAuthDone = function (req) {
	var doc = this._prepareResponse(req);
	if (doc.firstChild.nodeName != "success") {
		this.oDbg.log("auth failed", 1);
		this.disconnect();
	} else {
		this._reInitStream(this.domain, "_doStreamBind");
	}
};
JSJaCConnection.prototype._doStreamBind = function () {
	var iq = new JSJaCIQ();
	iq.setIQ(this.domain, "set", "bind_1");
	iq.appendNode("bind", {xmlns:"urn:ietf:params:xml:ns:xmpp-bind"}, [["resource", this.resource]]);
	this.oDbg.log("=-=-=-JSJaCConnection.prototype._doStreamBind=-=-=-=-"+iq.xml());
	this.send(iq, this._doXMPPSess);
};
JSJaCConnection.prototype._doXMPPSess = function (iq) {
	if (iq.getType() != "result" || iq.getType() == "error") {
		oCon.disconnect();
		if (iq.getType() == "error") {
			oCon._handleEvent("onerror", iq.getChild("error"));
		}
		return;
	}
	oCon.fulljid = iq.getChildVal("jid");
	oCon.jid = oCon.fulljid.substring(0, oCon.fulljid.lastIndexOf("/"));
	iq = new JSJaCIQ();
	iq.setIQ(this.domain, "set", "sess_1");
	iq.appendNode("session", {xmlns:"urn:ietf:params:xml:ns:xmpp-session"}, []);
	oCon.oDbg.log(iq.xml());
	oCon.send(iq, oCon._doXMPPSessDone);
};
JSJaCConnection.prototype._doXMPPSessDone = function (iq) {
	if (iq.getType() != "result" || iq.getType() == "error") {
		oCon.disconnect();
		if (iq.getType() == "error") {
			oCon._handleEvent("onerror", iq.getChild("error"));
		}
		return;
	} else {
		oCon._handleEvent("onconnect",iq);
	}
};
JSJaCConnection.prototype._handleEvent = function (event, arg) {
	event = event.toLowerCase();
	this.oDbg.log("incoming event '" + event + "'", 3);
	if (!this._events[event]) {
		return;
	}
	this.oDbg.log("handling event '" + event + "'", 2);
	for (var i = 0; i < this._events[event].length; i++) {
		var aEvent = this._events[event][i];
		if (aEvent.handler) {
			try {
				if (arg) {
					if (arg.pType) {
						if (!arg.getChild(aEvent.childName, aEvent.childNS)) {
							if(arg.pType()!="presence" && arg.pType()!="iq"){
								continue;
							}
						}
						if (aEvent.type != "*" && arg.getType() != aEvent.type) {
							continue;
						}
						this.oDbg.log(aEvent.childName + "/" + aEvent.childNS + "/" + aEvent.type + " => match for handler " + aEvent.handler, 3);
					}
					if (aEvent.handler(arg)) {
						break;
					}
				} else {
					if (aEvent.handler()) {
						break;
					}
				}
			}
			catch (e) {
				this.oDbg.log(aEvent.handler + "\n>>>" + e.name + ": " + e.message, 1);
			}
		}
	}
};
JSJaCConnection.prototype._handlePID = function (aJSJaCPacket) {
	if (!aJSJaCPacket.getID()) {
		return false;
	}
	for (var i in this._regIDs) {
		if (this._regIDs.hasOwnProperty(i) && this._regIDs[i] && i == aJSJaCPacket.getID()) {
			var pID = aJSJaCPacket.getID();
			this.oDbg.log("handling " + pID, 3);
			try {
				this._regIDs[i].cb(aJSJaCPacket, this._regIDs[i].arg);
			}
			catch (e) {
				this.oDbg.log(e.name + ": " + e.message);
			}
			this._unregisterPID(pID);
			return true;
		}
	}
	return false;
};
JSJaCConnection.prototype._handleResponse = function (req) {
	var rootEl = this._prepareResponse(req);
	if (!rootEl) {
		return null;
	}
	this.oDbg.log("childNodes: " + rootEl.childNodes.length, 3);
	for (var i = 0; i < rootEl.childNodes.length; i++) {
		this.oDbg.log("rootEl.childNodes.item(" + i + ").nodeName: " + rootEl.childNodes.item(i).nodeName, 3);
		this._inQ = this._inQ.concat(rootEl.childNodes.item(i));
	}
	return null;
};
JSJaCConnection.prototype._parseStreamFeatures = function (doc) {
	if (!doc) {
		this.oDbg.log("nothing to parse ... aborting", 1);
		return false;
	}
	this.mechs = new Object();
	var lMec1 = doc.getElementsByTagName("mechanisms");
	this.has_sasl = false;
	for (var i = 0; i < lMec1.length; i++) {
		if (lMec1.item(i).getAttribute("xmlns") == "urn:ietf:params:xml:ns:xmpp-sasl") {
			this.has_sasl = true;
			var lMec2 = lMec1.item(i).getElementsByTagName("mechanism");
			for (var j = 0; j < lMec2.length; j++) {
				this.mechs[lMec2.item(j).firstChild.nodeValue] = true;
			}
			break;
		}
	}
	if (this.has_sasl) {
		this.oDbg.log("SASL detected", 2);
	} else {
		this.authtype = "nonsasl";
		this.oDbg.log("No support for SASL detected", 2);
	}
};
JSJaCConnection.prototype._process = function (timerval) {
	if (!this.connected()) {
		this.oDbg.log("Connection lost ...", 1);
		if (this._interval) {
			clearInterval(this._interval);
		}
		return;
	}
	if (timerval) {
		this.setPollInterval(timerval);
	}
	if (this._timeout) {
		clearTimeout(this._timeout);
	}
	var slot = this._getFreeSlot();
	if (slot < 0) {
		return;
	}
	if (!this.isPolling() && this._pQueue.length == 0 && this._req[(slot + 1) % 2] && this._req[(slot + 1) % 2].r.readyState != 4) {
		this.oDbg.log("all slots busy, standby ...", 2);
		return;
	}
	if (!this.isPolling()) {
		this.oDbg.log("Found working slot at " + slot, 2);
	}
	this._req[slot] = this._setupRequest(true);
	this._req[slot].r.onload = function () {
		if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
			return;
		}
		oCon.oDbg.log("ready state changed for slot " + slot + " [" + oCon._req[slot].r.readyState + "]", 4);
		if (oCon._req[slot].r.readyState == 4) {
			oCon._setStatus("processing");
			oCon.oDbg.log("async recv: " + oCon._req[slot].r.responseText, 4);
			oCon._handleResponse(oCon._req[slot]);
			if (oCon._pQueue.length) {
				oCon._timeout = setTimeout("oCon._process()", 100);
			} else {
				oCon.oDbg.log("scheduling next poll in " + oCon.getPollInterval() + " msec", 4);
				oCon._timeout = setTimeout("oCon._process()", oCon.getPollInterval());
			}
		}
	};
	if (typeof (this._req[slot].r.onerror) != "undefined") {
		this._req[slot].r.onerror = function (e) {
			if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
				return;
			}
			oCon._errcnt++;
			oCon.oDbg.log("XmlHttpRequest error (" + oCon._errcnt + ")", 1);
			if (oCon._errcnt > JSJAC_ERR_COUNT) {
				oCon._abort();
				return false;
			}
			oCon._setStatus("onerror_fallback");
			setTimeout("oCon._resume()", oCon.getPollInterval());
			return false;
		};
	}
	var reqstr = this._getRequestString();
	if (typeof (this._rid) != "undefined") {
		this._req[slot].rid = this._rid;
	}
	this.oDbg.log("sending: " + reqstr, 4);
	this._req[slot].r.send(reqstr);
};
JSJaCConnection.prototype._registerPID = function (pID, cb, arg) {
	if (!pID || !cb) {
		return false;
	}
	this._regIDs[pID] = new Object();
	this._regIDs[pID].cb = cb;
	if (arg) {
		this._regIDs[pID].arg = arg;
	}
	this.oDbg.log("registered " + pID, 3);
	return true;
};
JSJaCConnection.prototype._sendEmpty = function JSJaCSendEmpty() {
	var slot = this._getFreeSlot();
	this._req[slot] = this._setupRequest(true);
	this._req[slot].r.onload = function () {
		if (typeof (oCon) == "undefined" || !oCon) {
			return;
		}
		if (oCon._req[slot].r.readyState == 4) {
			oCon.oDbg.log("async recv: " + oCon._req[slot].r.responseText, 4);
			oCon._getStreamID(slot);
		}
	};
	if (typeof (this._req[slot].r.onerror) != "undefined") {
		this._req[slot].r.onerror = function (e) {
			if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
				return;
			}
			oCon.oDbg.log("XmlHttpRequest error", 1);
			return false;
		};
	}
	var reqstr = this._getRequestString();
	this.oDbg.log("sending: " + reqstr, 4);
	this._req[slot].r.send(reqstr);
};
JSJaCConnection.prototype._setStatus = function (status) {
	if (!status || status == "") {
		return;
	}
	if (status != this._status) {
		this._status = status;
		this._handleEvent("onstatuschanged", status);
		this._handleEvent("status_changed", status);
	}
};
JSJaCConnection.prototype._unregisterPID = function (pID) {
	if (!this._regIDs[pID]) {
		return false;
	}
	this._regIDs[pID] = null;
	this.oDbg.log("unregistered " + pID, 3);
	return true;
};
function JSJaCConsoleLogger(level) {
	this.level = level || 4;
	this.start = function () {
	};
	this.log = function (msg, level) {
		level = level || 0;
		if (level > this.level) {
			return;
		}
		if (typeof (console) == "undefined") {
			return;
		}
		try {
			switch (level) {
			  case 0:
				console.warn(msg);
				break;
			  case 1:
				console.error(msg);
				break;
			  case 2:
				console.info(msg);
				break;
			  case 4:
				console.debug(msg);
				break;
			  default:
				console.log(msg);
				break;
			}
		}
		catch (e) {
			try {
				console.log(msg);
			}
			catch (e) {
			}
		}
	};
	this.setLevel = function (level) {
		this.level = level;
		return this;
	};
	this.getLevel = function () {
		return this.level;
	};
}
function JSJaCCookie(name, value, secs) {
	if (window == this) {
		return new JSJaCCookie(name, value, secs);
	}
	this.name = name;
	this.value = value;
	this.expires = secs;
	this.write = function () {
		if (this.expires) {
			var date = new Date();
			date.setTime(date.getTime() + (this.expires * 1000));
			var expires = "; expires=" + date.toGMTString();
		} else {
			var expires = "";
		}
		document.cookie = this.getName() + "=" + this.getValue() + expires + "; path=/";
	};
	this.erase = function () {
		var c = new JSJaCCookie(this.getName(), "", -1);
		c.write();
	};
	this.getName = function () {
		return this.name;
	};
	this.setName = function (name) {
		this.name = name;
		return this;
	};
	this.getValue = function () {
		return this.value;
	};
	this.setValue = function (value) {
		this.value = value;
		return this;
	};
}
JSJaCCookie.read = function (name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(";");
	for (var i = 0; i < ca.length; i++) {
		var c = ca[i];
		while (c.charAt(0) == " ") {
			c = c.substring(1, c.length);
		}
		if (c.indexOf(nameEQ) == 0) {
			return new JSJaCCookie(name, c.substring(nameEQ.length, c.length));
		}
	}
	throw new JSJaCCookieException("Cookie not found");
};
JSJaCCookie.get = function (name) {
	return JSJaCCookie.read(name).getValue();
};
JSJaCCookie.remove = function (name) {
	JSJaCCookie.read(name).erase();
};
function JSJaCCookieException(msg) {
	this.message = msg;
	this.name = "CookieException";
}
function JSJaCError(code, type, condition) {
	var xmldoc = XmlDocument.create("error", "jsjac");
	xmldoc.documentElement.setAttribute("code", code);
	xmldoc.documentElement.setAttribute("type", type);
	xmldoc.documentElement.appendChild(xmldoc.createElement(condition)).setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
	return xmldoc.documentElement;
}
function JSJaCHttpBindingConnection(oArg) {
	this.base = JSJaCConnection;
	this.base(oArg);
	this._hold = JSJACHBC_MAX_HOLD;
	this._inactivity = 0;
	this._last_requests = new Object();
	this._last_rid = 0;
	this._min_polling = 0;
	this._pause = 0;
	this._wait = JSJACHBC_MAX_WAIT;
	this.connect = JSJaCHBCConnect;
	this.disconnect = JSJaCHBCDisconnect;
	this.inherit = JSJaCHBCInherit;
	this.isPolling = function () {
		return (this._hold == 0);
	};
	this.setPollInterval = function (timerval) {
		if (!timerval || isNaN(timerval)) {
			this.oDbg.log("Invalid timerval: " + timerval, 1);
			return -1;
		}
		if (!this.isPolling()) {
			this._timerval = 100;
		} else {
			if (this._min_polling && timerval < this._min_polling * 1000) {
				this._timerval = this._min_polling * 1000;
			} else {
				if (this._inactivity && timerval > this._inactivity * 1000) {
					this._timerval = this._inactivity * 1000;
				} else {
					this._timerval = timerval;
				}
			}
		}
		return this._timerval;
	};
	this._getRequestString = JSJaCHBCGetRequestString;
	this._getFreeSlot = function () {
		for (var i = 0; i < this._hold + 1; i++) {
			if (typeof (this._req[i]) == "undefined" || typeof (this._req[i].r) == "undefined" || this._req[i].r.readyState == 4) {
				return i;
			}
		}
		return -1;
	};
	this._getHold = function () {
		return this._hold;
	};
	this._getStreamID = JSJaCHBCGetStreamID;
	this._getSuspendVars = function () {
		return ("host,port,secure,_rid,_last_rid,_wait,_min_polling,_inactivity,_hold,_last_requests,_pause").split(",");
	};
	this._handleInitialResponse = JSJaCHBCHandleInitialResponse;
	this._prepareResponse = JSJaCHBCPrepareResponse;
	this._reInitStream = JSJaCHBCReInitStream;
	this._resume = function () {
		if (this._pause == 0 && this._rid >= this._last_rid) {
			this._rid = this._last_rid - 1;
		}
		this._process();
		this._inQto = setInterval("oCon._checkInQ();", JSJAC_CHECKINQUEUEINTERVAL);
		this._interval = setInterval("oCon._checkQueue()", JSJAC_CHECKQUEUEINTERVAL);
	};
	this._setHold = function (hold) {
		if (!hold || isNaN(hold) || hold < 0) {
			hold = 0;
		} else {
			if (hold > JSJACHBC_MAX_HOLD) {
				hold = JSJACHBC_MAX_HOLD;
			}
		}
		this._hold = hold;
		return this._hold;
	};
	this._setupRequest = JSJaCHBCSetupRequest;
	this._suspend = function () {
		if (this._pause == 0) {
			return;
		}
		var slot = this._getFreeSlot();
		this._req[slot] = this._setupRequest(false);
		var reqstr = "<body pause='" + this._pause + "' xmlns='http://jabber.org/protocol/httpbind' sid='" + this._sid + "' rid='" + this._rid + "'>";
		while (this._pQueue.length) {
			var curNode = this._pQueue[0];
			reqstr += curNode;
			this._pQueue = this._pQueue.slice(1, this._pQueue.length);
		}
		reqstr += "</body>";
		var abortTimerID = setTimeout("oCon._req[" + slot + "].r.abort();", 5000);
		this.oDbg.log("Disconnecting: " + reqstr, 4);
		this._req[slot].r.send(reqstr);
		clearTimeout(abortTimerID);
	};
}
JSJaCHttpBindingConnection.prototype = new JSJaCConnection();
function JSJaCHBCConnect(oArg) {
	this._setStatus("connecting");
	this.domain = oArg.domain || "localhost";
	this.username = oArg.username;
	this.resource = oArg.resource;
	this.pass = oArg.pass;
	this.register = oArg.register;
	this.email = oArg.email;
	this.familyname = oArg.familyname;
	this.givenname = oArg.givenname;
	this.sex = oArg.sex;
	this.companyname = oArg.companyname;
	this.duty = oArg.duty || "";
	this.orgid = oArg.orgid;
	this.oDbg.log("httpbase: " + this._httpbase + "domain:" + this.domain, 2);
	this.host = oArg.host || this.domain;
	this.port = oArg.port || 5222;
	this.authhost = oArg.authhost || this.domain;
	this.authtype = oArg.authtype || "sasl";
	if (oArg.secure) {
		this.secure = "true";
	} else {
		this.secure = "false";
	}
	this.jid = this.username + "@" + this.domain;
	this.fulljid = this.jid + "/" + this.resource;
	if (oArg.wait) {
		this._wait = oArg.wait;
	}
	if (oArg.xmllang && oArg.xmllang != "") {
		this._xmllang = oArg.xmllang;
	}
	this._rid = Math.round(100000.5 + (((900000.49999) - (100000.5)) * Math.random()));
	var slot = this._getFreeSlot();
	this._req[slot] = this._setupRequest(true);
	var reqstr = "<body hold='" + this._hold + "' xmlns='http://jabber.org/protocol/httpbind' to='" + this.authhost + "' wait='" + this._wait + "' rid='" + this._rid + "'";
	if (oArg.host || oArg.port) {
		reqstr += " route='xmpp:" + this.host + ":" + this.port + "'";
	}
	if (oArg.secure) {
		reqstr += " secure='" + this.secure + "'";
	}
	if (this._xmllang) {
		reqstr += " xml:lang='" + this._xmllang + "'";
	}
	if (JSJACHBC_USE_BOSH_VER) {
		reqstr += " ver='" + JSJACHBC_BOSH_VERSION + "'";
		reqstr += " xmpp:xmlns='urn:xmpp:xbosh'";
		reqstr += " xmpp:version='1.0'";
	}
	reqstr += "/>";
	this.oDbg.log(reqstr, 4);
	this._req[slot].r.onload = function () {
		if (typeof (oCon) == "undefined" || !oCon) {
			return;
		}
		if (oCon._req[slot].r.readyState == 4) {
			oCon.oDbg.log("async recv: " + oCon._req[slot].r.responseText, 4);
			oCon._handleInitialResponse(slot);
		}
	};
	if (typeof (this._req[slot].r.onerror) != "undefined") {
		this._req[slot].r.onerror = function (e) {
			if (typeof (oCon) == "undefined" || !oCon || !oCon.connected()) {
				return;
			}
			oCon.oDbg.log("XmlHttpRequest error", 1);
			return false;
		};
	}
	this._req[slot].r.send(reqstr);
}
function JSJaCHBCHandleInitialResponse(slot) {
	try {
		this.oDbg.log(this._req[slot].r.getAllResponseHeaders(), 4);
		this.oDbg.log(this._req[slot].r.responseText, 4);
	}
	catch (ex) {
		this.oDbg.log("No response", 4);
	}
	if (this._req[slot].r.status != 200 || !this._req[slot].r.responseXML) {
		if(isCancel){
			isCancel=false;
			return;
		}
		this.oDbg.log("initial response broken (status: " + this._req[slot].r.status + ")", 1);
		this._handleEvent("onerror", JSJaCError("503", "cancel", "service-unavailable"));
		return;
	}
	var body = this._req[slot].r.responseXML.documentElement;
	if (!body || body.tagName != "body" || body.namespaceURI != "http://jabber.org/protocol/httpbind") {
		if(isCancel){
			isCancel=false;
			return;
		}
		this.oDbg.log("no body element or incorrect body in initial response", 1);
		this._handleEvent("onerror", JSJaCError("500", "wait", "internal-service-error"));
		return;
	}
	if (body.getAttribute("type") == "terminate") {
		if(isCancel){
			isCancel=false;
			return;
		}
		if(document.getElementById("login_textDiv")){
			document.getElementById("login_div_1").style.display="";
			document.getElementById("login_div_2").style.display="none";
		}
		this.oDbg.log("invalid response:\n" + this._req[slot].r.responseText, 1);
		clearTimeout(this._timeout);
		this._connected = false;
		this.oDbg.log("Disconnected.", 1);
		this._handleEvent("ondisconnect");
		this._handleEvent("onerror", JSJaCError("503", "cancel", "service-unavailable"));
		return;
	}
	this._sid = body.getAttribute("sid");
	if(isCancel){
		isCancel=false;
		$um_obj("storage").cancelLog(this._sid);
		return;
	}
	this.oDbg.log("got sid: " + this._sid, 2);
	if (body.getAttribute("polling")) {
		this._min_polling = body.getAttribute("polling");
	}
	if (body.getAttribute("inactivity")) {
		this._inactivity = body.getAttribute("inactivity");
	}
	if (body.getAttribute("requests")) {
		this._setHold(body.getAttribute("requests") - 1);
	}
	this.oDbg.log("set hold to " + this._getHold(), 2);
	if (body.getAttribute("ver")) {
		this._bosh_version = body.getAttribute("ver");
	}
	if (body.getAttribute("maxpause")) {
		this._pause = Number.max(body.getAttribute("maxpause"), JSJACHBC_MAXPAUSE);
	}
	this.setPollInterval(this._timerval);
	this._connected = true;
	this._inQto = setInterval("oCon._checkInQ();", JSJAC_CHECKINQUEUEINTERVAL);
	this._interval = setInterval("oCon._checkQueue()", JSJAC_CHECKQUEUEINTERVAL);
	this._getStreamID(slot);
}
function JSJaCHBCGetStreamID(slot) {
	this.oDbg.log(this._req[slot].r.responseText, 4);
	if (!this._req[slot].r.responseXML || !this._req[slot].r.responseXML.documentElement) {
		this._handleEvent("onerror", JSJaCError("503", "cancel", "service-unavailable"));
		return;
	}
	var body = this._req[slot].r.responseXML.documentElement;
	if (body.getAttribute("authid")) {
		this.streamid = body.getAttribute("authid");
		this.oDbg.log("got streamid: " + this.streamid, 2);
	} else {
		this._timeout = setTimeout("oCon._sendEmpty()", this.getPollInterval());
		return;
	}
	this._timeout = setTimeout("oCon._process()", this.getPollInterval());
	this._parseStreamFeatures(body);
	if (this.register) {
		this._doInBandReg();
	} else {
		this._doAuth();
	}
}
function JSJaCHBCInherit(oArg) {
	this.domain = oArg.domain || "localhost";
	this.username = oArg.username;
	this.resource = oArg.resource;
	this._sid = oArg.sid;
	this._rid = oArg.rid;
	this._min_polling = oArg.polling;
	this._inactivity = oArg.inactivity;
	this._setHold(oArg.requests - 1);
	this.setPollInterval(this._timerval);
	if (oArg.wait) {
		this._wait = oArg.wait;
	}
	this._connected = true;
	this._handleEvent("onconnect");
	this._interval = setInterval("oCon._checkQueue()", JSJAC_CHECKQUEUEINTERVAL);
	this._inQto = setInterval("oCon._checkInQ();", JSJAC_CHECKINQUEUEINTERVAL);
	this._timeout = setTimeout("oCon._process()", this.getPollInterval());
}
function JSJaCHBCReInitStream(to, cb, arg) {
	oCon._reinit = true;
	eval("oCon." + cb + "(" + arg + ")");
}
function JSJaCHBCDisconnect() {
	this._setStatus("disconnecting");
	if (!this.connected()) {
		return;
	}
	this._connected = false;
	clearInterval(this._interval);
	clearInterval(this._inQto);
	if (this._timeout) {
		clearTimeout(this._timeout);
	}
	var slot = this._getFreeSlot();
	this._req[slot] = this._setupRequest(false);
	var reqstr = "<body type='terminate' xmlns='http://jabber.org/protocol/httpbind' sid='" + this._sid + "' rid='" + this._rid + "'";
	if (JSJAC_HAVEKEYS) {
		reqstr += " key='" + this._keys.getKey() + "'";
	}
	reqstr += ">";
	while (this._pQueue.length) {
		var curNode = this._pQueue[0];
		reqstr += curNode;
		this._pQueue = this._pQueue.slice(1, this._pQueue.length);
	}
	reqstr += "</body>";
	var abortTimerID = setTimeout("oCon._req[" + slot + "].r.abort();", 5000);
	this.oDbg.log("Disconnecting: " + reqstr, 4);
	this._req[slot].r.send(reqstr);
	clearTimeout(abortTimerID);
	try {
		JSJaCCookie.read("JSJaC_State").erase();
	}
	catch (e) {
	}
	oCon.oDbg.log("Disconnected: " + oCon._req[slot].r.responseText, 2);
	oCon._handleEvent("ondisconnect");
}
function JSJaCHBCSetupRequest(async) {
	var req = new Object();
	req.r = new FlashXMLHttpRequest();
	req.rid = ++this._rid;
	return req;
}
function fileSend(status,schedulebar,aimJid,fileName,fileSize){
	var up_td=document.getElementById("contact" + aimJid + "_up_schedule");
	var user = roster.getUserByJID(aimJid);
	if(status.indexOf("3")==0){
		var frag = user.cFrame.createElement("div");
		frag.innerHTML = "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;文件&nbsp;[" + fileName + "]&nbsp;发送成功</div>";
		user.cFrame.body.appendChild(frag.firstChild);
		var iq = new JSJaCIQ();
		iq.setIQ(aimJid, "result", "file_" + con._rid);
		var query = iq.setQuery('jabber:iq:umofflinefiles');
		var xmldoc = XmlDocument.create('body','jabber:iq:umofflinefiles');
		xmldoc.loadXML('<body xmlns=\"jabber:iq:umofflinefiles\"><type>301</type><result>true</result></body>');
		for (var i=0; i<xmldoc.documentElement.childNodes.length; i++){
			query.appendChild(xmldoc.firstChild.childNodes.item(i).cloneNode(true));
		}
		con.send(iq);
	}else if(status.indexOf("2")==0){
		var frag = user.cFrame.createElement("div");
		frag.innerHTML = "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;文件&nbsp;[" + fileName + "]&nbsp;发送失败</div>";
		user.cFrame.body.appendChild(frag.firstChild);
	}else if(status.indexOf("4")==0){
		var frag = user.cFrame.createElement("div");
		frag.innerHTML = "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;暂不支持大于25MB的文件，&nbsp;\"" + fileName + "\"&nbsp;[" + Number(fileSize/1048576).toFixed(2) + "MB]传输失败</div>";
		user.cFrame.body.appendChild(frag.firstChild);
	}else if(status.indexOf("1")==0){
		if(up_td.parentNode.style.display!=""){
			up_td.parentNode.style.display="";
		}
		up_td.innerHTML=schedulebar;
		return;
	}else if(status.indexOf("6")==0){
		var frag = user.cFrame.createElement("div");
		frag.innerHTML = "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;文件&nbsp;[" + fileName + "]&nbsp;终止发送</div>";
		user.cFrame.body.appendChild(frag.firstChild);
	}
	newMessageNotification("[" + aimJid + "]来消息啦...");
	if (autoPopup && (autoPopupAway || onlstat == "available" || onlstat == "chat")) {
		roster.openChat(aimJid);
		playSound("chat_recv");
	} else {
		if (focusWindows) {
			window.focus();
		}
		playSound("chat_queue");
		for (var i = 0; i < user.groups.length; i++) {
			if (user.groups[i].name != "临时好友") {
				if (roster.hiddenGroups[user.groups[i].name]) {
					fmd.images[user.groups[i].name + "Img"].src = arrow_right_blinking.src;
				}
			}
		}
	}
	uploading=false;
	up_td.parentNode.style.display="none";
}
function fileReceive(status,schedulebar,realfilename,strFileSize){
	var down_td=document.getElementById("contact" + fileDownload[realfilename][0] + "_down_schedule");
	var user = roster.getUserByJID(fileDownload[realfilename][0]);
	if(status==1){
		down_td.parentNode.style.display="";
		down_td.innerHTML=schedulebar;
		return;
	}else if(status==2){
		down_td.parentNode.style.display="none";
		dd.elements.shared_downDiv.moveTo((dd.getWndW()-310)/2, (dd.getWndH()-160)/2);
		FlashHelper.getFlash().height = 160;
		FlashHelper.getFlash().width = 310;
		document.getElementById("shared_downDiv").style.zIndex=10000;
		return;
	}else if(status==3){
		FlashHelper.getFlash().height = 1;
		FlashHelper.getFlash().width = 1;
		return;
	}else if(status==4){
		var iq = new JSJaCIQ();
		iq.setIQ(fileDownload[realfilename][0], "result", "file_" + con._rid);
		var query = iq.setQuery('jabber:iq:umofflinefiles');
		var xmldoc = XmlDocument.create('body','jabber:iq:umofflinefiles');
		xmldoc.loadXML('<body xmlns=\"jabber:iq:umofflinefiles\"><type>202</type><result>true</result><realfilename>' + realfilename + '</realfilename></body>');
		for (var i=0; i<xmldoc.documentElement.childNodes.length; i++){
			query.appendChild(xmldoc.firstChild.childNodes.item(i).cloneNode(true));
		}
		con.send(iq);
		user.fileMsg += "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;成功接收文件[" + fileDownload[realfilename][1] + "]大小[" + strFileSize + "]</div>";
		downloading=false;
	}else if(status==5){
		down_td.parentNode.style.display="none";
		FlashHelper.getFlash().height = 1;
		FlashHelper.getFlash().width = 1;
		user.fileMsg += "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;您取消了文件[" + fileDownload[realfilename][1] + "]的接收</div>";
		downloading=false;
	}else if(status==6){
		down_td.parentNode.style.display="none";
		FlashHelper.getFlash().height = 1;
		FlashHelper.getFlash().width = 1;
		user.fileMsg += "<div>&nbsp;<span style=\"color:blue;font-size:12px;font-family:Tahoma;font-style: normal;font-weight: normal; \" class=msgnick>&lt;" + htmlEnc(roster.nick) + "&gt;</span>&nbsp;接收文件[" + fileDownload[realfilename][1] + "]失败</div>";
		downloading=false;
	}
	if(user.fileMsg!=""){
		newMessageNotification("[" + user.name + "]来消息啦...");
		if (autoPopup && (autoPopupAway || onlstat == "available" || onlstat == "chat")) {
			roster.openChat(fileDownload[realfilename][0]);
			popMsgs(user);
			playSound("chat_recv");
		} else {
			if (focusWindows) {
				window.focus();
			}
			playSound("chat_queue");
			for (var i = 0; i < user.groups.length; i++) {
				if (user.groups[i].name != "临时好友") {
					if (roster.hiddenGroups[user.groups[i].name]) {
						fmd.images[user.groups[i].name + "Img"].src = arrow_right_blinking.src;
					}
				}
			}
		}
	}
	delete fileDownload[realfilename];
}
function stopSend(){
    $um_obj("fileUpload").stopSend();
}
function JSJaCHBCGetRequestString(raw) {
	raw = raw || "";
	var reqstr = "";
	if (this._rid <= this._last_rid && typeof (this._last_requests[this._rid]) != "undefined") {
		reqstr = this._last_requests[this._rid].xml;
	} else {
		var xml = "";
		while (this._pQueue.length) {
			var curNode = this._pQueue[0];
			xml += curNode;
			this._pQueue = this._pQueue.slice(1, this._pQueue.length);
		}
		reqstr = "<body rid='" + this._rid + "' sid='" + this._sid + "' xmlns='http://jabber.org/protocol/httpbind' ";
		if (this._reinit) {
			reqstr += "xmpp:restart='true' ";
			this._reinit = false;
		}
		if (xml != "" || raw != "") {
			reqstr += ">" + raw + xml + "</body>";
		} else {
			reqstr += "/>";
		}
		this._last_requests[this._rid] = new Object();
		this._last_requests[this._rid].xml = reqstr;
		this._last_rid = this._rid;
		for (var i in this._last_requests) {
			if (this._last_requests.hasOwnProperty(i) && i < this._rid - this._hold) {
				delete (this._last_requests[i]);
			}
		}
	}
	return reqstr;
}
function JSJaCHBCPrepareResponse(req) {
	if (!this.connected()) {
		return null;
	}
	if (!req) {
		return null;
	}
	var r = req.r;
	try {
		if (r.status == 404 || r.status == 403) {
			oCon._abort();
			return null;
		}
		if (r.status != 200 || !r.responseXML) {
			this._errcnt++;
			var errmsg = "invalid response (" + r.status + "):\n" + r.getAllResponseHeaders() + "\n" + r.responseText;
			if (!r.responseXML) {
				errmsg += "\nResponse failed to parse!";
			}
			this.oDbg.log(errmsg, 1);
			if (this._errcnt > JSJAC_ERR_COUNT) {
				oCon._abort();
				return null;
			}
			this.oDbg.log("repeating (" + this._errcnt + ")", 1);
			this._setStatus("proto_error_fallback");
			setTimeout("oCon._resume()", oCon.getPollInterval());
			return null;
		}
	}
	catch (e) {
		this.oDbg.log("XMLHttpRequest error: status not available", 1);
		return null;
	}
	var body = r.responseXML.documentElement;
	if (!body || body.tagName != "body" || body.namespaceURI != "http://jabber.org/protocol/httpbind") {
		this.oDbg.log("invalid response:\n" + r.responseText, 1);
		this._setStatus("internal_server_error");
		clearTimeout(this._timeout);
		clearInterval(this._interval);
		clearInterval(this._inQto);
		this._handleEvent("onerror", JSJaCError("500", "wait", "internal-server-error"));
		this._connected = false;
		this.oDbg.log("Disconnected.", 1);
		this._handleEvent("ondisconnect");
		return null;
	}
	if (typeof (req.rid) != "undefined" && this._last_requests[req.rid]) {
		if (this._last_requests[req.rid].handled) {
			this.oDbg.log("already handled " + req.rid, 2);
			return null;
		} else {
			this._last_requests[req.rid].handled = true;
		}
	}
	if (body.getAttribute("type") == "terminate") {
		this.oDbg.log("session terminated:\n" + r.responseText, 1);
		clearTimeout(this._timeout);
		clearInterval(this._interval);
		clearInterval(this._inQto);
		if (body.getAttribute("condition") == "remote-stream-error") {
			if (body.getElementsByTagName("conflict").length > 0) {
				this._setStatus("session-terminate-conflict");
			}
		}
		this._handleEvent("onerror", JSJaCError("503", "cancel", body.getAttribute("condition")));
		this._connected = false;
		this.oDbg.log("Disconnected.", 1);
		this._handleEvent("ondisconnect");
		return null;
	}
	this._errcnt = 0;
	return r.responseXML.documentElement;
}
var JSJACJID_FORBIDDEN = ["\"", " ", "&", "'", "/", ":", "<", ">", "@"];
function JSJaCJID(jid) {
	this._node = "";
	this._domain = "";
	this._resource = "";
	if (typeof (jid) == "string") {
		if (jid.indexOf("@") != -1) {
			this.setNode(jid.substring(0, jid.indexOf("@")));
			jid = jid.substring(jid.indexOf("@") + 1);
		}
		if (jid.indexOf("/") != -1) {
			this.setResource(jid.substring(jid.indexOf("/") + 1));
			jid = jid.substring(0, jid.indexOf("/"));
		}
		this.setDomain(jid);
	} else {
		this.setNode(jid.node);
		this.setDomain(jid.domain);
		this.setResource(jid.resource);
	}
}
JSJaCJID.prototype.getNode = function () {
	return this._node;
};
JSJaCJID.prototype.getDomain = function () {
	return this._domain;
};
JSJaCJID.prototype.getResource = function () {
	return this._resource;
};
JSJaCJID.prototype.setNode = function (node) {
	JSJaCJID._checkNodeName(node);
	this._node = node || "";
	return this;
};
JSJaCJID.prototype.setDomain = function (domain) {
	if (!domain || domain == "") {
		throw new JSJaCJIDInvalidException("domain name missing");
	}
	JSJaCJID._checkNodeName(domain);
	this._domain = domain;
	return this;
};
JSJaCJID.prototype.setResource = function (resource) {
	this._resource = resource || "";
	return this;
};
JSJaCJID.prototype.toString = function () {
	var jid = "";
	if (this.getNode() && this.getNode() != "") {
		jid = this.getNode() + "@";
	}
	jid += this.getDomain();
	if (this.getResource() && this.getResource() != "") {
		jid += "/" + this.getResource();
	}
	return jid;
};
JSJaCJID.prototype.removeResource = function () {
	return this.setResource();
};
JSJaCJID._checkNodeName = function (nodeprep) {
	if (!nodeprep || nodeprep == "") {
		return;
	}
	for (var i = 0; i < JSJACJID_FORBIDDEN.length; i++) {
		if (nodeprep.indexOf(JSJACJID_FORBIDDEN[i]) != -1) {
			throw new JSJaCJIDInvalidException("forbidden char in nodename: " + JSJACJID_FORBIDDEN[i]);
		}
	}
};
function JSJaCJIDInvalidException(message) {
	this.message = message;
	this.name = "JSJaCJIDInvalidException";
}
var JSJACPACKET_USE_XMLNS = false;
function JSJaCPacket(name) {
	this.name = name;
	if (typeof (JSJACPACKET_USE_XMLNS) != "undefined" && JSJACPACKET_USE_XMLNS) {
		this.doc = XmlDocument.create(name, "jabber:client");
	} else {
		this.doc = XmlDocument.create(name, "");
	}
}
JSJaCPacket.prototype.pType = function () {
	return this.name;
};
JSJaCPacket.prototype.getDoc = function () {
	return this.doc;
};
JSJaCPacket.prototype.getNode = function () {
	if (this.getDoc() && this.getDoc().documentElement) {
		return this.getDoc().documentElement;
	} else {
		return null;
	}
};
JSJaCPacket.prototype.setTo = function (to) {
	if (!to || to == "") {
		this.getNode().removeAttribute("to");
	} else {
		if (typeof (to) == "string") {
			this.getNode().setAttribute("to", to);
		} else {
			this.getNode().setAttribute("to", to.toString());
		}
	}
	return this;
};
JSJaCPacket.prototype.setFrom = function (from) {
	if (!from || from == "") {
		this.getNode().removeAttribute("from");
	} else {
		if (typeof (from) == "string") {
			this.getNode().setAttribute("from", from);
		} else {
			this.getNode().setAttribute("from", from.toString());
		}
	}
	return this;
};
JSJaCPacket.prototype.setID = function (id) {
	if (!id || id == "") {
		this.getNode().removeAttribute("id");
	} else {
		this.getNode().setAttribute("id", id);
	}
	return this;
};
JSJaCPacket.prototype.setType = function (type) {
	if (!type || type == "") {
		this.getNode().removeAttribute("type");
	} else {
		this.getNode().setAttribute("type", type);
	}
	return this;
};
JSJaCPacket.prototype.setXMLLang = function (xmllang) {
	if (!xmllang || xmllang == "") {
		this.getNode().removeAttribute("xml:lang");
	} else {
		this.getNode().setAttribute("xml:lang", xmllang);
	}
	return this;
};
JSJaCPacket.prototype.getTo = function () {
	return this.getNode().getAttribute("to");
};
JSJaCPacket.prototype.getFrom = function () {
	return this.getNode().getAttribute("from");
};
JSJaCPacket.prototype.getToJID = function () {
	return new JSJaCJID(this.getTo());
};
JSJaCPacket.prototype.getFromJID = function () {
	return new JSJaCJID(this.getFrom());
};
JSJaCPacket.prototype.getID = function () {
	return this.getNode().getAttribute("id");
};
JSJaCPacket.prototype.getType = function () {
	return this.getNode().getAttribute("type");
};
JSJaCPacket.prototype.getXMLLang = function () {
	return this.getNode().getAttribute("xml:lang");
};
JSJaCPacket.prototype.getXMLNS = function () {
	return this.getNode().namespaceURI;
};
JSJaCPacket.prototype.getChild = function (name, ns) {
	if (!this.getNode()) {
		return null;
	}
	name = name || "*";
	ns = ns || "*";
	if (this.getNode().getElementsByTagNameNS) {
		return this.getNode().getElementsByTagNameNS(ns, name).item(0);
	}
	var nodes = this.getNode().childNodes;
	for (var i = 0; i < nodes.length; i++) {
		if (nodes.item(i).nodeType != 1) {
			continue;
		}
		if (name != "*" && nodes.item(i).tagName != name) {
			continue;
		}
		if (ns != "*" && nodes.item(i).namespaceURI != ns) {
			continue;
		}
		return nodes.item(i);
	}
	return null;
};
JSJaCPacket.prototype.getChildVal = function (name, ns) {
	var node = this.getChild(name, ns);
	if (node && node.firstChild) {
		return node.firstChild.nodeValue;
	} else {
		return "";
	}
};
JSJaCPacket.prototype.clone = function () {
	return JSJaCPacket.wrapNode(this.getNode());
};
JSJaCPacket.prototype.errorReply = function (stanza_error) {
	var rPacket = this.clone();
	rPacket.setTo(this.getFrom());
	rPacket.setFrom();
	rPacket.setType("error");
	rPacket.appendNode("error", {code:stanza_error.code, type:stanza_error.type}, [[stanza_error.cond]]);
	return rPacket;
};
JSJaCPacket.prototype.xml = function () {
	if (this.getDoc().xml) {
		return this.getDoc().xml.replace(/(\s*$)/g, "");
	}
	var xml = (new XMLSerializer()).serializeToString(this.getNode());
	
	if (typeof (xml) != "undefined") {
		return xml;
	}
	
	return (new XMLSerializer()).serializeToString(this.doc);
};
JSJaCPacket.prototype._getAttribute = function (attr) {
	return this.getNode().getAttribute(attr);
};
JSJaCPacket.prototype._replaceNode = function (aNode) {
	for (var i = 0; i < aNode.attributes.length; i++) {
		if (aNode.attributes.item(i).nodeName != "xmlns") {
			this.getNode().setAttribute(aNode.attributes.item(i).nodeName, aNode.attributes.item(i).nodeValue);
		}
	}
	for (var i = 0; i < aNode.childNodes.length; i++) {
		if (this.getDoc().importNode) {
			this.getNode().appendChild(this.getDoc().importNode(aNode.childNodes.item(i), true));
		} else {
			this.getNode().appendChild(aNode.childNodes.item(i).cloneNode(true));
		}
	}
};
JSJaCPacket.prototype._setChildNode = function (nodeName, nodeValue) {
	var aNode = this.getChild(nodeName);
	var tNode = this.getDoc().createTextNode(nodeValue);
	if (aNode) {
		try {
			aNode.replaceChild(tNode, aNode.firstChild);
		}
		catch (e) {
		}
	} else {
		aNode = this.getNode().appendChild(this.getDoc().createElement(nodeName));
		aNode.appendChild(tNode);
	}
	return aNode;
};
JSJaCPacket.prototype.buildNode = function (elementName) {
	return JSJaCBuilder.buildNode(this.getDoc(), elementName, arguments[1], arguments[2]);
};
JSJaCPacket.prototype.appendNode = function (element) {
	if (typeof element == "object") {
		return this.getNode().appendChild(element);
	} else {
		return this.getNode().appendChild(this.buildNode(element, arguments[1], arguments[2]));
	}
};
function JSJaCPresence() {
	this.base = JSJaCPacket;
	this.base("presence");
}
JSJaCPresence.prototype = new JSJaCPacket;
JSJaCPresence.prototype.setStatus = function (status) {
	this._setChildNode("status", status);
	return this;
};
JSJaCPresence.prototype.setMind = function (mind) {
	this._setChildNode("mind", mind);
	return this;
};
JSJaCPresence.prototype.setShow = function (show) {
	this._setChildNode("show", show);
	return this;
};
JSJaCPresence.prototype.setPriority = function (prio) {
	this._setChildNode("priority", prio);
	return this;
};
JSJaCPresence.prototype.setPresence = function (show, status, prio) {
	if (show) {
		this.setShow(show);
	}
	if (status) {
		this.setStatus(status);
	}
	if (prio) {
		this.setPriority(prio);
	}
	return this;
};
JSJaCPresence.prototype.getStatus = function () {
	return this.getChildVal("status");
};
JSJaCPresence.prototype.getShow = function () {
	return this.getChildVal("show");
};
JSJaCPresence.prototype.getPriority = function () {
	return this.getChildVal("priority");
};
function JSJaCIQ() {
	this.base = JSJaCPacket;
	this.base("iq");
}
JSJaCIQ.prototype = new JSJaCPacket;
JSJaCIQ.prototype.setIQ = function (to, type, id) {
	if (to) {
		this.setTo(to);
	}
	if (type) {
		this.setType(type);
	}
	if (id) {
		this.setID(id);
	}
	return this;
};
JSJaCIQ.prototype.setQuery = function (xmlns) {
	var query;
	try {
		query = this.getDoc().createElementNS(xmlns, "query");
	}
	catch (e) {
		query = this.getDoc().createElement("query");
	}
	if (query && query.getAttribute("xmlns") != xmlns) {
		query.setAttribute("xmlns", xmlns);
	}
	this.getNode().appendChild(query);
	return query;
};
JSJaCIQ.prototype.getQuery = function () {
	return this.getNode().getElementsByTagName("query").item(0);
};
JSJaCIQ.prototype.getQueryXMLNS = function () {
	if (this.getQuery()) {
		return this.getQuery().namespaceURI;
	} else {
		return null;
	}
};
JSJaCIQ.prototype.reply = function (payload) {
	var rIQ = this.clone();
	rIQ.setTo(this.getFrom());
	rIQ.setType("result");
	if (payload) {
		if (typeof payload == "string") {
			rIQ.getChild.appendChild(rIQ.getDoc().loadXML(payload));
		} else {
			if (payload.constructor == Array) {
				var node = rIQ.getChild();
				for (var i = 0; i < payload.length; i++) {
					if (typeof payload[i] == "string") {
						node.appendChild(rIQ.getDoc().loadXML(payload[i]));
					} else {
						if (typeof payload[i] == "object") {
							node.appendChild(payload[i]);
						}
					}
				}
			} else {
				if (typeof payload == "object") {
					rIQ.getChild().appendChild(payload);
				}
			}
		}
	}
	return rIQ;
};
function JSJaCMessage() {
	this.base = JSJaCPacket;
	this.base("message");
}
JSJaCMessage.prototype = new JSJaCPacket;
JSJaCMessage.prototype.setBody = function (body) {
	this._setChildNode("body", body);
	return this;
};
JSJaCMessage.prototype.setSubject = function (subject) {
	this._setChildNode("subject", subject);
	return this;
};
JSJaCMessage.prototype.setThread = function (thread) {
	this._setChildNode("thread", thread);
	return this;
};
JSJaCMessage.prototype.getThread = function () {
	return this.getChildVal("thread");
};
JSJaCMessage.prototype.getBody = function () {
	return this.getChildVal("body");
};
JSJaCMessage.prototype.getSubject = function () {
	return this.getChildVal("subject");
};
JSJaCPacket.wrapNode = function (node) {
	var aNode;
	switch (node.nodeName.toLowerCase()) {
	  case "presence":
		aNode = new JSJaCPresence();
		break;
	  case "message":
		aNode = new JSJaCMessage();
		break;
	  case "iq":
		aNode = new JSJaCIQ();
		break;
	  default:
		return null;
	}
	aNode._replaceNode(node);
	return aNode;
};

